aboutsummaryrefslogtreecommitdiff
path: root/src/daemon/session.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2007-06-13 01:12:50 +0000
committerChristian Grothoff <christian@grothoff.org>2007-06-13 01:12:50 +0000
commitbaa26cd045be80620924ce41ea506bc8b043f8c7 (patch)
tree1217606ace7801f488a4b272097408a998ea53a4 /src/daemon/session.c
parent39eda678e0942382936ace4480a4457a837adc2f (diff)
downloadlibmicrohttpd-baa26cd045be80620924ce41ea506bc8b043f8c7.tar.gz
libmicrohttpd-baa26cd045be80620924ce41ea506bc8b043f8c7.zip
fixing compile errors
Diffstat (limited to 'src/daemon/session.c')
-rw-r--r--src/daemon/session.c303
1 files changed, 145 insertions, 158 deletions
diff --git a/src/daemon/session.c b/src/daemon/session.c
index c50af0ba..fa3864ca 100644
--- a/src/daemon/session.c
+++ b/src/daemon/session.c
@@ -26,17 +26,6 @@
26 * @version 0.1.0 26 * @version 0.1.0
27 */ 27 */
28 28
29
30#include <stdio.h>
31#include <stdlib.h>
32#include <netdb.h>
33#include <string.h>
34#include <unistd.h>
35#include <stdarg>
36#include <fcntl.h>
37#include <pthread.h>
38#include <netinet/in.h>
39
40#include "microhttpd.h" 29#include "microhttpd.h"
41#include "session.h" 30#include "session.h"
42#include "response.h" 31#include "response.h"
@@ -55,7 +44,7 @@
55int 44int
56MHD_get_session_values(struct MHD_Session * session, 45MHD_get_session_values(struct MHD_Session * session,
57 enum MHD_ValueKind kind, 46 enum MHD_ValueKind kind,
58 MHD_KeyValueIterator * iterator, 47 MHD_KeyValueIterator iterator,
59 void * iterator_cls) { 48 void * iterator_cls) {
60 int ret; 49 int ret;
61 struct MHD_HTTP_Header * pos; 50 struct MHD_HTTP_Header * pos;
@@ -95,7 +84,6 @@ MHD_lookup_session_value(struct MHD_Session * session,
95 84
96 if (session == NULL) 85 if (session == NULL)
97 return NULL; 86 return NULL;
98 ret = 0;
99 pos = session->headers_received; 87 pos = session->headers_received;
100 while (pos != NULL) { 88 while (pos != NULL) {
101 if ( (0 != (pos->kind & kind)) && 89 if ( (0 != (pos->kind & kind)) &&
@@ -145,7 +133,8 @@ MHD_session_get_fdset(struct MHD_Session * session,
145 int * max_fd) { 133 int * max_fd) {
146 /* FIXME: need to be VERY careful here 134 /* FIXME: need to be VERY careful here
147 determining when the socket is ready for 135 determining when the socket is ready for
148 reading/writing; plenty of cases to handle! */ 136 reading/writing; plenty of cases to handle!
137 (the current code is one big bug) */
149 FD_SET(session->socket_fd, read_fd_set); 138 FD_SET(session->socket_fd, read_fd_set);
150 FD_SET(session->socket_fd, write_fd_set); 139 FD_SET(session->socket_fd, write_fd_set);
151 if (session->socket_fd > *max_fd) 140 if (session->socket_fd > *max_fd)
@@ -165,6 +154,7 @@ MHD_session_get_fdset(struct MHD_Session * session,
165 */ 154 */
166static void 155static void
167MHD_parse_URL(struct MHD_Session * session) { 156MHD_parse_URL(struct MHD_Session * session) {
157#if 0
168 char * working; 158 char * working;
169 int pos,i; 159 int pos,i;
170 160
@@ -179,10 +169,10 @@ MHD_parse_URL(struct MHD_Session * session) {
179 pos = 0; 169 pos = 0;
180 170
181 session->documentName = session->headers[0]->value+pos; 171 session->documentName = session->headers[0]->value+pos;
172#endif
182} 173}
183 174
184 175
185
186/** 176/**
187 * This function is designed to parse the input buffer of a given session. 177 * This function is designed to parse the input buffer of a given session.
188 * 178 *
@@ -195,6 +185,7 @@ MHD_parse_URL(struct MHD_Session * session) {
195 */ 185 */
196static void 186static void
197MHD_parse_session_headers(struct MHD_Session * session) { 187MHD_parse_session_headers(struct MHD_Session * session) {
188#if 0
198 const char * crlfcrlf = "\r\n\r\n"; 189 const char * crlfcrlf = "\r\n\r\n";
199 const char * crlf = "\r\n"; 190 const char * crlf = "\r\n";
200 191
@@ -249,8 +240,7 @@ MHD_parse_session_headers(struct MHD_Session * session) {
249 session->headers[session->firstFreeHeader++] = newHeader; 240 session->headers[session->firstFreeHeader++] = newHeader;
250 curTok = strtok_r(NULL, crlf, &saveptr); 241 curTok = strtok_r(NULL, crlf, &saveptr);
251 } 242 }
252 243#endif
253 return numBytes;
254} 244}
255 245
256 246
@@ -269,7 +259,7 @@ MHD_find_access_handler(struct MHD_Session * session) {
269 * (multithreaded, external select, internal select) call this function 259 * (multithreaded, external select, internal select) call this function
270 * to handle reads. 260 * to handle reads.
271 */ 261 */
272static int 262int
273MHD_session_handle_read(struct MHD_Session * session) { 263MHD_session_handle_read(struct MHD_Session * session) {
274 int bytes_read; 264 int bytes_read;
275 void * tmp; 265 void * tmp;
@@ -322,8 +312,8 @@ MHD_session_handle_read(struct MHD_Session * session) {
322 return MHD_NO; 312 return MHD_NO;
323 } 313 }
324 /* dh left "processed" bytes in buffer for next time... */ 314 /* dh left "processed" bytes in buffer for next time... */
325 memmove(session->readBuffer, 315 memmove(session->read_buffer,
326 &session->readBuffer[session->readLoc - processed], 316 &session->read_buffer[session->readLoc - processed],
327 processed); 317 processed);
328 session->readLoc = processed; 318 session->readLoc = processed;
329 session->uploadSize -= processed; 319 session->uploadSize -= processed;
@@ -332,157 +322,154 @@ MHD_session_handle_read(struct MHD_Session * session) {
332 return MHD_YES; 322 return MHD_YES;
333} 323}
334 324
325/**
326 * Allocate the session's write buffer and
327 * fill it with all of the headers from the
328 * HTTPd's response.
329 */
330static void
331MHD_build_header_response(struct MHD_Session * session) {
332 size_t size;
333 size_t off;
334 struct MHD_HTTP_Header * pos;
335 char code[32];
336 char * data;
337
338 sprintf(code,
339 "HTTP/1.1 %u\r\n",
340 session->responseCode);
341 off = strlen(code);
342 /* estimate size */
343 size = off + 2; /* extra \r\n at the end */
344 pos = session->response->first_header;
345 while (pos != NULL) {
346 size += strlen(pos->header) + strlen(pos->value) + 4; /* colon, space, linefeeds */
347 pos = pos->next;
348 }
349 /* produce data */
350 data = malloc(size);
351 memcpy(data,
352 code,
353 off);
354 pos = session->response->first_header;
355 while (pos != NULL) {
356 sprintf(&data[off],
357 "%s: %s\r\n",
358 pos->header,
359 pos->value);
360 off += strlen(pos->header) + strlen(pos->value) + 4;
361 pos = pos->next;
362 }
363 if (off != size)
364 abort();
365 session->write_buffer = data;
366 session->write_buffer_size = size;
367}
335 368
336/** 369/**
337 * This function was created to handle writes to sockets when it has been 370 * This function was created to handle writes to sockets when it has
338 * determined that the socket can be written to. If there is no data 371 * been determined that the socket can be written to. All
339 * to be written, however, the function call does nothing. All implementations 372 * implementations (multithreaded, external select, internal select)
340 * (multithreaded, external select, internal select) call this function 373 * call this function
341 */ 374 */
342int 375int
343MHD_session_handle_write(struct MHD_Session * session) { 376MHD_session_handle_write(struct MHD_Session * session) {
344 struct MHD_Response * response; 377 struct MHD_Response * response;
345 int i; 378 int ret;
346 char * buffer[2048];
347 char * responseMessage;
348 int numBytesInMessage;
349 379
350 response = session->response; 380 response = session->response;
351 if(response == NULL) { 381 if(response == NULL) {
352 /* FIXME: LOG: why are we here? */ 382 /* FIXME: LOG: why are we here? */
353 return MHD_NO; 383 return MHD_NO;
354 } 384 }
355 numBytesInMessage = 25; 385 if (! session->headersSent) {
356 responseMessage = malloc(25); 386 if (session->write_buffer == NULL)
357 387 MHD_build_header_response(session);
358 pthread_mutex_lock(&response->mutex); 388 ret = send(session->socket_fd,
359 389 &session->write_buffer[session->writeLoc],
360 if(!response->headersSent) { 390 session->write_buffer_size - session->writeLoc,
361 sprintf(responseMessage, "HTTP/1.1 %i Go to hell!\r\n", response->responseCode); 391 0);
362 fprintf(stderr, "%s\n", responseMessage); 392 if (ret < 0) {
363 if(send(session->socket_fd, responseMessage, strlen(responseMessage), 0) != strlen(responseMessage)) { 393 if (errno == EINTR)
364 fprintf(stderr, "Error! could not send an entire header in one call to send! unable to handle this case as of this time.\n"); 394 return MHD_YES;
365 pthread_mutex_unlock(&response->mutex); 395 /* FIXME: log error */
366 return MHD_NO; 396 close(session->socket_fd);
367 } 397 session->socket_fd = -1;
368 398 return MHD_NO;
369 for(i = 0; i < MHD_MAX_HEADERS; i++) { 399 }
370 if(response->headers[i] == NULL) 400 session->writeLoc += ret;
371 continue; 401 if (session->writeLoc == session->write_buffer_size) {
372 402 session->writeLoc = 0;
373 if(strlen(response->headers[i]->header) + strlen(response->headers[i]->value) + 5 > numBytesInMessage) { 403 free(session->write_buffer);
374 free(responseMessage); 404 session->write_buffer = NULL;
375 responseMessage = malloc(strlen(response->headers[i]->header) + strlen(response->headers[i]->value) + 5); 405 session->write_buffer_size = 0;
376 if(responseMessage == NULL) { 406 session->headersSent = 1;
377 if(daemon->options & MHD_USE_DEBUG) 407 }
378 fprintf(stderr, "Error allocating memory!\n"); 408 return MHD_YES;
379 pthread_mutex_unlock(&response->mutex); 409 }
380 return MHD_NO; 410 if (response->total_size <= session->messagePos)
381 } 411 abort(); /* internal error */
382 numBytesInMessage = strlen(response->headers[i]->header) + strlen(response->headers[i]->value) + 5; 412 if (response->crc != NULL)
383 } 413 pthread_mutex_lock(&response->mutex);
384 sprintf(responseMessage, "%s: %s\r\n", response->headers[i]->header, response->headers[i]->value); 414
385 fprintf(stderr, "%s\n", responseMessage); 415 /* prepare send buffer */
386 if(send(session->socket_fd, responseMessage, strlen(responseMessage), 0) != strlen(responseMessage)) { 416 if ( (response->data == NULL) ||
387 fprintf(stderr, "Error! could not send an entire header in one call to send! unable to handle this case as of this time.\n"); 417 (response->data_start > session->messagePos) ||
388 pthread_mutex_unlock(&response->mutex); 418 (response->data_start + response->data_size < session->messagePos) ) {
389 return MHD_NO; 419 if (response->data_size == 0) {
390 } 420 if (response->data != NULL)
391 } 421 free(response->data);
392 422 response->data = malloc(MHD_MAX_BUF_SIZE);
393 response->headersSent = 1; 423 response->data_size = MHD_MAX_BUF_SIZE;
394 } 424 }
395 425 ret = response->crc(response->crc_cls,
396 if(response->data != NULL) { 426 session->messagePos,
397 if(response->bytesSentSoFar == 0) { 427 response->data,
398 if(numBytesInMessage < 32) { 428 MAX(MHD_MAX_BUF_SIZE,
399 free(responseMessage); 429 response->data_size - session->messagePos));
400 responseMessage = malloc(32); 430 if (ret == -1) {
401 if(responseMessage == NULL) { 431 /* end of message, signal other side by closing! */
402 if(daemon->options & MHD_USE_DEBUG) 432 response->data_size = session->messagePos;
403 fprintf(stderr, "Error allocating memory!\n"); 433 close(session->socket_fd);
404 pthread_mutex_unlock(&response->mutex); 434 session->socket_fd = -1;
405 return MHD_NO; 435 return MHD_YES;
406 } 436 }
407 } 437 response->data_start = session->messagePos;
408 sprintf(responseMessage, "Content-length: %llu\r\n\r\n", (unsigned long long)response->size); 438 response->data_size = ret;
409 fprintf(stderr, "%s\n", responseMessage); 439 if (ret == 0)
410 if(send(session->socket_fd, responseMessage, strlen(responseMessage),0)!= strlen(responseMessage)) { 440 return MHD_YES; /* or NO? */
411 fprintf(stderr, "Error! could not send an entire header in one call to send! unable to handle this case as of this time.\n"); 441 }
412 pthread_mutex_unlock(&response->mutex); 442
413 return MHD_NO; 443 /* transmit */
414 } 444 ret = send(session->socket_fd,
415 } 445 &response->data[session->messagePos - response->data_start],
416 446 response->data_size - (session->messagePos - response->data_start),
417 i = send(session->socket_fd, response->data+response->bytesSentSoFar, response->size-response->bytesSentSoFar,0); 447 0);
418 response->bytesSentSoFar += i; 448 if (response->crc != NULL)
419 449 pthread_mutex_unlock(&response->mutex);
420 fprintf(stderr, "Sent %i bytes of data\nTotal to send is %llu bytes\n", i, (unsigned long long)response->size); 450 if (ret == -1) {
421 451 if (errno == EINTR)
422 if(response->bytesSentSoFar == response->size) { 452 return MHD_YES;
423 session->currentResponses[session->currentResponse] = NULL; 453 /* FIXME: log */
424 session->currentResponse = (session->currentResponse + 1) % MHD_MAX_RESPONSE; 454 return MHD_NO;
425 response->currentSession = NULL; 455 }
426 456 session->messagePos += ret;
427 if(response->freeWhenFinished) { 457 if (session->messagePos == response->data_size) {
428 pthread_mutex_unlock(&response->mutex); 458 /* reset session, wait for next request! */
429 MHD_destroy_response(response); 459 MHD_destroy_response(response);
430 } 460 session->responseCode = 0;
431 /*THIS NEEDS TO BE HANDLED ANOTHER WAY!!! TIMEOUT, ect..., as of now this is the only way to get test case to work 461 session->response = NULL;
432 * since client never disconnects on their own! 462 session->headersReceived = 0;
433 */ 463 session->headersSent = 0;
434 if(session->currentResponses[session->currentResponse] == NULL) { 464 session->bodyReceived = 0;
435 MHD_destroy_session(session); 465 session->messagePos = 0;
436 daemon->connections[connection_id] = NULL; 466 free(session->write_buffer);
437 return MHD_NO; 467 session->write_buffer = NULL;
438 } 468 session->write_buffer_size = 0;
439 } 469 }
440 } else { 470 return MHD_YES;
441 if(response->crc == NULL) {
442 pthread_mutex_unlock(&response->mutex);
443 return MHD_NO;
444 }
445
446 if(response->bytesSentSoFar == 0) {
447 if(send(session->socket_fd, "\r\n", response->size,0) != 2) {
448 fprintf(stderr, "Error! could not send an entire header in one call to send! unable to handle this case as of this time.\n");
449 pthread_mutex_unlock(&response->mutex);
450 return MHD_NO;
451 }
452 }
453 memset(buffer, 0, 2048);
454
455 i = response->crc(response->crc_cls, response->bytesSentSoFar, (char *)buffer, 2048);
456
457 if(i == -1) {
458 pthread_mutex_unlock(&response->mutex);
459
460 session->currentResponses[session->currentResponse] = NULL;
461 session->currentResponse = (session->currentResponse + 1) % MHD_MAX_RESPONSE;
462 response->currentSession = NULL;
463
464 if(response->freeWhenFinished) {
465 pthread_mutex_unlock(&response->mutex);
466 MHD_destroy_response(response);
467 }
468 /*THIS NEEDS TO BE HANDLED ANOTHER WAY!!! TIMEOUT, ect..., as of now this is the only way to get test case to work
469 * since client never disconnects on their own!
470 */
471 if(session->currentResponses[session->currentResponse] == NULL) {
472 MHD_destroy_session(session);
473 daemon->connections[connection_id] = NULL;
474 return MHD_NO;
475 }
476
477 } else {
478 i = send(session->socket_fd, buffer, i,0);
479 response->bytesSentSoFar += i;
480 }
481 }
482 pthread_mutex_unlock(&response->mutex);
483 return MHD_YES;
484} 471}
485 472
486 473/* end of session.c */
487 474
488 475