aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2010-11-17 11:24:22 +0000
committerChristian Grothoff <christian@grothoff.org>2010-11-17 11:24:22 +0000
commita1afe5d1c253dd3382ac5b2591d8eb3ea3ed181f (patch)
tree8b978f434fb6801deccd14b14b306389c7edba46 /src
parentc06b590afb3be1e876be1fcb887fd3eca9b1d65e (diff)
downloadlibmicrohttpd-a1afe5d1c253dd3382ac5b2591d8eb3ea3ed181f.tar.gz
libmicrohttpd-a1afe5d1c253dd3382ac5b2591d8eb3ea3ed181f.zip
allowing error signalling for chunked responses
Diffstat (limited to 'src')
-rw-r--r--src/daemon/connection.c20
-rw-r--r--src/examples/fileserver_example_dirs.c2
-rw-r--r--src/examples/minimal_example_comet.c2
-rw-r--r--src/include/microhttpd.h40
-rw-r--r--src/testcurl/daemontest_get_chunked.c4
-rw-r--r--src/testzzuf/daemontest_get_chunked.c4
6 files changed, 54 insertions, 18 deletions
diff --git a/src/daemon/connection.c b/src/daemon/connection.c
index cd8b6141..247ec178 100644
--- a/src/daemon/connection.c
+++ b/src/daemon/connection.c
@@ -357,14 +357,15 @@ try_ready_normal_body (struct MHD_Connection *connection)
357 NULL 357 NULL
358#endif 358#endif
359 ); 359 );
360 if (ret == -1) 360 if ( (ret == MHD_CONTENT_READER_END_OF_STREAM) ||
361 (ret == MHD_CONTENT_READER_END_WITH_ERROR) )
361 { 362 {
362 /* either error or http 1.0 transfer, close 363 /* either error or http 1.0 transfer, close
363 socket! */ 364 socket! */
364#if DEBUG_CLOSE 365#if DEBUG_CLOSE
365#if HAVE_MESSAGES 366#if HAVE_MESSAGES
366 MHD_DLOG (connection->daemon, 367 MHD_DLOG (connection->daemon,
367 "Closing connection (end of response)\n"); 368 "Closing connection (end of response or error)\n");
368#endif 369#endif
369#endif 370#endif
370 response->total_size = connection->response_write_position; 371 response->total_size = connection->response_write_position;
@@ -444,7 +445,20 @@ try_ready_chunked_body (struct MHD_Connection *connection)
444 &connection->write_buffer[sizeof (cbuf)], 445 &connection->write_buffer[sizeof (cbuf)],
445 connection->write_buffer_size - sizeof (cbuf) - 2); 446 connection->write_buffer_size - sizeof (cbuf) - 2);
446 } 447 }
447 if (ret == -1) 448 if (ret == MHD_CONTENT_READER_END_WITH_ERROR)
449 {
450 /* error, close socket! */
451#if DEBUG_CLOSE
452#if HAVE_MESSAGES
453 MHD_DLOG (connection->daemon,
454 "Closing connection (error generating response)\n");
455#endif
456#endif
457 response->total_size = connection->response_write_position;
458 connection_close_error (connection);
459 return MHD_NO;
460 }
461 if (ret == MHD_CONTENT_READER_END_OF_STREAM)
448 { 462 {
449 /* end of message, signal other side! */ 463 /* end of message, signal other side! */
450 strcpy (connection->write_buffer, "0\r\n"); 464 strcpy (connection->write_buffer, "0\r\n");
diff --git a/src/examples/fileserver_example_dirs.c b/src/examples/fileserver_example_dirs.c
index 8c874994..836c0623 100644
--- a/src/examples/fileserver_example_dirs.c
+++ b/src/examples/fileserver_example_dirs.c
@@ -66,7 +66,7 @@ dir_reader (void *cls, uint64_t pos, char *buf, size_t max)
66 { 66 {
67 e = readdir (dir); 67 e = readdir (dir);
68 if (e == NULL) 68 if (e == NULL)
69 return -1; 69 return MHD_CONTENT_READER_END_OF_STREAM;
70 } while (e->d_name[0] == '.'); 70 } while (e->d_name[0] == '.');
71 return snprintf (buf, max, 71 return snprintf (buf, max,
72 "<a href=\"/%s\">%s</a><br>", 72 "<a href=\"/%s\">%s</a><br>",
diff --git a/src/examples/minimal_example_comet.c b/src/examples/minimal_example_comet.c
index 9b25889e..83493243 100644
--- a/src/examples/minimal_example_comet.c
+++ b/src/examples/minimal_example_comet.c
@@ -56,7 +56,7 @@ ahc_echo (void *cls,
56 return MHD_YES; 56 return MHD_YES;
57 } 57 }
58 *ptr = NULL; /* reset when done */ 58 *ptr = NULL; /* reset when done */
59 response = MHD_create_response_from_callback (-1, 59 response = MHD_create_response_from_callback (MHD_SIZE_UNKNOWN,
60 80, 60 80,
61 &data_generator, NULL, NULL); 61 &data_generator, NULL, NULL);
62 ret = MHD_queue_response (connection, MHD_HTTP_OK, response); 62 ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h
index 1b1a986d..7d99948e 100644
--- a/src/include/microhttpd.h
+++ b/src/include/microhttpd.h
@@ -133,6 +133,15 @@ extern "C"
133#define MHD_SIZE_UNKNOWN ((uint64_t) -1LL) 133#define MHD_SIZE_UNKNOWN ((uint64_t) -1LL)
134#endif 134#endif
135 135
136#ifdef SIZE_MAX
137#define MHD_CONTENT_READER_END_OF_STREAM SIZE_MAX
138#define MHD_CONTENT_READER_END_WITH_ERROR (SIZE_MAX - 1)
139#else
140#define MHD_CONTENT_READER_END ((size_t) -1LL)
141#define MHD_CONTENT_READER_END_WITH_ERROR (((size_t) -LL) - 1)
142#endif
143
144
136/** 145/**
137 * HTTP response codes. 146 * HTTP response codes.
138 */ 147 */
@@ -868,15 +877,28 @@ typedef int
868 * obtained from the content reader so far. 877 * obtained from the content reader so far.
869 * @param buf where to copy the data 878 * @param buf where to copy the data
870 * @param max maximum number of bytes to copy to buf (size of buf) 879 * @param max maximum number of bytes to copy to buf (size of buf)
871 * @return -1 for the end of transmission (or on error); 880 * @return number of bytes written to 'buf';
872 * if a content transfer size was pre-set and the callback 881 * 0 is legal unless we are running in internal select mode (since
873 * has provided fewer than that amount of data, 882 * this would cause busy-waiting); 0 in external select mode
874 * MHD will close the connection with the client; 883 * will cause this function to be called again once the external
875 * if no content size was specified and this is an 884 * select calls MHD again;
876 * http 1.1 connection using chunked encoding, MHD will 885 * MHD_CONTENT_READER_END_OF_STREAM (-1) for the regular
877 * interpret "-1" as the normal end of the transfer 886 * end of transmission (with chunked encoding, MHD will then
878 * (possibly allowing the client to perform additional 887 * terminate the chunk and send any HTTP footers that might be
879 * requests using the same TCP connection). 888 * present; without chunked encoding and given an unknown
889 * response size, MHD will simply close the connection; note
890 * that while returning END_OF_STREAM is not technically
891 * legal if a response size was specified, MHD accepts this
892 * and treats it just as MHD_CONTENT_READER_END_WITH_ERROR;
893 * MHD_CONTENT_READER_END_WITH_ERROR (-2) to indicate a server
894 * error generating the response; this will cause MHD to simply
895 * close the connection immediately. If a response size was
896 * given or if chunked encoding is in use, this will indicate
897 * an error to the client. Note, however, that if the client
898 * does not know a response size and chunked encoding is not in
899 * use, then clients will not be able to tell the difference between
900 * MHD_CONTENT_READER_END_WITH_ERROR and MHD_CONTENT_READER_END_OF_STREAM.
901 * This is not a limitation of MHD but rather of the HTTP protocol.
880 */ 902 */
881typedef ssize_t 903typedef ssize_t
882 (*MHD_ContentReaderCallback) (void *cls, 904 (*MHD_ContentReaderCallback) (void *cls,
diff --git a/src/testcurl/daemontest_get_chunked.c b/src/testcurl/daemontest_get_chunked.c
index e5b1a73a..fd2561ca 100644
--- a/src/testcurl/daemontest_get_chunked.c
+++ b/src/testcurl/daemontest_get_chunked.c
@@ -71,7 +71,7 @@ crc (void *cls, uint64_t pos, char *buf, size_t max)
71 if (pos == 128 * 10) 71 if (pos == 128 * 10)
72 { 72 {
73 MHD_add_response_header (*responseptr, "Footer", "working"); 73 MHD_add_response_header (*responseptr, "Footer", "working");
74 return -1; /* end of stream */ 74 return MHD_CONTENT_READER_END_OF_STREAM;
75 } 75 }
76 if (max < 128) 76 if (max < 128)
77 abort (); /* should not happen in this testcase... */ 77 abort (); /* should not happen in this testcase... */
@@ -113,7 +113,7 @@ ahc_echo (void *cls,
113 responseptr = malloc (sizeof (struct MHD_Response *)); 113 responseptr = malloc (sizeof (struct MHD_Response *));
114 if (responseptr == NULL) 114 if (responseptr == NULL)
115 return MHD_NO; 115 return MHD_NO;
116 response = MHD_create_response_from_callback (-1, 116 response = MHD_create_response_from_callback (MHD_SIZE_UNKNOWN,
117 1024, 117 1024,
118 &crc, responseptr, &crcf); 118 &crc, responseptr, &crcf);
119 *responseptr = response; 119 *responseptr = response;
diff --git a/src/testzzuf/daemontest_get_chunked.c b/src/testzzuf/daemontest_get_chunked.c
index 655f402a..35eed49d 100644
--- a/src/testzzuf/daemontest_get_chunked.c
+++ b/src/testzzuf/daemontest_get_chunked.c
@@ -69,7 +69,7 @@ crc (void *cls, uint64_t pos, char *buf, size_t max)
69 if (pos == 128 * 10) 69 if (pos == 128 * 10)
70 { 70 {
71 MHD_add_response_header (*responseptr, "Footer", "working"); 71 MHD_add_response_header (*responseptr, "Footer", "working");
72 return -1; /* end of stream */ 72 return MHD_CONTENT_READER_END_OF_STREAM;
73 } 73 }
74 if (max < 128) 74 if (max < 128)
75 abort (); /* should not happen in this testcase... */ 75 abort (); /* should not happen in this testcase... */
@@ -109,7 +109,7 @@ ahc_echo (void *cls,
109 return MHD_YES; 109 return MHD_YES;
110 } 110 }
111 responseptr = malloc (sizeof (struct MHD_Response *)); 111 responseptr = malloc (sizeof (struct MHD_Response *));
112 response = MHD_create_response_from_callback (-1, 112 response = MHD_create_response_from_callback (MHD_SIZE_UNKNOWN,
113 1024, 113 1024,
114 &crc, responseptr, &crcf); 114 &crc, responseptr, &crcf);
115 *responseptr = response; 115 *responseptr = response;