From 39eda678e0942382936ace4480a4457a837adc2f Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Tue, 12 Jun 2007 21:03:28 +0000 Subject: hl --- src/daemon/daemon.c | 6 +- src/daemon/internal.h | 7 +- src/daemon/session.c | 259 +++++++++++++++++++++-------------------------- src/daemon/session.h | 11 +- src/include/microhttpd.h | 3 + 5 files changed, 137 insertions(+), 149 deletions(-) diff --git a/src/daemon/daemon.c b/src/daemon/daemon.c index 8a602df4..e52ac940 100644 --- a/src/daemon/daemon.c +++ b/src/daemon/daemon.c @@ -44,8 +44,6 @@ #define MHD_MAX_CONNECTIONS FD_SETSIZE -4 -#define MHD_MAX_BUF_SIZE 2048 - /** * fprintf-like helper function for logging debug @@ -490,6 +488,10 @@ MHD_start_daemon(unsigned int options, retVal->dh = dh; retVal->dh_cls = dh_cls; retVal->socket_fd = socket_fd; + retVal->default_handler.dh = dh; + retVal->default_handler.dh_cls = dh_cls; + retVal->default_henader.uri_prefix = ""; + retVal->default_handler.next = NULL; if ( ( (0 != (options & MHD_USE_THREAD_PER_CONNECTION)) || (0 != (options & MHD_USE_SELECT_INTERNALLY)) ) && (0 != pthread_create(&daemon->pid, diff --git a/src/daemon/internal.h b/src/daemon/internal.h index e09acf3b..2f7fd194 100644 --- a/src/daemon/internal.h +++ b/src/daemon/internal.h @@ -43,6 +43,9 @@ #include "microhttpd.h" #include "config.h" +#define MHD_MAX_BUF_SIZE 2048 + + /** * Header or cookie in HTTP request or response. @@ -73,12 +76,10 @@ struct MHD_Daemon { struct MHD_Access_Handler * handlers; - MHD_AccessHandlerCallback default_handler; + struct MHD_Access_Handler default_handler; struct MHD_Session * connections; - void * dh_cls; - MHD_AcceptPolicyCallback apc; void * apc_cls; diff --git a/src/daemon/session.c b/src/daemon/session.c index 9d17f12f..c50af0ba 100644 --- a/src/daemon/session.c +++ b/src/daemon/session.c @@ -143,6 +143,9 @@ MHD_session_get_fdset(struct MHD_Session * session, fd_set * write_fd_set, fd_set * except_fd_set, int * max_fd) { + /* FIXME: need to be VERY careful here + determining when the socket is ready for + reading/writing; plenty of cases to handle! */ FD_SET(session->socket_fd, read_fd_set); FD_SET(session->socket_fd, write_fd_set); if (session->socket_fd > *max_fd) @@ -155,16 +158,45 @@ MHD_session_get_fdset(struct MHD_Session * session, /* FIXME: implement/fix code below this line! */ +/** + * This function needs to do a lot more (i.e. break up get arguments) + * but for now just seperates the prefix of the url from the document + * portion. + */ +static void +MHD_parse_URL(struct MHD_Session * session) { + char * working; + int pos,i; + + working = session->headers[0]->value; + + pos = 0; + for(i = 0; i < strlen(working); i++) { + if(working[i] == '/') + pos = i+1; + } + if(pos >= strlen(working)) + pos = 0; + + session->documentName = session->headers[0]->value+pos; +} + + /** * This function is designed to parse the input buffer of a given session. - * It is assumed that the data being parsed originates at buffer location - * 0 (a valid assumption since the buffer is shifted after each message) + * + * Once the header is complete, it should have set the + * headers_received, url and method values and set + * headersReceived to 1. If no body is expected, it should + * also set "bodyReceived" to 1. Otherwise, it should + * set "uploadSize" to the expected size of the body. If the + * size of the body is unknown, it should be set to -1. */ -static int -MHD_parse_message(struct MHD_Session * session) { - const char * crlfcrlf = "\r\n\r\n"; - const char * crlf = "\r\n"; +static void +MHD_parse_session_headers(struct MHD_Session * session) { + const char * crlfcrlf = "\r\n\r\n"; + const char * crlf = "\r\n"; char * saveptr; char * saveptr1; @@ -223,26 +255,12 @@ MHD_parse_message(struct MHD_Session * session) { /** - * This function needs to do a lot more (i.e. break up get arguments) - * but for now just seperates the prefix of the url from the document - * portion. - */ -static void -MHD_parse_URL(struct MHD_Session * session) { - char * working; - int pos,i; - - working = session->headers[0]->value; - - pos = 0; - for(i = 0; i < strlen(working); i++) { - if(working[i] == '/') - pos = i+1; - } - if(pos >= strlen(working)) - pos = 0; - - session->documentName = session->headers[0]->value+pos; + * Find the handler responsible for this request. + */ +static struct MHD_Access_Handler * +MHD_find_access_handler(struct MHD_Session * session) { + /* FIXME: do real lookup based on URI! */ + return &session->daemon->default_handler; } /** @@ -253,74 +271,65 @@ MHD_parse_URL(struct MHD_Session * session) { */ static int MHD_session_handle_read(struct MHD_Session * session) { - int bytes_read,i; - - if((daemon->options & MHD_USE_DEBUG) != 0) { - fprintf(stderr, "Enter MHD_handle_read\n"); - } - - if(daemon == NULL || daemon->connections[connection_id]==NULL) { - return MHD_NO; - } - - if(daemon->connections[connection_id]->responsePending) { - return MHD_YES; - } - - daemon->connections[connection_id]->firstFreeHeader = 0; - daemon->connections[connection_id]->requestType = NULL; - - for(i = 0; i < MHD_MAX_HEADERS; i++) { - daemon->connections[connection_id]->headers[i] = NULL; - } - - - - memmove(daemon->connections[connection_id]->inbuf, daemon->connections[connection_id]->inbuf+daemon->connections[connection_id]->messagePos, daemon->connections[connection_id]->bufPos - daemon->connections[connection_id]->messagePos); - - memset(daemon->connections[connection_id]->inbuf + daemon->connections[connection_id]->bufPos - daemon->connections[connection_id]->messagePos, - 0, MHD_MAX_BUF_SIZE - daemon->connections[connection_id]->bufPos + (daemon->connections[connection_id]->bufPos - daemon->connections[connection_id]->messagePos)); - - bytes_read = recv(daemon->connections[connection_id]->socket_fd, - daemon->connections[connection_id]->inbuf + daemon->connections[connection_id]->bufPos - daemon->connections[connection_id]->messagePos, - MHD_MAX_BUF_SIZE - (daemon->connections[connection_id]->bufPos - daemon->connections[connection_id]->messagePos), 0); - - daemon->connections[connection_id]->bufPos = bytes_read + daemon->connections[connection_id]->bufPos - daemon->connections[connection_id]->messagePos; - - if(bytes_read == 0) { - MHD_destroy_session(daemon->connections[connection_id]); - daemon->connections[connection_id] = NULL; - return MHD_NO; - } else { - fprintf(stderr, "\"%s\"\n", daemon->connections[connection_id]->inbuf); - i = MHD_parse_message(daemon->connections[connection_id]); - if(i == -1) { - daemon->connections[connection_id]->messagePos = daemon->connections[connection_id]->bufPos; - return MHD_YES; - } else { - daemon->connections[connection_id]->messagePos = i; - fprintf(stderr, "Number of bytes in header: %i\n", daemon->connections[connection_id]->messagePos); - } - - daemon->connections[connection_id]->responsePending = 1; - - MHD_parse_URL(daemon->connections[connection_id]); - - for(i = 0; i < MHD_MAX_HANDLERS; i++) { - if(daemon->handlers[i] == NULL) - continue; - - //header 0 will hold the url of the request - if(strstr(daemon->connections[connection_id]->headers[0]->value, daemon->handlers[i]->uri_prefix) != NULL){ - return daemon->handlers[i]->dh(daemon->handlers[i]->dh_cls, daemon->connections[connection_id], - daemon->connections[connection_id]->documentName, daemon->connections[connection_id]->requestType, NULL, NULL); - } - } - return daemon->dh(daemon->dh_cls, daemon->connections[connection_id], - daemon->connections[connection_id]->documentName, daemon->connections[connection_id]->requestType, NULL, NULL); - } - - return MHD_YES; + int bytes_read; + void * tmp; + struct MHD_Access_Handler * ah; + unsigned int processed; + + if (session->bodyReceived) { + /* FIXME: LOG: why are we in select set? */ + return MHD_NO; + } + if (session->readLoc >= session->read_buffer_size) { + /* need to grow read buffer */ + tmp = malloc(session->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; + } + bytes_read = recv(session->socket_fd, + &session->read_buffer[session->readLoc], + session->read_buffer_size - session->readLoc, + 0); + if (bytes_read < 0) { + if (errno == EINTR) + return MHD_NO; + /* FIXME: log error */ + return MHD_NO; + } + if (bytes_read == 0) { + /* other side closed connection */ + close(session->socket_fd); + session->socket_fd = -1; + return MHD_NO; + } + session->readLoc += bytes_read; + if (session->headersReceived == 0) + MHD_parse_session_headers(session); + if (session->headersReceived == 1) { + ah = MHD_find_access_handler(session); + processed = session->readLoc; + if (MHD_NO == ah->dh(ah->dh_cls, + session, + session->url, + session->method, + session->read_buffer, + &processed)) { + /* serios error, close connection */ + close(session->socket_fd); + session->socket_fd = -1; + return MHD_NO; + } + /* dh left "processed" bytes in buffer for next time... */ + memmove(session->readBuffer, + &session->readBuffer[session->readLoc - processed], + processed); + session->readLoc = processed; + session->uploadSize -= processed; + /* FIXME: proper handling of end of upload! */ + } + return MHD_YES; } @@ -332,37 +341,19 @@ MHD_session_handle_read(struct MHD_Session * session) { */ int MHD_session_handle_write(struct MHD_Session * session) { - struct MHD_Session * session; - - struct MHD_Response * response; - - int i; - - char * buffer[2048]; - - char * responseMessage; - int numBytesInMessage; - - if((daemon->options & MHD_USE_DEBUG) != 0) { - fprintf(stderr, "Enter MHD_handle_write\n"); - } - - - session = daemon->connections[connection_id]; - - response = session->currentResponses[session->currentResponse]; - - numBytesInMessage = 25; - - responseMessage = malloc(25); - if(responseMessage == NULL) { - if(daemon->options & MHD_USE_DEBUG) - fprintf(stderr, "Error allocating memory!\n"); - return MHD_NO; - } - - if(response == NULL) - return MHD_NO; + struct MHD_Response * response; + int i; + char * buffer[2048]; + char * responseMessage; + int numBytesInMessage; + + response = session->response; + if(response == NULL) { + /* FIXME: LOG: why are we here? */ + return MHD_NO; + } + numBytesInMessage = 25; + responseMessage = malloc(25); pthread_mutex_lock(&response->mutex); @@ -495,21 +486,3 @@ MHD_session_handle_write(struct MHD_Session * session) { - - - - - -/** - * @return -1 if no data uploaded; otherwise number of bytes - * read into buf; 0 for end of transmission - * Specification not complete at this time. - */ -int -MHD_read_file_upload(struct MHD_Session * session, - void * buf, - size_t len) { - return -1; /* FIXME: not implemented */ -} - - diff --git a/src/daemon/session.h b/src/daemon/session.h index 5e8be40c..24ddd641 100644 --- a/src/daemon/session.h +++ b/src/daemon/session.h @@ -39,7 +39,9 @@ struct MHD_Session { struct MHD_Response * response; - char * requestType; + char * method; + + char * url; /** * Buffer for reading requests. @@ -77,6 +79,13 @@ struct MHD_Session { */ size_t messagePos; + /** + * Remaining (!) number of bytes in the upload. + * Set to -1 for unknown (connection will close + * to indicate end of upload). + */ + size_t uploadSize; + /** * Length of the foreign address. */ diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h index b88fede8..4a44f652 100644 --- a/src/include/microhttpd.h +++ b/src/include/microhttpd.h @@ -179,6 +179,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 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 * @return MHS_YES if the connection was handled successfully, * MHS_NO if the socket must be closed due to a serios * error while handling the request -- cgit v1.2.3