mirror of
https://git.gnunet.org/libmicrohttpd.git
synced 2026-09-25 04:09:31 +03:00
hl
This commit is contained in:
+4
-2
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
+114
-141
@@ -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;
|
||||
int bytes_read;
|
||||
void * tmp;
|
||||
struct MHD_Access_Handler * ah;
|
||||
unsigned int processed;
|
||||
|
||||
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;
|
||||
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;
|
||||
|
||||
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;
|
||||
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 */
|
||||
}
|
||||
|
||||
|
||||
|
||||
+10
-1
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user