From b7054096a4e58009d7eddbda083762883213f937 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Thu, 14 Jun 2007 00:09:32 +0000 Subject: extended API, setting content length automatically if needed --- README | 15 +++++++++++++++ src/daemon/daemon.c | 4 +++- src/daemon/daemontest.c | 1 + src/daemon/minimal_example.c | 2 +- src/daemon/response.c | 21 +++++++++++++++++++++ src/daemon/session.c | 41 +++++++++++++++++++++++++++++++++++------ src/include/microhttpd.h | 11 +++++++++++ 7 files changed, 87 insertions(+), 8 deletions(-) diff --git a/README b/README index ab45ad10..afcd9a53 100644 --- a/README +++ b/README @@ -27,6 +27,11 @@ session.c: - send proper error code back if headers are too long (investigate what we should do with those headers, read? give user control?) +- http 1.0 compatibility (if 1.0, force connection + close at the end!) + + + For IPv6: ========= @@ -41,3 +46,13 @@ microhttpd.h: - define appropriate APIs - everything else + +Other: +====== +- allow client to determine http 1.0 vs. 1.1 + (API extension) +- allow client to control size of input/output + buffers + + + diff --git a/src/daemon/daemon.c b/src/daemon/daemon.c index 24229793..657afb23 100644 --- a/src/daemon/daemon.c +++ b/src/daemon/daemon.c @@ -467,6 +467,7 @@ MHD_start_daemon(unsigned int options, strerror(errno)); return NULL; } + /* FIXME: setsockopt: SO_REUSEADDR? */ memset(&servaddr, 0, sizeof(struct sockaddr_in)); @@ -541,7 +542,8 @@ MHD_stop_daemon(struct MHD_Daemon * daemon) { close(daemon->connections->socket_fd); daemon->connections->socket_fd = -1; } - pthread_join(daemon->connections->pid, &unused); + if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) + pthread_join(daemon->connections->pid, &unused); MHD_cleanup_sessions(daemon); } diff --git a/src/daemon/daemontest.c b/src/daemon/daemontest.c index 923885b5..9e86e389 100644 --- a/src/daemon/daemontest.c +++ b/src/daemon/daemontest.c @@ -29,6 +29,7 @@ #include #include #include +#include static int testStartError() { struct MHD_Daemon * d; diff --git a/src/daemon/minimal_example.c b/src/daemon/minimal_example.c index 189c557e..009721d6 100644 --- a/src/daemon/minimal_example.c +++ b/src/daemon/minimal_example.c @@ -49,7 +49,7 @@ static int ahc_echo(void * cls, struct MHD_Response * response; int ret; - if (0 != strcmp(me, "GET")) + if (0 != strcmp(method, "GET")) return MHD_NO; /* unexpected method */ response = MHD_create_response_from_data(strlen(me), (void*) me, diff --git a/src/daemon/response.c b/src/daemon/response.c index 7fae9f90..0c4b1de4 100644 --- a/src/daemon/response.c +++ b/src/daemon/response.c @@ -125,6 +125,27 @@ MHD_get_response_headers(struct MHD_Response * response, } +/** + * Get a particular header from the response. + * + * @param key which header to get + * @return NULL if header does not exist + */ +const char * +MHD_get_response_header(struct MHD_Response * response, + const char * key) { + struct MHD_HTTP_Header * pos; + pos = response->first_header; + while (pos != NULL) { + if (0 == strcmp(key, + pos->header)) + return pos->value; + pos = pos->next; + } + return NULL; +} + + /** * Create a response object. The response object can be extended with * header information and then be used any number of times. diff --git a/src/daemon/session.c b/src/daemon/session.c index e3aa1241..9cba0d28 100644 --- a/src/daemon/session.c +++ b/src/daemon/session.c @@ -111,7 +111,7 @@ MHD_queue_response(struct MHD_Session * session, (response == NULL) || (session->response != NULL) || (session->bodyReceived == 0) || - (session->headers_received == 0) ) + (session->headersReceived == 0) ) return MHD_NO; MHD_increment_response_rc(response); session->response = response; @@ -131,13 +131,13 @@ MHD_session_get_fdset(struct MHD_Session * session, fd_set * write_fd_set, fd_set * except_fd_set, int * max_fd) { - if ( (session->headers_received == 0) || + if ( (session->headersReceived == 0) || (session->readLoc < session->read_buffer_size) ) FD_SET(session->socket_fd, read_fd_set); if (session->response != NULL) FD_SET(session->socket_fd, write_fd_set); if ( (session->socket_fd > *max_fd) && - ( (session->headers_received == 0) || + ( (session->headersReceived == 0) || (session->readLoc < session->read_buffer_size) || (session->response != NULL) ) ) *max_fd = session->socket_fd; @@ -310,7 +310,7 @@ MHD_call_session_handler(struct MHD_Session * session) { struct MHD_Access_Handler * ah; unsigned int processed; - if (session->headers_received == 0) + if (session->headersReceived == 0) abort(); /* bad timing... */ ah = MHD_find_access_handler(session); processed = session->readLoc; @@ -356,7 +356,7 @@ MHD_session_handle_read(struct MHD_Session * session) { if ( (session->readLoc >= session->read_buffer_size) && - (session->headers_received == 0) ) { + (session->headersReceived == 0) ) { /* need to grow read buffer */ tmp = malloc(session->read_buffer_size * 2 + MHD_MAX_BUF_SIZE); memcpy(tmp, @@ -404,6 +404,34 @@ MHD_session_handle_read(struct MHD_Session * session) { return MHD_YES; } +/** + * Check if we need to set some additional headers + * for http-compiliance. + */ +static void +MHD_add_extra_headers(struct MHD_Session * session) { + const char * have; + char buf[128]; + + if (session->response->total_size == -1) { + have = MHD_get_response_header(session->response, + "Connection"); + if (have == NULL) + MHD_add_response_header(session->response, + "Connection", + "close"); + } else if (NULL == MHD_get_response_header(session->response, + "Content-length")) { + snprintf(buf, + 128, + "%llu", + (unsigned long long) session->response->total_size); + MHD_add_response_header(session->response, + "Content-length", + buf); + } +} + /** * Allocate the session's write buffer and * fill it with all of the headers from the @@ -417,6 +445,7 @@ MHD_build_header_response(struct MHD_Session * session) { char code[32]; char * data; + MHD_add_extra_headers(session); sprintf(code, "HTTP/1.1 %u\r\n", session->responseCode); @@ -551,7 +580,7 @@ MHD_session_handle_write(struct MHD_Session * session) { abort(); /* internal error */ if (session->messagePos == response->data_size) { if ( (session->bodyReceived == 0) || - (session->headers_received == 0) ) + (session->headersReceived == 0) ) abort(); /* internal error */ MHD_destroy_response(response); session->responseCode = 0; diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h index cb2e280a..d0b1b5dc 100644 --- a/src/include/microhttpd.h +++ b/src/include/microhttpd.h @@ -507,6 +507,17 @@ MHD_get_response_headers(struct MHD_Response * response, void * iterator_cls); +/** + * Get a particular header from the response. + * + * @param key which header to get + * @return NULL if header does not exist + */ +const char * +MHD_get_response_header(struct MHD_Response * response, + const char * key); + + #if 0 /* keep Emacsens' auto-indent happy */ { #endif -- cgit v1.2.3