From 4884490319a3d0b9f36474412882130529f08078 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Mon, 9 Jul 2007 03:20:40 +0000 Subject: stuff --- src/daemon/Makefile.am | 4 +- src/daemon/daemon.c | 76 ++++----- src/daemon/session.c | 434 +++++++++++++++++++++++------------------------ src/daemon/session.h | 20 +-- src/include/microhttpd.h | 65 ++++--- 5 files changed, 309 insertions(+), 290 deletions(-) (limited to 'src') diff --git a/src/daemon/Makefile.am b/src/daemon/Makefile.am index a948c667..5ce824cc 100644 --- a/src/daemon/Makefile.am +++ b/src/daemon/Makefile.am @@ -8,11 +8,11 @@ lib_LTLIBRARIES = \ libmicrohttpd_la_LDFLAGS = \ -export-dynamic -version-info 0:0:0 libmicrohttpd_la_SOURCES = \ + connection.c connection.h \ daemon.c \ internal.c internal.h \ plibc.h \ - response.c response.h \ - session.c session.h + response.c response.h # example programs diff --git a/src/daemon/daemon.c b/src/daemon/daemon.c index 379e3cf9..8b4d25dd 100644 --- a/src/daemon/daemon.c +++ b/src/daemon/daemon.c @@ -27,7 +27,7 @@ #include "internal.h" #include "response.h" -#include "session.h" +#include "connection.h" #define MHD_MAX_CONNECTIONS FD_SETSIZE -4 @@ -120,7 +120,7 @@ MHD_get_fdset(struct MHD_Daemon * daemon, fd_set * write_fd_set, fd_set * except_fd_set, int * max_fd) { - struct MHD_Session * pos; + struct MHD_Connection * pos; if ( (daemon == NULL) || (read_fd_set == NULL) || @@ -135,7 +135,7 @@ MHD_get_fdset(struct MHD_Daemon * daemon, *max_fd = daemon->socket_fd; pos = daemon->connections; while (pos != NULL) { - if (MHD_YES != MHD_session_get_fdset(pos, + if (MHD_YES != MHD_connection_get_fdset(pos, read_fd_set, write_fd_set, except_fd_set, @@ -153,7 +153,7 @@ MHD_get_fdset(struct MHD_Daemon * daemon, */ static void * MHD_handle_connection(void * data) { - struct MHD_Session * con = data; + struct MHD_Connection * con = data; int num_ready; fd_set rs; fd_set ws; @@ -168,7 +168,7 @@ MHD_handle_connection(void * data) { FD_ZERO(&ws); FD_ZERO(&es); max = 0; - MHD_session_get_fdset(con, + MHD_connection_get_fdset(con, &rs, &ws, &es, @@ -184,14 +184,14 @@ MHD_handle_connection(void * data) { break; } if ( ( (FD_ISSET(con->socket_fd, &rs)) && - (MHD_YES != MHD_session_handle_read(con)) ) || + (MHD_YES != MHD_connection_handle_read(con)) ) || ( (con->socket_fd != -1) && (FD_ISSET(con->socket_fd, &ws)) && - (MHD_YES != MHD_session_handle_write(con)) ) ) + (MHD_YES != MHD_connection_handle_write(con)) ) ) break; if ( (con->headersReceived == 1) && (con->response == NULL) ) - MHD_call_session_handler(con); + MHD_call_connection_handler(con); } if (con->socket_fd != -1) { CLOSE(con->socket_fd); @@ -202,13 +202,13 @@ MHD_handle_connection(void * data) { /** - * Accept an incoming connection and create the MHD_Session object for + * Accept an incoming connection and create the MHD_Connection object for * it. This function also enforces policy by way of checking with the * accept policy callback. */ static int MHD_accept_connection(struct MHD_Daemon * daemon) { - struct MHD_Session * session; + struct MHD_Connection * connection; struct sockaddr addr; socklen_t addrlen; int s; @@ -233,50 +233,50 @@ MHD_accept_connection(struct MHD_Daemon * daemon) { CLOSE(s); return MHD_YES; } - session = malloc(sizeof(struct MHD_Session)); - memset(session, + connection = malloc(sizeof(struct MHD_Connection)); + memset(connection, 0, - sizeof(struct MHD_Session)); - session->addr = malloc(addrlen); - memcpy(session->addr, + sizeof(struct MHD_Connection)); + connection->addr = malloc(addrlen); + memcpy(connection->addr, &addr, addrlen); - session->addr_len = addrlen; - session->socket_fd = s; - session->daemon = daemon; + connection->addr_len = addrlen; + connection->socket_fd = s; + connection->daemon = daemon; if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION) ) && - (0 != pthread_create(&session->pid, + (0 != pthread_create(&connection->pid, NULL, &MHD_handle_connection, - session)) ) { + connection)) ) { MHD_DLOG(daemon, "Failed to create a thread: %s\n", STRERROR(errno)); - free(session->addr); + free(connection->addr); CLOSE(s); - free(session); + free(connection); return MHD_NO; } - session->next = daemon->connections; - daemon->connections = session; + connection->next = daemon->connections; + daemon->connections = connection; return MHD_YES; } /** - * Free resources associated with all closed sessions. - * (destroy responses, free buffers, etc.). A session + * Free resources associated with all closed connections. + * (destroy responses, free buffers, etc.). A connection * is known to be closed if the socket_fd is -1. * - * Also performs session actions that need to be run - * even if the session is not selectable (such as + * Also performs connection actions that need to be run + * even if the connection is not selectable (such as * calling the application again with upload data when * the upload data buffer is full). */ static void -MHD_cleanup_sessions(struct MHD_Daemon * daemon) { - struct MHD_Session * pos; - struct MHD_Session * prev; +MHD_cleanup_connections(struct MHD_Daemon * daemon) { + struct MHD_Connection * pos; + struct MHD_Connection * prev; struct MHD_HTTP_Header * hpos; void * unused; @@ -320,7 +320,7 @@ MHD_cleanup_sessions(struct MHD_Daemon * daemon) { if ( (pos->headersReceived == 1) && (pos->response == NULL) ) - MHD_call_session_handler(pos); + MHD_call_connection_handler(pos); prev = pos; pos = pos->next; @@ -337,7 +337,7 @@ MHD_cleanup_sessions(struct MHD_Daemon * daemon) { static int MHD_select(struct MHD_Daemon * daemon, int may_block) { - struct MHD_Session * pos; + struct MHD_Connection * pos; int num_ready; fd_set rs; fd_set ws; @@ -397,9 +397,9 @@ MHD_select(struct MHD_Daemon * daemon, continue; } if (FD_ISSET(ds, &rs)) - MHD_session_handle_read(pos); + MHD_connection_handle_read(pos); if (FD_ISSET(ds, &ws)) - MHD_session_handle_write(pos); + MHD_connection_handle_write(pos); pos = pos->next; } } @@ -424,7 +424,7 @@ MHD_run(struct MHD_Daemon * daemon) { (0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) ) return MHD_NO; MHD_select(daemon, MHD_NO); - MHD_cleanup_sessions(daemon); + MHD_cleanup_connections(daemon); return MHD_YES; } @@ -438,7 +438,7 @@ MHD_select_thread(void * cls) { struct MHD_Daemon * daemon = cls; while (daemon->shutdown == 0) { MHD_select(daemon, MHD_YES); - MHD_cleanup_sessions(daemon); + MHD_cleanup_connections(daemon); } return NULL; } @@ -559,7 +559,7 @@ MHD_stop_daemon(struct MHD_Daemon * daemon) { CLOSE(daemon->connections->socket_fd); daemon->connections->socket_fd = -1; } - MHD_cleanup_sessions(daemon); + MHD_cleanup_connections(daemon); } free(daemon); } diff --git a/src/daemon/session.c b/src/daemon/session.c index 48f88868..6b82f9e7 100644 --- a/src/daemon/session.c +++ b/src/daemon/session.c @@ -19,14 +19,14 @@ */ /** - * @file session.c - * @brief Methods for managing sessions + * @file connection.c + * @brief Methods for managing connections * @author Daniel Pittman * @author Christian Grothoff */ #include "internal.h" -#include "session.h" +#include "connection.h" #include "response.h" @@ -39,17 +39,17 @@ * @return number of entries iterated over */ int -MHD_get_session_values(struct MHD_Session * session, +MHD_get_connection_values(struct MHD_Connection * connection, enum MHD_ValueKind kind, MHD_KeyValueIterator iterator, void * iterator_cls) { int ret; struct MHD_HTTP_Header * pos; - if (session == NULL) + if (connection == NULL) return -1; ret = 0; - pos = session->headers_received; + pos = connection->headers_received; while (pos != NULL) { if (0 != (pos->kind & kind)) { ret++; @@ -74,14 +74,14 @@ MHD_get_session_values(struct MHD_Session * session, * @return NULL if no such item was found */ const char * -MHD_lookup_session_value(struct MHD_Session * session, +MHD_lookup_connection_value(struct MHD_Connection * connection, enum MHD_ValueKind kind, const char * key) { struct MHD_HTTP_Header * pos; - if (session == NULL) + if (connection == NULL) return NULL; - pos = session->headers_received; + pos = connection->headers_received; while (pos != NULL) { if ( (0 != (pos->kind & kind)) && (0 == strcasecmp(key, @@ -96,55 +96,55 @@ MHD_lookup_session_value(struct MHD_Session * session, * Queue a response to be transmitted to the client (as soon as * possible). * - * @param session the session identifying the client + * @param connection the connection identifying the client * @param status_code HTTP status code (i.e. 200 for OK) * @param response response to transmit * @return MHD_NO on error (i.e. reply already sent), * MHD_YES on success or if message has been queued */ int -MHD_queue_response(struct MHD_Session * session, +MHD_queue_response(struct MHD_Connection * connection, unsigned int status_code, struct MHD_Response * response) { - if ( (session == NULL) || + if ( (connection == NULL) || (response == NULL) || - (session->response != NULL) || - (session->bodyReceived == 0) || - (session->headersReceived == 0) ) + (connection->response != NULL) || + (connection->bodyReceived == 0) || + (connection->headersReceived == 0) ) return MHD_NO; MHD_increment_response_rc(response); - session->response = response; - session->responseCode = status_code; + connection->response = response; + connection->responseCode = status_code; return MHD_YES; } /** - * Obtain the select sets for this session + * Obtain the select sets for this connection * * @return MHD_YES on success */ int -MHD_session_get_fdset(struct MHD_Session * session, +MHD_connection_get_fdset(struct MHD_Connection * connection, fd_set * read_fd_set, fd_set * write_fd_set, fd_set * except_fd_set, int * max_fd) { int fd; - fd = session->socket_fd; + fd = connection->socket_fd; if (fd == -1) return MHD_YES; - if ( (session->read_close == 0) && - ( (session->headersReceived == 0) || - (session->readLoc < session->read_buffer_size) ) ) + if ( (connection->read_close == 0) && + ( (connection->headersReceived == 0) || + (connection->readLoc < connection->read_buffer_size) ) ) FD_SET(fd, read_fd_set); - if (session->response != NULL) + if (connection->response != NULL) FD_SET(fd, write_fd_set); if ( (fd > *max_fd) && - ( (session->headersReceived == 0) || - (session->readLoc < session->read_buffer_size) || - (session->response != NULL) ) ) + ( (connection->headersReceived == 0) || + (connection->readLoc < connection->read_buffer_size) || + (connection->response != NULL) ) ) *max_fd = fd; return MHD_YES; } @@ -158,39 +158,39 @@ MHD_session_get_fdset(struct MHD_Session * session, * return NULL. Otherwise return a copy of the line. */ static char * -MHD_get_next_header_line(struct MHD_Session * session) { +MHD_get_next_header_line(struct MHD_Connection * connection) { char * rbuf; size_t pos; size_t start; - if (session->readLoc == 0) + if (connection->readLoc == 0) return NULL; start = 0; pos = 0; - rbuf = session->read_buffer; - while ( (pos < session->readLoc - 1) && + rbuf = connection->read_buffer; + while ( (pos < connection->readLoc - 1) && (rbuf[pos] != '\r') && (rbuf[pos] != '\n') ) pos++; - if (pos == session->readLoc - 1) { + if (pos == connection->readLoc - 1) { /* not found, consider growing... */ - if (session->readLoc == session->read_buffer_size) { + if (connection->readLoc == connection->read_buffer_size) { /* grow buffer to read larger header or die... */ - if (session->read_buffer_size < 4 * MHD_MAX_BUF_SIZE) { - rbuf = malloc(session->read_buffer_size * 2); + if (connection->read_buffer_size < 4 * MHD_MAX_BUF_SIZE) { + rbuf = malloc(connection->read_buffer_size * 2); memcpy(rbuf, - session->read_buffer, - session->readLoc); - free(session->read_buffer); - session->read_buffer = rbuf; - session->read_buffer_size *= 2; + connection->read_buffer, + connection->readLoc); + free(connection->read_buffer); + connection->read_buffer = rbuf; + connection->read_buffer_size *= 2; } else { /* die, header far too long to be reasonable */ - MHD_DLOG(session->daemon, + MHD_DLOG(connection->daemon, "Received excessively long header line (>%u), closing connection.\n", 4 * MHD_MAX_BUF_SIZE); - CLOSE(session->socket_fd); - session->socket_fd = -1; + CLOSE(connection->socket_fd); + connection->socket_fd = -1; } } return NULL; @@ -198,33 +198,33 @@ MHD_get_next_header_line(struct MHD_Session * session) { /* found, check if we have proper CRLF */ rbuf = malloc(pos + 1); memcpy(rbuf, - session->read_buffer, + connection->read_buffer, pos); rbuf[pos] = '\0'; - if ( (session->read_buffer[pos] == '\r') && - (session->read_buffer[pos+1] == '\n') ) + if ( (connection->read_buffer[pos] == '\r') && + (connection->read_buffer[pos+1] == '\n') ) pos++; /* skip both r and n */ pos++; - memmove(session->read_buffer, - &session->read_buffer[pos], - session->readLoc - pos); - session->readLoc -= pos; + memmove(connection->read_buffer, + &connection->read_buffer[pos], + connection->readLoc - pos); + connection->readLoc -= pos; return rbuf; } static void -MHD_session_add_header(struct MHD_Session * session, +MHD_connection_add_header(struct MHD_Connection * connection, const char * key, const char * value, enum MHD_ValueKind kind) { struct MHD_HTTP_Header * hdr; hdr = malloc(sizeof(struct MHD_HTTP_Header)); - hdr->next = session->headers_received; + hdr->next = connection->headers_received; hdr->header = strdup(key); hdr->value = strdup(value); hdr->kind = kind; - session->headers_received = hdr; + connection->headers_received = hdr; } /** @@ -254,7 +254,7 @@ MHD_http_unescape(char * val) { } static void -MHD_parse_arguments(struct MHD_Session * session, +MHD_parse_arguments(struct MHD_Connection * connection, char * args) { char * equals; char * amper; @@ -272,7 +272,7 @@ MHD_parse_arguments(struct MHD_Session * session, } MHD_http_unescape(args); MHD_http_unescape(equals); - MHD_session_add_header(session, + MHD_connection_add_header(connection, args, equals, MHD_GET_ARGUMENT_KIND); @@ -284,7 +284,7 @@ MHD_parse_arguments(struct MHD_Session * session, * Parse the cookie header (see RFC 2109). */ static void -MHD_parse_cookie_header(struct MHD_Session * session) { +MHD_parse_cookie_header(struct MHD_Connection * connection) { const char * hdr; char * cpy; char * pos; @@ -292,7 +292,7 @@ MHD_parse_cookie_header(struct MHD_Session * session) { char * equals; int quotes; - hdr = MHD_lookup_session_value(session, + hdr = MHD_lookup_connection_value(connection, MHD_HEADER_KIND, "Cookie"); if (hdr == NULL) @@ -327,7 +327,7 @@ MHD_parse_cookie_header(struct MHD_Session * session) { equals[strlen(equals)-1] = '\0'; equals++; } - MHD_session_add_header(session, + MHD_connection_add_header(connection, pos, equals, MHD_COOKIE_KIND); @@ -338,7 +338,7 @@ MHD_parse_cookie_header(struct MHD_Session * session) { /** - * This function is designed to parse the input buffer of a given session. + * This function is designed to parse the input buffer of a given connection. * * Once the header is complete, it should have set the * headers_received, url and method values and set @@ -348,7 +348,7 @@ MHD_parse_cookie_header(struct MHD_Session * session) { * size of the body is unknown, it should be set to -1. */ static void -MHD_parse_session_headers(struct MHD_Session * session) { +MHD_parse_connection_headers(struct MHD_Connection * connection) { char * last; char * line; char * colon; @@ -359,10 +359,10 @@ MHD_parse_session_headers(struct MHD_Session * session) { const char * clen; unsigned long long cval; - if (session->bodyReceived == 1) + if (connection->bodyReceived == 1) abort(); last = NULL; - while (NULL != (line = MHD_get_next_header_line(session))) { + while (NULL != (line = MHD_get_next_header_line(connection))) { if (last != NULL) { if ( (line[0] == ' ') || (line[0] == '\t') ) { @@ -373,11 +373,11 @@ MHD_parse_session_headers(struct MHD_Session * session) { free(line); free(last); last = NULL; - MHD_DLOG(session->daemon, + MHD_DLOG(connection->daemon, "Received excessively long header line (>%u), closing connection.\n", 4 * MHD_MAX_BUF_SIZE); - CLOSE(session->socket_fd); - session->socket_fd = -1; + CLOSE(connection->socket_fd); + connection->socket_fd = -1; break; } tmp = malloc(strlen(line) + strlen(last) + 1); @@ -392,7 +392,7 @@ MHD_parse_session_headers(struct MHD_Session * session) { free(line); continue; /* possibly more than 2 lines... */ } else { - MHD_session_add_header(session, + MHD_connection_add_header(connection, last, colon, MHD_HEADER_KIND); @@ -400,13 +400,13 @@ MHD_parse_session_headers(struct MHD_Session * session) { last = NULL; } } - if (session->url == NULL) { + if (connection->url == NULL) { /* line must be request line */ uri = strstr(line, " "); if (uri == NULL) goto DIE; uri[0] = '\0'; - session->method = strdup(line); + connection->method = strdup(line); uri++; httpType = strstr(uri, " "); if (httpType != NULL) { @@ -417,14 +417,14 @@ MHD_parse_session_headers(struct MHD_Session * session) { if (args != NULL) { args[0] = '\0'; args++; - MHD_parse_arguments(session, + MHD_parse_arguments(connection, args); } - session->url = strdup(uri); + connection->url = strdup(uri); if (httpType == NULL) - session->version = strdup(""); + connection->version = strdup(""); else - session->version = strdup(httpType); + connection->version = strdup(httpType); free(line); continue; } @@ -432,31 +432,31 @@ MHD_parse_session_headers(struct MHD_Session * session) { if (strlen(line) == 0) { free(line); /* end of header */ - session->headersReceived = 1; - clen = MHD_lookup_session_value(session, + connection->headersReceived = 1; + clen = MHD_lookup_connection_value(connection, MHD_HEADER_KIND, "Content-Length"); if (clen != NULL) { if (1 != sscanf(clen, "%llu", &cval)) { - MHD_DLOG(session->daemon, + MHD_DLOG(connection->daemon, "Failed to parse Content-Length header `%s', closing connection.\n", clen); goto DIE; } - session->uploadSize = cval; - session->bodyReceived = cval == 0 ? 1 : 0; + connection->uploadSize = cval; + connection->bodyReceived = cval == 0 ? 1 : 0; } else { - if (NULL == MHD_lookup_session_value(session, + if (NULL == MHD_lookup_connection_value(connection, MHD_HEADER_KIND, "Transfer-Encoding")) { /* this request does not have a body */ - session->uploadSize = 0; - session->bodyReceived = 1; + connection->uploadSize = 0; + connection->bodyReceived = 1; } else { - session->uploadSize = -1; /* unknown size */ - session->bodyReceived = 0; + connection->uploadSize = -1; /* unknown size */ + connection->bodyReceived = 0; } } break; @@ -465,7 +465,7 @@ MHD_parse_session_headers(struct MHD_Session * session) { colon = strstr(line, ":"); if (colon == NULL) { /* error in header line, die hard */ - MHD_DLOG(session->daemon, + MHD_DLOG(connection->daemon, "Received malformed line (no colon), closing connection.\n"); goto DIE; } @@ -476,24 +476,24 @@ MHD_parse_session_headers(struct MHD_Session * session) { ( (colon[0] == ' ') || (colon[0] == '\t') ) ) colon++; - /* we do the actual adding of the session + /* we do the actual adding of the connection header at the beginning of the while loop since we need to be able to inspect the *next* header line (in case it starts with a space...) */ } if (last != NULL) { - MHD_session_add_header(session, + MHD_connection_add_header(connection, last, colon, MHD_HEADER_KIND); free(last); } - MHD_parse_cookie_header(session); + MHD_parse_cookie_header(connection); return; DIE: - CLOSE(session->socket_fd); - session->socket_fd = -1; + CLOSE(connection->socket_fd); + connection->socket_fd = -1; } @@ -501,61 +501,61 @@ MHD_parse_session_headers(struct MHD_Session * session) { * Find the handler responsible for this request. */ static struct MHD_Access_Handler * -MHD_find_access_handler(struct MHD_Session * session) { +MHD_find_access_handler(struct MHD_Connection * connection) { struct MHD_Access_Handler * pos; - pos = session->daemon->handlers; + pos = connection->daemon->handlers; while (pos != NULL) { - if (0 == strcmp(session->url, + if (0 == strcmp(connection->url, pos->uri_prefix)) return pos; pos = pos->next; } - return &session->daemon->default_handler; + return &connection->daemon->default_handler; } /** * Call the handler of the application for this - * session. + * connection. */ void -MHD_call_session_handler(struct MHD_Session * session) { +MHD_call_connection_handler(struct MHD_Connection * connection) { struct MHD_Access_Handler * ah; unsigned int processed; - if (session->headersReceived == 0) + if (connection->headersReceived == 0) abort(); /* bad timing... */ - ah = MHD_find_access_handler(session); - processed = session->readLoc; + ah = MHD_find_access_handler(connection); + processed = connection->readLoc; if (MHD_NO == ah->dh(ah->dh_cls, - session, - session->url, - session->method, - session->read_buffer, + connection, + connection->url, + connection->method, + connection->read_buffer, &processed)) { /* serios internal error, close connection */ - MHD_DLOG(session->daemon, + MHD_DLOG(connection->daemon, "Internal application error, closing connection."); - CLOSE(session->socket_fd); - session->socket_fd = -1; + CLOSE(connection->socket_fd); + connection->socket_fd = -1; return; } /* dh left "processed" bytes in buffer for next time... */ - memmove(session->read_buffer, - &session->read_buffer[session->readLoc - processed], + memmove(connection->read_buffer, + &connection->read_buffer[connection->readLoc - processed], processed); - if (session->uploadSize != -1) - session->uploadSize -= (session->readLoc - processed); - session->readLoc = processed; - if ( (session->uploadSize == 0) || - ( (session->readLoc == 0) && - (session->uploadSize == -1) && - (session->socket_fd == -1) ) ) { - session->bodyReceived = 1; - session->readLoc = 0; - session->read_buffer_size = 0; - free(session->read_buffer); - session->read_buffer = NULL; + if (connection->uploadSize != -1) + connection->uploadSize -= (connection->readLoc - processed); + connection->readLoc = processed; + if ( (connection->uploadSize == 0) || + ( (connection->readLoc == 0) && + (connection->uploadSize == -1) && + (connection->socket_fd == -1) ) ) { + connection->bodyReceived = 1; + connection->readLoc = 0; + connection->read_buffer_size = 0; + free(connection->read_buffer); + connection->read_buffer = NULL; } } @@ -567,54 +567,54 @@ MHD_call_session_handler(struct MHD_Session * session) { * to handle reads. */ int -MHD_session_handle_read(struct MHD_Session * session) { +MHD_connection_handle_read(struct MHD_Connection * connection) { int bytes_read; void * tmp; - if ( (session->readLoc >= session->read_buffer_size) && - (session->headersReceived == 0) ) { + if ( (connection->readLoc >= connection->read_buffer_size) && + (connection->headersReceived == 0) ) { /* need to grow read buffer */ - tmp = malloc(session->read_buffer_size * 2 + MHD_MAX_BUF_SIZE); + tmp = malloc(connection->read_buffer_size * 2 + MHD_MAX_BUF_SIZE); memcpy(tmp, - session->read_buffer, - session->read_buffer_size); - session->read_buffer_size = session->read_buffer_size * 2 + MHD_MAX_BUF_SIZE; - if (session->read_buffer != NULL) - free(session->read_buffer); - session->read_buffer = tmp; + connection->read_buffer, + connection->read_buffer_size); + connection->read_buffer_size = connection->read_buffer_size * 2 + MHD_MAX_BUF_SIZE; + if (connection->read_buffer != NULL) + free(connection->read_buffer); + connection->read_buffer = tmp; } - if (session->readLoc >= session->read_buffer_size) { - MHD_DLOG(session->daemon, + if (connection->readLoc >= connection->read_buffer_size) { + MHD_DLOG(connection->daemon, "Unexpected call to %s.\n", __FUNCTION__); return MHD_NO; } - bytes_read = RECV(session->socket_fd, - &session->read_buffer[session->readLoc], - session->read_buffer_size - session->readLoc, + bytes_read = RECV(connection->socket_fd, + &connection->read_buffer[connection->readLoc], + connection->read_buffer_size - connection->readLoc, 0); if (bytes_read < 0) { if (errno == EINTR) return MHD_NO; - MHD_DLOG(session->daemon, + MHD_DLOG(connection->daemon, "Failed to receive data: %s\n", STRERROR(errno)); - CLOSE(session->socket_fd); - session->socket_fd = -1; + CLOSE(connection->socket_fd); + connection->socket_fd = -1; return MHD_YES; } if (bytes_read == 0) { /* other side closed connection */ - if (session->readLoc > 0) - MHD_call_session_handler(session); - shutdown(session->socket_fd, SHUT_RD); + if (connection->readLoc > 0) + MHD_call_connection_handler(connection); + shutdown(connection->socket_fd, SHUT_RD); return MHD_YES; } - session->readLoc += bytes_read; - if (session->headersReceived == 0) - MHD_parse_session_headers(session); - if (session->headersReceived == 1) - MHD_call_session_handler(session); + connection->readLoc += bytes_read; + if (connection->headersReceived == 0) + MHD_parse_connection_headers(connection); + if (connection->headersReceived == 1) + MHD_call_connection_handler(connection); return MHD_YES; } @@ -623,50 +623,50 @@ MHD_session_handle_read(struct MHD_Session * session) { * for http-compiliance. */ static void -MHD_add_extra_headers(struct MHD_Session * session) { +MHD_add_extra_headers(struct MHD_Connection * connection) { const char * have; char buf[128]; - if (session->response->total_size == -1) { - have = MHD_get_response_header(session->response, + if (connection->response->total_size == -1) { + have = MHD_get_response_header(connection->response, "Connection"); if (have == NULL) - MHD_add_response_header(session->response, + MHD_add_response_header(connection->response, "Connection", "close"); - } else if (NULL == MHD_get_response_header(session->response, + } else if (NULL == MHD_get_response_header(connection->response, "Content-Length")) { _REAL_SNPRINTF(buf, 128, "%llu", - (unsigned long long) session->response->total_size); - MHD_add_response_header(session->response, + (unsigned long long) connection->response->total_size); + MHD_add_response_header(connection->response, "Content-Length", buf); } } /** - * Allocate the session's write buffer and + * Allocate the connection's write buffer and * fill it with all of the headers from the * HTTPd's response. */ static void -MHD_build_header_response(struct MHD_Session * session) { +MHD_build_header_response(struct MHD_Connection * connection) { size_t size; size_t off; struct MHD_HTTP_Header * pos; char code[32]; char * data; - MHD_add_extra_headers(session); + MHD_add_extra_headers(connection); SPRINTF(code, "HTTP/1.1 %u\r\n", - session->responseCode); + connection->responseCode); off = strlen(code); /* estimate size */ size = off + 2; /* extra \r\n at the end */ - pos = session->response->first_header; + pos = connection->response->first_header; while (pos != NULL) { size += strlen(pos->header) + strlen(pos->value) + 4; /* colon, space, linefeeds */ pos = pos->next; @@ -676,7 +676,7 @@ MHD_build_header_response(struct MHD_Session * session) { memcpy(data, code, off); - pos = session->response->first_header; + pos = connection->response->first_header; while (pos != NULL) { SPRINTF(&data[off], "%s: %s\r\n", @@ -690,8 +690,8 @@ MHD_build_header_response(struct MHD_Session * session) { off += 2; if (off != size) abort(); - session->write_buffer = data; - session->write_buffer_size = size; + connection->write_buffer = data; + connection->write_buffer_size = size; } /** @@ -701,53 +701,53 @@ MHD_build_header_response(struct MHD_Session * session) { * call this function */ int -MHD_session_handle_write(struct MHD_Session * session) { +MHD_connection_handle_write(struct MHD_Connection * connection) { struct MHD_Response * response; int ret; - response = session->response; + response = connection->response; if(response == NULL) { - MHD_DLOG(session->daemon, + MHD_DLOG(connection->daemon, "Unexpected call to %s.\n", __FUNCTION__); return MHD_NO; } - if (! session->headersSent) { - if (session->write_buffer == NULL) - MHD_build_header_response(session); - ret = SEND(session->socket_fd, - &session->write_buffer[session->writeLoc], - session->write_buffer_size - session->writeLoc, + if (! connection->headersSent) { + if (connection->write_buffer == NULL) + MHD_build_header_response(connection); + ret = SEND(connection->socket_fd, + &connection->write_buffer[connection->writeLoc], + connection->write_buffer_size - connection->writeLoc, 0); if (ret < 0) { if (errno == EINTR) return MHD_YES; - MHD_DLOG(session->daemon, + MHD_DLOG(connection->daemon, "Failed to send data: %s\n", STRERROR(errno)); - CLOSE(session->socket_fd); - session->socket_fd = -1; + CLOSE(connection->socket_fd); + connection->socket_fd = -1; return MHD_YES; } - session->writeLoc += ret; - if (session->writeLoc == session->write_buffer_size) { - session->writeLoc = 0; - free(session->write_buffer); - session->write_buffer = NULL; - session->write_buffer_size = 0; - session->headersSent = 1; + connection->writeLoc += ret; + if (connection->writeLoc == connection->write_buffer_size) { + connection->writeLoc = 0; + free(connection->write_buffer); + connection->write_buffer = NULL; + connection->write_buffer_size = 0; + connection->headersSent = 1; } return MHD_YES; } - if (response->total_size <= session->messagePos) + if (response->total_size <= connection->messagePos) abort(); /* internal error */ if (response->crc != NULL) pthread_mutex_lock(&response->mutex); /* prepare send buffer */ if ( (response->data == NULL) || - (response->data_start > session->messagePos) || - (response->data_start + response->data_size < session->messagePos) ) { + (response->data_start > connection->messagePos) || + (response->data_start + response->data_size < connection->messagePos) ) { if (response->data_size == 0) { if (response->data != NULL) free(response->data); @@ -755,20 +755,20 @@ MHD_session_handle_write(struct MHD_Session * session) { response->data_size = MHD_MAX_BUF_SIZE; } ret = response->crc(response->crc_cls, - session->messagePos, + connection->messagePos, response->data, MAX(MHD_MAX_BUF_SIZE, - response->data_size - session->messagePos)); + response->data_size - connection->messagePos)); if (ret == -1) { /* end of message, signal other side by closing! */ - response->data_size = session->messagePos; - CLOSE(session->socket_fd); - session->socket_fd = -1; + response->data_size = connection->messagePos; + CLOSE(connection->socket_fd); + connection->socket_fd = -1; if (response->crc != NULL) pthread_mutex_unlock(&response->mutex); return MHD_YES; } - response->data_start = session->messagePos; + response->data_start = connection->messagePos; response->data_size = ret; if (ret == 0) { if (response->crc != NULL) @@ -778,54 +778,54 @@ MHD_session_handle_write(struct MHD_Session * session) { } /* transmit */ - ret = SEND(session->socket_fd, - &response->data[session->messagePos - response->data_start], - response->data_size - (session->messagePos - response->data_start), + ret = SEND(connection->socket_fd, + &response->data[connection->messagePos - response->data_start], + response->data_size - (connection->messagePos - response->data_start), 0); if (response->crc != NULL) pthread_mutex_unlock(&response->mutex); if (ret < 0) { if (errno == EINTR) return MHD_YES; - MHD_DLOG(session->daemon, + MHD_DLOG(connection->daemon, "Failed to send data: %s\n", STRERROR(errno)); - CLOSE(session->socket_fd); - session->socket_fd = -1; + CLOSE(connection->socket_fd); + connection->socket_fd = -1; return MHD_YES; } - session->messagePos += ret; - if (session->messagePos > response->data_size) + connection->messagePos += ret; + if (connection->messagePos > response->data_size) abort(); /* internal error */ - if (session->messagePos == response->data_size) { - if ( (session->bodyReceived == 0) || - (session->headersReceived == 0) ) + if (connection->messagePos == response->data_size) { + if ( (connection->bodyReceived == 0) || + (connection->headersReceived == 0) ) abort(); /* internal error */ MHD_destroy_response(response); - session->responseCode = 0; - session->response = NULL; - session->headersReceived = 0; - session->headersSent = 0; - session->bodyReceived = 0; - session->messagePos = 0; - free(session->method); - session->method = NULL; - free(session->url); - session->url = NULL; - free(session->version); - session->version = NULL; - free(session->write_buffer); - session->write_buffer = NULL; - session->write_buffer_size = 0; - if (session->read_close != 0) { + connection->responseCode = 0; + connection->response = NULL; + connection->headersReceived = 0; + connection->headersSent = 0; + connection->bodyReceived = 0; + connection->messagePos = 0; + free(connection->method); + connection->method = NULL; + free(connection->url); + connection->url = NULL; + free(connection->version); + connection->version = NULL; + free(connection->write_buffer); + connection->write_buffer = NULL; + connection->write_buffer_size = 0; + if (connection->read_close != 0) { /* closed for reading => close for good! */ - CLOSE(session->socket_fd); - session->socket_fd = -1; + CLOSE(connection->socket_fd); + connection->socket_fd = -1; } } return MHD_YES; } -/* end of session.c */ +/* end of connection.c */ diff --git a/src/daemon/session.h b/src/daemon/session.h index 269c2f17..59b99004 100644 --- a/src/daemon/session.h +++ b/src/daemon/session.h @@ -19,23 +19,23 @@ */ /** - * @file session.h - * @brief Methods for managing sessions + * @file connection.h + * @brief Methods for managing connections * @author Daniel Pittman * @author Christian Grothoff */ -#ifndef SESSION_H -#define SESSION_H +#ifndef CONNECTION_H +#define CONNECTION_H /** - * Obtain the select sets for this session. + * Obtain the select sets for this connection. * * @return MHD_YES on success */ int -MHD_session_get_fdset(struct MHD_Session * session, +MHD_connection_get_fdset(struct MHD_Connection * connection, fd_set * read_fd_set, fd_set * write_fd_set, fd_set * except_fd_set, @@ -44,10 +44,10 @@ MHD_session_get_fdset(struct MHD_Session * session, /** * Call the handler of the application for this - * session. + * connection. */ void -MHD_call_session_handler(struct MHD_Session * session); +MHD_call_connection_handler(struct MHD_Connection * connection); /** * This function handles a particular connection when it has been @@ -56,7 +56,7 @@ MHD_call_session_handler(struct MHD_Session * session); * to handle reads. */ int -MHD_session_handle_read(struct MHD_Session * session); +MHD_connection_handle_read(struct MHD_Connection * connection); /** @@ -66,7 +66,7 @@ MHD_session_handle_read(struct MHD_Session * session); * (multithreaded, external select, internal select) call this function */ int -MHD_session_handle_write(struct MHD_Session * session); +MHD_connection_handle_write(struct MHD_Connection * connection); #endif diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h index b8209862..ae918b4a 100644 --- a/src/include/microhttpd.h +++ b/src/include/microhttpd.h @@ -133,19 +133,15 @@ extern "C" { * used, the client wants control over the process and will call the * appropriate microhttpd callbacks.

* - * Note that it is legal to specify that both IPv4 and IPv6 - * should be used. However, if neither IPv4 nor IPv6 is - * specified, starting the daemon will fail.

- * * Starting the daemon may also fail if a particular option is not * implemented or not supported on the target platform (i.e. no * support for SSL, threads or IPv6). */ -enum MHD_OPTION { +enum MHD_FLAG { /** * No options selected. */ - MHD_NO_OPTION = 0, + MHD_NO_FLAG = 0, /** * Run in debug mode. If this flag is used, the @@ -170,14 +166,29 @@ enum MHD_OPTION { MHD_USE_SELECT_INTERNALLY = 8, /** - * Run using the IPv4 protocol + * Run using the IPv6 protocol (otherwise, MHD will + * just support IPv4). + */ + MHD_USE_IPv6 = 16, + +}; + +/** + * MHD options. Passed in the varargs portion + * of MHD_start_daemon. + */ +enum MHD_OPTION { + + /** + * No more options / last option. This is used + * to terminate the VARARGs list. */ - MHD_USE_IPv4 = 16, + MHD_OPTION_END = 0, /** - * Run using the IPv6 protocol + * FIXME: add options for buffer sizes here... */ - MHD_USE_IPv6 = 32, + }; /** @@ -215,7 +226,7 @@ enum MHD_ValueKind { struct MHD_Daemon; -struct MHD_Session; +struct MHD_Connection; struct MHD_Response; @@ -238,6 +249,9 @@ typedef int * callbacks to provide content to give back to the client and return * an HTTP status code (i.e. 200 for OK, 404, etc.). * + * @param url the requested url + * @param method the HTTP method used ("GET", "PUT", etc.) + * @param version the HTTP version string (i.e. "HTTP/1.1") * @param upload_data_size set initially to the size of the * upload_data provided; the method must update this * value to the number of bytes NOT processed @@ -247,9 +261,10 @@ typedef int */ typedef int (*MHD_AccessHandlerCallback)(void * cls, - struct MHD_Session * session, + struct MHD_Connection * connection, const char * url, const char * method, + const char * version, const char * upload_data, unsigned int * upload_data_size); @@ -312,21 +327,25 @@ typedef void /** * Start a webserver on the given port. + * @param flags combination of MHD_FLAG values * @param port port to bind to * @param apc callback to call to check which clients * will be allowed to connect * @param apc_cls extra argument to apc * @param dh default handler for all URIs * @param dh_cls extra argument to dh + * @param ... list of options (type-value pairs, + * terminated with MHD_OPTION_END). * @return NULL on error, handle to daemon on success */ struct MHD_Daemon * -MHD_start_daemon(unsigned int options, +MHD_start_daemon(unsigned int flags, unsigned short port, MHD_AcceptPolicyCallback apc, void * apc_cls, MHD_AccessHandlerCallback dh, - void * dh_cls); + void * dh_cls, + ...); @@ -401,10 +420,10 @@ MHD_unregister_handler(struct MHD_Daemon * daemon, * @return number of entries iterated over */ int -MHD_get_session_values(struct MHD_Session * session, - enum MHD_ValueKind kind, - MHD_KeyValueIterator iterator, - void * iterator_cls); +MHD_get_connection_values(struct MHD_Connection * connection, + enum MHD_ValueKind kind, + MHD_KeyValueIterator iterator, + void * iterator_cls); /** * Get a particular header value. If multiple @@ -414,22 +433,22 @@ MHD_get_session_values(struct MHD_Session * session, * @return NULL if no such item was found */ const char * -MHD_lookup_session_value(struct MHD_Session * session, - enum MHD_ValueKind kind, - const char * key); +MHD_lookup_connection_value(struct MHD_Connection * connection, + enum MHD_ValueKind kind, + const char * key); /** * Queue a response to be transmitted to the client (as soon as * possible). * - * @param session the session identifying the client + * @param connection the connection identifying the client * @param status_code HTTP status code (i.e. 200 for OK) * @param response response to transmit * @return MHD_NO on error (i.e. reply already sent), * MHD_YES on success or if message has been queued */ int -MHD_queue_response(struct MHD_Session * session, +MHD_queue_response(struct MHD_Connection * connection, unsigned int status_code, struct MHD_Response * response); -- cgit v1.2.3