diff options
author | Christian Grothoff <christian@grothoff.org> | 2007-06-12 21:03:28 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2007-06-12 21:03:28 +0000 |
commit | 39eda678e0942382936ace4480a4457a837adc2f (patch) | |
tree | 29d13b3283dbc69bfc8d8d66afc6b54b01592348 | |
parent | 641853be5073b9b2dc5c60fa414271ccbec0c0aa (diff) | |
download | libmicrohttpd-39eda678e0942382936ace4480a4457a837adc2f.tar.gz libmicrohttpd-39eda678e0942382936ace4480a4457a837adc2f.zip |
hl
-rw-r--r-- | src/daemon/daemon.c | 6 | ||||
-rw-r--r-- | src/daemon/internal.h | 7 | ||||
-rw-r--r-- | src/daemon/session.c | 259 | ||||
-rw-r--r-- | src/daemon/session.h | 11 | ||||
-rw-r--r-- | 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 @@ | |||
44 | 44 | ||
45 | #define MHD_MAX_CONNECTIONS FD_SETSIZE -4 | 45 | #define MHD_MAX_CONNECTIONS FD_SETSIZE -4 |
46 | 46 | ||
47 | #define MHD_MAX_BUF_SIZE 2048 | ||
48 | |||
49 | 47 | ||
50 | /** | 48 | /** |
51 | * fprintf-like helper function for logging debug | 49 | * fprintf-like helper function for logging debug |
@@ -490,6 +488,10 @@ MHD_start_daemon(unsigned int options, | |||
490 | retVal->dh = dh; | 488 | retVal->dh = dh; |
491 | retVal->dh_cls = dh_cls; | 489 | retVal->dh_cls = dh_cls; |
492 | retVal->socket_fd = socket_fd; | 490 | retVal->socket_fd = socket_fd; |
491 | retVal->default_handler.dh = dh; | ||
492 | retVal->default_handler.dh_cls = dh_cls; | ||
493 | retVal->default_henader.uri_prefix = ""; | ||
494 | retVal->default_handler.next = NULL; | ||
493 | if ( ( (0 != (options & MHD_USE_THREAD_PER_CONNECTION)) || | 495 | if ( ( (0 != (options & MHD_USE_THREAD_PER_CONNECTION)) || |
494 | (0 != (options & MHD_USE_SELECT_INTERNALLY)) ) && | 496 | (0 != (options & MHD_USE_SELECT_INTERNALLY)) ) && |
495 | (0 != pthread_create(&daemon->pid, | 497 | (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 @@ | |||
43 | #include "microhttpd.h" | 43 | #include "microhttpd.h" |
44 | #include "config.h" | 44 | #include "config.h" |
45 | 45 | ||
46 | #define MHD_MAX_BUF_SIZE 2048 | ||
47 | |||
48 | |||
46 | 49 | ||
47 | /** | 50 | /** |
48 | * Header or cookie in HTTP request or response. | 51 | * Header or cookie in HTTP request or response. |
@@ -73,12 +76,10 @@ struct MHD_Daemon { | |||
73 | 76 | ||
74 | struct MHD_Access_Handler * handlers; | 77 | struct MHD_Access_Handler * handlers; |
75 | 78 | ||
76 | MHD_AccessHandlerCallback default_handler; | 79 | struct MHD_Access_Handler default_handler; |
77 | 80 | ||
78 | struct MHD_Session * connections; | 81 | struct MHD_Session * connections; |
79 | 82 | ||
80 | void * dh_cls; | ||
81 | |||
82 | MHD_AcceptPolicyCallback apc; | 83 | MHD_AcceptPolicyCallback apc; |
83 | 84 | ||
84 | void * apc_cls; | 85 | 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, | |||
143 | fd_set * write_fd_set, | 143 | fd_set * write_fd_set, |
144 | fd_set * except_fd_set, | 144 | fd_set * except_fd_set, |
145 | int * max_fd) { | 145 | int * max_fd) { |
146 | /* FIXME: need to be VERY careful here | ||
147 | determining when the socket is ready for | ||
148 | reading/writing; plenty of cases to handle! */ | ||
146 | FD_SET(session->socket_fd, read_fd_set); | 149 | FD_SET(session->socket_fd, read_fd_set); |
147 | FD_SET(session->socket_fd, write_fd_set); | 150 | FD_SET(session->socket_fd, write_fd_set); |
148 | if (session->socket_fd > *max_fd) | 151 | if (session->socket_fd > *max_fd) |
@@ -155,16 +158,45 @@ MHD_session_get_fdset(struct MHD_Session * session, | |||
155 | /* FIXME: implement/fix code below this line! */ | 158 | /* FIXME: implement/fix code below this line! */ |
156 | 159 | ||
157 | 160 | ||
161 | /** | ||
162 | * This function needs to do a lot more (i.e. break up get arguments) | ||
163 | * but for now just seperates the prefix of the url from the document | ||
164 | * portion. | ||
165 | */ | ||
166 | static void | ||
167 | MHD_parse_URL(struct MHD_Session * session) { | ||
168 | char * working; | ||
169 | int pos,i; | ||
170 | |||
171 | working = session->headers[0]->value; | ||
172 | |||
173 | pos = 0; | ||
174 | for(i = 0; i < strlen(working); i++) { | ||
175 | if(working[i] == '/') | ||
176 | pos = i+1; | ||
177 | } | ||
178 | if(pos >= strlen(working)) | ||
179 | pos = 0; | ||
180 | |||
181 | session->documentName = session->headers[0]->value+pos; | ||
182 | } | ||
183 | |||
184 | |||
158 | 185 | ||
159 | /** | 186 | /** |
160 | * This function is designed to parse the input buffer of a given session. | 187 | * This function is designed to parse the input buffer of a given session. |
161 | * It is assumed that the data being parsed originates at buffer location | 188 | * |
162 | * 0 (a valid assumption since the buffer is shifted after each message) | 189 | * Once the header is complete, it should have set the |
190 | * headers_received, url and method values and set | ||
191 | * headersReceived to 1. If no body is expected, it should | ||
192 | * also set "bodyReceived" to 1. Otherwise, it should | ||
193 | * set "uploadSize" to the expected size of the body. If the | ||
194 | * size of the body is unknown, it should be set to -1. | ||
163 | */ | 195 | */ |
164 | static int | 196 | static void |
165 | MHD_parse_message(struct MHD_Session * session) { | 197 | MHD_parse_session_headers(struct MHD_Session * session) { |
166 | const char * crlfcrlf = "\r\n\r\n"; | 198 | const char * crlfcrlf = "\r\n\r\n"; |
167 | const char * crlf = "\r\n"; | 199 | const char * crlf = "\r\n"; |
168 | 200 | ||
169 | char * saveptr; | 201 | char * saveptr; |
170 | char * saveptr1; | 202 | char * saveptr1; |
@@ -223,26 +255,12 @@ MHD_parse_message(struct MHD_Session * session) { | |||
223 | 255 | ||
224 | 256 | ||
225 | /** | 257 | /** |
226 | * This function needs to do a lot more (i.e. break up get arguments) | 258 | * Find the handler responsible for this request. |
227 | * but for now just seperates the prefix of the url from the document | 259 | */ |
228 | * portion. | 260 | static struct MHD_Access_Handler * |
229 | */ | 261 | MHD_find_access_handler(struct MHD_Session * session) { |
230 | static void | 262 | /* FIXME: do real lookup based on URI! */ |
231 | MHD_parse_URL(struct MHD_Session * session) { | 263 | return &session->daemon->default_handler; |
232 | char * working; | ||
233 | int pos,i; | ||
234 | |||
235 | working = session->headers[0]->value; | ||
236 | |||
237 | pos = 0; | ||
238 | for(i = 0; i < strlen(working); i++) { | ||
239 | if(working[i] == '/') | ||
240 | pos = i+1; | ||
241 | } | ||
242 | if(pos >= strlen(working)) | ||
243 | pos = 0; | ||
244 | |||
245 | session->documentName = session->headers[0]->value+pos; | ||
246 | } | 264 | } |
247 | 265 | ||
248 | /** | 266 | /** |
@@ -253,74 +271,65 @@ MHD_parse_URL(struct MHD_Session * session) { | |||
253 | */ | 271 | */ |
254 | static int | 272 | static int |
255 | MHD_session_handle_read(struct MHD_Session * session) { | 273 | MHD_session_handle_read(struct MHD_Session * session) { |
256 | int bytes_read,i; | 274 | int bytes_read; |
257 | 275 | void * tmp; | |
258 | if((daemon->options & MHD_USE_DEBUG) != 0) { | 276 | struct MHD_Access_Handler * ah; |
259 | fprintf(stderr, "Enter MHD_handle_read\n"); | 277 | unsigned int processed; |
260 | } | 278 | |
261 | 279 | if (session->bodyReceived) { | |
262 | if(daemon == NULL || daemon->connections[connection_id]==NULL) { | 280 | /* FIXME: LOG: why are we in select set? */ |
263 | return MHD_NO; | 281 | return MHD_NO; |
264 | } | 282 | } |
265 | 283 | if (session->readLoc >= session->read_buffer_size) { | |
266 | if(daemon->connections[connection_id]->responsePending) { | 284 | /* need to grow read buffer */ |
267 | return MHD_YES; | 285 | tmp = malloc(session->read_buffer_size * 2 + MHD_MAX_BUF_SIZE); |
268 | } | 286 | memcpy(tmp, |
269 | 287 | session->read_buffer, | |
270 | daemon->connections[connection_id]->firstFreeHeader = 0; | 288 | session->read_buffer_size); |
271 | daemon->connections[connection_id]->requestType = NULL; | 289 | session->read_buffer_size = session->read_buffer_size * 2 + MHD_MAX_BUF_SIZE; |
272 | 290 | } | |
273 | for(i = 0; i < MHD_MAX_HEADERS; i++) { | 291 | bytes_read = recv(session->socket_fd, |
274 | daemon->connections[connection_id]->headers[i] = NULL; | 292 | &session->read_buffer[session->readLoc], |
275 | } | 293 | session->read_buffer_size - session->readLoc, |
276 | 294 | 0); | |
277 | 295 | if (bytes_read < 0) { | |
278 | 296 | if (errno == EINTR) | |
279 | 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); | 297 | return MHD_NO; |
280 | 298 | /* FIXME: log error */ | |
281 | memset(daemon->connections[connection_id]->inbuf + daemon->connections[connection_id]->bufPos - daemon->connections[connection_id]->messagePos, | 299 | return MHD_NO; |
282 | 0, MHD_MAX_BUF_SIZE - daemon->connections[connection_id]->bufPos + (daemon->connections[connection_id]->bufPos - daemon->connections[connection_id]->messagePos)); | 300 | } |
283 | 301 | if (bytes_read == 0) { | |
284 | bytes_read = recv(daemon->connections[connection_id]->socket_fd, | 302 | /* other side closed connection */ |
285 | daemon->connections[connection_id]->inbuf + daemon->connections[connection_id]->bufPos - daemon->connections[connection_id]->messagePos, | 303 | close(session->socket_fd); |
286 | MHD_MAX_BUF_SIZE - (daemon->connections[connection_id]->bufPos - daemon->connections[connection_id]->messagePos), 0); | 304 | session->socket_fd = -1; |
287 | 305 | return MHD_NO; | |
288 | daemon->connections[connection_id]->bufPos = bytes_read + daemon->connections[connection_id]->bufPos - daemon->connections[connection_id]->messagePos; | 306 | } |
289 | 307 | session->readLoc += bytes_read; | |
290 | if(bytes_read == 0) { | 308 | if (session->headersReceived == 0) |
291 | MHD_destroy_session(daemon->connections[connection_id]); | 309 | MHD_parse_session_headers(session); |
292 | daemon->connections[connection_id] = NULL; | 310 | if (session->headersReceived == 1) { |
293 | return MHD_NO; | 311 | ah = MHD_find_access_handler(session); |
294 | } else { | 312 | processed = session->readLoc; |
295 | fprintf(stderr, "\"%s\"\n", daemon->connections[connection_id]->inbuf); | 313 | if (MHD_NO == ah->dh(ah->dh_cls, |
296 | i = MHD_parse_message(daemon->connections[connection_id]); | 314 | session, |
297 | if(i == -1) { | 315 | session->url, |
298 | daemon->connections[connection_id]->messagePos = daemon->connections[connection_id]->bufPos; | 316 | session->method, |
299 | return MHD_YES; | 317 | session->read_buffer, |
300 | } else { | 318 | &processed)) { |
301 | daemon->connections[connection_id]->messagePos = i; | 319 | /* serios error, close connection */ |
302 | fprintf(stderr, "Number of bytes in header: %i\n", daemon->connections[connection_id]->messagePos); | 320 | close(session->socket_fd); |
303 | } | 321 | session->socket_fd = -1; |
304 | 322 | return MHD_NO; | |
305 | daemon->connections[connection_id]->responsePending = 1; | 323 | } |
306 | 324 | /* dh left "processed" bytes in buffer for next time... */ | |
307 | MHD_parse_URL(daemon->connections[connection_id]); | 325 | memmove(session->readBuffer, |
308 | 326 | &session->readBuffer[session->readLoc - processed], | |
309 | for(i = 0; i < MHD_MAX_HANDLERS; i++) { | 327 | processed); |
310 | if(daemon->handlers[i] == NULL) | 328 | session->readLoc = processed; |
311 | continue; | 329 | session->uploadSize -= processed; |
312 | 330 | /* FIXME: proper handling of end of upload! */ | |
313 | //header 0 will hold the url of the request | 331 | } |
314 | if(strstr(daemon->connections[connection_id]->headers[0]->value, daemon->handlers[i]->uri_prefix) != NULL){ | 332 | return MHD_YES; |
315 | return daemon->handlers[i]->dh(daemon->handlers[i]->dh_cls, daemon->connections[connection_id], | ||
316 | daemon->connections[connection_id]->documentName, daemon->connections[connection_id]->requestType, NULL, NULL); | ||
317 | } | ||
318 | } | ||
319 | return daemon->dh(daemon->dh_cls, daemon->connections[connection_id], | ||
320 | daemon->connections[connection_id]->documentName, daemon->connections[connection_id]->requestType, NULL, NULL); | ||
321 | } | ||
322 | |||
323 | return MHD_YES; | ||
324 | } | 333 | } |
325 | 334 | ||
326 | 335 | ||
@@ -332,37 +341,19 @@ MHD_session_handle_read(struct MHD_Session * session) { | |||
332 | */ | 341 | */ |
333 | int | 342 | int |
334 | MHD_session_handle_write(struct MHD_Session * session) { | 343 | MHD_session_handle_write(struct MHD_Session * session) { |
335 | struct MHD_Session * session; | 344 | struct MHD_Response * response; |
336 | 345 | int i; | |
337 | struct MHD_Response * response; | 346 | char * buffer[2048]; |
338 | 347 | char * responseMessage; | |
339 | int i; | 348 | int numBytesInMessage; |
340 | 349 | ||
341 | char * buffer[2048]; | 350 | response = session->response; |
342 | 351 | if(response == NULL) { | |
343 | char * responseMessage; | 352 | /* FIXME: LOG: why are we here? */ |
344 | int numBytesInMessage; | 353 | return MHD_NO; |
345 | 354 | } | |
346 | if((daemon->options & MHD_USE_DEBUG) != 0) { | 355 | numBytesInMessage = 25; |
347 | fprintf(stderr, "Enter MHD_handle_write\n"); | 356 | responseMessage = malloc(25); |
348 | } | ||
349 | |||
350 | |||
351 | session = daemon->connections[connection_id]; | ||
352 | |||
353 | response = session->currentResponses[session->currentResponse]; | ||
354 | |||
355 | numBytesInMessage = 25; | ||
356 | |||
357 | responseMessage = malloc(25); | ||
358 | if(responseMessage == NULL) { | ||
359 | if(daemon->options & MHD_USE_DEBUG) | ||
360 | fprintf(stderr, "Error allocating memory!\n"); | ||
361 | return MHD_NO; | ||
362 | } | ||
363 | |||
364 | if(response == NULL) | ||
365 | return MHD_NO; | ||
366 | 357 | ||
367 | pthread_mutex_lock(&response->mutex); | 358 | pthread_mutex_lock(&response->mutex); |
368 | 359 | ||
@@ -495,21 +486,3 @@ MHD_session_handle_write(struct MHD_Session * session) { | |||
495 | 486 | ||
496 | 487 | ||
497 | 488 | ||
498 | |||
499 | |||
500 | |||
501 | |||
502 | |||
503 | /** | ||
504 | * @return -1 if no data uploaded; otherwise number of bytes | ||
505 | * read into buf; 0 for end of transmission | ||
506 | * Specification not complete at this time. | ||
507 | */ | ||
508 | int | ||
509 | MHD_read_file_upload(struct MHD_Session * session, | ||
510 | void * buf, | ||
511 | size_t len) { | ||
512 | return -1; /* FIXME: not implemented */ | ||
513 | } | ||
514 | |||
515 | |||
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 { | |||
39 | 39 | ||
40 | struct MHD_Response * response; | 40 | struct MHD_Response * response; |
41 | 41 | ||
42 | char * requestType; | 42 | char * method; |
43 | |||
44 | char * url; | ||
43 | 45 | ||
44 | /** | 46 | /** |
45 | * Buffer for reading requests. | 47 | * Buffer for reading requests. |
@@ -78,6 +80,13 @@ struct MHD_Session { | |||
78 | size_t messagePos; | 80 | size_t messagePos; |
79 | 81 | ||
80 | /** | 82 | /** |
83 | * Remaining (!) number of bytes in the upload. | ||
84 | * Set to -1 for unknown (connection will close | ||
85 | * to indicate end of upload). | ||
86 | */ | ||
87 | size_t uploadSize; | ||
88 | |||
89 | /** | ||
81 | * Length of the foreign address. | 90 | * Length of the foreign address. |
82 | */ | 91 | */ |
83 | socklen_t addr_len; | 92 | socklen_t addr_len; |
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 | |||
179 | * callbacks to provide content to give back to the client and return | 179 | * callbacks to provide content to give back to the client and return |
180 | * an HTTP status code (i.e. 200 for OK, 404, etc.). | 180 | * an HTTP status code (i.e. 200 for OK, 404, etc.). |
181 | * | 181 | * |
182 | * @param upload_data_size set initially to the size of the | ||
183 | * upload_data provided; the method must update this | ||
184 | * value to the number of bytes NOT processed | ||
182 | * @return MHS_YES if the connection was handled successfully, | 185 | * @return MHS_YES if the connection was handled successfully, |
183 | * MHS_NO if the socket must be closed due to a serios | 186 | * MHS_NO if the socket must be closed due to a serios |
184 | * error while handling the request | 187 | * error while handling the request |