Example #1
0
static void
httpd_remove_connection(httpd_t *httpd, http_connection_t *connection)
{
	if (connection->request) {
		http_request_destroy(connection->request);
		connection->request = NULL;
	}
	httpd->callbacks.conn_destroy(connection->user_data);
	shutdown(connection->socket_fd, SHUT_WR);
	closesocket(connection->socket_fd);
	connection->connected = 0;
	httpd->open_connections--;
}
int test_parse_valid_method()
{
  printf("test_parse_valid_method - running\n");
  http_request* req;
  http_request_init(&req);
  char* data = "GET http://www.redd.it/hej/ HTTP/1.1\r\n";
  http_parse_method(req, data);
  assert(strcmp(http_methods[req->method], "GET") == 0);
  assert(req->version == HTTP_VERSION_1_1);
  assert(strcmp(req->search_path, "http://www.redd.it/hej/") == 0);
  http_request_destroy(req);
  printf("test_parse_valid_method - ok\n");
  return 0;
}
Example #3
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 #4
0
void http_disconnect(http_client_t *http_client)
{
    http_request_destroy(&http_client->request);
    http_response_destroy(&http_client->response);
    close_tcp(&http_client->connection);
}