diff options
author | Christian Grothoff <christian@grothoff.org> | 2010-11-17 11:24:22 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2010-11-17 11:24:22 +0000 |
commit | a1afe5d1c253dd3382ac5b2591d8eb3ea3ed181f (patch) | |
tree | 8b978f434fb6801deccd14b14b306389c7edba46 /src | |
parent | c06b590afb3be1e876be1fcb887fd3eca9b1d65e (diff) | |
download | libmicrohttpd-a1afe5d1c253dd3382ac5b2591d8eb3ea3ed181f.tar.gz libmicrohttpd-a1afe5d1c253dd3382ac5b2591d8eb3ea3ed181f.zip |
allowing error signalling for chunked responses
Diffstat (limited to 'src')
-rw-r--r-- | src/daemon/connection.c | 20 | ||||
-rw-r--r-- | src/examples/fileserver_example_dirs.c | 2 | ||||
-rw-r--r-- | src/examples/minimal_example_comet.c | 2 | ||||
-rw-r--r-- | src/include/microhttpd.h | 40 | ||||
-rw-r--r-- | src/testcurl/daemontest_get_chunked.c | 4 | ||||
-rw-r--r-- | src/testzzuf/daemontest_get_chunked.c | 4 |
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 | */ |
881 | typedef ssize_t | 903 | typedef 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; |