diff options
author | Christian Grothoff <christian@grothoff.org> | 2007-08-30 06:59:15 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2007-08-30 06:59:15 +0000 |
commit | b259da7c7f97e1fbafeef634bd16af3a21f83e72 (patch) | |
tree | 6d51feb9f34832e27e831c8a05bc865186f35a67 | |
parent | 44f694198ba0d2b9b7172468989a83f6e1e51929 (diff) | |
download | libmicrohttpd-b259da7c7f97e1fbafeef634bd16af3a21f83e72.tar.gz libmicrohttpd-b259da7c7f97e1fbafeef634bd16af3a21f83e72.zip |
improving API to allow clients to associate state with a connection and to be notified about request termination
-rw-r--r-- | src/daemon/connection.c | 52 | ||||
-rw-r--r-- | src/daemon/daemon.c | 16 | ||||
-rw-r--r-- | src/daemon/daemontest.c | 3 | ||||
-rw-r--r-- | src/daemon/daemontest_get.c | 3 | ||||
-rw-r--r-- | src/daemon/daemontest_large_put.c | 3 | ||||
-rw-r--r-- | src/daemon/daemontest_long_header.c | 3 | ||||
-rw-r--r-- | src/daemon/daemontest_post.c | 3 | ||||
-rw-r--r-- | src/daemon/daemontest_put.c | 3 | ||||
-rw-r--r-- | src/daemon/fileserver_example.c | 3 | ||||
-rw-r--r-- | src/daemon/internal.h | 12 | ||||
-rw-r--r-- | src/daemon/minimal_example.c | 3 | ||||
-rw-r--r-- | src/include/microhttpd.h | 82 |
12 files changed, 156 insertions, 30 deletions
diff --git a/src/daemon/connection.c b/src/daemon/connection.c index cdc8540b..1b7a04ed 100644 --- a/src/daemon/connection.c +++ b/src/daemon/connection.c | |||
@@ -181,6 +181,22 @@ MHD_need_100_continue (struct MHD_Connection *connection) | |||
181 | } | 181 | } |
182 | 182 | ||
183 | /** | 183 | /** |
184 | * A serious error occured, close the | ||
185 | * connection (and notify the application). | ||
186 | */ | ||
187 | static void | ||
188 | connection_close_error(struct MHD_Connection * connection) | ||
189 | { | ||
190 | CLOSE (connection->socket_fd); | ||
191 | connection->socket_fd = -1; | ||
192 | if (connection->daemon->notify_completed != NULL) | ||
193 | connection->daemon->notify_completed(connection->daemon->notify_completed_cls, | ||
194 | connection, | ||
195 | &connection->client_context, | ||
196 | MHD_REQUEST_TERMINATED_WITH_ERROR); | ||
197 | } | ||
198 | |||
199 | /** | ||
184 | * Prepare the response buffer of this connection for | 200 | * Prepare the response buffer of this connection for |
185 | * sending. Assumes that the response mutex is | 201 | * sending. Assumes that the response mutex is |
186 | * already held. If the transmission is complete, | 202 | * already held. If the transmission is complete, |
@@ -209,8 +225,7 @@ ready_response (struct MHD_Connection *connection) | |||
209 | "Closing connection (end of response)\n"); | 225 | "Closing connection (end of response)\n"); |
210 | #endif | 226 | #endif |
211 | response->total_size = connection->messagePos; | 227 | response->total_size = connection->messagePos; |
212 | CLOSE (connection->socket_fd); | 228 | connection_close_error(connection); |
213 | connection->socket_fd = -1; | ||
214 | return MHD_NO; | 229 | return MHD_NO; |
215 | } | 230 | } |
216 | response->data_start = connection->messagePos; | 231 | response->data_start = connection->messagePos; |
@@ -746,8 +761,7 @@ MHD_parse_connection_headers (struct MHD_Connection *connection) | |||
746 | DIE: | 761 | DIE: |
747 | MHD_DLOG (connection->daemon, | 762 | MHD_DLOG (connection->daemon, |
748 | "Closing connection (problem parsing headers)\n"); | 763 | "Closing connection (problem parsing headers)\n"); |
749 | CLOSE (connection->socket_fd); | 764 | connection_close_error(connection); |
750 | connection->socket_fd = -1; | ||
751 | } | 765 | } |
752 | 766 | ||
753 | 767 | ||
@@ -889,13 +903,13 @@ MHD_call_connection_handler (struct MHD_Connection *connection) | |||
889 | connection->url, | 903 | connection->url, |
890 | connection->method, | 904 | connection->method, |
891 | connection->version, | 905 | connection->version, |
892 | connection->read_buffer, &processed)) | 906 | connection->read_buffer, &processed, |
907 | &connection->client_context)) | ||
893 | { | 908 | { |
894 | /* serios internal error, close connection */ | 909 | /* serios internal error, close connection */ |
895 | MHD_DLOG (connection->daemon, | 910 | MHD_DLOG (connection->daemon, |
896 | "Internal application error, closing connection.\n"); | 911 | "Internal application error, closing connection.\n"); |
897 | CLOSE (connection->socket_fd); | 912 | connection_close_error(connection); |
898 | connection->socket_fd = -1; | ||
899 | return; | 913 | return; |
900 | } | 914 | } |
901 | /* dh left "processed" bytes in buffer for next time... */ | 915 | /* dh left "processed" bytes in buffer for next time... */ |
@@ -934,8 +948,7 @@ MHD_connection_handle_read (struct MHD_Connection *connection) | |||
934 | if (connection->pool == NULL) | 948 | if (connection->pool == NULL) |
935 | { | 949 | { |
936 | MHD_DLOG (connection->daemon, "Failed to create memory pool!\n"); | 950 | MHD_DLOG (connection->daemon, "Failed to create memory pool!\n"); |
937 | CLOSE (connection->socket_fd); | 951 | connection_close_error(connection); |
938 | connection->socket_fd = -1; | ||
939 | return MHD_NO; | 952 | return MHD_NO; |
940 | } | 953 | } |
941 | if ((connection->readLoc >= connection->read_buffer_size) && | 954 | if ((connection->readLoc >= connection->read_buffer_size) && |
@@ -973,8 +986,7 @@ MHD_connection_handle_read (struct MHD_Connection *connection) | |||
973 | return MHD_NO; | 986 | return MHD_NO; |
974 | MHD_DLOG (connection->daemon, | 987 | MHD_DLOG (connection->daemon, |
975 | "Failed to receive data: %s\n", STRERROR (errno)); | 988 | "Failed to receive data: %s\n", STRERROR (errno)); |
976 | CLOSE (connection->socket_fd); | 989 | connection_close_error(connection); |
977 | connection->socket_fd = -1; | ||
978 | return MHD_YES; | 990 | return MHD_YES; |
979 | } | 991 | } |
980 | if (bytes_read == 0) | 992 | if (bytes_read == 0) |
@@ -1150,8 +1162,7 @@ MHD_connection_handle_write (struct MHD_Connection *connection) | |||
1150 | return MHD_YES; | 1162 | return MHD_YES; |
1151 | MHD_DLOG (connection->daemon, | 1163 | MHD_DLOG (connection->daemon, |
1152 | "Failed to send data: %s\n", STRERROR (errno)); | 1164 | "Failed to send data: %s\n", STRERROR (errno)); |
1153 | CLOSE (connection->socket_fd); | 1165 | connection_close_error(connection); |
1154 | connection->socket_fd = -1; | ||
1155 | return MHD_YES; | 1166 | return MHD_YES; |
1156 | } | 1167 | } |
1157 | #if DEBUG_SEND_DATA | 1168 | #if DEBUG_SEND_DATA |
@@ -1176,8 +1187,7 @@ MHD_connection_handle_write (struct MHD_Connection *connection) | |||
1176 | /* oops - close! */ | 1187 | /* oops - close! */ |
1177 | MHD_DLOG (connection->daemon, | 1188 | MHD_DLOG (connection->daemon, |
1178 | "Closing connection (failed to create response header)\n"); | 1189 | "Closing connection (failed to create response header)\n"); |
1179 | CLOSE (connection->socket_fd); | 1190 | connection_close_error(connection); |
1180 | connection->socket_fd = -1; | ||
1181 | return MHD_NO; | 1191 | return MHD_NO; |
1182 | } | 1192 | } |
1183 | ret = SEND (connection->socket_fd, | 1193 | ret = SEND (connection->socket_fd, |
@@ -1189,8 +1199,7 @@ MHD_connection_handle_write (struct MHD_Connection *connection) | |||
1189 | return MHD_YES; | 1199 | return MHD_YES; |
1190 | MHD_DLOG (connection->daemon, | 1200 | MHD_DLOG (connection->daemon, |
1191 | "Failed to send data: %s\n", STRERROR (errno)); | 1201 | "Failed to send data: %s\n", STRERROR (errno)); |
1192 | CLOSE (connection->socket_fd); | 1202 | connection_close_error(connection); |
1193 | connection->socket_fd = -1; | ||
1194 | return MHD_YES; | 1203 | return MHD_YES; |
1195 | } | 1204 | } |
1196 | #if DEBUG_SEND_DATA | 1205 | #if DEBUG_SEND_DATA |
@@ -1240,8 +1249,7 @@ MHD_connection_handle_write (struct MHD_Connection *connection) | |||
1240 | return MHD_YES; | 1249 | return MHD_YES; |
1241 | MHD_DLOG (connection->daemon, | 1250 | MHD_DLOG (connection->daemon, |
1242 | "Failed to send data: %s\n", STRERROR (errno)); | 1251 | "Failed to send data: %s\n", STRERROR (errno)); |
1243 | CLOSE (connection->socket_fd); | 1252 | connection_close_error(connection); |
1244 | connection->socket_fd = -1; | ||
1245 | return MHD_YES; | 1253 | return MHD_YES; |
1246 | } | 1254 | } |
1247 | #if DEBUG_SEND_DATA | 1255 | #if DEBUG_SEND_DATA |
@@ -1259,6 +1267,12 @@ MHD_connection_handle_write (struct MHD_Connection *connection) | |||
1259 | (connection->headersReceived == 0)) | 1267 | (connection->headersReceived == 0)) |
1260 | abort (); /* internal error */ | 1268 | abort (); /* internal error */ |
1261 | MHD_destroy_response (response); | 1269 | MHD_destroy_response (response); |
1270 | if (connection->daemon->notify_completed != NULL) | ||
1271 | connection->daemon->notify_completed(connection->daemon->notify_completed_cls, | ||
1272 | connection, | ||
1273 | &connection->client_context, | ||
1274 | MHD_REQUEST_TERMINATED_COMPLETED_OK); | ||
1275 | connection->client_context = NULL; | ||
1262 | connection->continuePos = 0; | 1276 | connection->continuePos = 0; |
1263 | connection->responseCode = 0; | 1277 | connection->responseCode = 0; |
1264 | connection->response = NULL; | 1278 | connection->response = NULL; |
diff --git a/src/daemon/daemon.c b/src/daemon/daemon.c index 35eeccce..2dd7551f 100644 --- a/src/daemon/daemon.c +++ b/src/daemon/daemon.c | |||
@@ -354,6 +354,11 @@ MHD_cleanup_connections (struct MHD_Daemon *daemon) | |||
354 | #endif | 354 | #endif |
355 | CLOSE (pos->socket_fd); | 355 | CLOSE (pos->socket_fd); |
356 | pos->socket_fd = -1; | 356 | pos->socket_fd = -1; |
357 | if (pos->daemon->notify_completed != NULL) | ||
358 | pos->daemon->notify_completed(pos->daemon->notify_completed_cls, | ||
359 | pos, | ||
360 | &pos->client_context, | ||
361 | MHD_REQUEST_TERMINATED_TIMEOUT_REACHED); | ||
357 | } | 362 | } |
358 | if (pos->socket_fd == -1) | 363 | if (pos->socket_fd == -1) |
359 | { | 364 | { |
@@ -680,6 +685,10 @@ MHD_start_daemon (unsigned int options, | |||
680 | case MHD_OPTION_CONNECTION_TIMEOUT: | 685 | case MHD_OPTION_CONNECTION_TIMEOUT: |
681 | retVal->connection_timeout = va_arg (ap, unsigned int); | 686 | retVal->connection_timeout = va_arg (ap, unsigned int); |
682 | break; | 687 | break; |
688 | case MHD_OPTION_NOTIFY_COMPLETED: | ||
689 | retVal->notify_completed = va_arg(ap, MHD_RequestCompletedCallback); | ||
690 | retVal->notify_completed_cls = va_arg(ap, void *); | ||
691 | break; | ||
683 | default: | 692 | default: |
684 | fprintf (stderr, | 693 | fprintf (stderr, |
685 | "Invalid MHD_OPTION argument! (Did you terminate the list with MHD_OPTION_END?)\n"); | 694 | "Invalid MHD_OPTION argument! (Did you terminate the list with MHD_OPTION_END?)\n"); |
@@ -733,7 +742,12 @@ MHD_stop_daemon (struct MHD_Daemon *daemon) | |||
733 | MHD_DLOG (daemon, | 742 | MHD_DLOG (daemon, |
734 | "MHD shutdown, closing active connections\n"); | 743 | "MHD shutdown, closing active connections\n"); |
735 | #endif | 744 | #endif |
736 | CLOSE (daemon->connections->socket_fd); | 745 | if (daemon->notify_completed != NULL) |
746 | daemon->notify_completed(daemon->notify_completed_cls, | ||
747 | daemon->connections, | ||
748 | &daemon->connections->client_context, | ||
749 | MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN); | ||
750 | CLOSE (daemon->connections->socket_fd); | ||
737 | daemon->connections->socket_fd = -1; | 751 | daemon->connections->socket_fd = -1; |
738 | } | 752 | } |
739 | MHD_cleanup_connections (daemon); | 753 | MHD_cleanup_connections (daemon); |
diff --git a/src/daemon/daemontest.c b/src/daemon/daemontest.c index 53f56989..2ecb87f2 100644 --- a/src/daemon/daemontest.c +++ b/src/daemon/daemontest.c | |||
@@ -64,7 +64,8 @@ ahc_nothing (void *cls, | |||
64 | const char *url, | 64 | const char *url, |
65 | const char *method, | 65 | const char *method, |
66 | const char *version, | 66 | const char *version, |
67 | const char *upload_data, unsigned int *upload_data_size) | 67 | const char *upload_data, unsigned int *upload_data_size, |
68 | void ** unused) | ||
68 | { | 69 | { |
69 | return MHD_NO; | 70 | return MHD_NO; |
70 | } | 71 | } |
diff --git a/src/daemon/daemontest_get.c b/src/daemon/daemontest_get.c index e8ce1e7a..79726a11 100644 --- a/src/daemon/daemontest_get.c +++ b/src/daemon/daemontest_get.c | |||
@@ -63,7 +63,8 @@ ahc_echo (void *cls, | |||
63 | const char *url, | 63 | const char *url, |
64 | const char *method, | 64 | const char *method, |
65 | const char *version, | 65 | const char *version, |
66 | const char *upload_data, unsigned int *upload_data_size) | 66 | const char *upload_data, unsigned int *upload_data_size, |
67 | void ** unused) | ||
67 | { | 68 | { |
68 | const char *me = cls; | 69 | const char *me = cls; |
69 | struct MHD_Response *response; | 70 | struct MHD_Response *response; |
diff --git a/src/daemon/daemontest_large_put.c b/src/daemon/daemontest_large_put.c index e176d29c..f4ae5583 100644 --- a/src/daemon/daemontest_large_put.c +++ b/src/daemon/daemontest_large_put.c | |||
@@ -85,7 +85,8 @@ ahc_echo (void *cls, | |||
85 | const char *url, | 85 | const char *url, |
86 | const char *method, | 86 | const char *method, |
87 | const char *version, | 87 | const char *version, |
88 | const char *upload_data, unsigned int *upload_data_size) | 88 | const char *upload_data, unsigned int *upload_data_size, |
89 | void ** unused) | ||
89 | { | 90 | { |
90 | int *done = cls; | 91 | int *done = cls; |
91 | struct MHD_Response *response; | 92 | struct MHD_Response *response; |
diff --git a/src/daemon/daemontest_long_header.c b/src/daemon/daemontest_long_header.c index 6377ac07..6a451136 100644 --- a/src/daemon/daemontest_long_header.c +++ b/src/daemon/daemontest_long_header.c | |||
@@ -69,7 +69,8 @@ ahc_echo (void *cls, | |||
69 | const char *url, | 69 | const char *url, |
70 | const char *method, | 70 | const char *method, |
71 | const char *version, | 71 | const char *version, |
72 | const char *upload_data, unsigned int *upload_data_size) | 72 | const char *upload_data, unsigned int *upload_data_size, |
73 | void ** unused) | ||
73 | { | 74 | { |
74 | const char *me = cls; | 75 | const char *me = cls; |
75 | struct MHD_Response *response; | 76 | struct MHD_Response *response; |
diff --git a/src/daemon/daemontest_post.c b/src/daemon/daemontest_post.c index ec60575b..10f6ea97 100644 --- a/src/daemon/daemontest_post.c +++ b/src/daemon/daemontest_post.c | |||
@@ -69,7 +69,8 @@ ahc_echo (void *cls, | |||
69 | const char *url, | 69 | const char *url, |
70 | const char *method, | 70 | const char *method, |
71 | const char *version, | 71 | const char *version, |
72 | const char *upload_data, unsigned int *upload_data_size) | 72 | const char *upload_data, unsigned int *upload_data_size, |
73 | void ** unused) | ||
73 | { | 74 | { |
74 | struct MHD_Response *response; | 75 | struct MHD_Response *response; |
75 | int ret; | 76 | int ret; |
diff --git a/src/daemon/daemontest_put.c b/src/daemon/daemontest_put.c index bd3e0a52..f61cfb8e 100644 --- a/src/daemon/daemontest_put.c +++ b/src/daemon/daemontest_put.c | |||
@@ -76,7 +76,8 @@ ahc_echo (void *cls, | |||
76 | const char *url, | 76 | const char *url, |
77 | const char *method, | 77 | const char *method, |
78 | const char *version, | 78 | const char *version, |
79 | const char *upload_data, unsigned int *upload_data_size) | 79 | const char *upload_data, unsigned int *upload_data_size, |
80 | void ** unused) | ||
80 | { | 81 | { |
81 | int *done = cls; | 82 | int *done = cls; |
82 | struct MHD_Response *response; | 83 | struct MHD_Response *response; |
diff --git a/src/daemon/fileserver_example.c b/src/daemon/fileserver_example.c index 85b154e3..15b6aa24 100644 --- a/src/daemon/fileserver_example.c +++ b/src/daemon/fileserver_example.c | |||
@@ -52,7 +52,8 @@ ahc_echo (void *cls, | |||
52 | const char *url, | 52 | const char *url, |
53 | const char *method, | 53 | const char *method, |
54 | const char *upload_data, | 54 | const char *upload_data, |
55 | const char *version, unsigned int *upload_data_size) | 55 | const char *version, unsigned int *upload_data_size, |
56 | void ** unused) | ||
56 | { | 57 | { |
57 | struct MHD_Response *response; | 58 | struct MHD_Response *response; |
58 | int ret; | 59 | int ret; |
diff --git a/src/daemon/internal.h b/src/daemon/internal.h index 353312b4..b6f8336e 100644 --- a/src/daemon/internal.h +++ b/src/daemon/internal.h | |||
@@ -203,6 +203,14 @@ struct MHD_Connection | |||
203 | struct MemoryPool *pool; | 203 | struct MemoryPool *pool; |
204 | 204 | ||
205 | /** | 205 | /** |
206 | * We allow the main application to associate some | ||
207 | * pointer with the connection. Here is where we | ||
208 | * store it. (MHD does not know or care what it | ||
209 | * is). | ||
210 | */ | ||
211 | void * client_context; | ||
212 | |||
213 | /** | ||
206 | * Request method. Should be GET/POST/etc. Allocated | 214 | * Request method. Should be GET/POST/etc. Allocated |
207 | * in pool. | 215 | * in pool. |
208 | */ | 216 | */ |
@@ -376,6 +384,10 @@ struct MHD_Daemon | |||
376 | 384 | ||
377 | void *apc_cls; | 385 | void *apc_cls; |
378 | 386 | ||
387 | MHD_RequestCompletedCallback notify_completed; | ||
388 | |||
389 | void * notify_completed_cls; | ||
390 | |||
379 | /** | 391 | /** |
380 | * PID of the select thread (if we have internal select) | 392 | * PID of the select thread (if we have internal select) |
381 | */ | 393 | */ |
diff --git a/src/daemon/minimal_example.c b/src/daemon/minimal_example.c index 8de0064e..80442072 100644 --- a/src/daemon/minimal_example.c +++ b/src/daemon/minimal_example.c | |||
@@ -41,7 +41,8 @@ ahc_echo (void *cls, | |||
41 | const char *url, | 41 | const char *url, |
42 | const char *method, | 42 | const char *method, |
43 | const char *upload_data, | 43 | const char *upload_data, |
44 | const char *version, unsigned int *upload_data_size) | 44 | const char *version, unsigned int *upload_data_size, |
45 | void ** unused) | ||
45 | { | 46 | { |
46 | const char *me = cls; | 47 | const char *me = cls; |
47 | struct MHD_Response *response; | 48 | struct MHD_Response *response; |
diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h index d09c66a9..3a46c085 100644 --- a/src/include/microhttpd.h +++ b/src/include/microhttpd.h | |||
@@ -84,7 +84,7 @@ extern "C" | |||
84 | /** | 84 | /** |
85 | * Current version of the library. | 85 | * Current version of the library. |
86 | */ | 86 | */ |
87 | #define MHD_VERSION 0x00000003 | 87 | #define MHD_VERSION 0x00000004 |
88 | 88 | ||
89 | /** | 89 | /** |
90 | * MHD-internal return codes. | 90 | * MHD-internal return codes. |
@@ -319,6 +319,20 @@ enum MHD_OPTION | |||
319 | */ | 319 | */ |
320 | MHD_OPTION_CONNECTION_TIMEOUT = 3, | 320 | MHD_OPTION_CONNECTION_TIMEOUT = 3, |
321 | 321 | ||
322 | /** | ||
323 | * Register a function that should be called whenever a request has | ||
324 | * been completed (this can be used for application-specific clean | ||
325 | * up). Requests that have never been presented to the application | ||
326 | * (via MHD_AccessHandlerCallback) will not result in | ||
327 | * notifications.<p> | ||
328 | * | ||
329 | * This option should be followed by TWO pointers. First a pointer | ||
330 | * to a function of type "MHD_RequestCompletedCallback" and second a | ||
331 | * pointer to a closure to pass to the request completed callback. | ||
332 | * The second pointer maybe NULL. | ||
333 | */ | ||
334 | MHD_OPTION_NOTIFY_COMPLETED = 4, | ||
335 | |||
322 | }; | 336 | }; |
323 | 337 | ||
324 | /** | 338 | /** |
@@ -362,6 +376,40 @@ enum MHD_ValueKind | |||
362 | }; | 376 | }; |
363 | 377 | ||
364 | /** | 378 | /** |
379 | * The MHD_RequestTerminationCode specifies reasons | ||
380 | * why a request has been terminated (or completed). | ||
381 | */ | ||
382 | enum MHD_RequestTerminationCode | ||
383 | { | ||
384 | |||
385 | /** | ||
386 | * We finished sending the response. | ||
387 | */ | ||
388 | MHD_REQUEST_TERMINATED_COMPLETED_OK = 0, | ||
389 | |||
390 | /** | ||
391 | * Error handling the connection (resources | ||
392 | * exhausted, other side closed connection, | ||
393 | * application error accepting request, etc.) | ||
394 | */ | ||
395 | MHD_REQUEST_TERMINATED_WITH_ERROR = 1, | ||
396 | |||
397 | /** | ||
398 | * No activity on the connection for the number | ||
399 | * of seconds specified using | ||
400 | * MHD_OPTION_CONNECTION_TIMEOUT. | ||
401 | */ | ||
402 | MHD_REQUEST_TERMINATED_TIMEOUT_REACHED = 2, | ||
403 | |||
404 | /** | ||
405 | * We had to close the session since MHD was being | ||
406 | * shut down. | ||
407 | */ | ||
408 | MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN = 3, | ||
409 | |||
410 | }; | ||
411 | |||
412 | /** | ||
365 | * Handle for the daemon (listening on a socket for HTTP traffic). | 413 | * Handle for the daemon (listening on a socket for HTTP traffic). |
366 | */ | 414 | */ |
367 | struct MHD_Daemon; | 415 | struct MHD_Daemon; |
@@ -398,6 +446,8 @@ typedef int | |||
398 | * callbacks to provide content to give back to the client and return | 446 | * callbacks to provide content to give back to the client and return |
399 | * an HTTP status code (i.e. 200 for OK, 404, etc.). | 447 | * an HTTP status code (i.e. 200 for OK, 404, etc.). |
400 | * | 448 | * |
449 | * @param cls argument given together with the function | ||
450 | * pointer when the handler was registered with MHD | ||
401 | * @param url the requested url | 451 | * @param url the requested url |
402 | * @param method the HTTP method used ("GET", "PUT", etc.) | 452 | * @param method the HTTP method used ("GET", "PUT", etc.) |
403 | * @param version the HTTP version string (i.e. "HTTP/1.1") | 453 | * @param version the HTTP version string (i.e. "HTTP/1.1") |
@@ -411,6 +461,16 @@ typedef int | |||
411 | * @param upload_data_size set initially to the size of the | 461 | * @param upload_data_size set initially to the size of the |
412 | * upload_data provided; the method must update this | 462 | * upload_data provided; the method must update this |
413 | * value to the number of bytes NOT processed; | 463 | * value to the number of bytes NOT processed; |
464 | * @param con_cls pointer that the callback can set to some | ||
465 | * address and that will be preserved by MHD for future | ||
466 | * calls for this request; since the access handler may | ||
467 | * be called many times (i.e., for a PUT/POST operation | ||
468 | * with plenty of upload data) this allows the application | ||
469 | * to easily associate some request-specific state. | ||
470 | * If necessary, this state can be cleaned up in the | ||
471 | * global "MHD_RequestCompleted" callback (which | ||
472 | * can be set with the MHD_OPTION_NOTIFY_COMPLETED). | ||
473 | * Initially, <tt>*con_cls</tt> will be NULL. | ||
414 | * @return MHS_YES if the connection was handled successfully, | 474 | * @return MHS_YES if the connection was handled successfully, |
415 | * MHS_NO if the socket must be closed due to a serios | 475 | * MHS_NO if the socket must be closed due to a serios |
416 | * error while handling the request | 476 | * error while handling the request |
@@ -422,7 +482,25 @@ typedef int | |||
422 | const char *method, | 482 | const char *method, |
423 | const char *version, | 483 | const char *version, |
424 | const char *upload_data, | 484 | const char *upload_data, |
425 | unsigned int *upload_data_size); | 485 | unsigned int *upload_data_size, |
486 | void ** con_cls); | ||
487 | |||
488 | /** | ||
489 | * Signature of the callback used by MHD to notify the | ||
490 | * application about completed requests. | ||
491 | * | ||
492 | * @param cls client-defined closure | ||
493 | * @param connection connection handle | ||
494 | * @param con_cls value as set by the last call to | ||
495 | * the MHD_AccessHandlerCallback | ||
496 | * @param toe reason for request termination | ||
497 | * @see MHD_OPTION_NOTIFY_COMPLETED | ||
498 | */ | ||
499 | typedef void | ||
500 | (*MHD_RequestCompletedCallback) (void *cls, | ||
501 | struct MHD_Connection * connection, | ||
502 | void ** con_cls, | ||
503 | enum MHD_RequestTerminationCode toe); | ||
426 | 504 | ||
427 | /** | 505 | /** |
428 | * Iterator over key-value pairs. This iterator | 506 | * Iterator over key-value pairs. This iterator |