aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2007-06-14 00:09:32 +0000
committerChristian Grothoff <christian@grothoff.org>2007-06-14 00:09:32 +0000
commitb7054096a4e58009d7eddbda083762883213f937 (patch)
treec6ee744359d5c13e9c0de3238c0acc1a823f782d
parent6e12c7fae2b6350a65f1b2eeedafd6f05510726b (diff)
downloadlibmicrohttpd-b7054096a4e58009d7eddbda083762883213f937.tar.gz
libmicrohttpd-b7054096a4e58009d7eddbda083762883213f937.zip
extended API, setting content length automatically if needed
-rw-r--r--README15
-rw-r--r--src/daemon/daemon.c4
-rw-r--r--src/daemon/daemontest.c1
-rw-r--r--src/daemon/minimal_example.c2
-rw-r--r--src/daemon/response.c21
-rw-r--r--src/daemon/session.c41
-rw-r--r--src/include/microhttpd.h11
7 files changed, 87 insertions, 8 deletions
diff --git a/README b/README
index ab45ad10..afcd9a53 100644
--- a/README
+++ b/README
@@ -27,6 +27,11 @@ session.c:
27- send proper error code back if headers are too long 27- send proper error code back if headers are too long
28 (investigate what we should do with those headers, 28 (investigate what we should do with those headers,
29 read? give user control?) 29 read? give user control?)
30- http 1.0 compatibility (if 1.0, force connection
31 close at the end!)
32
33
34
30 35
31For IPv6: 36For IPv6:
32========= 37=========
@@ -41,3 +46,13 @@ microhttpd.h:
41- define appropriate APIs 46- define appropriate APIs
42- everything else 47- everything else
43 48
49
50Other:
51======
52- allow client to determine http 1.0 vs. 1.1
53 (API extension)
54- allow client to control size of input/output
55 buffers
56
57
58
diff --git a/src/daemon/daemon.c b/src/daemon/daemon.c
index 24229793..657afb23 100644
--- a/src/daemon/daemon.c
+++ b/src/daemon/daemon.c
@@ -467,6 +467,7 @@ MHD_start_daemon(unsigned int options,
467 strerror(errno)); 467 strerror(errno));
468 return NULL; 468 return NULL;
469 } 469 }
470 /* FIXME: setsockopt: SO_REUSEADDR? */
470 memset(&servaddr, 471 memset(&servaddr,
471 0, 472 0,
472 sizeof(struct sockaddr_in)); 473 sizeof(struct sockaddr_in));
@@ -541,7 +542,8 @@ MHD_stop_daemon(struct MHD_Daemon * daemon) {
541 close(daemon->connections->socket_fd); 542 close(daemon->connections->socket_fd);
542 daemon->connections->socket_fd = -1; 543 daemon->connections->socket_fd = -1;
543 } 544 }
544 pthread_join(daemon->connections->pid, &unused); 545 if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
546 pthread_join(daemon->connections->pid, &unused);
545 547
546 MHD_cleanup_sessions(daemon); 548 MHD_cleanup_sessions(daemon);
547 } 549 }
diff --git a/src/daemon/daemontest.c b/src/daemon/daemontest.c
index 923885b5..9e86e389 100644
--- a/src/daemon/daemontest.c
+++ b/src/daemon/daemontest.c
@@ -29,6 +29,7 @@
29#include <stdlib.h> 29#include <stdlib.h>
30#include <unistd.h> 30#include <unistd.h>
31#include <string.h> 31#include <string.h>
32#include <stdio.h>
32 33
33static int testStartError() { 34static int testStartError() {
34 struct MHD_Daemon * d; 35 struct MHD_Daemon * d;
diff --git a/src/daemon/minimal_example.c b/src/daemon/minimal_example.c
index 189c557e..009721d6 100644
--- a/src/daemon/minimal_example.c
+++ b/src/daemon/minimal_example.c
@@ -49,7 +49,7 @@ static int ahc_echo(void * cls,
49 struct MHD_Response * response; 49 struct MHD_Response * response;
50 int ret; 50 int ret;
51 51
52 if (0 != strcmp(me, "GET")) 52 if (0 != strcmp(method, "GET"))
53 return MHD_NO; /* unexpected method */ 53 return MHD_NO; /* unexpected method */
54 response = MHD_create_response_from_data(strlen(me), 54 response = MHD_create_response_from_data(strlen(me),
55 (void*) me, 55 (void*) me,
diff --git a/src/daemon/response.c b/src/daemon/response.c
index 7fae9f90..0c4b1de4 100644
--- a/src/daemon/response.c
+++ b/src/daemon/response.c
@@ -126,6 +126,27 @@ MHD_get_response_headers(struct MHD_Response * response,
126 126
127 127
128/** 128/**
129 * Get a particular header from the response.
130 *
131 * @param key which header to get
132 * @return NULL if header does not exist
133 */
134const char *
135MHD_get_response_header(struct MHD_Response * response,
136 const char * key) {
137 struct MHD_HTTP_Header * pos;
138 pos = response->first_header;
139 while (pos != NULL) {
140 if (0 == strcmp(key,
141 pos->header))
142 return pos->value;
143 pos = pos->next;
144 }
145 return NULL;
146}
147
148
149/**
129 * Create a response object. The response object can be extended with 150 * Create a response object. The response object can be extended with
130 * header information and then be used any number of times. 151 * header information and then be used any number of times.
131 * 152 *
diff --git a/src/daemon/session.c b/src/daemon/session.c
index e3aa1241..9cba0d28 100644
--- a/src/daemon/session.c
+++ b/src/daemon/session.c
@@ -111,7 +111,7 @@ MHD_queue_response(struct MHD_Session * session,
111 (response == NULL) || 111 (response == NULL) ||
112 (session->response != NULL) || 112 (session->response != NULL) ||
113 (session->bodyReceived == 0) || 113 (session->bodyReceived == 0) ||
114 (session->headers_received == 0) ) 114 (session->headersReceived == 0) )
115 return MHD_NO; 115 return MHD_NO;
116 MHD_increment_response_rc(response); 116 MHD_increment_response_rc(response);
117 session->response = response; 117 session->response = response;
@@ -131,13 +131,13 @@ MHD_session_get_fdset(struct MHD_Session * session,
131 fd_set * write_fd_set, 131 fd_set * write_fd_set,
132 fd_set * except_fd_set, 132 fd_set * except_fd_set,
133 int * max_fd) { 133 int * max_fd) {
134 if ( (session->headers_received == 0) || 134 if ( (session->headersReceived == 0) ||
135 (session->readLoc < session->read_buffer_size) ) 135 (session->readLoc < session->read_buffer_size) )
136 FD_SET(session->socket_fd, read_fd_set); 136 FD_SET(session->socket_fd, read_fd_set);
137 if (session->response != NULL) 137 if (session->response != NULL)
138 FD_SET(session->socket_fd, write_fd_set); 138 FD_SET(session->socket_fd, write_fd_set);
139 if ( (session->socket_fd > *max_fd) && 139 if ( (session->socket_fd > *max_fd) &&
140 ( (session->headers_received == 0) || 140 ( (session->headersReceived == 0) ||
141 (session->readLoc < session->read_buffer_size) || 141 (session->readLoc < session->read_buffer_size) ||
142 (session->response != NULL) ) ) 142 (session->response != NULL) ) )
143 *max_fd = session->socket_fd; 143 *max_fd = session->socket_fd;
@@ -310,7 +310,7 @@ MHD_call_session_handler(struct MHD_Session * session) {
310 struct MHD_Access_Handler * ah; 310 struct MHD_Access_Handler * ah;
311 unsigned int processed; 311 unsigned int processed;
312 312
313 if (session->headers_received == 0) 313 if (session->headersReceived == 0)
314 abort(); /* bad timing... */ 314 abort(); /* bad timing... */
315 ah = MHD_find_access_handler(session); 315 ah = MHD_find_access_handler(session);
316 processed = session->readLoc; 316 processed = session->readLoc;
@@ -356,7 +356,7 @@ MHD_session_handle_read(struct MHD_Session * session) {
356 356
357 357
358 if ( (session->readLoc >= session->read_buffer_size) && 358 if ( (session->readLoc >= session->read_buffer_size) &&
359 (session->headers_received == 0) ) { 359 (session->headersReceived == 0) ) {
360 /* need to grow read buffer */ 360 /* need to grow read buffer */
361 tmp = malloc(session->read_buffer_size * 2 + MHD_MAX_BUF_SIZE); 361 tmp = malloc(session->read_buffer_size * 2 + MHD_MAX_BUF_SIZE);
362 memcpy(tmp, 362 memcpy(tmp,
@@ -405,6 +405,34 @@ MHD_session_handle_read(struct MHD_Session * session) {
405} 405}
406 406
407/** 407/**
408 * Check if we need to set some additional headers
409 * for http-compiliance.
410 */
411static void
412MHD_add_extra_headers(struct MHD_Session * session) {
413 const char * have;
414 char buf[128];
415
416 if (session->response->total_size == -1) {
417 have = MHD_get_response_header(session->response,
418 "Connection");
419 if (have == NULL)
420 MHD_add_response_header(session->response,
421 "Connection",
422 "close");
423 } else if (NULL == MHD_get_response_header(session->response,
424 "Content-length")) {
425 snprintf(buf,
426 128,
427 "%llu",
428 (unsigned long long) session->response->total_size);
429 MHD_add_response_header(session->response,
430 "Content-length",
431 buf);
432 }
433}
434
435/**
408 * Allocate the session's write buffer and 436 * Allocate the session's write buffer and
409 * fill it with all of the headers from the 437 * fill it with all of the headers from the
410 * HTTPd's response. 438 * HTTPd's response.
@@ -417,6 +445,7 @@ MHD_build_header_response(struct MHD_Session * session) {
417 char code[32]; 445 char code[32];
418 char * data; 446 char * data;
419 447
448 MHD_add_extra_headers(session);
420 sprintf(code, 449 sprintf(code,
421 "HTTP/1.1 %u\r\n", 450 "HTTP/1.1 %u\r\n",
422 session->responseCode); 451 session->responseCode);
@@ -551,7 +580,7 @@ MHD_session_handle_write(struct MHD_Session * session) {
551 abort(); /* internal error */ 580 abort(); /* internal error */
552 if (session->messagePos == response->data_size) { 581 if (session->messagePos == response->data_size) {
553 if ( (session->bodyReceived == 0) || 582 if ( (session->bodyReceived == 0) ||
554 (session->headers_received == 0) ) 583 (session->headersReceived == 0) )
555 abort(); /* internal error */ 584 abort(); /* internal error */
556 MHD_destroy_response(response); 585 MHD_destroy_response(response);
557 session->responseCode = 0; 586 session->responseCode = 0;
diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h
index cb2e280a..d0b1b5dc 100644
--- a/src/include/microhttpd.h
+++ b/src/include/microhttpd.h
@@ -507,6 +507,17 @@ MHD_get_response_headers(struct MHD_Response * response,
507 void * iterator_cls); 507 void * iterator_cls);
508 508
509 509
510/**
511 * Get a particular header from the response.
512 *
513 * @param key which header to get
514 * @return NULL if header does not exist
515 */
516const char *
517MHD_get_response_header(struct MHD_Response * response,
518 const char * key);
519
520
510#if 0 /* keep Emacsens' auto-indent happy */ 521#if 0 /* keep Emacsens' auto-indent happy */
511{ 522{
512#endif 523#endif