Example #1
0
static THREAD_RETVAL
httpd_thread(void *arg)
{
	httpd_t *httpd = arg;
	char buffer[1024];
	int i;

	assert(httpd);

	while (1) {
		fd_set rfds;
		struct timeval tv;
		int nfds=0;
		int ret;

		MUTEX_LOCK(httpd->run_mutex);
		if (!httpd->running) {
			MUTEX_UNLOCK(httpd->run_mutex);
			break;
		}
		MUTEX_UNLOCK(httpd->run_mutex);

		/* Set timeout value to 5ms */
		tv.tv_sec = 1;
		tv.tv_usec = 5000;

		/* Get the correct nfds value and set rfds */
		FD_ZERO(&rfds);
		if (httpd->open_connections < httpd->max_connections) {
			FD_SET(httpd->server_fd4, &rfds);
			nfds = httpd->server_fd4+1;
			if (httpd->server_fd6 != -1) {
				FD_SET(httpd->server_fd6, &rfds);
				if (nfds <= httpd->server_fd6) {
					nfds = httpd->server_fd6+1;
				}
			}
		}
		for (i=0; i<httpd->max_connections; i++) {
			int socket_fd;
			if (!httpd->connections[i].connected) {
				continue;
			}
			socket_fd = httpd->connections[i].socket_fd;
			FD_SET(socket_fd, &rfds);
			if (nfds <= socket_fd) {
				nfds = socket_fd+1;
			}
		}

		ret = select(nfds, &rfds, NULL, NULL, &tv);
		if (ret == 0) {
			/* Timeout happened */
			continue;
		} else if (ret == -1) {
			/* FIXME: Error happened */
			logger_log(httpd->logger, LOGGER_INFO, "Error in select");
			break;
		}

		if (FD_ISSET(httpd->server_fd4, &rfds)) {
			ret = httpd_accept_connection(httpd, httpd->server_fd4, 0);
			if (ret == -1) {
				break;
			} else if (ret == 0) {
				continue;
			}
		}
		if (httpd->server_fd6 != -1 && FD_ISSET(httpd->server_fd6, &rfds)) {
			ret = httpd_accept_connection(httpd, httpd->server_fd6, 1);
			if (ret == -1) {
				break;
			} else if (ret == 0) {
				continue;
			}
		}
		for (i=0; i<httpd->max_connections; i++) {
			http_connection_t *connection = &httpd->connections[i];

			if (!connection->connected) {
				continue;
			}
			if (!FD_ISSET(connection->socket_fd, &rfds)) {
				continue;
			}

			/* If not in the middle of request, allocate one */
			if (!connection->request) {
				connection->request = http_request_init(httpd->use_rtsp);
				assert(connection->request);
			}

			logger_log(httpd->logger, LOGGER_DEBUG, "Receiving on socket %d", connection->socket_fd);
			ret = recv(connection->socket_fd, buffer, sizeof(buffer), 0);
			if (ret == 0) {
				logger_log(httpd->logger, LOGGER_INFO, "Connection closed for socket %d", connection->socket_fd);
				httpd_remove_connection(httpd, connection);
				continue;
			}

			/* Parse HTTP request from data read from connection */
			http_request_add_data(connection->request, buffer, ret);
			if (http_request_has_error(connection->request)) {
				logger_log(httpd->logger, LOGGER_INFO, "Error in parsing: %s", http_request_get_error_name(connection->request));
				httpd_remove_connection(httpd, connection);
				continue;
			}

			/* If request is finished, process and deallocate */
			if (http_request_is_complete(connection->request)) {
				http_response_t *response = NULL;

				httpd->callbacks.conn_request(connection->user_data, connection->request, &response);
				http_request_destroy(connection->request);
				connection->request = NULL;

				if (response) {
					const char *data;
					int datalen;
					int written;
					int ret;

					/* Get response data and datalen */
					data = http_response_get_data(response, &datalen);

					written = 0;
					while (written < datalen) {
						ret = send(connection->socket_fd, data+written, datalen-written, 0);
						if (ret == -1) {
							/* FIXME: Error happened */
							logger_log(httpd->logger, LOGGER_INFO, "Error in sending data");
							break;
						}
						written += ret;
					}
				} else {
					logger_log(httpd->logger, LOGGER_INFO, "Didn't get response");
				}
				http_response_destroy(response);
			}
		}
	}

	/* Remove all connections that are still connected */
	for (i=0; i<httpd->max_connections; i++) {
		http_connection_t *connection = &httpd->connections[i];

		if (!connection->connected) {
			continue;
		}
		logger_log(httpd->logger, LOGGER_INFO, "Removing connection for socket %d", connection->socket_fd);
		httpd_remove_connection(httpd, connection);
	}

	logger_log(httpd->logger, LOGGER_INFO, "Exiting HTTP thread");

	return 0;
}
Example #2
0
File: raop.c Project: viettd56/SA
                printf("fh == 3\n");

                data = (char *) malloc(12 + 20);
                length_res = 12 + 20;
                memcpy(data, fply_4, 12);
                memcpy(data + 12, payload + datalen - 20, 20);
            }

            http_response_add_header(res, "Content-Type", "application/octet-stream");
            http_response_add_header(res, "Server", "AirTunes/110.92");
        }
    }
    int i;
    http_response_finish(res, data, length_res);

    printf("%s\n", http_response_get_data(res, &i));

    logger_log(conn->raop->logger, LOGGER_DEBUG, "Handled request %s with URL %s", method, http_request_get_url(request));
    *response = res;
}

static void
conn_destroy(void *ptr)
{
    raop_conn_t *conn = ptr;

    if (conn->raop_rtp)
    {
        /* This is done in case TEARDOWN was not called */
        raop_rtp_destroy(conn->raop_rtp);
    }