diff options
author | Christian Grothoff <christian@grothoff.org> | 2007-08-12 06:01:48 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2007-08-12 06:01:48 +0000 |
commit | 85b7d00955a8adb9e6d8d42ba37c5c0d53cafc53 (patch) | |
tree | a5c244da50ef0a5659e368cb9c1ac91b0861076c | |
parent | c75bf1093162231d4e2f09f399f2d6039d2c321f (diff) | |
download | libmicrohttpd-85b7d00955a8adb9e6d8d42ba37c5c0d53cafc53.tar.gz libmicrohttpd-85b7d00955a8adb9e6d8d42ba37c5c0d53cafc53.zip |
formatting and versioning
-rw-r--r-- | README | 1 | ||||
-rw-r--r-- | configure.ac | 4 | ||||
-rw-r--r-- | doc/libmicrohttpd.3 | 6 | ||||
-rw-r--r-- | src/daemon/Makefile.am | 4 | ||||
-rw-r--r-- | src/daemon/connection.c | 1541 | ||||
-rw-r--r-- | src/daemon/connection.h | 18 | ||||
-rw-r--r-- | src/daemon/daemon.c | 747 | ||||
-rw-r--r-- | src/daemon/daemontest.c | 153 | ||||
-rw-r--r-- | src/daemon/daemontest_get.c | 470 | ||||
-rw-r--r-- | src/daemon/daemontest_long_header.c | 321 | ||||
-rw-r--r-- | src/daemon/daemontest_post.c | 538 | ||||
-rw-r--r-- | src/daemon/daemontest_put.c | 562 | ||||
-rw-r--r-- | src/daemon/fileserver_example.c | 113 | ||||
-rw-r--r-- | src/daemon/internal.c | 15 | ||||
-rw-r--r-- | src/daemon/internal.h | 67 | ||||
-rw-r--r-- | src/daemon/memorypool.c | 147 | ||||
-rw-r--r-- | src/daemon/memorypool.h | 16 | ||||
-rw-r--r-- | src/daemon/minimal_example.c | 67 | ||||
-rw-r--r-- | src/daemon/plibc.h | 774 | ||||
-rw-r--r-- | src/daemon/response.c | 257 | ||||
-rw-r--r-- | src/daemon/response.h | 2 | ||||
-rw-r--r-- | src/include/microhttpd.h | 156 |
22 files changed, 2805 insertions, 3174 deletions
@@ -38,4 +38,3 @@ Documentation: | |||
38 | ============== | 38 | ============== |
39 | - manual (texinfo, man) | 39 | - manual (texinfo, man) |
40 | - tutorial | 40 | - tutorial |
41 | - web page | ||
diff --git a/configure.ac b/configure.ac index de88f861..b87f8d95 100644 --- a/configure.ac +++ b/configure.ac | |||
@@ -21,8 +21,8 @@ | |||
21 | # | 21 | # |
22 | # | 22 | # |
23 | AC_PREREQ(2.57) | 23 | AC_PREREQ(2.57) |
24 | AC_INIT([libmicrohttpd], [0.0.0],[libmicrohttpd@gnunet.org]) | 24 | AC_INIT([libmicrohttpd], [0.0.1],[libmicrohttpd@gnunet.org]) |
25 | AM_INIT_AUTOMAKE([libmicrohttpd], [0.0.0]) | 25 | AM_INIT_AUTOMAKE([libmicrohttpd], [0.0.1]) |
26 | AM_CONFIG_HEADER([config.h]) | 26 | AM_CONFIG_HEADER([config.h]) |
27 | 27 | ||
28 | AH_TOP([#define _GNU_SOURCE 1]) | 28 | AH_TOP([#define _GNU_SOURCE 1]) |
diff --git a/doc/libmicrohttpd.3 b/doc/libmicrohttpd.3 index 4480c93c..3c478c72 100644 --- a/doc/libmicrohttpd.3 +++ b/doc/libmicrohttpd.3 | |||
@@ -5,11 +5,11 @@ libmicrohttpd \- library for embedding HTTP servers | |||
5 | 5 | ||
6 | \fB#include <microhttpd.h> | 6 | \fB#include <microhttpd.h> |
7 | 7 | ||
8 | \fPInsert API here. | ||
9 | |||
10 | .SH "DESCRIPTION" | 8 | .SH "DESCRIPTION" |
11 | .P | 9 | .P |
12 | Insert API description here. | 10 | libmicrohttpd (short MHD) allows applications to easily integrate the functionality of a simple HTTP server. |
11 | .P | ||
12 | The details of the API are described in comments in the header file and on the webpage. | ||
13 | 13 | ||
14 | .P | 14 | .P |
15 | .SH "SEE ALSO" | 15 | .SH "SEE ALSO" |
diff --git a/src/daemon/Makefile.am b/src/daemon/Makefile.am index 80a8d751..0f11b662 100644 --- a/src/daemon/Makefile.am +++ b/src/daemon/Makefile.am | |||
@@ -6,7 +6,7 @@ lib_LTLIBRARIES = \ | |||
6 | libmicrohttpd.la | 6 | libmicrohttpd.la |
7 | 7 | ||
8 | libmicrohttpd_la_LDFLAGS = \ | 8 | libmicrohttpd_la_LDFLAGS = \ |
9 | -export-dynamic -version-info 0:0:0 | 9 | -export-dynamic -version-info 0:1:0 |
10 | libmicrohttpd_la_SOURCES = \ | 10 | libmicrohttpd_la_SOURCES = \ |
11 | connection.c connection.h \ | 11 | connection.c connection.h \ |
12 | daemon.c \ | 12 | daemon.c \ |
@@ -92,4 +92,4 @@ daemontest_long_header_LDADD = \ | |||
92 | $(top_builddir)/src/daemon/libmicrohttpd.la \ | 92 | $(top_builddir)/src/daemon/libmicrohttpd.la \ |
93 | @LIBCURL@ | 93 | @LIBCURL@ |
94 | 94 | ||
95 | endif \ No newline at end of file | 95 | endif |
diff --git a/src/daemon/connection.c b/src/daemon/connection.c index b5d0b3dd..fdbc975c 100644 --- a/src/daemon/connection.c +++ b/src/daemon/connection.c | |||
@@ -50,29 +50,29 @@ | |||
50 | * @return number of entries iterated over | 50 | * @return number of entries iterated over |
51 | */ | 51 | */ |
52 | int | 52 | int |
53 | MHD_get_connection_values(struct MHD_Connection * connection, | 53 | MHD_get_connection_values (struct MHD_Connection *connection, |
54 | enum MHD_ValueKind kind, | 54 | enum MHD_ValueKind kind, |
55 | MHD_KeyValueIterator iterator, | 55 | MHD_KeyValueIterator iterator, void *iterator_cls) |
56 | void * iterator_cls) { | 56 | { |
57 | int ret; | 57 | int ret; |
58 | struct MHD_HTTP_Header * pos; | 58 | struct MHD_HTTP_Header *pos; |
59 | 59 | ||
60 | if (connection == NULL) | 60 | if (connection == NULL) |
61 | return -1; | 61 | return -1; |
62 | ret = 0; | 62 | ret = 0; |
63 | pos = connection->headers_received; | 63 | pos = connection->headers_received; |
64 | while (pos != NULL) { | 64 | while (pos != NULL) |
65 | if (0 != (pos->kind & kind)) { | 65 | { |
66 | ret++; | 66 | if (0 != (pos->kind & kind)) |
67 | if ( (iterator != NULL) && | 67 | { |
68 | (MHD_YES != iterator(iterator_cls, | 68 | ret++; |
69 | kind, | 69 | if ((iterator != NULL) && |
70 | pos->header, | 70 | (MHD_YES != iterator (iterator_cls, |
71 | pos->value)) ) | 71 | kind, pos->header, pos->value))) |
72 | return ret; | 72 | return ret; |
73 | } | ||
74 | pos = pos->next; | ||
73 | } | 75 | } |
74 | pos = pos->next; | ||
75 | } | ||
76 | return ret; | 76 | return ret; |
77 | } | 77 | } |
78 | 78 | ||
@@ -85,21 +85,20 @@ MHD_get_connection_values(struct MHD_Connection * connection, | |||
85 | * @return NULL if no such item was found | 85 | * @return NULL if no such item was found |
86 | */ | 86 | */ |
87 | const char * | 87 | const char * |
88 | MHD_lookup_connection_value(struct MHD_Connection * connection, | 88 | MHD_lookup_connection_value (struct MHD_Connection *connection, |
89 | enum MHD_ValueKind kind, | 89 | enum MHD_ValueKind kind, const char *key) |
90 | const char * key) { | 90 | { |
91 | struct MHD_HTTP_Header * pos; | 91 | struct MHD_HTTP_Header *pos; |
92 | 92 | ||
93 | if (connection == NULL) | 93 | if (connection == NULL) |
94 | return NULL; | 94 | return NULL; |
95 | pos = connection->headers_received; | 95 | pos = connection->headers_received; |
96 | while (pos != NULL) { | 96 | while (pos != NULL) |
97 | if ( (0 != (pos->kind & kind)) && | 97 | { |
98 | (0 == strcasecmp(key, | 98 | if ((0 != (pos->kind & kind)) && (0 == strcasecmp (key, pos->header))) |
99 | pos->header)) ) | 99 | return pos->value; |
100 | return pos->value; | 100 | pos = pos->next; |
101 | pos = pos->next; | 101 | } |
102 | } | ||
103 | return NULL; | 102 | return NULL; |
104 | } | 103 | } |
105 | 104 | ||
@@ -114,25 +113,24 @@ MHD_lookup_connection_value(struct MHD_Connection * connection, | |||
114 | * MHD_YES on success or if message has been queued | 113 | * MHD_YES on success or if message has been queued |
115 | */ | 114 | */ |
116 | int | 115 | int |
117 | MHD_queue_response(struct MHD_Connection * connection, | 116 | MHD_queue_response (struct MHD_Connection *connection, |
118 | unsigned int status_code, | 117 | unsigned int status_code, struct MHD_Response *response) |
119 | struct MHD_Response * response) { | 118 | { |
120 | if ( (connection == NULL) || | 119 | if ((connection == NULL) || |
121 | (response == NULL) || | 120 | (response == NULL) || |
122 | (connection->response != NULL) || | 121 | (connection->response != NULL) || |
123 | (connection->bodyReceived == 0) || | 122 | (connection->bodyReceived == 0) || (connection->headersReceived == 0)) |
124 | (connection->headersReceived == 0) ) | 123 | return MHD_NO; |
125 | return MHD_NO; | 124 | MHD_increment_response_rc (response); |
126 | MHD_increment_response_rc(response); | ||
127 | connection->response = response; | 125 | connection->response = response; |
128 | connection->responseCode = status_code; | 126 | connection->responseCode = status_code; |
129 | if ( (connection->method != NULL) && | 127 | if ((connection->method != NULL) && |
130 | (0 == strcasecmp(connection->method, | 128 | (0 == strcasecmp (connection->method, MHD_HTTP_METHOD_HEAD))) |
131 | MHD_HTTP_METHOD_HEAD)) ) { | 129 | { |
132 | /* if this is a "HEAD" request, pretend that we | 130 | /* if this is a "HEAD" request, pretend that we |
133 | have already sent the full message body */ | 131 | have already sent the full message body */ |
134 | connection->messagePos = response->total_size; | 132 | connection->messagePos = response->total_size; |
135 | } | 133 | } |
136 | return MHD_YES; | 134 | return MHD_YES; |
137 | } | 135 | } |
138 | 136 | ||
@@ -140,20 +138,20 @@ MHD_queue_response(struct MHD_Connection * connection, | |||
140 | * Do we (still) need to send a 100 continue | 138 | * Do we (still) need to send a 100 continue |
141 | * message for this connection? | 139 | * message for this connection? |
142 | */ | 140 | */ |
143 | static int | 141 | static int |
144 | MHD_need_100_continue(struct MHD_Connection * connection) { | 142 | MHD_need_100_continue (struct MHD_Connection *connection) |
145 | const char * expect; | 143 | { |
144 | const char *expect; | ||
146 | 145 | ||
147 | return ( (connection->version != NULL) && | 146 | return ((connection->version != NULL) && |
148 | (0 == strcasecmp(connection->version, | 147 | (0 == strcasecmp (connection->version, |
149 | MHD_HTTP_VERSION_1_1)) && | 148 | MHD_HTTP_VERSION_1_1)) && |
150 | (connection->headersReceived == 1) && | 149 | (connection->headersReceived == 1) && |
151 | (NULL != (expect = MHD_lookup_connection_value(connection, | 150 | (NULL != (expect = MHD_lookup_connection_value (connection, |
152 | MHD_HEADER_KIND, | 151 | MHD_HEADER_KIND, |
153 | MHD_HTTP_HEADER_EXPECT))) && | 152 | MHD_HTTP_HEADER_EXPECT))) |
154 | (0 == strcasecmp(expect, | 153 | && (0 == strcasecmp (expect, "100-continue")) |
155 | "100-continue")) && | 154 | && (connection->continuePos < strlen (HTTP_100_CONTINUE))); |
156 | (connection->continuePos < strlen(HTTP_100_CONTINUE)) ); | ||
157 | } | 155 | } |
158 | 156 | ||
159 | /** | 157 | /** |
@@ -162,49 +160,56 @@ MHD_need_100_continue(struct MHD_Connection * connection) { | |||
162 | * @return MHD_YES on success | 160 | * @return MHD_YES on success |
163 | */ | 161 | */ |
164 | int | 162 | int |
165 | MHD_connection_get_fdset(struct MHD_Connection * connection, | 163 | MHD_connection_get_fdset (struct MHD_Connection *connection, |
166 | fd_set * read_fd_set, | 164 | fd_set * read_fd_set, |
167 | fd_set * write_fd_set, | 165 | fd_set * write_fd_set, |
168 | fd_set * except_fd_set, | 166 | fd_set * except_fd_set, int *max_fd) |
169 | int * max_fd) { | 167 | { |
170 | int fd; | 168 | int fd; |
171 | void * buf; | 169 | void *buf; |
172 | 170 | ||
173 | fd = connection->socket_fd; | 171 | fd = connection->socket_fd; |
174 | if (fd == -1) | 172 | if (fd == -1) |
175 | return MHD_YES; | 173 | return MHD_YES; |
176 | if ( (connection->read_close == MHD_NO) && | 174 | if ((connection->read_close == MHD_NO) && |
177 | ( (connection->headersReceived == 0) || | 175 | ((connection->headersReceived == 0) || |
178 | (connection->readLoc < connection->read_buffer_size) ) ) { | 176 | (connection->readLoc < connection->read_buffer_size))) |
179 | FD_SET(fd, read_fd_set); | 177 | { |
180 | if (fd > *max_fd) | 178 | FD_SET (fd, read_fd_set); |
181 | *max_fd = fd; | 179 | if (fd > *max_fd) |
182 | } else { | 180 | *max_fd = fd; |
183 | if ( (connection->read_close == MHD_NO) && | 181 | } |
184 | ( (connection->headersReceived == 1) && | 182 | else |
185 | (connection->post_processed == MHD_NO) && | 183 | { |
186 | (connection->readLoc == connection->read_buffer_size) ) ) { | 184 | if ((connection->read_close == MHD_NO) && |
187 | /* try growing the read buffer, just in case */ | 185 | ((connection->headersReceived == 1) && |
188 | buf = MHD_pool_reallocate(connection->pool, | 186 | (connection->post_processed == MHD_NO) && |
189 | connection->read_buffer, | 187 | (connection->readLoc == connection->read_buffer_size))) |
190 | connection->read_buffer_size, | 188 | { |
191 | connection->read_buffer_size * 2 + MHD_BUF_INC_SIZE); | 189 | /* try growing the read buffer, just in case */ |
192 | if (buf != NULL) { | 190 | buf = MHD_pool_reallocate (connection->pool, |
193 | /* we can actually grow the buffer, do it! */ | 191 | connection->read_buffer, |
194 | connection->read_buffer = buf; | 192 | connection->read_buffer_size, |
195 | connection->read_buffer_size = connection->read_buffer_size * 2 + MHD_BUF_INC_SIZE; | 193 | connection->read_buffer_size * 2 + |
196 | FD_SET(fd, read_fd_set); | 194 | MHD_BUF_INC_SIZE); |
197 | if (fd > *max_fd) | 195 | if (buf != NULL) |
198 | *max_fd = fd; | 196 | { |
199 | } | 197 | /* we can actually grow the buffer, do it! */ |
198 | connection->read_buffer = buf; | ||
199 | connection->read_buffer_size = | ||
200 | connection->read_buffer_size * 2 + MHD_BUF_INC_SIZE; | ||
201 | FD_SET (fd, read_fd_set); | ||
202 | if (fd > *max_fd) | ||
203 | *max_fd = fd; | ||
204 | } | ||
205 | } | ||
206 | } | ||
207 | if ((connection->response != NULL) || MHD_need_100_continue (connection)) | ||
208 | { | ||
209 | FD_SET (fd, write_fd_set); | ||
210 | if (fd > *max_fd) | ||
211 | *max_fd = fd; | ||
200 | } | 212 | } |
201 | } | ||
202 | if ( (connection->response != NULL) || | ||
203 | MHD_need_100_continue(connection) ) { | ||
204 | FD_SET(fd, write_fd_set); | ||
205 | if (fd > *max_fd) | ||
206 | *max_fd = fd; | ||
207 | } | ||
208 | return MHD_YES; | 213 | return MHD_YES; |
209 | } | 214 | } |
210 | 215 | ||
@@ -216,9 +221,10 @@ MHD_connection_get_fdset(struct MHD_Connection * connection, | |||
216 | * @param status_code the response code to send (413 or 414) | 221 | * @param status_code the response code to send (413 or 414) |
217 | */ | 222 | */ |
218 | static void | 223 | static void |
219 | MHD_excessive_data_handler(struct MHD_Connection * connection, | 224 | MHD_excessive_data_handler (struct MHD_Connection *connection, |
220 | unsigned int status_code) { | 225 | unsigned int status_code) |
221 | struct MHD_Response * response; | 226 | { |
227 | struct MHD_Response *response; | ||
222 | 228 | ||
223 | /* die, header far too long to be reasonable; | 229 | /* die, header far too long to be reasonable; |
224 | FIXME: send proper response to client | 230 | FIXME: send proper response to client |
@@ -226,16 +232,12 @@ MHD_excessive_data_handler(struct MHD_Connection * connection, | |||
226 | connection->read_close = MHD_YES; | 232 | connection->read_close = MHD_YES; |
227 | connection->headersReceived = MHD_YES; | 233 | connection->headersReceived = MHD_YES; |
228 | connection->bodyReceived = MHD_YES; | 234 | connection->bodyReceived = MHD_YES; |
229 | MHD_DLOG(connection->daemon, | 235 | MHD_DLOG (connection->daemon, |
230 | "Received excessively long header, closing connection.\n"); | 236 | "Received excessively long header, closing connection.\n"); |
231 | response = MHD_create_response_from_data(strlen(REQUEST_TOO_BIG), | 237 | response = MHD_create_response_from_data (strlen (REQUEST_TOO_BIG), |
232 | REQUEST_TOO_BIG, | 238 | REQUEST_TOO_BIG, MHD_NO, MHD_NO); |
233 | MHD_NO, | 239 | MHD_queue_response (connection, status_code, response); |
234 | MHD_NO); | 240 | MHD_destroy_response (response); |
235 | MHD_queue_response(connection, | ||
236 | status_code, | ||
237 | response); | ||
238 | MHD_destroy_response(response); | ||
239 | } | 241 | } |
240 | 242 | ||
241 | /** | 243 | /** |
@@ -247,41 +249,47 @@ MHD_excessive_data_handler(struct MHD_Connection * connection, | |||
247 | * return NULL. Otherwise return a pointer to the line. | 249 | * return NULL. Otherwise return a pointer to the line. |
248 | */ | 250 | */ |
249 | static char * | 251 | static char * |
250 | MHD_get_next_header_line(struct MHD_Connection * connection) { | 252 | MHD_get_next_header_line (struct MHD_Connection *connection) |
251 | char * rbuf; | 253 | { |
254 | char *rbuf; | ||
252 | size_t pos; | 255 | size_t pos; |
253 | 256 | ||
254 | if (connection->readLoc == 0) | 257 | if (connection->readLoc == 0) |
255 | return NULL; | 258 | return NULL; |
256 | pos = 0; | 259 | pos = 0; |
257 | rbuf = connection->read_buffer; | 260 | rbuf = connection->read_buffer; |
258 | while ( (pos < connection->readLoc - 1) && | 261 | while ((pos < connection->readLoc - 1) && |
259 | (rbuf[pos] != '\r') && | 262 | (rbuf[pos] != '\r') && (rbuf[pos] != '\n')) |
260 | (rbuf[pos] != '\n') ) | ||
261 | pos++; | 263 | pos++; |
262 | if (pos == connection->readLoc - 1) { | 264 | if (pos == connection->readLoc - 1) |
263 | /* not found, consider growing... */ | 265 | { |
264 | if (connection->readLoc == connection->read_buffer_size) { | 266 | /* not found, consider growing... */ |
265 | rbuf = MHD_pool_reallocate(connection->pool, | 267 | if (connection->readLoc == connection->read_buffer_size) |
266 | connection->read_buffer, | 268 | { |
267 | connection->read_buffer_size, | 269 | rbuf = MHD_pool_reallocate (connection->pool, |
268 | connection->read_buffer_size * 2 + MHD_BUF_INC_SIZE); | 270 | connection->read_buffer, |
269 | if (rbuf == NULL) { | 271 | connection->read_buffer_size, |
270 | MHD_excessive_data_handler(connection, | 272 | connection->read_buffer_size * 2 + |
271 | (connection->url != NULL) | 273 | MHD_BUF_INC_SIZE); |
272 | ? MHD_HTTP_REQUEST_ENTITY_TOO_LARGE | 274 | if (rbuf == NULL) |
273 | : MHD_HTTP_REQUEST_URI_TOO_LONG); | 275 | { |
274 | } else { | 276 | MHD_excessive_data_handler (connection, |
275 | connection->read_buffer_size = connection->read_buffer_size * 2 + MHD_BUF_INC_SIZE; | 277 | (connection->url != NULL) |
276 | connection->read_buffer = rbuf; | 278 | ? MHD_HTTP_REQUEST_ENTITY_TOO_LARGE |
277 | } | 279 | : MHD_HTTP_REQUEST_URI_TOO_LONG); |
280 | } | ||
281 | else | ||
282 | { | ||
283 | connection->read_buffer_size = | ||
284 | connection->read_buffer_size * 2 + MHD_BUF_INC_SIZE; | ||
285 | connection->read_buffer = rbuf; | ||
286 | } | ||
287 | } | ||
288 | return NULL; | ||
278 | } | 289 | } |
279 | return NULL; | ||
280 | } | ||
281 | /* found, check if we have proper CRLF */ | 290 | /* found, check if we have proper CRLF */ |
282 | if ( (rbuf[pos] == '\r') && | 291 | if ((rbuf[pos] == '\r') && (rbuf[pos + 1] == '\n')) |
283 | (rbuf[pos+1] == '\n') ) | 292 | rbuf[pos++] = '\0'; /* skip both r and n */ |
284 | rbuf[pos++] = '\0'; /* skip both r and n */ | ||
285 | rbuf[pos++] = '\0'; | 293 | rbuf[pos++] = '\0'; |
286 | connection->read_buffer += pos; | 294 | connection->read_buffer += pos; |
287 | connection->read_buffer_size -= pos; | 295 | connection->read_buffer_size -= pos; |
@@ -293,22 +301,21 @@ MHD_get_next_header_line(struct MHD_Connection * connection) { | |||
293 | * @return MHD_NO on failure (out of memory), MHD_YES for success | 301 | * @return MHD_NO on failure (out of memory), MHD_YES for success |
294 | */ | 302 | */ |
295 | static int | 303 | static int |
296 | MHD_connection_add_header(struct MHD_Connection * connection, | 304 | MHD_connection_add_header (struct MHD_Connection *connection, |
297 | char * key, | 305 | char *key, char *value, enum MHD_ValueKind kind) |
298 | char * value, | 306 | { |
299 | enum MHD_ValueKind kind) { | 307 | struct MHD_HTTP_Header *hdr; |
300 | struct MHD_HTTP_Header * hdr; | ||
301 | 308 | ||
302 | hdr = MHD_pool_allocate(connection->pool, | 309 | hdr = MHD_pool_allocate (connection->pool, |
303 | sizeof(struct MHD_HTTP_Header), | 310 | sizeof (struct MHD_HTTP_Header), MHD_YES); |
304 | MHD_YES); | 311 | if (hdr == NULL) |
305 | if (hdr == NULL) { | 312 | { |
306 | MHD_DLOG(connection->daemon, | 313 | MHD_DLOG (connection->daemon, |
307 | "Not enough memory to allocate header record!\n"); | 314 | "Not enough memory to allocate header record!\n"); |
308 | MHD_excessive_data_handler(connection, | 315 | MHD_excessive_data_handler (connection, |
309 | MHD_HTTP_REQUEST_ENTITY_TOO_LARGE); | 316 | MHD_HTTP_REQUEST_ENTITY_TOO_LARGE); |
310 | return MHD_NO; | 317 | return MHD_NO; |
311 | } | 318 | } |
312 | hdr->next = connection->headers_received; | 319 | hdr->next = connection->headers_received; |
313 | hdr->header = key; | 320 | hdr->header = key; |
314 | hdr->value = value; | 321 | hdr->value = value; |
@@ -319,60 +326,57 @@ MHD_connection_add_header(struct MHD_Connection * connection, | |||
319 | 326 | ||
320 | /** | 327 | /** |
321 | * Process escape sequences ('+'=space, %HH) | 328 | * Process escape sequences ('+'=space, %HH) |
322 | */ | 329 | */ |
323 | static void | 330 | static void |
324 | MHD_http_unescape(char * val) { | 331 | MHD_http_unescape (char *val) |
325 | char * esc; | 332 | { |
333 | char *esc; | ||
326 | unsigned int num; | 334 | unsigned int num; |
327 | 335 | ||
328 | while (NULL != (esc = strstr(val, "+"))) | 336 | while (NULL != (esc = strstr (val, "+"))) |
329 | *esc = ' '; | 337 | *esc = ' '; |
330 | while (NULL != (esc = strstr(val, "%"))) { | 338 | while (NULL != (esc = strstr (val, "%"))) |
331 | if ( (1 == sscanf(&esc[1], | 339 | { |
332 | "%2x", | 340 | if ((1 == sscanf (&esc[1], |
333 | &num)) || | 341 | "%2x", &num)) || (1 == sscanf (&esc[1], "%2X", &num))) |
334 | (1 == sscanf(&esc[1], | 342 | { |
335 | "%2X", | 343 | esc[0] = (unsigned char) num; |
336 | &num)) ) { | 344 | memmove (&esc[1], &esc[3], strlen (&esc[3])); |
337 | esc[0] = (unsigned char) num; | 345 | } |
338 | memmove(&esc[1], | 346 | val = esc + 1; |
339 | &esc[3], | ||
340 | strlen(&esc[3])); | ||
341 | } | 347 | } |
342 | val = esc+1; | ||
343 | } | ||
344 | } | 348 | } |
345 | 349 | ||
346 | /** | 350 | /** |
347 | * @return MHD_NO on failure (out of memory), MHD_YES for success | 351 | * @return MHD_NO on failure (out of memory), MHD_YES for success |
348 | */ | 352 | */ |
349 | static int | 353 | static int |
350 | parse_arguments(enum MHD_ValueKind kind, | 354 | parse_arguments (enum MHD_ValueKind kind, |
351 | struct MHD_Connection * connection, | 355 | struct MHD_Connection *connection, char *args) |
352 | char * args) { | 356 | { |
353 | char * equals; | 357 | char *equals; |
354 | char * amper; | 358 | char *amper; |
355 | 359 | ||
356 | while (args != NULL) { | 360 | while (args != NULL) |
357 | equals = strstr(args, "="); | 361 | { |
358 | if (equals == NULL) | 362 | equals = strstr (args, "="); |
359 | return MHD_NO; /* invalid, ignore */ | 363 | if (equals == NULL) |
360 | equals[0] = '\0'; | 364 | return MHD_NO; /* invalid, ignore */ |
361 | equals++; | 365 | equals[0] = '\0'; |
362 | amper = strstr(equals, "&"); | 366 | equals++; |
363 | if (amper != NULL) { | 367 | amper = strstr (equals, "&"); |
364 | amper[0] = '\0'; | 368 | if (amper != NULL) |
365 | amper++; | 369 | { |
370 | amper[0] = '\0'; | ||
371 | amper++; | ||
372 | } | ||
373 | MHD_http_unescape (args); | ||
374 | MHD_http_unescape (equals); | ||
375 | if (MHD_NO == MHD_connection_add_header (connection, | ||
376 | args, equals, kind)) | ||
377 | return MHD_NO; | ||
378 | args = amper; | ||
366 | } | 379 | } |
367 | MHD_http_unescape(args); | ||
368 | MHD_http_unescape(equals); | ||
369 | if (MHD_NO == MHD_connection_add_header(connection, | ||
370 | args, | ||
371 | equals, | ||
372 | kind)) | ||
373 | return MHD_NO; | ||
374 | args = amper; | ||
375 | } | ||
376 | return MHD_YES; | 380 | return MHD_YES; |
377 | } | 381 | } |
378 | 382 | ||
@@ -382,68 +386,63 @@ parse_arguments(enum MHD_ValueKind kind, | |||
382 | * @return MHD_YES for success, MHD_NO for failure (malformed, out of memory) | 386 | * @return MHD_YES for success, MHD_NO for failure (malformed, out of memory) |
383 | */ | 387 | */ |
384 | static int | 388 | static int |
385 | MHD_parse_cookie_header(struct MHD_Connection * connection) { | 389 | MHD_parse_cookie_header (struct MHD_Connection *connection) |
386 | const char * hdr; | 390 | { |
387 | char * cpy; | 391 | const char *hdr; |
388 | char * pos; | 392 | char *cpy; |
389 | char * semicolon; | 393 | char *pos; |
390 | char * equals; | 394 | char *semicolon; |
395 | char *equals; | ||
391 | int quotes; | 396 | int quotes; |
392 | 397 | ||
393 | hdr = MHD_lookup_connection_value(connection, | 398 | hdr = MHD_lookup_connection_value (connection, MHD_HEADER_KIND, "Cookie"); |
394 | MHD_HEADER_KIND, | ||
395 | "Cookie"); | ||
396 | if (hdr == NULL) | 399 | if (hdr == NULL) |
397 | return MHD_YES; | 400 | return MHD_YES; |
398 | cpy = MHD_pool_allocate(connection->pool, | 401 | cpy = MHD_pool_allocate (connection->pool, strlen (hdr) + 1, MHD_YES); |
399 | strlen(hdr)+1, | 402 | if (cpy == NULL) |
400 | MHD_YES); | 403 | { |
401 | if (cpy == NULL) { | 404 | MHD_DLOG (connection->daemon, "Not enough memory to parse cookies!\n"); |
402 | MHD_DLOG(connection->daemon, | 405 | MHD_excessive_data_handler (connection, |
403 | "Not enough memory to parse cookies!\n"); | 406 | MHD_HTTP_REQUEST_ENTITY_TOO_LARGE); |
404 | MHD_excessive_data_handler(connection, | 407 | return MHD_NO; |
405 | MHD_HTTP_REQUEST_ENTITY_TOO_LARGE); | ||
406 | return MHD_NO; | ||
407 | } | ||
408 | memcpy(cpy, | ||
409 | hdr, | ||
410 | strlen(hdr)+1); | ||
411 | pos = cpy; | ||
412 | while (pos != NULL) { | ||
413 | equals = strstr(pos, "="); | ||
414 | if (equals == NULL) | ||
415 | break; | ||
416 | equals[0] = '\0'; | ||
417 | equals++; | ||
418 | quotes = 0; | ||
419 | semicolon = equals; | ||
420 | while ( (semicolon[0] != '\0') && | ||
421 | ( (quotes != 0) || | ||
422 | ( (semicolon[0] != ';') && | ||
423 | (semicolon[0] != ',') ) ) ) { | ||
424 | if (semicolon[0] == '"') | ||
425 | quotes = (quotes + 1) & 1; | ||
426 | semicolon++; | ||
427 | } | ||
428 | if (semicolon[0] == '\0') | ||
429 | semicolon = NULL; | ||
430 | if (semicolon != NULL) { | ||
431 | semicolon[0] = '\0'; | ||
432 | semicolon++; | ||
433 | } | 408 | } |
434 | /* remove quotes */ | 409 | memcpy (cpy, hdr, strlen (hdr) + 1); |
435 | if ( (equals[0] == '"') && | 410 | pos = cpy; |
436 | (equals[strlen(equals)-1] == '"') ) { | 411 | while (pos != NULL) |
437 | equals[strlen(equals)-1] = '\0'; | 412 | { |
413 | equals = strstr (pos, "="); | ||
414 | if (equals == NULL) | ||
415 | break; | ||
416 | equals[0] = '\0'; | ||
438 | equals++; | 417 | equals++; |
418 | quotes = 0; | ||
419 | semicolon = equals; | ||
420 | while ((semicolon[0] != '\0') && | ||
421 | ((quotes != 0) || | ||
422 | ((semicolon[0] != ';') && (semicolon[0] != ',')))) | ||
423 | { | ||
424 | if (semicolon[0] == '"') | ||
425 | quotes = (quotes + 1) & 1; | ||
426 | semicolon++; | ||
427 | } | ||
428 | if (semicolon[0] == '\0') | ||
429 | semicolon = NULL; | ||
430 | if (semicolon != NULL) | ||
431 | { | ||
432 | semicolon[0] = '\0'; | ||
433 | semicolon++; | ||
434 | } | ||
435 | /* remove quotes */ | ||
436 | if ((equals[0] == '"') && (equals[strlen (equals) - 1] == '"')) | ||
437 | { | ||
438 | equals[strlen (equals) - 1] = '\0'; | ||
439 | equals++; | ||
440 | } | ||
441 | if (MHD_NO == MHD_connection_add_header (connection, | ||
442 | pos, equals, MHD_COOKIE_KIND)) | ||
443 | return MHD_NO; | ||
444 | pos = semicolon; | ||
439 | } | 445 | } |
440 | if (MHD_NO == MHD_connection_add_header(connection, | ||
441 | pos, | ||
442 | equals, | ||
443 | MHD_COOKIE_KIND)) | ||
444 | return MHD_NO; | ||
445 | pos = semicolon; | ||
446 | } | ||
447 | return MHD_YES; | 446 | return MHD_YES; |
448 | } | 447 | } |
449 | 448 | ||
@@ -455,33 +454,33 @@ MHD_parse_cookie_header(struct MHD_Connection * connection) { | |||
455 | * @return MHD_YES if the line is ok, MHD_NO if it is malformed | 454 | * @return MHD_YES if the line is ok, MHD_NO if it is malformed |
456 | */ | 455 | */ |
457 | static int | 456 | static int |
458 | parse_initial_message_line(struct MHD_Connection * connection, | 457 | parse_initial_message_line (struct MHD_Connection *connection, char *line) |
459 | char * line) { | 458 | { |
460 | char * uri; | 459 | char *uri; |
461 | char * httpVersion; | 460 | char *httpVersion; |
462 | char * args; | 461 | char *args; |
463 | 462 | ||
464 | uri = strstr(line, " "); | 463 | uri = strstr (line, " "); |
465 | if (uri == NULL) | 464 | if (uri == NULL) |
466 | return MHD_NO; /* serious error */ | 465 | return MHD_NO; /* serious error */ |
467 | uri[0] = '\0'; | 466 | uri[0] = '\0'; |
468 | connection->method = line; | 467 | connection->method = line; |
469 | uri++; | 468 | uri++; |
470 | while (uri[0] == ' ') | 469 | while (uri[0] == ' ') |
471 | uri++; | 470 | uri++; |
472 | httpVersion = strstr(uri, " "); | 471 | httpVersion = strstr (uri, " "); |
473 | if (httpVersion != NULL) { | 472 | if (httpVersion != NULL) |
474 | httpVersion[0] = '\0'; | 473 | { |
475 | httpVersion++; | 474 | httpVersion[0] = '\0'; |
476 | } | 475 | httpVersion++; |
477 | args = strstr(uri, "?"); | 476 | } |
478 | if (args != NULL) { | 477 | args = strstr (uri, "?"); |
479 | args[0] = '\0'; | 478 | if (args != NULL) |
480 | args++; | 479 | { |
481 | parse_arguments(MHD_GET_ARGUMENT_KIND, | 480 | args[0] = '\0'; |
482 | connection, | 481 | args++; |
483 | args); | 482 | parse_arguments (MHD_GET_ARGUMENT_KIND, connection, args); |
484 | } | 483 | } |
485 | connection->url = uri; | 484 | connection->url = uri; |
486 | if (httpVersion == NULL) | 485 | if (httpVersion == NULL) |
487 | connection->version = ""; | 486 | connection->version = ""; |
@@ -502,131 +501,137 @@ parse_initial_message_line(struct MHD_Connection * connection, | |||
502 | * size of the body is unknown, it should be set to -1. | 501 | * size of the body is unknown, it should be set to -1. |
503 | */ | 502 | */ |
504 | static void | 503 | static void |
505 | MHD_parse_connection_headers(struct MHD_Connection * connection) { | 504 | MHD_parse_connection_headers (struct MHD_Connection *connection) |
506 | char * last; | 505 | { |
507 | char * line; | 506 | char *last; |
508 | char * colon; | 507 | char *line; |
509 | char * tmp; | 508 | char *colon; |
510 | const char * clen; | 509 | char *tmp; |
511 | const char * end; | 510 | const char *clen; |
511 | const char *end; | ||
512 | unsigned long long cval; | 512 | unsigned long long cval; |
513 | 513 | ||
514 | if (connection->bodyReceived == 1) | 514 | if (connection->bodyReceived == 1) |
515 | abort(); | 515 | abort (); |
516 | last = NULL; | 516 | last = NULL; |
517 | while (NULL != (line = MHD_get_next_header_line(connection))) { | 517 | while (NULL != (line = MHD_get_next_header_line (connection))) |
518 | if (last != NULL) { | 518 | { |
519 | if ( (line[0] == ' ') || | 519 | if (last != NULL) |
520 | (line[0] == '\t') ) { | 520 | { |
521 | /* value was continued on the next line, see | 521 | if ((line[0] == ' ') || (line[0] == '\t')) |
522 | http://www.jmarshall.com/easy/http/ */ | 522 | { |
523 | last = MHD_pool_reallocate(connection->pool, | 523 | /* value was continued on the next line, see |
524 | last, | 524 | http://www.jmarshall.com/easy/http/ */ |
525 | strlen(last)+1, | 525 | last = MHD_pool_reallocate (connection->pool, |
526 | strlen(line) + strlen(last) + 1); | 526 | last, |
527 | if (last == NULL) { | 527 | strlen (last) + 1, |
528 | MHD_excessive_data_handler(connection, | 528 | strlen (line) + strlen (last) + 1); |
529 | MHD_HTTP_REQUEST_ENTITY_TOO_LARGE); | 529 | if (last == NULL) |
530 | break; | 530 | { |
531 | } | 531 | MHD_excessive_data_handler (connection, |
532 | tmp = line; | 532 | MHD_HTTP_REQUEST_ENTITY_TOO_LARGE); |
533 | while ( (tmp[0] == ' ') || | 533 | break; |
534 | (tmp[0] == '\t') ) | 534 | } |
535 | tmp++; /* skip whitespace at start of 2nd line */ | 535 | tmp = line; |
536 | strcat(last, tmp); | 536 | while ((tmp[0] == ' ') || (tmp[0] == '\t')) |
537 | continue; /* possibly more than 2 lines... */ | 537 | tmp++; /* skip whitespace at start of 2nd line */ |
538 | } else { | 538 | strcat (last, tmp); |
539 | if (MHD_NO == MHD_connection_add_header(connection, | 539 | continue; /* possibly more than 2 lines... */ |
540 | last, | 540 | } |
541 | colon, | 541 | else |
542 | MHD_HEADER_KIND)) | 542 | { |
543 | return; | 543 | if (MHD_NO == MHD_connection_add_header (connection, |
544 | last = NULL; | 544 | last, |
545 | } | 545 | colon, |
546 | MHD_HEADER_KIND)) | ||
547 | return; | ||
548 | last = NULL; | ||
549 | } | ||
550 | } | ||
551 | if (connection->url == NULL) | ||
552 | { | ||
553 | /* line must be request line (first line of header) */ | ||
554 | if (MHD_NO == parse_initial_message_line (connection, line)) | ||
555 | goto DIE; | ||
556 | continue; | ||
557 | } | ||
558 | /* check if this is the end of the header */ | ||
559 | if (strlen (line) == 0) | ||
560 | { | ||
561 | /* end of header */ | ||
562 | connection->headersReceived = 1; | ||
563 | clen = MHD_lookup_connection_value (connection, | ||
564 | MHD_HEADER_KIND, | ||
565 | MHD_HTTP_HEADER_CONTENT_LENGTH); | ||
566 | if (clen != NULL) | ||
567 | { | ||
568 | if (1 != sscanf (clen, "%llu", &cval)) | ||
569 | { | ||
570 | MHD_DLOG (connection->daemon, | ||
571 | "Failed to parse `%s' header `%s', closing connection.\n", | ||
572 | MHD_HTTP_HEADER_CONTENT_LENGTH, clen); | ||
573 | goto DIE; | ||
574 | } | ||
575 | connection->uploadSize = cval; | ||
576 | connection->bodyReceived = cval == 0 ? 1 : 0; | ||
577 | } | ||
578 | else | ||
579 | { | ||
580 | if (NULL == MHD_lookup_connection_value (connection, | ||
581 | MHD_HEADER_KIND, | ||
582 | MHD_HTTP_HEADER_TRANSFER_ENCODING)) | ||
583 | { | ||
584 | /* this request does not have a body */ | ||
585 | connection->uploadSize = 0; | ||
586 | connection->bodyReceived = 1; | ||
587 | } | ||
588 | else | ||
589 | { | ||
590 | connection->uploadSize = -1; /* unknown size */ | ||
591 | connection->bodyReceived = 0; | ||
592 | } | ||
593 | } | ||
594 | end = MHD_lookup_connection_value (connection, | ||
595 | MHD_HEADER_KIND, | ||
596 | MHD_HTTP_HEADER_CONNECTION); | ||
597 | if ((end != NULL) && (0 == strcasecmp (end, "close"))) | ||
598 | { | ||
599 | /* other side explicitly requested | ||
600 | that we close the connection after | ||
601 | this request */ | ||
602 | connection->read_close = MHD_YES; | ||
603 | } | ||
604 | break; | ||
605 | } | ||
606 | /* line should be normal header line, find colon */ | ||
607 | colon = strstr (line, ":"); | ||
608 | if (colon == NULL) | ||
609 | { | ||
610 | /* error in header line, die hard */ | ||
611 | MHD_DLOG (connection->daemon, | ||
612 | "Received malformed line (no colon), closing connection.\n"); | ||
613 | goto DIE; | ||
614 | } | ||
615 | /* zero-terminate header */ | ||
616 | colon[0] = '\0'; | ||
617 | colon++; /* advance to value */ | ||
618 | while ((colon[0] != '\0') && ((colon[0] == ' ') || (colon[0] == '\t'))) | ||
619 | colon++; | ||
620 | /* we do the actual adding of the connection | ||
621 | header at the beginning of the while | ||
622 | loop since we need to be able to inspect | ||
623 | the *next* header line (in case it starts | ||
624 | with a space...) */ | ||
625 | last = line; | ||
546 | } | 626 | } |
547 | if (connection->url == NULL) { | 627 | if ((last != NULL) && |
548 | /* line must be request line (first line of header) */ | 628 | (MHD_NO == MHD_connection_add_header (connection, |
549 | if (MHD_NO == parse_initial_message_line(connection, | 629 | last, colon, MHD_HEADER_KIND))) |
550 | line)) | 630 | return; /* error */ |
551 | goto DIE; | 631 | MHD_parse_cookie_header (connection); |
552 | continue; | ||
553 | } | ||
554 | /* check if this is the end of the header */ | ||
555 | if (strlen(line) == 0) { | ||
556 | /* end of header */ | ||
557 | connection->headersReceived = 1; | ||
558 | clen = MHD_lookup_connection_value(connection, | ||
559 | MHD_HEADER_KIND, | ||
560 | MHD_HTTP_HEADER_CONTENT_LENGTH); | ||
561 | if (clen != NULL) { | ||
562 | if (1 != sscanf(clen, | ||
563 | "%llu", | ||
564 | &cval)) { | ||
565 | MHD_DLOG(connection->daemon, | ||
566 | "Failed to parse `%s' header `%s', closing connection.\n", | ||
567 | MHD_HTTP_HEADER_CONTENT_LENGTH, | ||
568 | clen); | ||
569 | goto DIE; | ||
570 | } | ||
571 | connection->uploadSize = cval; | ||
572 | connection->bodyReceived = cval == 0 ? 1 : 0; | ||
573 | } else { | ||
574 | if (NULL == MHD_lookup_connection_value(connection, | ||
575 | MHD_HEADER_KIND, | ||
576 | MHD_HTTP_HEADER_TRANSFER_ENCODING)) { | ||
577 | /* this request does not have a body */ | ||
578 | connection->uploadSize = 0; | ||
579 | connection->bodyReceived = 1; | ||
580 | } else { | ||
581 | connection->uploadSize = -1; /* unknown size */ | ||
582 | connection->bodyReceived = 0; | ||
583 | } | ||
584 | } | ||
585 | end = MHD_lookup_connection_value(connection, | ||
586 | MHD_HEADER_KIND, | ||
587 | MHD_HTTP_HEADER_CONNECTION); | ||
588 | if ( (end != NULL) && | ||
589 | (0 == strcasecmp(end, | ||
590 | "close")) ) { | ||
591 | /* other side explicitly requested | ||
592 | that we close the connection after | ||
593 | this request */ | ||
594 | connection->read_close = MHD_YES; | ||
595 | } | ||
596 | break; | ||
597 | } | ||
598 | /* line should be normal header line, find colon */ | ||
599 | colon = strstr(line, ":"); | ||
600 | if (colon == NULL) { | ||
601 | /* error in header line, die hard */ | ||
602 | MHD_DLOG(connection->daemon, | ||
603 | "Received malformed line (no colon), closing connection.\n"); | ||
604 | goto DIE; | ||
605 | } | ||
606 | /* zero-terminate header */ | ||
607 | colon[0] = '\0'; | ||
608 | colon++; /* advance to value */ | ||
609 | while ( (colon[0] != '\0') && | ||
610 | ( (colon[0] == ' ') || | ||
611 | (colon[0] == '\t') ) ) | ||
612 | colon++; | ||
613 | /* we do the actual adding of the connection | ||
614 | header at the beginning of the while | ||
615 | loop since we need to be able to inspect | ||
616 | the *next* header line (in case it starts | ||
617 | with a space...) */ | ||
618 | last = line; | ||
619 | } | ||
620 | if ( (last != NULL) && | ||
621 | (MHD_NO == MHD_connection_add_header(connection, | ||
622 | last, | ||
623 | colon, | ||
624 | MHD_HEADER_KIND)) ) | ||
625 | return; /* error */ | ||
626 | MHD_parse_cookie_header(connection); | ||
627 | return; | 632 | return; |
628 | DIE: | 633 | DIE: |
629 | CLOSE(connection->socket_fd); | 634 | CLOSE (connection->socket_fd); |
630 | connection->socket_fd = -1; | 635 | connection->socket_fd = -1; |
631 | } | 636 | } |
632 | 637 | ||
@@ -635,16 +640,17 @@ MHD_parse_connection_headers(struct MHD_Connection * connection) { | |||
635 | * Find the handler responsible for this request. | 640 | * Find the handler responsible for this request. |
636 | */ | 641 | */ |
637 | static struct MHD_Access_Handler * | 642 | static struct MHD_Access_Handler * |
638 | MHD_find_access_handler(struct MHD_Connection * connection) { | 643 | MHD_find_access_handler (struct MHD_Connection *connection) |
639 | struct MHD_Access_Handler * pos; | 644 | { |
645 | struct MHD_Access_Handler *pos; | ||
640 | 646 | ||
641 | pos = connection->daemon->handlers; | 647 | pos = connection->daemon->handlers; |
642 | while (pos != NULL) { | 648 | while (pos != NULL) |
643 | if (0 == strcmp(connection->url, | 649 | { |
644 | pos->uri_prefix)) | 650 | if (0 == strcmp (connection->url, pos->uri_prefix)) |
645 | return pos; | 651 | return pos; |
646 | pos = pos->next; | 652 | pos = pos->next; |
647 | } | 653 | } |
648 | return &connection->daemon->default_handler; | 654 | return &connection->daemon->default_handler; |
649 | } | 655 | } |
650 | 656 | ||
@@ -659,33 +665,33 @@ MHD_find_access_handler(struct MHD_Connection * connection) { | |||
659 | * @return MHD_YES if so | 665 | * @return MHD_YES if so |
660 | */ | 666 | */ |
661 | static int | 667 | static int |
662 | MHD_test_post_data(struct MHD_Connection * connection) { | 668 | MHD_test_post_data (struct MHD_Connection *connection) |
663 | const char * encoding; | 669 | { |
664 | void * buf; | 670 | const char *encoding; |
671 | void *buf; | ||
665 | 672 | ||
666 | if ( (connection->method == NULL) || | 673 | if ((connection->method == NULL) || |
667 | (connection->response != NULL) || | 674 | (connection->response != NULL) || |
668 | (0 != strcasecmp(connection->method, | 675 | (0 != strcasecmp (connection->method, MHD_HTTP_METHOD_POST))) |
669 | MHD_HTTP_METHOD_POST)) ) | ||
670 | return MHD_NO; | 676 | return MHD_NO; |
671 | encoding = MHD_lookup_connection_value(connection, | 677 | encoding = MHD_lookup_connection_value (connection, |
672 | MHD_HEADER_KIND, | 678 | MHD_HEADER_KIND, |
673 | MHD_HTTP_HEADER_CONTENT_TYPE); | 679 | MHD_HTTP_HEADER_CONTENT_TYPE); |
674 | if (encoding == NULL) | 680 | if (encoding == NULL) |
675 | return MHD_NO; | 681 | return MHD_NO; |
676 | if ( (0 == strcasecmp(MHD_HTTP_POST_ENCODING_FORM_URLENCODED, | 682 | if ((0 == strcasecmp (MHD_HTTP_POST_ENCODING_FORM_URLENCODED, |
677 | encoding)) && | 683 | encoding)) && (connection->uploadSize != -1)) |
678 | (connection->uploadSize != -1) ) { | 684 | { |
679 | buf = MHD_pool_reallocate(connection->pool, | 685 | buf = MHD_pool_reallocate (connection->pool, |
680 | connection->read_buffer, | 686 | connection->read_buffer, |
681 | connection->read_buffer_size, | 687 | connection->read_buffer_size, |
682 | connection->uploadSize + 1); | 688 | connection->uploadSize + 1); |
683 | if (buf == NULL) | 689 | if (buf == NULL) |
684 | return MHD_NO; | 690 | return MHD_NO; |
685 | connection->read_buffer_size = connection->uploadSize + 1; | 691 | connection->read_buffer_size = connection->uploadSize + 1; |
686 | connection->read_buffer = buf; | 692 | connection->read_buffer = buf; |
687 | return MHD_YES; | 693 | return MHD_YES; |
688 | } | 694 | } |
689 | return MHD_NO; | 695 | return MHD_NO; |
690 | } | 696 | } |
691 | 697 | ||
@@ -704,47 +710,47 @@ MHD_test_post_data(struct MHD_Connection * connection) { | |||
704 | * memory). | 710 | * memory). |
705 | */ | 711 | */ |
706 | static int | 712 | static int |
707 | MHD_parse_post_data(struct MHD_Connection * connection) { | 713 | MHD_parse_post_data (struct MHD_Connection *connection) |
708 | const char * encoding; | 714 | { |
715 | const char *encoding; | ||
709 | int ret; | 716 | int ret; |
710 | 717 | ||
711 | encoding = MHD_lookup_connection_value(connection, | 718 | encoding = MHD_lookup_connection_value (connection, |
712 | MHD_HEADER_KIND, | 719 | MHD_HEADER_KIND, |
713 | MHD_HTTP_HEADER_CONTENT_TYPE); | 720 | MHD_HTTP_HEADER_CONTENT_TYPE); |
714 | if (encoding == NULL) | 721 | if (encoding == NULL) |
715 | return MHD_NO; | ||
716 | if (0 == strcasecmp(MHD_HTTP_POST_ENCODING_FORM_URLENCODED, | ||
717 | encoding)) { | ||
718 | ret = parse_arguments(MHD_POSTDATA_KIND, | ||
719 | connection, | ||
720 | connection->read_buffer); | ||
721 | /* invalidate read buffer for other uses -- | ||
722 | in particular, do not give it to the | ||
723 | client; if this were to be needed, we would | ||
724 | have to make a copy, which would double memory | ||
725 | requirements */ | ||
726 | connection->read_buffer_size = 0; | ||
727 | connection->readLoc = 0; | ||
728 | connection->uploadSize = 0; | ||
729 | connection->read_buffer = NULL; | ||
730 | return ret; | ||
731 | } | ||
732 | if (0 == strcasecmp(MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA, | ||
733 | encoding)) { | ||
734 | /* this code should never been reached right now, | ||
735 | since the test_post_data function would already | ||
736 | return MHD_NO; code is here only for future | ||
737 | extensions... */ | ||
738 | /* see http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4 */ | ||
739 | MHD_DLOG(connection->daemon, | ||
740 | "Unsupported multipart encoding of POST data specified, not processing POST data.\n"); | ||
741 | return MHD_NO; | 722 | return MHD_NO; |
742 | } | 723 | if (0 == strcasecmp (MHD_HTTP_POST_ENCODING_FORM_URLENCODED, encoding)) |
724 | { | ||
725 | ret = parse_arguments (MHD_POSTDATA_KIND, | ||
726 | connection, connection->read_buffer); | ||
727 | /* invalidate read buffer for other uses -- | ||
728 | in particular, do not give it to the | ||
729 | client; if this were to be needed, we would | ||
730 | have to make a copy, which would double memory | ||
731 | requirements */ | ||
732 | connection->read_buffer_size = 0; | ||
733 | connection->readLoc = 0; | ||
734 | connection->uploadSize = 0; | ||
735 | connection->read_buffer = NULL; | ||
736 | return ret; | ||
737 | } | ||
738 | if (0 == strcasecmp (MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA, encoding)) | ||
739 | { | ||
740 | /* this code should never been reached right now, | ||
741 | since the test_post_data function would already | ||
742 | return MHD_NO; code is here only for future | ||
743 | extensions... */ | ||
744 | /* see http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4 */ | ||
745 | MHD_DLOG (connection->daemon, | ||
746 | "Unsupported multipart encoding of POST data specified, not processing POST data.\n"); | ||
747 | return MHD_NO; | ||
748 | } | ||
743 | /* this should never be reached, just here for | 749 | /* this should never be reached, just here for |
744 | error checking */ | 750 | error checking */ |
745 | MHD_DLOG(connection->daemon, | 751 | MHD_DLOG (connection->daemon, |
746 | "Unknown encoding of POST data specified, not processing POST data.\n"); | 752 | "Unknown encoding of POST data specified, not processing POST data.\n"); |
747 | return MHD_NO; | 753 | return MHD_NO; |
748 | } | 754 | } |
749 | 755 | ||
750 | /** | 756 | /** |
@@ -752,46 +758,47 @@ MHD_parse_post_data(struct MHD_Connection * connection) { | |||
752 | * connection. | 758 | * connection. |
753 | */ | 759 | */ |
754 | void | 760 | void |
755 | MHD_call_connection_handler(struct MHD_Connection * connection) { | 761 | MHD_call_connection_handler (struct MHD_Connection *connection) |
756 | struct MHD_Access_Handler * ah; | 762 | { |
763 | struct MHD_Access_Handler *ah; | ||
757 | unsigned int processed; | 764 | unsigned int processed; |
758 | 765 | ||
759 | if (connection->response != NULL) | 766 | if (connection->response != NULL) |
760 | return; /* already queued a response */ | 767 | return; /* already queued a response */ |
761 | if (connection->headersReceived == 0) | 768 | if (connection->headersReceived == 0) |
762 | abort(); /* bad timing... */ | 769 | abort (); /* bad timing... */ |
763 | ah = MHD_find_access_handler(connection); | 770 | ah = MHD_find_access_handler (connection); |
764 | processed = connection->readLoc; | 771 | processed = connection->readLoc; |
765 | if (MHD_NO == ah->dh(ah->dh_cls, | 772 | if (MHD_NO == ah->dh (ah->dh_cls, |
766 | connection, | 773 | connection, |
767 | connection->url, | 774 | connection->url, |
768 | connection->method, | 775 | connection->method, |
769 | connection->version, | 776 | connection->version, |
770 | connection->read_buffer, | 777 | connection->read_buffer, &processed)) |
771 | &processed)) { | 778 | { |
772 | /* serios internal error, close connection */ | 779 | /* serios internal error, close connection */ |
773 | MHD_DLOG(connection->daemon, | 780 | MHD_DLOG (connection->daemon, |
774 | "Internal application error, closing connection.\n"); | 781 | "Internal application error, closing connection.\n"); |
775 | CLOSE(connection->socket_fd); | 782 | CLOSE (connection->socket_fd); |
776 | connection->socket_fd = -1; | 783 | connection->socket_fd = -1; |
777 | return; | 784 | return; |
778 | } | 785 | } |
779 | /* dh left "processed" bytes in buffer for next time... */ | 786 | /* dh left "processed" bytes in buffer for next time... */ |
780 | memmove(connection->read_buffer, | 787 | memmove (connection->read_buffer, |
781 | &connection->read_buffer[connection->readLoc - processed], | 788 | &connection->read_buffer[connection->readLoc - processed], |
782 | processed); | 789 | processed); |
783 | if (connection->uploadSize != -1) | 790 | if (connection->uploadSize != -1) |
784 | connection->uploadSize -= (connection->readLoc - processed); | 791 | connection->uploadSize -= (connection->readLoc - processed); |
785 | connection->readLoc = processed; | 792 | connection->readLoc = processed; |
786 | if ( (connection->uploadSize == 0) || | 793 | if ((connection->uploadSize == 0) || |
787 | ( (connection->readLoc == 0) && | 794 | ((connection->readLoc == 0) && |
788 | (connection->uploadSize == -1) && | 795 | (connection->uploadSize == -1) && (connection->socket_fd == -1))) |
789 | (connection->socket_fd == -1) ) ) { | 796 | { |
790 | connection->bodyReceived = 1; | 797 | connection->bodyReceived = 1; |
791 | connection->readLoc = 0; | 798 | connection->readLoc = 0; |
792 | connection->read_buffer_size = 0; | 799 | connection->read_buffer_size = 0; |
793 | connection->read_buffer = NULL; | 800 | connection->read_buffer = NULL; |
794 | } | 801 | } |
795 | } | 802 | } |
796 | 803 | ||
797 | 804 | ||
@@ -802,81 +809,88 @@ MHD_call_connection_handler(struct MHD_Connection * connection) { | |||
802 | * to handle reads. | 809 | * to handle reads. |
803 | */ | 810 | */ |
804 | int | 811 | int |
805 | MHD_connection_handle_read(struct MHD_Connection * connection) { | 812 | MHD_connection_handle_read (struct MHD_Connection *connection) |
813 | { | ||
806 | int bytes_read; | 814 | int bytes_read; |
807 | void * tmp; | 815 | void *tmp; |
808 | 816 | ||
809 | if (connection->pool == NULL) | 817 | if (connection->pool == NULL) |
810 | connection->pool = MHD_pool_create(connection->daemon->pool_size); | 818 | connection->pool = MHD_pool_create (connection->daemon->pool_size); |
811 | if (connection->pool == NULL) { | 819 | if (connection->pool == NULL) |
812 | MHD_DLOG(connection->daemon, | 820 | { |
813 | "Failed to create memory pool!\n"); | 821 | MHD_DLOG (connection->daemon, "Failed to create memory pool!\n"); |
814 | CLOSE(connection->socket_fd); | 822 | CLOSE (connection->socket_fd); |
815 | connection->socket_fd = -1; | 823 | connection->socket_fd = -1; |
816 | return MHD_NO; | ||
817 | } | ||
818 | if ( (connection->readLoc >= connection->read_buffer_size) && | ||
819 | (connection->headersReceived == 0) ) { | ||
820 | /* need to grow read buffer */ | ||
821 | tmp = MHD_pool_reallocate(connection->pool, | ||
822 | connection->read_buffer, | ||
823 | connection->read_buffer_size, | ||
824 | connection->read_buffer_size * 2 + MHD_BUF_INC_SIZE); | ||
825 | if (tmp == NULL) { | ||
826 | MHD_DLOG(connection->daemon, | ||
827 | "Not enough memory for reading headers!\n"); | ||
828 | MHD_excessive_data_handler(connection, | ||
829 | MHD_HTTP_REQUEST_ENTITY_TOO_LARGE); | ||
830 | return MHD_NO; | 824 | return MHD_NO; |
831 | } | 825 | } |
832 | connection->read_buffer = tmp; | 826 | if ((connection->readLoc >= connection->read_buffer_size) && |
833 | connection->read_buffer_size = connection->read_buffer_size * 2 + MHD_BUF_INC_SIZE; | 827 | (connection->headersReceived == 0)) |
834 | } | 828 | { |
835 | if (connection->readLoc >= connection->read_buffer_size) { | 829 | /* need to grow read buffer */ |
836 | MHD_DLOG(connection->daemon, | 830 | tmp = MHD_pool_reallocate (connection->pool, |
837 | "Unexpected call to %s.\n", | 831 | connection->read_buffer, |
838 | __FUNCTION__); | 832 | connection->read_buffer_size, |
839 | return MHD_NO; | 833 | connection->read_buffer_size * 2 + |
840 | } | 834 | MHD_BUF_INC_SIZE); |
841 | bytes_read = RECV(connection->socket_fd, | 835 | if (tmp == NULL) |
842 | &connection->read_buffer[connection->readLoc], | 836 | { |
843 | connection->read_buffer_size - connection->readLoc, | 837 | MHD_DLOG (connection->daemon, |
844 | 0); | 838 | "Not enough memory for reading headers!\n"); |
845 | if (bytes_read < 0) { | 839 | MHD_excessive_data_handler (connection, |
846 | if (errno == EINTR) | 840 | MHD_HTTP_REQUEST_ENTITY_TOO_LARGE); |
841 | return MHD_NO; | ||
842 | } | ||
843 | connection->read_buffer = tmp; | ||
844 | connection->read_buffer_size = | ||
845 | connection->read_buffer_size * 2 + MHD_BUF_INC_SIZE; | ||
846 | } | ||
847 | if (connection->readLoc >= connection->read_buffer_size) | ||
848 | { | ||
849 | MHD_DLOG (connection->daemon, "Unexpected call to %s.\n", __FUNCTION__); | ||
847 | return MHD_NO; | 850 | return MHD_NO; |
848 | MHD_DLOG(connection->daemon, | 851 | } |
849 | "Failed to receive data: %s\n", | 852 | bytes_read = RECV (connection->socket_fd, |
850 | STRERROR(errno)); | 853 | &connection->read_buffer[connection->readLoc], |
851 | CLOSE(connection->socket_fd); | 854 | connection->read_buffer_size - connection->readLoc, 0); |
852 | connection->socket_fd = -1; | 855 | if (bytes_read < 0) |
853 | return MHD_YES; | 856 | { |
854 | } | 857 | if (errno == EINTR) |
855 | if (bytes_read == 0) { | 858 | return MHD_NO; |
856 | /* other side closed connection */ | 859 | MHD_DLOG (connection->daemon, |
857 | connection->read_close = MHD_YES; | 860 | "Failed to receive data: %s\n", STRERROR (errno)); |
858 | if (connection->readLoc > 0) | 861 | CLOSE (connection->socket_fd); |
859 | MHD_call_connection_handler(connection); | 862 | connection->socket_fd = -1; |
860 | shutdown(connection->socket_fd, SHUT_RD); | 863 | return MHD_YES; |
861 | return MHD_YES; | 864 | } |
862 | } | 865 | if (bytes_read == 0) |
866 | { | ||
867 | /* other side closed connection */ | ||
868 | connection->read_close = MHD_YES; | ||
869 | if (connection->readLoc > 0) | ||
870 | MHD_call_connection_handler (connection); | ||
871 | shutdown (connection->socket_fd, SHUT_RD); | ||
872 | return MHD_YES; | ||
873 | } | ||
863 | connection->readLoc += bytes_read; | 874 | connection->readLoc += bytes_read; |
864 | if (connection->headersReceived == 0) { | 875 | if (connection->headersReceived == 0) |
865 | MHD_parse_connection_headers(connection); | 876 | { |
866 | if (connection->headersReceived == 1) { | 877 | MHD_parse_connection_headers (connection); |
867 | connection->post_processed = MHD_test_post_data(connection); | 878 | if (connection->headersReceived == 1) |
879 | { | ||
880 | connection->post_processed = MHD_test_post_data (connection); | ||
881 | } | ||
882 | } | ||
883 | if (connection->headersReceived == 1) | ||
884 | { | ||
885 | if ((connection->post_processed == MHD_YES) && | ||
886 | (connection->uploadSize == connection->readLoc)) | ||
887 | if (MHD_NO == MHD_parse_post_data (connection)) | ||
888 | connection->post_processed = MHD_NO; | ||
889 | if (((connection->post_processed == MHD_NO) || | ||
890 | (connection->read_buffer_size == connection->readLoc)) && | ||
891 | (connection->method != NULL)) | ||
892 | MHD_call_connection_handler (connection); | ||
868 | } | 893 | } |
869 | } | ||
870 | if (connection->headersReceived == 1) { | ||
871 | if ( (connection->post_processed == MHD_YES) && | ||
872 | (connection->uploadSize == connection->readLoc) ) | ||
873 | if (MHD_NO == MHD_parse_post_data(connection)) | ||
874 | connection->post_processed = MHD_NO; | ||
875 | if ( ( (connection->post_processed == MHD_NO) || | ||
876 | (connection->read_buffer_size == connection->readLoc) ) && | ||
877 | (connection->method != NULL) ) | ||
878 | MHD_call_connection_handler(connection); | ||
879 | } | ||
880 | return MHD_YES; | 894 | return MHD_YES; |
881 | } | 895 | } |
882 | 896 | ||
@@ -885,48 +899,51 @@ MHD_connection_handle_read(struct MHD_Connection * connection) { | |||
885 | * for http-compiliance. | 899 | * for http-compiliance. |
886 | */ | 900 | */ |
887 | static void | 901 | static void |
888 | MHD_add_extra_headers(struct MHD_Connection * connection) { | 902 | MHD_add_extra_headers (struct MHD_Connection *connection) |
889 | const char * have; | 903 | { |
904 | const char *have; | ||
890 | char buf[128]; | 905 | char buf[128]; |
891 | 906 | ||
892 | if (connection->response->total_size == -1) { | 907 | if (connection->response->total_size == -1) |
893 | have = MHD_get_response_header(connection->response, | 908 | { |
894 | MHD_HTTP_HEADER_CONNECTION); | 909 | have = MHD_get_response_header (connection->response, |
895 | if (have == NULL) | 910 | MHD_HTTP_HEADER_CONNECTION); |
896 | MHD_add_response_header(connection->response, | 911 | if (have == NULL) |
897 | MHD_HTTP_HEADER_CONNECTION, | 912 | MHD_add_response_header (connection->response, |
898 | "close"); | 913 | MHD_HTTP_HEADER_CONNECTION, "close"); |
899 | } else if (NULL == MHD_get_response_header(connection->response, | 914 | } |
900 | MHD_HTTP_HEADER_CONTENT_LENGTH)) { | 915 | else if (NULL == MHD_get_response_header (connection->response, |
901 | _REAL_SNPRINTF(buf, | 916 | MHD_HTTP_HEADER_CONTENT_LENGTH)) |
902 | 128, | 917 | { |
903 | "%llu", | 918 | _REAL_SNPRINTF (buf, |
904 | (unsigned long long) connection->response->total_size); | 919 | 128, |
905 | MHD_add_response_header(connection->response, | 920 | "%llu", |
906 | MHD_HTTP_HEADER_CONTENT_LENGTH, | 921 | (unsigned long long) connection->response->total_size); |
907 | buf); | 922 | MHD_add_response_header (connection->response, |
908 | } | 923 | MHD_HTTP_HEADER_CONTENT_LENGTH, buf); |
924 | } | ||
909 | } | 925 | } |
910 | 926 | ||
911 | static void get_date_string(char * date, | 927 | static void |
912 | unsigned int max) { | 928 | get_date_string (char *date, unsigned int max) |
913 | static const char * days[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; | 929 | { |
914 | static const char * mons[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; | 930 | static const char *days[] = |
931 | { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; | ||
932 | static const char *mons[] = | ||
933 | { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", | ||
934 | "Nov", "Dec" }; | ||
915 | struct tm now; | 935 | struct tm now; |
916 | time_t t; | 936 | time_t t; |
917 | 937 | ||
918 | time(&t); | 938 | time (&t); |
919 | gmtime_r(&t, &now); | 939 | gmtime_r (&t, &now); |
920 | snprintf(date, | 940 | snprintf (date, |
921 | max-1, | 941 | max - 1, |
922 | "Date: %3s, %02u %3s %04u %02u:%02u:%02u GMT\r\n", | 942 | "Date: %3s, %02u %3s %04u %02u:%02u:%02u GMT\r\n", |
923 | days[now.tm_wday % 7], | 943 | days[now.tm_wday % 7], |
924 | now.tm_mday, | 944 | now.tm_mday, |
925 | mons[now.tm_mon % 12], | 945 | mons[now.tm_mon % 12], |
926 | now.tm_year, | 946 | now.tm_year, now.tm_hour, now.tm_min, now.tm_sec); |
927 | now.tm_hour, | ||
928 | now.tm_min, | ||
929 | now.tm_sec); | ||
930 | } | 947 | } |
931 | 948 | ||
932 | /** | 949 | /** |
@@ -935,62 +952,53 @@ static void get_date_string(char * date, | |||
935 | * HTTPd's response. | 952 | * HTTPd's response. |
936 | */ | 953 | */ |
937 | static int | 954 | static int |
938 | MHD_build_header_response(struct MHD_Connection * connection) { | 955 | MHD_build_header_response (struct MHD_Connection *connection) |
956 | { | ||
939 | size_t size; | 957 | size_t size; |
940 | size_t off; | 958 | size_t off; |
941 | struct MHD_HTTP_Header * pos; | 959 | struct MHD_HTTP_Header *pos; |
942 | char code[32]; | 960 | char code[32]; |
943 | char date[128]; | 961 | char date[128]; |
944 | char * data; | 962 | char *data; |
945 | 963 | ||
946 | MHD_add_extra_headers(connection); | 964 | MHD_add_extra_headers (connection); |
947 | SPRINTF(code, | 965 | SPRINTF (code, "%s %u\r\n", MHD_HTTP_VERSION_1_1, connection->responseCode); |
948 | "%s %u\r\n", | 966 | off = strlen (code); |
949 | MHD_HTTP_VERSION_1_1, | ||
950 | connection->responseCode); | ||
951 | off = strlen(code); | ||
952 | /* estimate size */ | 967 | /* estimate size */ |
953 | size = off + 2; /* extra \r\n at the end */ | 968 | size = off + 2; /* extra \r\n at the end */ |
954 | pos = connection->response->first_header; | 969 | pos = connection->response->first_header; |
955 | while (pos != NULL) { | 970 | while (pos != NULL) |
956 | size += strlen(pos->header) + strlen(pos->value) + 4; /* colon, space, linefeeds */ | 971 | { |
957 | pos = pos->next; | 972 | size += strlen (pos->header) + strlen (pos->value) + 4; /* colon, space, linefeeds */ |
958 | } | 973 | pos = pos->next; |
959 | if (NULL == MHD_get_response_header(connection->response, | 974 | } |
960 | MHD_HTTP_HEADER_DATE)) | 975 | if (NULL == MHD_get_response_header (connection->response, |
961 | get_date_string(date, sizeof(date)); | 976 | MHD_HTTP_HEADER_DATE)) |
977 | get_date_string (date, sizeof (date)); | ||
962 | else | 978 | else |
963 | date[0] = '\0'; | 979 | date[0] = '\0'; |
964 | size += strlen(date); | 980 | size += strlen (date); |
965 | /* produce data */ | 981 | /* produce data */ |
966 | data = MHD_pool_allocate(connection->pool, | 982 | data = MHD_pool_allocate (connection->pool, size + 1, MHD_YES); |
967 | size + 1, | 983 | if (data == NULL) |
968 | MHD_YES); | 984 | { |
969 | if (data == NULL) { | 985 | MHD_DLOG (connection->daemon, "Not enough memory for write!\n"); |
970 | MHD_DLOG(connection->daemon, | 986 | return MHD_NO; |
971 | "Not enough memory for write!\n"); | 987 | } |
972 | return MHD_NO; | 988 | memcpy (data, code, off); |
973 | } | ||
974 | memcpy(data, | ||
975 | code, | ||
976 | off); | ||
977 | pos = connection->response->first_header; | 989 | pos = connection->response->first_header; |
978 | while (pos != NULL) { | 990 | while (pos != NULL) |
979 | SPRINTF(&data[off], | 991 | { |
980 | "%s: %s\r\n", | 992 | SPRINTF (&data[off], "%s: %s\r\n", pos->header, pos->value); |
981 | pos->header, | 993 | off += strlen (pos->header) + strlen (pos->value) + 4; |
982 | pos->value); | 994 | pos = pos->next; |
983 | off += strlen(pos->header) + strlen(pos->value) + 4; | 995 | } |
984 | pos = pos->next; | 996 | strcpy (&data[off], date); |
985 | } | 997 | off += strlen (date); |
986 | strcpy(&data[off], | 998 | sprintf (&data[off], "\r\n"); |
987 | date); | ||
988 | off += strlen(date); | ||
989 | sprintf(&data[off], | ||
990 | "\r\n"); | ||
991 | off += 2; | 999 | off += 2; |
992 | if (off != size) | 1000 | if (off != size) |
993 | abort(); | 1001 | abort (); |
994 | connection->write_buffer = data; | 1002 | connection->write_buffer = data; |
995 | connection->writeLoc = size; | 1003 | connection->writeLoc = size; |
996 | connection->writePos = 0; | 1004 | connection->writePos = 0; |
@@ -1005,159 +1013,164 @@ MHD_build_header_response(struct MHD_Connection * connection) { | |||
1005 | * call this function | 1013 | * call this function |
1006 | */ | 1014 | */ |
1007 | int | 1015 | int |
1008 | MHD_connection_handle_write(struct MHD_Connection * connection) { | 1016 | MHD_connection_handle_write (struct MHD_Connection *connection) |
1009 | struct MHD_Response * response; | 1017 | { |
1018 | struct MHD_Response *response; | ||
1010 | int ret; | 1019 | int ret; |
1011 | 1020 | ||
1012 | if (MHD_need_100_continue(connection)) { | 1021 | if (MHD_need_100_continue (connection)) |
1013 | ret = SEND(connection->socket_fd, | 1022 | { |
1014 | &HTTP_100_CONTINUE[connection->continuePos], | 1023 | ret = SEND (connection->socket_fd, |
1015 | strlen(HTTP_100_CONTINUE) - connection->continuePos, | 1024 | &HTTP_100_CONTINUE[connection->continuePos], |
1016 | 0); | 1025 | strlen (HTTP_100_CONTINUE) - connection->continuePos, 0); |
1017 | if (ret < 0) { | 1026 | if (ret < 0) |
1018 | if (errno == EINTR) | 1027 | { |
1019 | return MHD_YES; | 1028 | if (errno == EINTR) |
1020 | MHD_DLOG(connection->daemon, | 1029 | return MHD_YES; |
1021 | "Failed to send data: %s\n", | 1030 | MHD_DLOG (connection->daemon, |
1022 | STRERROR(errno)); | 1031 | "Failed to send data: %s\n", STRERROR (errno)); |
1023 | CLOSE(connection->socket_fd); | 1032 | CLOSE (connection->socket_fd); |
1024 | connection->socket_fd = -1; | 1033 | connection->socket_fd = -1; |
1034 | return MHD_YES; | ||
1035 | } | ||
1036 | connection->continuePos += ret; | ||
1025 | return MHD_YES; | 1037 | return MHD_YES; |
1026 | } | 1038 | } |
1027 | connection->continuePos += ret; | ||
1028 | return MHD_YES; | ||
1029 | } | ||
1030 | response = connection->response; | 1039 | response = connection->response; |
1031 | if(response == NULL) { | 1040 | if (response == NULL) |
1032 | MHD_DLOG(connection->daemon, | 1041 | { |
1033 | "Unexpected call to %s.\n", | 1042 | MHD_DLOG (connection->daemon, "Unexpected call to %s.\n", __FUNCTION__); |
1034 | __FUNCTION__); | 1043 | return MHD_NO; |
1035 | return MHD_NO; | ||
1036 | } | ||
1037 | if (! connection->headersSent) { | ||
1038 | if ( (connection->write_buffer == NULL) && | ||
1039 | (MHD_NO == MHD_build_header_response(connection)) ) { | ||
1040 | /* oops - close! */ | ||
1041 | CLOSE(connection->socket_fd); | ||
1042 | connection->socket_fd = -1; | ||
1043 | return MHD_NO; | ||
1044 | } | 1044 | } |
1045 | ret = SEND(connection->socket_fd, | 1045 | if (!connection->headersSent) |
1046 | &connection->write_buffer[connection->writePos], | 1046 | { |
1047 | connection->writeLoc - connection->writePos, | 1047 | if ((connection->write_buffer == NULL) && |
1048 | 0); | 1048 | (MHD_NO == MHD_build_header_response (connection))) |
1049 | if (ret < 0) { | 1049 | { |
1050 | if (errno == EINTR) | 1050 | /* oops - close! */ |
1051 | return MHD_YES; | 1051 | CLOSE (connection->socket_fd); |
1052 | MHD_DLOG(connection->daemon, | 1052 | connection->socket_fd = -1; |
1053 | "Failed to send data: %s\n", | 1053 | return MHD_NO; |
1054 | STRERROR(errno)); | 1054 | } |
1055 | CLOSE(connection->socket_fd); | 1055 | ret = SEND (connection->socket_fd, |
1056 | connection->socket_fd = -1; | 1056 | &connection->write_buffer[connection->writePos], |
1057 | connection->writeLoc - connection->writePos, 0); | ||
1058 | if (ret < 0) | ||
1059 | { | ||
1060 | if (errno == EINTR) | ||
1061 | return MHD_YES; | ||
1062 | MHD_DLOG (connection->daemon, | ||
1063 | "Failed to send data: %s\n", STRERROR (errno)); | ||
1064 | CLOSE (connection->socket_fd); | ||
1065 | connection->socket_fd = -1; | ||
1066 | return MHD_YES; | ||
1067 | } | ||
1068 | connection->writePos += ret; | ||
1069 | if (connection->writeLoc == connection->writePos) | ||
1070 | { | ||
1071 | connection->writeLoc = 0; | ||
1072 | connection->writePos = 0; | ||
1073 | connection->headersSent = 1; | ||
1074 | MHD_pool_reallocate (connection->pool, | ||
1075 | connection->write_buffer, | ||
1076 | connection->write_buffer_size, 0); | ||
1077 | connection->write_buffer = NULL; | ||
1078 | connection->write_buffer_size = 0; | ||
1079 | } | ||
1057 | return MHD_YES; | 1080 | return MHD_YES; |
1058 | } | 1081 | } |
1059 | connection->writePos += ret; | ||
1060 | if (connection->writeLoc == connection->writePos) { | ||
1061 | connection->writeLoc = 0; | ||
1062 | connection->writePos = 0; | ||
1063 | connection->headersSent = 1; | ||
1064 | MHD_pool_reallocate(connection->pool, | ||
1065 | connection->write_buffer, | ||
1066 | connection->write_buffer_size, | ||
1067 | 0); | ||
1068 | connection->write_buffer = NULL; | ||
1069 | connection->write_buffer_size = 0; | ||
1070 | } | ||
1071 | return MHD_YES; | ||
1072 | } | ||
1073 | if (response->total_size < connection->messagePos) | 1082 | if (response->total_size < connection->messagePos) |
1074 | abort(); /* internal error */ | 1083 | abort (); /* internal error */ |
1075 | if (response->crc != NULL) | 1084 | if (response->crc != NULL) |
1076 | pthread_mutex_lock(&response->mutex); | 1085 | pthread_mutex_lock (&response->mutex); |
1077 | 1086 | ||
1078 | /* prepare send buffer */ | 1087 | /* prepare send buffer */ |
1079 | if ( (response->crc != NULL) && | 1088 | if ((response->crc != NULL) && |
1080 | ( (response->data_start > connection->messagePos) || | 1089 | ((response->data_start > connection->messagePos) || |
1081 | (response->data_start + response->data_size <= connection->messagePos) ) ) { | 1090 | (response->data_start + response->data_size <= |
1082 | ret = response->crc(response->crc_cls, | 1091 | connection->messagePos))) |
1083 | connection->messagePos, | 1092 | { |
1084 | response->data, | 1093 | ret = response->crc (response->crc_cls, |
1085 | MIN(response->data_buffer_size, | 1094 | connection->messagePos, |
1086 | response->total_size - connection->messagePos)); | 1095 | response->data, |
1087 | if (ret == -1) { | 1096 | MIN (response->data_buffer_size, |
1088 | /* end of message, signal other side by closing! */ | 1097 | response->total_size - |
1089 | response->total_size = connection->messagePos; | 1098 | connection->messagePos)); |
1090 | CLOSE(connection->socket_fd); | 1099 | if (ret == -1) |
1091 | connection->socket_fd = -1; | 1100 | { |
1092 | if (response->crc != NULL) | 1101 | /* end of message, signal other side by closing! */ |
1093 | pthread_mutex_unlock(&response->mutex); | 1102 | response->total_size = connection->messagePos; |
1094 | return MHD_YES; | 1103 | CLOSE (connection->socket_fd); |
1095 | } | 1104 | connection->socket_fd = -1; |
1096 | response->data_start = connection->messagePos; | 1105 | if (response->crc != NULL) |
1097 | response->data_size = ret; | 1106 | pthread_mutex_unlock (&response->mutex); |
1098 | if (ret == 0) { | 1107 | return MHD_YES; |
1099 | if (response->crc != NULL) | 1108 | } |
1100 | pthread_mutex_unlock(&response->mutex); | 1109 | response->data_start = connection->messagePos; |
1101 | return MHD_YES; | 1110 | response->data_size = ret; |
1111 | if (ret == 0) | ||
1112 | { | ||
1113 | if (response->crc != NULL) | ||
1114 | pthread_mutex_unlock (&response->mutex); | ||
1115 | return MHD_YES; | ||
1116 | } | ||
1102 | } | 1117 | } |
1103 | } | ||
1104 | /* transmit */ | 1118 | /* transmit */ |
1105 | ret = SEND(connection->socket_fd, | 1119 | ret = SEND (connection->socket_fd, |
1106 | &response->data[connection->messagePos - response->data_start], | 1120 | &response->data[connection->messagePos - response->data_start], |
1107 | response->data_size - (connection->messagePos - response->data_start), | 1121 | response->data_size - (connection->messagePos - |
1108 | 0); | 1122 | response->data_start), 0); |
1109 | if (response->crc != NULL) | 1123 | if (response->crc != NULL) |
1110 | pthread_mutex_unlock(&response->mutex); | 1124 | pthread_mutex_unlock (&response->mutex); |
1111 | if (ret < 0) { | 1125 | if (ret < 0) |
1112 | if (errno == EINTR) | 1126 | { |
1127 | if (errno == EINTR) | ||
1128 | return MHD_YES; | ||
1129 | MHD_DLOG (connection->daemon, | ||
1130 | "Failed to send data: %s\n", STRERROR (errno)); | ||
1131 | CLOSE (connection->socket_fd); | ||
1132 | connection->socket_fd = -1; | ||
1113 | return MHD_YES; | 1133 | return MHD_YES; |
1114 | MHD_DLOG(connection->daemon, | 1134 | } |
1115 | "Failed to send data: %s\n", | ||
1116 | STRERROR(errno)); | ||
1117 | CLOSE(connection->socket_fd); | ||
1118 | connection->socket_fd = -1; | ||
1119 | return MHD_YES; | ||
1120 | } | ||
1121 | connection->messagePos += ret; | 1135 | connection->messagePos += ret; |
1122 | if (connection->messagePos > response->total_size) | 1136 | if (connection->messagePos > response->total_size) |
1123 | abort(); /* internal error */ | 1137 | abort (); /* internal error */ |
1124 | if (connection->messagePos == response->total_size) { | 1138 | if (connection->messagePos == response->total_size) |
1125 | if ( (connection->bodyReceived == 0) || | 1139 | { |
1126 | (connection->headersReceived == 0) ) | 1140 | if ((connection->bodyReceived == 0) || |
1127 | abort(); /* internal error */ | 1141 | (connection->headersReceived == 0)) |
1128 | MHD_destroy_response(response); | 1142 | abort (); /* internal error */ |
1129 | connection->continuePos = 0; | 1143 | MHD_destroy_response (response); |
1130 | connection->responseCode = 0; | 1144 | connection->continuePos = 0; |
1131 | connection->response = NULL; | 1145 | connection->responseCode = 0; |
1132 | connection->headers_received = NULL; | 1146 | connection->response = NULL; |
1133 | connection->headersReceived = 0; | 1147 | connection->headers_received = NULL; |
1134 | connection->headersSent = 0; | 1148 | connection->headersReceived = 0; |
1135 | connection->bodyReceived = 0; | 1149 | connection->headersSent = 0; |
1136 | connection->messagePos = 0; | 1150 | connection->bodyReceived = 0; |
1137 | connection->method = NULL; | 1151 | connection->messagePos = 0; |
1138 | connection->url = NULL; | 1152 | connection->method = NULL; |
1139 | if ( (connection->read_close == MHD_YES) || | 1153 | connection->url = NULL; |
1140 | (0 != strcasecmp(MHD_HTTP_VERSION_1_1, | 1154 | if ((connection->read_close == MHD_YES) || |
1141 | connection->version)) ) { | 1155 | (0 != strcasecmp (MHD_HTTP_VERSION_1_1, connection->version))) |
1142 | /* closed for reading => close for good! */ | 1156 | { |
1143 | if (connection->socket_fd != -1) | 1157 | /* closed for reading => close for good! */ |
1144 | CLOSE(connection->socket_fd); | 1158 | if (connection->socket_fd != -1) |
1145 | connection->socket_fd = -1; | 1159 | CLOSE (connection->socket_fd); |
1160 | connection->socket_fd = -1; | ||
1161 | } | ||
1162 | connection->version = NULL; | ||
1163 | connection->read_buffer = NULL; | ||
1164 | connection->write_buffer = NULL; | ||
1165 | connection->read_buffer_size = 0; | ||
1166 | connection->readLoc = 0; | ||
1167 | connection->write_buffer_size = 0; | ||
1168 | connection->writePos = 0; | ||
1169 | connection->writeLoc = 0; | ||
1170 | MHD_pool_destroy (connection->pool); | ||
1171 | connection->pool = NULL; | ||
1146 | } | 1172 | } |
1147 | connection->version = NULL; | ||
1148 | connection->read_buffer = NULL; | ||
1149 | connection->write_buffer = NULL; | ||
1150 | connection->read_buffer_size = 0; | ||
1151 | connection->readLoc = 0; | ||
1152 | connection->write_buffer_size = 0; | ||
1153 | connection->writePos = 0; | ||
1154 | connection->writeLoc = 0; | ||
1155 | MHD_pool_destroy(connection->pool); | ||
1156 | connection->pool = NULL; | ||
1157 | } | ||
1158 | return MHD_YES; | 1173 | return MHD_YES; |
1159 | } | 1174 | } |
1160 | 1175 | ||
1161 | /* end of connection.c */ | 1176 | /* end of connection.c */ |
1162 | |||
1163 | |||
diff --git a/src/daemon/connection.h b/src/daemon/connection.h index 840ae640..4955931d 100644 --- a/src/daemon/connection.h +++ b/src/daemon/connection.h | |||
@@ -35,19 +35,17 @@ | |||
35 | * @return MHD_YES on success | 35 | * @return MHD_YES on success |
36 | */ | 36 | */ |
37 | int | 37 | int |
38 | MHD_connection_get_fdset(struct MHD_Connection * connection, | 38 | MHD_connection_get_fdset (struct MHD_Connection *connection, |
39 | fd_set * read_fd_set, | 39 | fd_set * read_fd_set, |
40 | fd_set * write_fd_set, | 40 | fd_set * write_fd_set, |
41 | fd_set * except_fd_set, | 41 | fd_set * except_fd_set, int *max_fd); |
42 | int * max_fd); | ||
43 | 42 | ||
44 | 43 | ||
45 | /** | 44 | /** |
46 | * Call the handler of the application for this | 45 | * Call the handler of the application for this |
47 | * connection. | 46 | * connection. |
48 | */ | 47 | */ |
49 | void | 48 | void MHD_call_connection_handler (struct MHD_Connection *connection); |
50 | MHD_call_connection_handler(struct MHD_Connection * connection); | ||
51 | 49 | ||
52 | /** | 50 | /** |
53 | * This function handles a particular connection when it has been | 51 | * This function handles a particular connection when it has been |
@@ -55,8 +53,7 @@ MHD_call_connection_handler(struct MHD_Connection * connection); | |||
55 | * (multithreaded, external select, internal select) call this function | 53 | * (multithreaded, external select, internal select) call this function |
56 | * to handle reads. | 54 | * to handle reads. |
57 | */ | 55 | */ |
58 | int | 56 | int MHD_connection_handle_read (struct MHD_Connection *connection); |
59 | MHD_connection_handle_read(struct MHD_Connection * connection); | ||
60 | 57 | ||
61 | 58 | ||
62 | /** | 59 | /** |
@@ -65,8 +62,7 @@ MHD_connection_handle_read(struct MHD_Connection * connection); | |||
65 | * to be written, however, the function call does nothing. All implementations | 62 | * to be written, however, the function call does nothing. All implementations |
66 | * (multithreaded, external select, internal select) call this function | 63 | * (multithreaded, external select, internal select) call this function |
67 | */ | 64 | */ |
68 | int | 65 | int MHD_connection_handle_write (struct MHD_Connection *connection); |
69 | MHD_connection_handle_write(struct MHD_Connection * connection); | ||
70 | 66 | ||
71 | 67 | ||
72 | #endif | 68 | #endif |
diff --git a/src/daemon/daemon.c b/src/daemon/daemon.c index 2fbd3abc..3b2ebab0 100644 --- a/src/daemon/daemon.c +++ b/src/daemon/daemon.c | |||
@@ -48,30 +48,28 @@ | |||
48 | * already exists | 48 | * already exists |
49 | */ | 49 | */ |
50 | int | 50 | int |
51 | MHD_register_handler(struct MHD_Daemon * daemon, | 51 | MHD_register_handler (struct MHD_Daemon *daemon, |
52 | const char * uri_prefix, | 52 | const char *uri_prefix, |
53 | MHD_AccessHandlerCallback dh, | 53 | MHD_AccessHandlerCallback dh, void *dh_cls) |
54 | void * dh_cls) { | 54 | { |
55 | struct MHD_Access_Handler * ah; | 55 | struct MHD_Access_Handler *ah; |
56 | 56 | ||
57 | if ( (daemon == NULL) || | 57 | if ((daemon == NULL) || (uri_prefix == NULL) || (dh == NULL)) |
58 | (uri_prefix == NULL) || | 58 | return MHD_NO; |
59 | (dh == NULL) ) | ||
60 | return MHD_NO; | ||
61 | ah = daemon->handlers; | 59 | ah = daemon->handlers; |
62 | while (ah != NULL) { | 60 | while (ah != NULL) |
63 | if (0 == strcmp(uri_prefix, | 61 | { |
64 | ah->uri_prefix)) | 62 | if (0 == strcmp (uri_prefix, ah->uri_prefix)) |
65 | return MHD_NO; | 63 | return MHD_NO; |
66 | ah = ah->next; | 64 | ah = ah->next; |
67 | } | 65 | } |
68 | ah = malloc(sizeof(struct MHD_Access_Handler)); | 66 | ah = malloc (sizeof (struct MHD_Access_Handler)); |
69 | ah->next = daemon->handlers; | 67 | ah->next = daemon->handlers; |
70 | ah->uri_prefix = strdup(uri_prefix); | 68 | ah->uri_prefix = strdup (uri_prefix); |
71 | ah->dh = dh; | 69 | ah->dh = dh; |
72 | ah->dh_cls = dh_cls; | 70 | ah->dh_cls = dh_cls; |
73 | daemon->handlers = ah; | 71 | daemon->handlers = ah; |
74 | return MHD_YES; | 72 | return MHD_YES; |
75 | } | 73 | } |
76 | 74 | ||
77 | 75 | ||
@@ -84,34 +82,33 @@ MHD_register_handler(struct MHD_Daemon * daemon, | |||
84 | * is not known for this daemon | 82 | * is not known for this daemon |
85 | */ | 83 | */ |
86 | int | 84 | int |
87 | MHD_unregister_handler(struct MHD_Daemon * daemon, | 85 | MHD_unregister_handler (struct MHD_Daemon *daemon, |
88 | const char * uri_prefix, | 86 | const char *uri_prefix, |
89 | MHD_AccessHandlerCallback dh, | 87 | MHD_AccessHandlerCallback dh, void *dh_cls) |
90 | void * dh_cls) { | 88 | { |
91 | struct MHD_Access_Handler * prev; | 89 | struct MHD_Access_Handler *prev; |
92 | struct MHD_Access_Handler * pos; | 90 | struct MHD_Access_Handler *pos; |
93 | 91 | ||
94 | if ( (daemon == NULL) || | 92 | if ((daemon == NULL) || (uri_prefix == NULL) || (dh == NULL)) |
95 | (uri_prefix == NULL) || | 93 | return MHD_NO; |
96 | (dh == NULL) ) | ||
97 | return MHD_NO; | ||
98 | pos = daemon->handlers; | 94 | pos = daemon->handlers; |
99 | prev = NULL; | 95 | prev = NULL; |
100 | while (pos != NULL) { | 96 | while (pos != NULL) |
101 | if ( (dh == pos->dh) && | 97 | { |
102 | (dh_cls == pos->dh_cls) && | 98 | if ((dh == pos->dh) && |
103 | (0 == strcmp(uri_prefix, | 99 | (dh_cls == pos->dh_cls) && |
104 | pos->uri_prefix)) ) { | 100 | (0 == strcmp (uri_prefix, pos->uri_prefix))) |
105 | if (prev == NULL) | 101 | { |
106 | daemon->handlers = pos->next; | 102 | if (prev == NULL) |
107 | else | 103 | daemon->handlers = pos->next; |
108 | prev->next = pos->next; | 104 | else |
109 | free(pos); | 105 | prev->next = pos->next; |
110 | return MHD_YES; | 106 | free (pos); |
107 | return MHD_YES; | ||
108 | } | ||
109 | prev = pos; | ||
110 | pos = pos->next; | ||
111 | } | 111 | } |
112 | prev = pos; | ||
113 | pos = pos->next; | ||
114 | } | ||
115 | return MHD_NO; | 112 | return MHD_NO; |
116 | } | 113 | } |
117 | 114 | ||
@@ -123,34 +120,32 @@ MHD_unregister_handler(struct MHD_Daemon * daemon, | |||
123 | * options for this call. | 120 | * options for this call. |
124 | */ | 121 | */ |
125 | int | 122 | int |
126 | MHD_get_fdset(struct MHD_Daemon * daemon, | 123 | MHD_get_fdset (struct MHD_Daemon *daemon, |
127 | fd_set * read_fd_set, | 124 | fd_set * read_fd_set, |
128 | fd_set * write_fd_set, | 125 | fd_set * write_fd_set, fd_set * except_fd_set, int *max_fd) |
129 | fd_set * except_fd_set, | 126 | { |
130 | int * max_fd) { | 127 | struct MHD_Connection *pos; |
131 | struct MHD_Connection * pos; | 128 | |
132 | 129 | if ((daemon == NULL) || | |
133 | if ( (daemon == NULL) || | 130 | (read_fd_set == NULL) || |
134 | (read_fd_set == NULL) || | 131 | (write_fd_set == NULL) || |
135 | (write_fd_set == NULL) || | 132 | (except_fd_set == NULL) || |
136 | (except_fd_set == NULL) || | 133 | (max_fd == NULL) || |
137 | (max_fd == NULL) || | 134 | ((daemon->options & MHD_USE_THREAD_PER_CONNECTION) != 0)) |
138 | ( (daemon->options & MHD_USE_THREAD_PER_CONNECTION) != 0) ) | 135 | return MHD_NO; |
139 | return MHD_NO; | 136 | FD_SET (daemon->socket_fd, read_fd_set); |
140 | FD_SET(daemon->socket_fd, | 137 | if ((*max_fd) < daemon->socket_fd) |
141 | read_fd_set); | ||
142 | if ( (*max_fd) < daemon->socket_fd) | ||
143 | *max_fd = daemon->socket_fd; | 138 | *max_fd = daemon->socket_fd; |
144 | pos = daemon->connections; | 139 | pos = daemon->connections; |
145 | while (pos != NULL) { | 140 | while (pos != NULL) |
146 | if (MHD_YES != MHD_connection_get_fdset(pos, | 141 | { |
147 | read_fd_set, | 142 | if (MHD_YES != MHD_connection_get_fdset (pos, |
148 | write_fd_set, | 143 | read_fd_set, |
149 | except_fd_set, | 144 | write_fd_set, |
150 | max_fd)) | 145 | except_fd_set, max_fd)) |
151 | return MHD_NO; | 146 | return MHD_NO; |
152 | pos = pos->next; | 147 | pos = pos->next; |
153 | } | 148 | } |
154 | return MHD_YES; | 149 | return MHD_YES; |
155 | } | 150 | } |
156 | 151 | ||
@@ -160,8 +155,9 @@ MHD_get_fdset(struct MHD_Daemon * daemon, | |||
160 | * connection. | 155 | * connection. |
161 | */ | 156 | */ |
162 | static void * | 157 | static void * |
163 | MHD_handle_connection(void * data) { | 158 | MHD_handle_connection (void *data) |
164 | struct MHD_Connection * con = data; | 159 | { |
160 | struct MHD_Connection *con = data; | ||
165 | int num_ready; | 161 | int num_ready; |
166 | fd_set rs; | 162 | fd_set rs; |
167 | fd_set ws; | 163 | fd_set ws; |
@@ -169,42 +165,35 @@ MHD_handle_connection(void * data) { | |||
169 | int max; | 165 | int max; |
170 | 166 | ||
171 | if (con == NULL) | 167 | if (con == NULL) |
172 | abort(); | 168 | abort (); |
173 | while ( (! con->daemon->shutdown) && | 169 | while ((!con->daemon->shutdown) && (con->socket_fd != -1)) |
174 | (con->socket_fd != -1) ) { | 170 | { |
175 | FD_ZERO(&rs); | 171 | FD_ZERO (&rs); |
176 | FD_ZERO(&ws); | 172 | FD_ZERO (&ws); |
177 | FD_ZERO(&es); | 173 | FD_ZERO (&es); |
178 | max = 0; | 174 | max = 0; |
179 | MHD_connection_get_fdset(con, | 175 | MHD_connection_get_fdset (con, &rs, &ws, &es, &max); |
180 | &rs, | 176 | num_ready = SELECT (max + 1, &rs, &ws, &es, NULL); |
181 | &ws, | 177 | if (num_ready <= 0) |
182 | &es, | 178 | { |
183 | &max); | 179 | if (errno == EINTR) |
184 | num_ready = SELECT(max + 1, | 180 | continue; |
185 | &rs, | 181 | break; |
186 | &ws, | 182 | } |
187 | &es, | 183 | if (((FD_ISSET (con->socket_fd, &rs)) && |
188 | NULL); | 184 | (MHD_YES != MHD_connection_handle_read (con))) || |
189 | if (num_ready <= 0) { | 185 | ((con->socket_fd != -1) && |
190 | if (errno == EINTR) | 186 | (FD_ISSET (con->socket_fd, &ws)) && |
191 | continue; | 187 | (MHD_YES != MHD_connection_handle_write (con)))) |
192 | break; | 188 | break; |
189 | if ((con->headersReceived == 1) && (con->response == NULL)) | ||
190 | MHD_call_connection_handler (con); | ||
191 | } | ||
192 | if (con->socket_fd != -1) | ||
193 | { | ||
194 | CLOSE (con->socket_fd); | ||
195 | con->socket_fd = -1; | ||
193 | } | 196 | } |
194 | if ( ( (FD_ISSET(con->socket_fd, &rs)) && | ||
195 | (MHD_YES != MHD_connection_handle_read(con)) ) || | ||
196 | ( (con->socket_fd != -1) && | ||
197 | (FD_ISSET(con->socket_fd, &ws)) && | ||
198 | (MHD_YES != MHD_connection_handle_write(con)) ) ) | ||
199 | break; | ||
200 | if ( (con->headersReceived == 1) && | ||
201 | (con->response == NULL) ) | ||
202 | MHD_call_connection_handler(con); | ||
203 | } | ||
204 | if (con->socket_fd != -1) { | ||
205 | CLOSE(con->socket_fd); | ||
206 | con->socket_fd = -1; | ||
207 | } | ||
208 | return NULL; | 197 | return NULL; |
209 | } | 198 | } |
210 | 199 | ||
@@ -215,77 +204,66 @@ MHD_handle_connection(void * data) { | |||
215 | * accept policy callback. | 204 | * accept policy callback. |
216 | */ | 205 | */ |
217 | static int | 206 | static int |
218 | MHD_accept_connection(struct MHD_Daemon * daemon) { | 207 | MHD_accept_connection (struct MHD_Daemon *daemon) |
219 | struct MHD_Connection * connection; | 208 | { |
209 | struct MHD_Connection *connection; | ||
220 | struct sockaddr_in6 addr6; | 210 | struct sockaddr_in6 addr6; |
221 | struct sockaddr * addr = (struct sockaddr*) &addr6; | 211 | struct sockaddr *addr = (struct sockaddr *) &addr6; |
222 | socklen_t addrlen; | 212 | socklen_t addrlen; |
223 | int s; | 213 | int s; |
224 | 214 | ||
225 | 215 | ||
226 | if (sizeof(struct sockaddr) > sizeof(struct sockaddr_in6)) | 216 | if (sizeof (struct sockaddr) > sizeof (struct sockaddr_in6)) |
227 | abort(); /* fatal, serious error */ | 217 | abort (); /* fatal, serious error */ |
228 | addrlen = sizeof(struct sockaddr_in6); | 218 | addrlen = sizeof (struct sockaddr_in6); |
229 | memset(addr, | 219 | memset (addr, 0, sizeof (struct sockaddr_in6)); |
230 | 0, | 220 | s = ACCEPT (daemon->socket_fd, addr, &addrlen); |
231 | sizeof(struct sockaddr_in6)); | 221 | if ((s < 0) || (addrlen <= 0)) |
232 | s = ACCEPT(daemon->socket_fd, | 222 | { |
233 | addr, | 223 | MHD_DLOG (daemon, "Error accepting connection: %s\n", STRERROR (errno)); |
234 | &addrlen); | 224 | if (s != -1) |
235 | if ( (s < 0) || | 225 | CLOSE (s); /* just in case */ |
236 | (addrlen <= 0) ) { | 226 | return MHD_NO; |
237 | MHD_DLOG(daemon, | 227 | } |
238 | "Error accepting connection: %s\n", | 228 | if (daemon->max_connections == 0) |
239 | STRERROR(errno)); | 229 | { |
240 | if (s != -1) | 230 | /* above connection limit - reject */ |
241 | CLOSE(s); /* just in case */ | 231 | CLOSE (s); |
242 | return MHD_NO; | 232 | return MHD_NO; |
243 | } | 233 | } |
244 | if (daemon->max_connections == 0) { | 234 | if ((daemon->apc != NULL) && |
245 | /* above connection limit - reject */ | 235 | (MHD_NO == daemon->apc (daemon->apc_cls, addr, addrlen))) |
246 | CLOSE(s); | 236 | { |
247 | return MHD_NO; | 237 | CLOSE (s); |
248 | } | 238 | return MHD_YES; |
249 | if ( (daemon->apc != NULL) && | 239 | } |
250 | (MHD_NO == daemon->apc(daemon->apc_cls, | 240 | connection = malloc (sizeof (struct MHD_Connection)); |
251 | addr, | 241 | memset (connection, 0, sizeof (struct MHD_Connection)); |
252 | addrlen)) ) { | ||
253 | CLOSE(s); | ||
254 | return MHD_YES; | ||
255 | } | ||
256 | connection = malloc(sizeof(struct MHD_Connection)); | ||
257 | memset(connection, | ||
258 | 0, | ||
259 | sizeof(struct MHD_Connection)); | ||
260 | connection->pool = NULL; | 242 | connection->pool = NULL; |
261 | connection->addr = malloc(addrlen); | 243 | connection->addr = malloc (addrlen); |
262 | if (connection->addr == NULL) { | 244 | if (connection->addr == NULL) |
263 | CLOSE(s); | 245 | { |
264 | free(connection); | 246 | CLOSE (s); |
265 | return MHD_NO; | 247 | free (connection); |
266 | } | 248 | return MHD_NO; |
267 | memcpy(connection->addr, | 249 | } |
268 | addr, | 250 | memcpy (connection->addr, addr, addrlen); |
269 | addrlen); | ||
270 | connection->addr_len = addrlen; | 251 | connection->addr_len = addrlen; |
271 | connection->socket_fd = s; | 252 | connection->socket_fd = s; |
272 | connection->daemon = daemon; | 253 | connection->daemon = daemon; |
273 | if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION) ) && | 254 | if ((0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && |
274 | (0 != pthread_create(&connection->pid, | 255 | (0 != pthread_create (&connection->pid, |
275 | NULL, | 256 | NULL, &MHD_handle_connection, connection))) |
276 | &MHD_handle_connection, | 257 | { |
277 | connection)) ) { | 258 | MHD_DLOG (daemon, "Failed to create a thread: %s\n", STRERROR (errno)); |
278 | MHD_DLOG(daemon, | 259 | CLOSE (s); |
279 | "Failed to create a thread: %s\n", | 260 | free (connection->addr); |
280 | STRERROR(errno)); | 261 | free (connection); |
281 | CLOSE(s); | 262 | return MHD_NO; |
282 | free(connection->addr); | 263 | } |
283 | free(connection); | ||
284 | return MHD_NO; | ||
285 | } | ||
286 | connection->next = daemon->connections; | 264 | connection->next = daemon->connections; |
287 | daemon->connections = connection; | 265 | daemon->connections = connection; |
288 | daemon->max_connections--; | 266 | daemon->max_connections--; |
289 | return MHD_YES; | 267 | return MHD_YES; |
290 | } | 268 | } |
291 | 269 | ||
@@ -301,43 +279,46 @@ MHD_accept_connection(struct MHD_Daemon * daemon) { | |||
301 | * the upload data buffer is full). | 279 | * the upload data buffer is full). |
302 | */ | 280 | */ |
303 | static void | 281 | static void |
304 | MHD_cleanup_connections(struct MHD_Daemon * daemon) { | 282 | MHD_cleanup_connections (struct MHD_Daemon *daemon) |
305 | struct MHD_Connection * pos; | 283 | { |
306 | struct MHD_Connection * prev; | 284 | struct MHD_Connection *pos; |
307 | void * unused; | 285 | struct MHD_Connection *prev; |
286 | void *unused; | ||
308 | 287 | ||
309 | pos = daemon->connections; | 288 | pos = daemon->connections; |
310 | prev = NULL; | 289 | prev = NULL; |
311 | while (pos != NULL) { | 290 | while (pos != NULL) |
312 | if (pos->socket_fd == -1) { | 291 | { |
313 | if (prev == NULL) | 292 | if (pos->socket_fd == -1) |
314 | daemon->connections = pos->next; | 293 | { |
315 | else | 294 | if (prev == NULL) |
316 | prev->next = pos->next; | 295 | daemon->connections = pos->next; |
317 | if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) { | 296 | else |
318 | pthread_kill(pos->pid, SIGALRM); | 297 | prev->next = pos->next; |
319 | pthread_join(pos->pid, &unused); | 298 | if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) |
320 | } | 299 | { |
321 | if (pos->response != NULL) | 300 | pthread_kill (pos->pid, SIGALRM); |
322 | MHD_destroy_response(pos->response); | 301 | pthread_join (pos->pid, &unused); |
323 | MHD_pool_destroy(pos->pool); | 302 | } |
324 | free(pos->addr); | 303 | if (pos->response != NULL) |
325 | free(pos); | 304 | MHD_destroy_response (pos->response); |
326 | daemon->max_connections++; | 305 | MHD_pool_destroy (pos->pool); |
327 | if (prev == NULL) | 306 | free (pos->addr); |
328 | pos = daemon->connections; | 307 | free (pos); |
329 | else | 308 | daemon->max_connections++; |
330 | pos = prev->next; | 309 | if (prev == NULL) |
331 | continue; | 310 | pos = daemon->connections; |
311 | else | ||
312 | pos = prev->next; | ||
313 | continue; | ||
314 | } | ||
315 | |||
316 | if ((pos->headersReceived == 1) && (pos->response == NULL)) | ||
317 | MHD_call_connection_handler (pos); | ||
318 | |||
319 | prev = pos; | ||
320 | pos = pos->next; | ||
332 | } | 321 | } |
333 | |||
334 | if ( (pos->headersReceived == 1) && | ||
335 | (pos->response == NULL) ) | ||
336 | MHD_call_connection_handler(pos); | ||
337 | |||
338 | prev = pos; | ||
339 | pos = pos->next; | ||
340 | } | ||
341 | } | 322 | } |
342 | 323 | ||
343 | 324 | ||
@@ -348,9 +329,9 @@ MHD_cleanup_connections(struct MHD_Daemon * daemon) { | |||
348 | * @return MHD_NO on serious errors, MHD_YES on success | 329 | * @return MHD_NO on serious errors, MHD_YES on success |
349 | */ | 330 | */ |
350 | static int | 331 | static int |
351 | MHD_select(struct MHD_Daemon * daemon, | 332 | MHD_select (struct MHD_Daemon *daemon, int may_block) |
352 | int may_block) { | 333 | { |
353 | struct MHD_Connection * pos; | 334 | struct MHD_Connection *pos; |
354 | int num_ready; | 335 | int num_ready; |
355 | fd_set rs; | 336 | fd_set rs; |
356 | fd_set ws; | 337 | fd_set ws; |
@@ -361,61 +342,58 @@ MHD_select(struct MHD_Daemon * daemon, | |||
361 | 342 | ||
362 | timeout.tv_sec = 0; | 343 | timeout.tv_sec = 0; |
363 | timeout.tv_usec = 0; | 344 | timeout.tv_usec = 0; |
364 | if(daemon == NULL) | 345 | if (daemon == NULL) |
365 | abort(); | 346 | abort (); |
366 | FD_ZERO(&rs); | 347 | FD_ZERO (&rs); |
367 | FD_ZERO(&ws); | 348 | FD_ZERO (&ws); |
368 | FD_ZERO(&es); | 349 | FD_ZERO (&es); |
369 | max = 0; | 350 | max = 0; |
370 | 351 | ||
371 | if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) { | 352 | if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) |
372 | /* single-threaded, go over everything */ | 353 | { |
373 | if (MHD_NO == MHD_get_fdset(daemon, | 354 | /* single-threaded, go over everything */ |
374 | &rs, | 355 | if (MHD_NO == MHD_get_fdset (daemon, &rs, &ws, &es, &max)) |
375 | &ws, | 356 | return MHD_NO; |
376 | &es, | 357 | } |
377 | &max)) | 358 | else |
359 | { | ||
360 | /* accept only, have one thread per connection */ | ||
361 | max = daemon->socket_fd; | ||
362 | FD_SET (daemon->socket_fd, &rs); | ||
363 | } | ||
364 | num_ready = SELECT (max + 1, | ||
365 | &rs, &ws, &es, may_block == MHD_NO ? &timeout : NULL); | ||
366 | if (num_ready < 0) | ||
367 | { | ||
368 | if (errno == EINTR) | ||
369 | return MHD_YES; | ||
370 | MHD_DLOG (daemon, "Select failed: %s\n", STRERROR (errno)); | ||
378 | return MHD_NO; | 371 | return MHD_NO; |
379 | } else { | 372 | } |
380 | /* accept only, have one thread per connection */ | ||
381 | max = daemon->socket_fd; | ||
382 | FD_SET(daemon->socket_fd, &rs); | ||
383 | } | ||
384 | num_ready = SELECT(max + 1, | ||
385 | &rs, | ||
386 | &ws, | ||
387 | &es, | ||
388 | may_block == MHD_NO ? &timeout : NULL); | ||
389 | if (num_ready < 0) { | ||
390 | if (errno == EINTR) | ||
391 | return MHD_YES; | ||
392 | MHD_DLOG(daemon, | ||
393 | "Select failed: %s\n", | ||
394 | STRERROR(errno)); | ||
395 | return MHD_NO; | ||
396 | } | ||
397 | ds = daemon->socket_fd; | 373 | ds = daemon->socket_fd; |
398 | if (ds == -1) | 374 | if (ds == -1) |
399 | return MHD_YES; | 375 | return MHD_YES; |
400 | if (FD_ISSET(ds, | 376 | if (FD_ISSET (ds, &rs)) |
401 | &rs)) | 377 | MHD_accept_connection (daemon); |
402 | MHD_accept_connection(daemon); | 378 | if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) |
403 | if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) { | 379 | { |
404 | /* do not have a thread per connection, process all connections now */ | 380 | /* do not have a thread per connection, process all connections now */ |
405 | pos = daemon->connections; | 381 | pos = daemon->connections; |
406 | while (pos != NULL) { | 382 | while (pos != NULL) |
407 | ds = pos->socket_fd; | 383 | { |
408 | if (ds == -1) { | 384 | ds = pos->socket_fd; |
409 | pos = pos->next; | 385 | if (ds == -1) |
410 | continue; | 386 | { |
411 | } | 387 | pos = pos->next; |
412 | if (FD_ISSET(ds, &rs)) | 388 | continue; |
413 | MHD_connection_handle_read(pos); | 389 | } |
414 | if (FD_ISSET(ds, &ws)) | 390 | if (FD_ISSET (ds, &rs)) |
415 | MHD_connection_handle_write(pos); | 391 | MHD_connection_handle_read (pos); |
416 | pos = pos->next; | 392 | if (FD_ISSET (ds, &ws)) |
393 | MHD_connection_handle_write (pos); | ||
394 | pos = pos->next; | ||
395 | } | ||
417 | } | 396 | } |
418 | } | ||
419 | return MHD_YES; | 397 | return MHD_YES; |
420 | } | 398 | } |
421 | 399 | ||
@@ -431,13 +409,14 @@ MHD_select(struct MHD_Daemon * daemon, | |||
431 | * options for this call. | 409 | * options for this call. |
432 | */ | 410 | */ |
433 | int | 411 | int |
434 | MHD_run(struct MHD_Daemon * daemon) { | 412 | MHD_run (struct MHD_Daemon *daemon) |
435 | if ( (daemon->shutdown != 0) || | 413 | { |
436 | (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) || | 414 | if ((daemon->shutdown != 0) || |
437 | (0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) ) | 415 | (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) || |
416 | (0 != (daemon->options & MHD_USE_SELECT_INTERNALLY))) | ||
438 | return MHD_NO; | 417 | return MHD_NO; |
439 | MHD_select(daemon, MHD_NO); | 418 | MHD_select (daemon, MHD_NO); |
440 | MHD_cleanup_connections(daemon); | 419 | MHD_cleanup_connections (daemon); |
441 | return MHD_YES; | 420 | return MHD_YES; |
442 | } | 421 | } |
443 | 422 | ||
@@ -447,12 +426,14 @@ MHD_run(struct MHD_Daemon * daemon) { | |||
447 | * is explicitly shut down. | 426 | * is explicitly shut down. |
448 | */ | 427 | */ |
449 | static void * | 428 | static void * |
450 | MHD_select_thread(void * cls) { | 429 | MHD_select_thread (void *cls) |
451 | struct MHD_Daemon * daemon = cls; | 430 | { |
452 | while (daemon->shutdown == 0) { | 431 | struct MHD_Daemon *daemon = cls; |
453 | MHD_select(daemon, MHD_YES); | 432 | while (daemon->shutdown == 0) |
454 | MHD_cleanup_connections(daemon); | 433 | { |
455 | } | 434 | MHD_select (daemon, MHD_YES); |
435 | MHD_cleanup_connections (daemon); | ||
436 | } | ||
456 | return NULL; | 437 | return NULL; |
457 | } | 438 | } |
458 | 439 | ||
@@ -469,88 +450,75 @@ MHD_select_thread(void * cls) { | |||
469 | * @return NULL on error, handle to daemon on success | 450 | * @return NULL on error, handle to daemon on success |
470 | */ | 451 | */ |
471 | struct MHD_Daemon * | 452 | struct MHD_Daemon * |
472 | MHD_start_daemon(unsigned int options, | 453 | MHD_start_daemon (unsigned int options, |
473 | unsigned short port, | 454 | unsigned short port, |
474 | MHD_AcceptPolicyCallback apc, | 455 | MHD_AcceptPolicyCallback apc, |
475 | void * apc_cls, | 456 | void *apc_cls, |
476 | MHD_AccessHandlerCallback dh, | 457 | MHD_AccessHandlerCallback dh, void *dh_cls, ...) |
477 | void * dh_cls, | 458 | { |
478 | ...) { | ||
479 | const int on = 1; | 459 | const int on = 1; |
480 | struct MHD_Daemon * retVal; | 460 | struct MHD_Daemon *retVal; |
481 | int socket_fd; | 461 | int socket_fd; |
482 | struct sockaddr_in servaddr4; | 462 | struct sockaddr_in servaddr4; |
483 | struct sockaddr_in6 servaddr6; | 463 | struct sockaddr_in6 servaddr6; |
484 | const struct sockaddr * servaddr; | 464 | const struct sockaddr *servaddr; |
485 | socklen_t addrlen; | 465 | socklen_t addrlen; |
486 | va_list ap; | 466 | va_list ap; |
487 | enum MHD_OPTION opt; | 467 | enum MHD_OPTION opt; |
488 | 468 | ||
489 | if ((options & MHD_USE_SSL) != 0) | 469 | if ((options & MHD_USE_SSL) != 0) |
490 | return NULL; | 470 | return NULL; |
491 | if ( (port == 0) || | 471 | if ((port == 0) || (dh == NULL)) |
492 | (dh == NULL) ) | ||
493 | return NULL; | 472 | return NULL; |
494 | if ((options & MHD_USE_IPv6) != 0) | 473 | if ((options & MHD_USE_IPv6) != 0) |
495 | socket_fd = SOCKET(PF_INET6, SOCK_STREAM, 0); | 474 | socket_fd = SOCKET (PF_INET6, SOCK_STREAM, 0); |
496 | else | 475 | else |
497 | socket_fd = SOCKET(PF_INET, SOCK_STREAM, 0); | 476 | socket_fd = SOCKET (PF_INET, SOCK_STREAM, 0); |
498 | if (socket_fd < 0) { | 477 | if (socket_fd < 0) |
499 | if ((options & MHD_USE_DEBUG) != 0) | 478 | { |
500 | fprintf(stderr, | 479 | if ((options & MHD_USE_DEBUG) != 0) |
501 | "Call to socket failed: %s\n", | 480 | fprintf (stderr, "Call to socket failed: %s\n", STRERROR (errno)); |
502 | STRERROR(errno)); | 481 | return NULL; |
503 | return NULL; | 482 | } |
504 | } | 483 | if ((SETSOCKOPT (socket_fd, |
505 | if ( (SETSOCKOPT(socket_fd, | 484 | SOL_SOCKET, |
506 | SOL_SOCKET, | 485 | SO_REUSEADDR, |
507 | SO_REUSEADDR, | 486 | &on, sizeof (on)) < 0) && (options & MHD_USE_DEBUG) != 0) |
508 | &on, | 487 | fprintf (stderr, "setsockopt failed: %s\n", STRERROR (errno)); |
509 | sizeof(on)) < 0) && | 488 | if ((options & MHD_USE_IPv6) != 0) |
510 | (options & MHD_USE_DEBUG) != 0) | 489 | { |
511 | fprintf(stderr, | 490 | memset (&servaddr6, 0, sizeof (struct sockaddr_in6)); |
512 | "setsockopt failed: %s\n", | 491 | servaddr6.sin6_family = AF_INET6; |
513 | STRERROR(errno)); | 492 | servaddr6.sin6_port = htons (port); |
514 | if ((options & MHD_USE_IPv6) != 0) { | 493 | servaddr = (struct sockaddr *) &servaddr6; |
515 | memset(&servaddr6, | 494 | addrlen = sizeof (struct sockaddr_in6); |
516 | 0, | 495 | } |
517 | sizeof(struct sockaddr_in6)); | 496 | else |
518 | servaddr6.sin6_family = AF_INET6; | 497 | { |
519 | servaddr6.sin6_port = htons(port); | 498 | memset (&servaddr4, 0, sizeof (struct sockaddr_in)); |
520 | servaddr = (struct sockaddr*) &servaddr6; | 499 | servaddr4.sin_family = AF_INET; |
521 | addrlen = sizeof(struct sockaddr_in6); | 500 | servaddr4.sin_port = htons (port); |
522 | } else { | 501 | servaddr = (struct sockaddr *) &servaddr4; |
523 | memset(&servaddr4, | 502 | addrlen = sizeof (struct sockaddr_in); |
524 | 0, | 503 | } |
525 | sizeof(struct sockaddr_in)); | 504 | if (BIND (socket_fd, servaddr, addrlen) < 0) |
526 | servaddr4.sin_family = AF_INET; | 505 | { |
527 | servaddr4.sin_port = htons(port); | 506 | if ((options & MHD_USE_DEBUG) != 0) |
528 | servaddr = (struct sockaddr*) &servaddr4; | 507 | fprintf (stderr, |
529 | addrlen = sizeof(struct sockaddr_in); | 508 | "Failed to bind to port %u: %s\n", port, STRERROR (errno)); |
530 | } | 509 | CLOSE (socket_fd); |
531 | if (BIND(socket_fd, | 510 | return NULL; |
532 | servaddr, | 511 | } |
533 | addrlen) < 0) { | 512 | if (LISTEN (socket_fd, 20) < 0) |
534 | if ( (options & MHD_USE_DEBUG) != 0) | 513 | { |
535 | fprintf(stderr, | 514 | if ((options & MHD_USE_DEBUG) != 0) |
536 | "Failed to bind to port %u: %s\n", | 515 | fprintf (stderr, |
537 | port, | 516 | "Failed to listen for connections: %s\n", STRERROR (errno)); |
538 | STRERROR(errno)); | 517 | CLOSE (socket_fd); |
539 | CLOSE(socket_fd); | 518 | return NULL; |
540 | return NULL; | 519 | } |
541 | } | 520 | retVal = malloc (sizeof (struct MHD_Daemon)); |
542 | if (LISTEN(socket_fd, 20) < 0) { | 521 | memset (retVal, 0, sizeof (struct MHD_Daemon)); |
543 | if ((options & MHD_USE_DEBUG) != 0) | ||
544 | fprintf(stderr, | ||
545 | "Failed to listen for connections: %s\n", | ||
546 | STRERROR(errno)); | ||
547 | CLOSE(socket_fd); | ||
548 | return NULL; | ||
549 | } | ||
550 | retVal = malloc(sizeof(struct MHD_Daemon)); | ||
551 | memset(retVal, | ||
552 | 0, | ||
553 | sizeof(struct MHD_Daemon)); | ||
554 | retVal->options = options; | 522 | retVal->options = options; |
555 | retVal->port = port; | 523 | retVal->port = port; |
556 | retVal->apc = apc; | 524 | retVal->apc = apc; |
@@ -562,35 +530,34 @@ MHD_start_daemon(unsigned int options, | |||
562 | retVal->default_handler.next = NULL; | 530 | retVal->default_handler.next = NULL; |
563 | retVal->max_connections = MHD_MAX_CONNECTIONS_DEFAULT; | 531 | retVal->max_connections = MHD_MAX_CONNECTIONS_DEFAULT; |
564 | retVal->pool_size = MHD_POOL_SIZE_DEFAULT; | 532 | retVal->pool_size = MHD_POOL_SIZE_DEFAULT; |
565 | va_start(ap, dh_cls); | 533 | va_start (ap, dh_cls); |
566 | while (MHD_OPTION_END != (opt = va_arg(ap, enum MHD_OPTION))) { | 534 | while (MHD_OPTION_END != (opt = va_arg (ap, enum MHD_OPTION))) |
567 | switch (opt) { | 535 | { |
568 | case MHD_OPTION_CONNECTION_MEMORY_LIMIT: | 536 | switch (opt) |
569 | retVal->pool_size = va_arg(ap, unsigned int); | 537 | { |
570 | break; | 538 | case MHD_OPTION_CONNECTION_MEMORY_LIMIT: |
571 | case MHD_OPTION_CONNECTION_LIMIT: | 539 | retVal->pool_size = va_arg (ap, unsigned int); |
572 | retVal->max_connections = va_arg(ap, unsigned int); | 540 | break; |
573 | break; | 541 | case MHD_OPTION_CONNECTION_LIMIT: |
574 | default: | 542 | retVal->max_connections = va_arg (ap, unsigned int); |
575 | fprintf(stderr, | 543 | break; |
576 | "Invalid MHD_OPTION argument! (Did you terminate the list with MHD_OPTION_END?)\n"); | 544 | default: |
577 | abort(); | 545 | fprintf (stderr, |
546 | "Invalid MHD_OPTION argument! (Did you terminate the list with MHD_OPTION_END?)\n"); | ||
547 | abort (); | ||
548 | } | ||
549 | } | ||
550 | va_end (ap); | ||
551 | if (((0 != (options & MHD_USE_THREAD_PER_CONNECTION)) || | ||
552 | (0 != (options & MHD_USE_SELECT_INTERNALLY))) && | ||
553 | (0 != pthread_create (&retVal->pid, NULL, &MHD_select_thread, retVal))) | ||
554 | { | ||
555 | MHD_DLOG (retVal, | ||
556 | "Failed to create listen thread: %s\n", STRERROR (errno)); | ||
557 | free (retVal); | ||
558 | CLOSE (socket_fd); | ||
559 | return NULL; | ||
578 | } | 560 | } |
579 | } | ||
580 | va_end(ap); | ||
581 | if ( ( (0 != (options & MHD_USE_THREAD_PER_CONNECTION)) || | ||
582 | (0 != (options & MHD_USE_SELECT_INTERNALLY)) ) && | ||
583 | (0 != pthread_create(&retVal->pid, | ||
584 | NULL, | ||
585 | &MHD_select_thread, | ||
586 | retVal)) ) { | ||
587 | MHD_DLOG(retVal, | ||
588 | "Failed to create listen thread: %s\n", | ||
589 | STRERROR(errno)); | ||
590 | free(retVal); | ||
591 | CLOSE(socket_fd); | ||
592 | return NULL; | ||
593 | } | ||
594 | return retVal; | 561 | return retVal; |
595 | } | 562 | } |
596 | 563 | ||
@@ -598,27 +565,31 @@ MHD_start_daemon(unsigned int options, | |||
598 | * Shutdown an http daemon. | 565 | * Shutdown an http daemon. |
599 | */ | 566 | */ |
600 | void | 567 | void |
601 | MHD_stop_daemon(struct MHD_Daemon * daemon) { | 568 | MHD_stop_daemon (struct MHD_Daemon *daemon) |
602 | void * unused; | 569 | { |
570 | void *unused; | ||
603 | 571 | ||
604 | if (daemon == NULL) | 572 | if (daemon == NULL) |
605 | return; | 573 | return; |
606 | daemon->shutdown = 1; | 574 | daemon->shutdown = 1; |
607 | CLOSE(daemon->socket_fd); | 575 | CLOSE (daemon->socket_fd); |
608 | daemon->socket_fd = -1; | 576 | daemon->socket_fd = -1; |
609 | if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) || | 577 | if ((0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) || |
610 | (0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) ) { | 578 | (0 != (daemon->options & MHD_USE_SELECT_INTERNALLY))) |
611 | pthread_kill(daemon->pid, SIGALRM); | 579 | { |
612 | pthread_join(daemon->pid, &unused); | 580 | pthread_kill (daemon->pid, SIGALRM); |
613 | } | 581 | pthread_join (daemon->pid, &unused); |
614 | while (daemon->connections != NULL) { | 582 | } |
615 | if (-1 != daemon->connections->socket_fd) { | 583 | while (daemon->connections != NULL) |
616 | CLOSE(daemon->connections->socket_fd); | 584 | { |
617 | daemon->connections->socket_fd = -1; | 585 | if (-1 != daemon->connections->socket_fd) |
586 | { | ||
587 | CLOSE (daemon->connections->socket_fd); | ||
588 | daemon->connections->socket_fd = -1; | ||
589 | } | ||
590 | MHD_cleanup_connections (daemon); | ||
618 | } | 591 | } |
619 | MHD_cleanup_connections(daemon); | 592 | free (daemon); |
620 | } | ||
621 | free(daemon); | ||
622 | } | 593 | } |
623 | 594 | ||
624 | #ifndef WINDOWS | 595 | #ifndef WINDOWS |
@@ -627,23 +598,27 @@ static struct sigaction sig; | |||
627 | 598 | ||
628 | static struct sigaction old; | 599 | static struct sigaction old; |
629 | 600 | ||
630 | static void sigalrmHandler(int sig) { | 601 | static void |
602 | sigalrmHandler (int sig) | ||
603 | { | ||
631 | } | 604 | } |
632 | 605 | ||
633 | /** | 606 | /** |
634 | * Initialize the signal handler for SIGALRM. | 607 | * Initialize the signal handler for SIGALRM. |
635 | */ | 608 | */ |
636 | void __attribute__ ((constructor)) MHD_pthread_handlers_ltdl_init() { | 609 | void __attribute__ ((constructor)) MHD_pthread_handlers_ltdl_init () |
610 | { | ||
637 | /* make sure SIGALRM does not kill us */ | 611 | /* make sure SIGALRM does not kill us */ |
638 | memset(&sig, 0, sizeof(struct sigaction)); | 612 | memset (&sig, 0, sizeof (struct sigaction)); |
639 | memset(&old, 0, sizeof(struct sigaction)); | 613 | memset (&old, 0, sizeof (struct sigaction)); |
640 | sig.sa_flags = SA_NODEFER; | 614 | sig.sa_flags = SA_NODEFER; |
641 | sig.sa_handler = &sigalrmHandler; | 615 | sig.sa_handler = &sigalrmHandler; |
642 | sigaction(SIGALRM, &sig, &old); | 616 | sigaction (SIGALRM, &sig, &old); |
643 | } | 617 | } |
644 | 618 | ||
645 | void __attribute__ ((destructor)) MHD_pthread_handlers_ltdl_fini() { | 619 | void __attribute__ ((destructor)) MHD_pthread_handlers_ltdl_fini () |
646 | sigaction(SIGALRM, &old, &sig); | 620 | { |
621 | sigaction (SIGALRM, &old, &sig); | ||
647 | } | 622 | } |
648 | 623 | ||
649 | #endif | 624 | #endif |
diff --git a/src/daemon/daemontest.c b/src/daemon/daemontest.c index e7378cdd..7b4ad4de 100644 --- a/src/daemon/daemontest.c +++ b/src/daemon/daemontest.c | |||
@@ -31,131 +31,128 @@ | |||
31 | #include <string.h> | 31 | #include <string.h> |
32 | #include <stdio.h> | 32 | #include <stdio.h> |
33 | 33 | ||
34 | static int testStartError() { | 34 | static int |
35 | struct MHD_Daemon * d; | 35 | testStartError () |
36 | { | ||
37 | struct MHD_Daemon *d; | ||
36 | 38 | ||
37 | d = MHD_start_daemon(MHD_USE_DEBUG, 0, NULL, NULL, NULL, NULL); | 39 | d = MHD_start_daemon (MHD_USE_DEBUG, 0, NULL, NULL, NULL, NULL); |
38 | if (d != NULL) | 40 | if (d != NULL) |
39 | return 1; | 41 | return 1; |
40 | return 0; | 42 | return 0; |
41 | } | 43 | } |
42 | 44 | ||
43 | static int apc_nothing(void * cls, | 45 | static int |
44 | const struct sockaddr * addr, | 46 | apc_nothing (void *cls, const struct sockaddr *addr, socklen_t addrlen) |
45 | socklen_t addrlen) { | 47 | { |
46 | return MHD_NO; | 48 | return MHD_NO; |
47 | } | 49 | } |
48 | 50 | ||
49 | static int apc_all(void * cls, | 51 | static int |
50 | const struct sockaddr * addr, | 52 | apc_all (void *cls, const struct sockaddr *addr, socklen_t addrlen) |
51 | socklen_t addrlen) { | 53 | { |
52 | return MHD_YES; | 54 | return MHD_YES; |
53 | } | 55 | } |
54 | 56 | ||
55 | static int ahc_nothing(void * cls, | 57 | static int |
56 | struct MHD_Connection * connection, | 58 | ahc_nothing (void *cls, |
57 | const char * url, | 59 | struct MHD_Connection *connection, |
58 | const char * method, | 60 | const char *url, |
59 | const char * version, | 61 | const char *method, |
60 | const char * upload_data, | 62 | const char *version, |
61 | unsigned int * upload_data_size) { | 63 | const char *upload_data, unsigned int *upload_data_size) |
64 | { | ||
62 | return MHD_NO; | 65 | return MHD_NO; |
63 | } | 66 | } |
64 | 67 | ||
65 | static int testStartStop() { | 68 | static int |
66 | struct MHD_Daemon * d; | 69 | testStartStop () |
70 | { | ||
71 | struct MHD_Daemon *d; | ||
67 | 72 | ||
68 | d = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG, | 73 | d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG, |
69 | 1080, | 74 | 1080, |
70 | &apc_nothing, | 75 | &apc_nothing, |
71 | NULL, | 76 | NULL, &ahc_nothing, NULL, MHD_OPTION_END); |
72 | &ahc_nothing, | ||
73 | NULL, | ||
74 | MHD_OPTION_END); | ||
75 | if (d == NULL) | 77 | if (d == NULL) |
76 | return 2; | 78 | return 2; |
77 | MHD_stop_daemon(d); | 79 | MHD_stop_daemon (d); |
78 | return 0; | 80 | return 0; |
79 | } | 81 | } |
80 | 82 | ||
81 | static int testExternalRun() { | 83 | static int |
82 | struct MHD_Daemon * d; | 84 | testExternalRun () |
85 | { | ||
86 | struct MHD_Daemon *d; | ||
83 | fd_set rs; | 87 | fd_set rs; |
84 | int maxfd; | 88 | int maxfd; |
85 | int i; | 89 | int i; |
86 | 90 | ||
87 | d = MHD_start_daemon(MHD_USE_DEBUG, | 91 | d = MHD_start_daemon (MHD_USE_DEBUG, |
88 | 1081, | 92 | 1081, |
89 | &apc_all, | 93 | &apc_all, NULL, &ahc_nothing, NULL, MHD_OPTION_END); |
90 | NULL, | ||
91 | &ahc_nothing, | ||
92 | NULL, | ||
93 | MHD_OPTION_END); | ||
94 | 94 | ||
95 | if (d == NULL) | 95 | if (d == NULL) |
96 | return 4; | 96 | return 4; |
97 | i = 0; | 97 | i = 0; |
98 | while(i < 15) { | 98 | while (i < 15) |
99 | maxfd = 0; | 99 | { |
100 | FD_ZERO(&rs); | 100 | maxfd = 0; |
101 | MHD_get_fdset(d, &rs, &rs, &rs, &maxfd); | 101 | FD_ZERO (&rs); |
102 | if (MHD_run(d) == MHD_NO) { | 102 | MHD_get_fdset (d, &rs, &rs, &rs, &maxfd); |
103 | MHD_stop_daemon(d); | 103 | if (MHD_run (d) == MHD_NO) |
104 | return 8; | 104 | { |
105 | MHD_stop_daemon (d); | ||
106 | return 8; | ||
107 | } | ||
108 | i++; | ||
105 | } | 109 | } |
106 | i++; | 110 | MHD_stop_daemon (d); |
107 | } | ||
108 | MHD_stop_daemon(d); | ||
109 | return 0; | 111 | return 0; |
110 | } | 112 | } |
111 | 113 | ||
112 | static int testThread() { | 114 | static int |
113 | struct MHD_Daemon * d; | 115 | testThread () |
114 | d = MHD_start_daemon(MHD_USE_DEBUG | MHD_USE_SELECT_INTERNALLY, | 116 | { |
115 | 1082, | 117 | struct MHD_Daemon *d; |
116 | &apc_all, | 118 | d = MHD_start_daemon (MHD_USE_DEBUG | MHD_USE_SELECT_INTERNALLY, |
117 | NULL, | 119 | 1082, |
118 | &ahc_nothing, | 120 | &apc_all, NULL, &ahc_nothing, NULL, MHD_OPTION_END); |
119 | NULL, | ||
120 | MHD_OPTION_END); | ||
121 | 121 | ||
122 | if (d == NULL) | 122 | if (d == NULL) |
123 | return 16; | 123 | return 16; |
124 | if (MHD_run(d) != MHD_NO) | 124 | if (MHD_run (d) != MHD_NO) |
125 | return 32; | 125 | return 32; |
126 | MHD_stop_daemon(d); | 126 | MHD_stop_daemon (d); |
127 | return 0; | 127 | return 0; |
128 | } | 128 | } |
129 | 129 | ||
130 | static int testMultithread() { | 130 | static int |
131 | struct MHD_Daemon * d; | 131 | testMultithread () |
132 | d = MHD_start_daemon(MHD_USE_DEBUG | MHD_USE_THREAD_PER_CONNECTION, | 132 | { |
133 | 1083, | 133 | struct MHD_Daemon *d; |
134 | &apc_all, | 134 | d = MHD_start_daemon (MHD_USE_DEBUG | MHD_USE_THREAD_PER_CONNECTION, |
135 | NULL, | 135 | 1083, |
136 | &ahc_nothing, | 136 | &apc_all, NULL, &ahc_nothing, NULL, MHD_OPTION_END); |
137 | NULL, | ||
138 | MHD_OPTION_END); | ||
139 | 137 | ||
140 | if (d == NULL) | 138 | if (d == NULL) |
141 | return 64; | 139 | return 64; |
142 | if (MHD_run(d) != MHD_NO) | 140 | if (MHD_run (d) != MHD_NO) |
143 | return 128; | 141 | return 128; |
144 | MHD_stop_daemon(d); | 142 | MHD_stop_daemon (d); |
145 | return 0; | 143 | return 0; |
146 | } | 144 | } |
147 | 145 | ||
148 | int main(int argc, | 146 | int |
149 | char * const * argv) { | 147 | main (int argc, char *const *argv) |
148 | { | ||
150 | unsigned int errorCount = 0; | 149 | unsigned int errorCount = 0; |
151 | errorCount += testStartError(); | 150 | errorCount += testStartError (); |
152 | errorCount += testStartStop(); | 151 | errorCount += testStartStop (); |
153 | errorCount += testExternalRun(); | 152 | errorCount += testExternalRun (); |
154 | errorCount += testThread(); | 153 | errorCount += testThread (); |
155 | errorCount += testMultithread(); | 154 | errorCount += testMultithread (); |
156 | if (errorCount != 0) | 155 | if (errorCount != 0) |
157 | fprintf(stderr, | 156 | fprintf (stderr, "Error (code: %u)\n", errorCount); |
158 | "Error (code: %u)\n", | 157 | return errorCount != 0; /* 0 == pass */ |
159 | errorCount); | ||
160 | return errorCount != 0; /* 0 == pass */ | ||
161 | } | 158 | } |
diff --git a/src/daemon/daemontest_get.c b/src/daemon/daemontest_get.c index 08de296d..f200a4c8 100644 --- a/src/daemon/daemontest_get.c +++ b/src/daemon/daemontest_get.c | |||
@@ -35,210 +35,167 @@ | |||
35 | 35 | ||
36 | static int oneone; | 36 | static int oneone; |
37 | 37 | ||
38 | struct CBC { | 38 | struct CBC |
39 | char * buf; | 39 | { |
40 | char *buf; | ||
40 | size_t pos; | 41 | size_t pos; |
41 | size_t size; | 42 | size_t size; |
42 | }; | 43 | }; |
43 | 44 | ||
44 | static size_t copyBuffer(void * ptr, | 45 | static size_t |
45 | size_t size, | 46 | copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx) |
46 | size_t nmemb, | 47 | { |
47 | void * ctx) { | 48 | struct CBC *cbc = ctx; |
48 | struct CBC * cbc = ctx; | ||
49 | 49 | ||
50 | if (cbc->pos + size * nmemb > cbc->size) | 50 | if (cbc->pos + size * nmemb > cbc->size) |
51 | return 0; /* overflow */ | 51 | return 0; /* overflow */ |
52 | memcpy(&cbc->buf[cbc->pos], | 52 | memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb); |
53 | ptr, | ||
54 | size * nmemb); | ||
55 | cbc->pos += size * nmemb; | 53 | cbc->pos += size * nmemb; |
56 | return size * nmemb; | 54 | return size * nmemb; |
57 | } | 55 | } |
58 | 56 | ||
59 | static int ahc_echo(void * cls, | 57 | static int |
60 | struct MHD_Connection * connection, | 58 | ahc_echo (void *cls, |
61 | const char * url, | 59 | struct MHD_Connection *connection, |
62 | const char * method, | 60 | const char *url, |
63 | const char * version, | 61 | const char *method, |
64 | const char * upload_data, | 62 | const char *version, |
65 | unsigned int * upload_data_size) { | 63 | const char *upload_data, unsigned int *upload_data_size) |
66 | const char * me = cls; | 64 | { |
67 | struct MHD_Response * response; | 65 | const char *me = cls; |
66 | struct MHD_Response *response; | ||
68 | int ret; | 67 | int ret; |
69 | 68 | ||
70 | if (0 != strcmp(me, method)) | 69 | if (0 != strcmp (me, method)) |
71 | return MHD_NO; /* unexpected method */ | 70 | return MHD_NO; /* unexpected method */ |
72 | response = MHD_create_response_from_data(strlen(url), | 71 | response = MHD_create_response_from_data (strlen (url), |
73 | (void*) url, | 72 | (void *) url, MHD_NO, MHD_YES); |
74 | MHD_NO, | 73 | ret = MHD_queue_response (connection, MHD_HTTP_OK, response); |
75 | MHD_YES); | 74 | MHD_destroy_response (response); |
76 | ret = MHD_queue_response(connection, | ||
77 | MHD_HTTP_OK, | ||
78 | response); | ||
79 | MHD_destroy_response(response); | ||
80 | return ret; | 75 | return ret; |
81 | } | 76 | } |
82 | 77 | ||
83 | 78 | ||
84 | static int testInternalGet() { | 79 | static int |
85 | struct MHD_Daemon * d; | 80 | testInternalGet () |
86 | CURL * c; | 81 | { |
82 | struct MHD_Daemon *d; | ||
83 | CURL *c; | ||
87 | char buf[2048]; | 84 | char buf[2048]; |
88 | struct CBC cbc; | 85 | struct CBC cbc; |
89 | 86 | ||
90 | cbc.buf = buf; | 87 | cbc.buf = buf; |
91 | cbc.size = 2048; | 88 | cbc.size = 2048; |
92 | cbc.pos = 0; | 89 | cbc.pos = 0; |
93 | d = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG, | 90 | d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG, |
94 | 1080, | 91 | 1080, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END); |
95 | NULL, | ||
96 | NULL, | ||
97 | &ahc_echo, | ||
98 | "GET", | ||
99 | MHD_OPTION_END); | ||
100 | if (d == NULL) | 92 | if (d == NULL) |
101 | return 1; | 93 | return 1; |
102 | c = curl_easy_init(); | 94 | c = curl_easy_init (); |
103 | curl_easy_setopt(c, | 95 | curl_easy_setopt (c, CURLOPT_URL, "http://localhost:1080/hello_world"); |
104 | CURLOPT_URL, | 96 | curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer); |
105 | "http://localhost:1080/hello_world"); | 97 | curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc); |
106 | curl_easy_setopt(c, | 98 | curl_easy_setopt (c, CURLOPT_FAILONERROR, 1); |
107 | CURLOPT_WRITEFUNCTION, | 99 | curl_easy_setopt (c, CURLOPT_TIMEOUT, 2L); |
108 | ©Buffer); | 100 | curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 2L); |
109 | curl_easy_setopt(c, | ||
110 | CURLOPT_WRITEDATA, | ||
111 | &cbc); | ||
112 | curl_easy_setopt(c, | ||
113 | CURLOPT_FAILONERROR, | ||
114 | 1); | ||
115 | curl_easy_setopt(c, | ||
116 | CURLOPT_TIMEOUT, | ||
117 | 2L); | ||
118 | curl_easy_setopt(c, | ||
119 | CURLOPT_CONNECTTIMEOUT, | ||
120 | 2L); | ||
121 | if (oneone) | 101 | if (oneone) |
122 | curl_easy_setopt(c, | 102 | curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); |
123 | CURLOPT_HTTP_VERSION, | ||
124 | CURL_HTTP_VERSION_1_1); | ||
125 | else | 103 | else |
126 | curl_easy_setopt(c, | 104 | curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); |
127 | CURLOPT_HTTP_VERSION, | 105 | // NOTE: use of CONNECTTIMEOUT without also |
128 | CURL_HTTP_VERSION_1_0); | ||
129 | // NOTE: use of CONNECTTIMEOUT without also | ||
130 | // setting NOSIGNAL results in really weird | 106 | // setting NOSIGNAL results in really weird |
131 | // crashes on my system! | 107 | // crashes on my system! |
132 | curl_easy_setopt(c, | 108 | curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1); |
133 | CURLOPT_NOSIGNAL, | 109 | if (CURLE_OK != curl_easy_perform (c)) |
134 | 1); | 110 | { |
135 | if (CURLE_OK != curl_easy_perform(c)) { | 111 | curl_easy_cleanup (c); |
136 | curl_easy_cleanup(c); | 112 | MHD_stop_daemon (d); |
137 | MHD_stop_daemon(d); | 113 | return 2; |
138 | return 2; | 114 | } |
139 | } | 115 | curl_easy_cleanup (c); |
140 | curl_easy_cleanup(c); | 116 | if (cbc.pos != strlen ("/hello_world")) |
141 | if (cbc.pos != strlen("/hello_world")) { | 117 | { |
142 | MHD_stop_daemon(d); | 118 | MHD_stop_daemon (d); |
143 | return 4; | 119 | return 4; |
144 | } | 120 | } |
145 | 121 | ||
146 | if (0 != strncmp("/hello_world", | 122 | if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world"))) |
147 | cbc.buf, | 123 | { |
148 | strlen("/hello_world"))) { | 124 | MHD_stop_daemon (d); |
149 | MHD_stop_daemon(d); | 125 | return 8; |
150 | return 8; | 126 | } |
151 | } | 127 | MHD_stop_daemon (d); |
152 | MHD_stop_daemon(d); | ||
153 | 128 | ||
154 | return 0; | 129 | return 0; |
155 | } | 130 | } |
156 | 131 | ||
157 | static int testMultithreadedGet() { | 132 | static int |
158 | struct MHD_Daemon * d; | 133 | testMultithreadedGet () |
159 | CURL * c; | 134 | { |
135 | struct MHD_Daemon *d; | ||
136 | CURL *c; | ||
160 | char buf[2048]; | 137 | char buf[2048]; |
161 | struct CBC cbc; | 138 | struct CBC cbc; |
162 | 139 | ||
163 | cbc.buf = buf; | 140 | cbc.buf = buf; |
164 | cbc.size = 2048; | 141 | cbc.size = 2048; |
165 | cbc.pos = 0; | 142 | cbc.pos = 0; |
166 | d = MHD_start_daemon(MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG, | 143 | d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG, |
167 | 1081, | 144 | 1081, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END); |
168 | NULL, | ||
169 | NULL, | ||
170 | &ahc_echo, | ||
171 | "GET", | ||
172 | MHD_OPTION_END); | ||
173 | if (d == NULL) | 145 | if (d == NULL) |
174 | return 16; | 146 | return 16; |
175 | c = curl_easy_init(); | 147 | c = curl_easy_init (); |
176 | curl_easy_setopt(c, | 148 | curl_easy_setopt (c, CURLOPT_URL, "http://localhost:1081/hello_world"); |
177 | CURLOPT_URL, | 149 | curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer); |
178 | "http://localhost:1081/hello_world"); | 150 | curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc); |
179 | curl_easy_setopt(c, | 151 | curl_easy_setopt (c, CURLOPT_FAILONERROR, 1); |
180 | CURLOPT_WRITEFUNCTION, | 152 | curl_easy_setopt (c, CURLOPT_TIMEOUT, 2L); |
181 | ©Buffer); | ||
182 | curl_easy_setopt(c, | ||
183 | CURLOPT_WRITEDATA, | ||
184 | &cbc); | ||
185 | curl_easy_setopt(c, | ||
186 | CURLOPT_FAILONERROR, | ||
187 | 1); | ||
188 | curl_easy_setopt(c, | ||
189 | CURLOPT_TIMEOUT, | ||
190 | 2L); | ||
191 | if (oneone) | 153 | if (oneone) |
192 | curl_easy_setopt(c, | 154 | curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); |
193 | CURLOPT_HTTP_VERSION, | ||
194 | CURL_HTTP_VERSION_1_1); | ||
195 | else | 155 | else |
196 | curl_easy_setopt(c, | 156 | curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); |
197 | CURLOPT_HTTP_VERSION, | 157 | curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 2L); |
198 | CURL_HTTP_VERSION_1_0); | ||
199 | curl_easy_setopt(c, | ||
200 | CURLOPT_CONNECTTIMEOUT, | ||
201 | 2L); | ||
202 | // NOTE: use of CONNECTTIMEOUT without also | 158 | // NOTE: use of CONNECTTIMEOUT without also |
203 | // setting NOSIGNAL results in really weird | 159 | // setting NOSIGNAL results in really weird |
204 | // crashes on my system! | 160 | // crashes on my system! |
205 | curl_easy_setopt(c, | 161 | curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1); |
206 | CURLOPT_NOSIGNAL, | 162 | if (CURLE_OK != curl_easy_perform (c)) |
207 | 1); | 163 | { |
208 | if (CURLE_OK != curl_easy_perform(c)) { | 164 | MHD_stop_daemon (d); |
209 | MHD_stop_daemon(d); | 165 | return 32; |
210 | return 32; | 166 | } |
211 | } | 167 | curl_easy_cleanup (c); |
212 | curl_easy_cleanup(c); | 168 | if (cbc.pos != strlen ("/hello_world")) |
213 | if (cbc.pos != strlen("/hello_world")) { | 169 | { |
214 | MHD_stop_daemon(d); | 170 | MHD_stop_daemon (d); |
215 | return 64; | 171 | return 64; |
216 | } | 172 | } |
217 | if (0 != strncmp("/hello_world", | 173 | if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world"))) |
218 | cbc.buf, | 174 | { |
219 | strlen("/hello_world"))) { | 175 | MHD_stop_daemon (d); |
220 | MHD_stop_daemon(d); | 176 | return 128; |
221 | return 128; | 177 | } |
222 | } | 178 | MHD_stop_daemon (d); |
223 | MHD_stop_daemon(d); | ||
224 | 179 | ||
225 | return 0; | 180 | return 0; |
226 | } | 181 | } |
227 | 182 | ||
228 | 183 | ||
229 | static int testExternalGet() { | 184 | static int |
230 | struct MHD_Daemon * d; | 185 | testExternalGet () |
231 | CURL * c; | 186 | { |
187 | struct MHD_Daemon *d; | ||
188 | CURL *c; | ||
232 | char buf[2048]; | 189 | char buf[2048]; |
233 | struct CBC cbc; | 190 | struct CBC cbc; |
234 | CURLM * multi; | 191 | CURLM *multi; |
235 | CURLMcode mret; | 192 | CURLMcode mret; |
236 | fd_set rs; | 193 | fd_set rs; |
237 | fd_set ws; | 194 | fd_set ws; |
238 | fd_set es; | 195 | fd_set es; |
239 | int max; | 196 | int max; |
240 | int running; | 197 | int running; |
241 | struct CURLMsg * msg; | 198 | struct CURLMsg *msg; |
242 | time_t start; | 199 | time_t start; |
243 | struct timeval tv; | 200 | struct timeval tv; |
244 | 201 | ||
@@ -246,154 +203,121 @@ static int testExternalGet() { | |||
246 | cbc.buf = buf; | 203 | cbc.buf = buf; |
247 | cbc.size = 2048; | 204 | cbc.size = 2048; |
248 | cbc.pos = 0; | 205 | cbc.pos = 0; |
249 | d = MHD_start_daemon(MHD_USE_DEBUG, | 206 | d = MHD_start_daemon (MHD_USE_DEBUG, |
250 | 1082, | 207 | 1082, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END); |
251 | NULL, | ||
252 | NULL, | ||
253 | &ahc_echo, | ||
254 | "GET", | ||
255 | MHD_OPTION_END); | ||
256 | if (d == NULL) | 208 | if (d == NULL) |
257 | return 256; | 209 | return 256; |
258 | c = curl_easy_init(); | 210 | c = curl_easy_init (); |
259 | curl_easy_setopt(c, | 211 | curl_easy_setopt (c, CURLOPT_URL, "http://localhost:1082/hello_world"); |
260 | CURLOPT_URL, | 212 | curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer); |
261 | "http://localhost:1082/hello_world"); | 213 | curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc); |
262 | curl_easy_setopt(c, | 214 | curl_easy_setopt (c, CURLOPT_FAILONERROR, 1); |
263 | CURLOPT_WRITEFUNCTION, | ||
264 | ©Buffer); | ||
265 | curl_easy_setopt(c, | ||
266 | CURLOPT_WRITEDATA, | ||
267 | &cbc); | ||
268 | curl_easy_setopt(c, | ||
269 | CURLOPT_FAILONERROR, | ||
270 | 1); | ||
271 | if (oneone) | 215 | if (oneone) |
272 | curl_easy_setopt(c, | 216 | curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); |
273 | CURLOPT_HTTP_VERSION, | ||
274 | CURL_HTTP_VERSION_1_1); | ||
275 | else | 217 | else |
276 | curl_easy_setopt(c, | 218 | curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); |
277 | CURLOPT_HTTP_VERSION, | 219 | curl_easy_setopt (c, CURLOPT_TIMEOUT, 5L); |
278 | CURL_HTTP_VERSION_1_0); | 220 | curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 5L); |
279 | curl_easy_setopt(c, | ||
280 | CURLOPT_TIMEOUT, | ||
281 | 5L); | ||
282 | curl_easy_setopt(c, | ||
283 | CURLOPT_CONNECTTIMEOUT, | ||
284 | 5L); | ||
285 | // NOTE: use of CONNECTTIMEOUT without also | 221 | // NOTE: use of CONNECTTIMEOUT without also |
286 | // setting NOSIGNAL results in really weird | 222 | // setting NOSIGNAL results in really weird |
287 | // crashes on my system! | 223 | // crashes on my system! |
288 | curl_easy_setopt(c, | 224 | curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1); |
289 | CURLOPT_NOSIGNAL, | ||
290 | 1); | ||
291 | 225 | ||
292 | 226 | ||
293 | multi = curl_multi_init(); | 227 | multi = curl_multi_init (); |
294 | if (multi == NULL) { | 228 | if (multi == NULL) |
295 | curl_easy_cleanup(c); | 229 | { |
296 | MHD_stop_daemon(d); | 230 | curl_easy_cleanup (c); |
297 | return 512; | 231 | MHD_stop_daemon (d); |
298 | } | 232 | return 512; |
299 | mret = curl_multi_add_handle(multi, c); | 233 | } |
300 | if (mret != CURLM_OK) { | 234 | mret = curl_multi_add_handle (multi, c); |
301 | curl_multi_cleanup(multi); | 235 | if (mret != CURLM_OK) |
302 | curl_easy_cleanup(c); | 236 | { |
303 | MHD_stop_daemon(d); | 237 | curl_multi_cleanup (multi); |
304 | return 1024; | 238 | curl_easy_cleanup (c); |
305 | } | 239 | MHD_stop_daemon (d); |
306 | start = time(NULL); | 240 | return 1024; |
307 | while ( (time(NULL) - start < 5) && | 241 | } |
308 | (multi != NULL) ) { | 242 | start = time (NULL); |
309 | max = 0; | 243 | while ((time (NULL) - start < 5) && (multi != NULL)) |
310 | FD_ZERO(&rs); | 244 | { |
311 | FD_ZERO(&ws); | 245 | max = 0; |
312 | FD_ZERO(&es); | 246 | FD_ZERO (&rs); |
313 | curl_multi_perform(multi, &running); | 247 | FD_ZERO (&ws); |
314 | mret = curl_multi_fdset(multi, | 248 | FD_ZERO (&es); |
315 | &rs, | 249 | curl_multi_perform (multi, &running); |
316 | &ws, | 250 | mret = curl_multi_fdset (multi, &rs, &ws, &es, &max); |
317 | &es, | 251 | if (mret != CURLM_OK) |
318 | &max); | 252 | { |
319 | if (mret != CURLM_OK) { | 253 | curl_multi_remove_handle (multi, c); |
320 | curl_multi_remove_handle(multi, c); | 254 | curl_multi_cleanup (multi); |
321 | curl_multi_cleanup(multi); | 255 | curl_easy_cleanup (c); |
322 | curl_easy_cleanup(c); | 256 | MHD_stop_daemon (d); |
323 | MHD_stop_daemon(d); | 257 | return 2048; |
324 | return 2048; | 258 | } |
259 | if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max)) | ||
260 | { | ||
261 | curl_multi_remove_handle (multi, c); | ||
262 | curl_multi_cleanup (multi); | ||
263 | curl_easy_cleanup (c); | ||
264 | MHD_stop_daemon (d); | ||
265 | return 4096; | ||
266 | } | ||
267 | tv.tv_sec = 0; | ||
268 | tv.tv_usec = 1000; | ||
269 | select (max + 1, &rs, &ws, &es, &tv); | ||
270 | curl_multi_perform (multi, &running); | ||
271 | if (running == 0) | ||
272 | { | ||
273 | msg = curl_multi_info_read (multi, &running); | ||
274 | if (msg == NULL) | ||
275 | break; | ||
276 | if (msg->msg == CURLMSG_DONE) | ||
277 | { | ||
278 | if (msg->data.result != CURLE_OK) | ||
279 | printf ("%s failed at %s:%d: `%s'\n", | ||
280 | "curl_multi_perform", | ||
281 | __FILE__, | ||
282 | __LINE__, curl_easy_strerror (msg->data.result)); | ||
283 | curl_multi_remove_handle (multi, c); | ||
284 | curl_multi_cleanup (multi); | ||
285 | curl_easy_cleanup (c); | ||
286 | c = NULL; | ||
287 | multi = NULL; | ||
288 | } | ||
289 | } | ||
290 | MHD_run (d); | ||
325 | } | 291 | } |
326 | if (MHD_YES != MHD_get_fdset(d, | 292 | if (multi != NULL) |
327 | &rs, | 293 | { |
328 | &ws, | 294 | curl_multi_remove_handle (multi, c); |
329 | &es, | 295 | curl_easy_cleanup (c); |
330 | &max)) { | 296 | curl_multi_cleanup (multi); |
331 | curl_multi_remove_handle(multi, c); | ||
332 | curl_multi_cleanup(multi); | ||
333 | curl_easy_cleanup(c); | ||
334 | MHD_stop_daemon(d); | ||
335 | return 4096; | ||
336 | } | 297 | } |
337 | tv.tv_sec = 0; | 298 | MHD_stop_daemon (d); |
338 | tv.tv_usec = 1000; | 299 | if (cbc.pos != strlen ("/hello_world")) |
339 | select(max + 1, | ||
340 | &rs, | ||
341 | &ws, | ||
342 | &es, | ||
343 | &tv); | ||
344 | curl_multi_perform(multi, &running); | ||
345 | if (running == 0) { | ||
346 | msg = curl_multi_info_read(multi, | ||
347 | &running); | ||
348 | if (msg == NULL) | ||
349 | break; | ||
350 | if (msg->msg == CURLMSG_DONE) { | ||
351 | if (msg->data.result != CURLE_OK) | ||
352 | printf("%s failed at %s:%d: `%s'\n", | ||
353 | "curl_multi_perform", | ||
354 | __FILE__, | ||
355 | __LINE__, | ||
356 | curl_easy_strerror(msg->data.result)); | ||
357 | curl_multi_remove_handle(multi, c); | ||
358 | curl_multi_cleanup(multi); | ||
359 | curl_easy_cleanup(c); | ||
360 | c = NULL; | ||
361 | multi = NULL; | ||
362 | } | ||
363 | } | ||
364 | MHD_run(d); | ||
365 | } | ||
366 | if (multi != NULL) { | ||
367 | curl_multi_remove_handle(multi, c); | ||
368 | curl_easy_cleanup(c); | ||
369 | curl_multi_cleanup(multi); | ||
370 | } | ||
371 | MHD_stop_daemon(d); | ||
372 | if (cbc.pos != strlen("/hello_world")) | ||
373 | return 8192; | 300 | return 8192; |
374 | if (0 != strncmp("/hello_world", | 301 | if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world"))) |
375 | cbc.buf, | ||
376 | strlen("/hello_world"))) | ||
377 | return 16384; | 302 | return 16384; |
378 | return 0; | 303 | return 0; |
379 | } | 304 | } |
380 | 305 | ||
381 | 306 | ||
382 | 307 | ||
383 | int main(int argc, | 308 | int |
384 | char * const * argv) { | 309 | main (int argc, char *const *argv) |
310 | { | ||
385 | unsigned int errorCount = 0; | 311 | unsigned int errorCount = 0; |
386 | 312 | ||
387 | oneone = NULL != strstr(argv[0], "11"); | 313 | oneone = NULL != strstr (argv[0], "11"); |
388 | if (0 != curl_global_init(CURL_GLOBAL_WIN32)) | 314 | if (0 != curl_global_init (CURL_GLOBAL_WIN32)) |
389 | return 2; | 315 | return 2; |
390 | errorCount += testInternalGet(); | 316 | errorCount += testInternalGet (); |
391 | errorCount += testMultithreadedGet(); | 317 | errorCount += testMultithreadedGet (); |
392 | errorCount += testExternalGet(); | 318 | errorCount += testExternalGet (); |
393 | if (errorCount != 0) | 319 | if (errorCount != 0) |
394 | fprintf(stderr, | 320 | fprintf (stderr, "Error (code: %u)\n", errorCount); |
395 | "Error (code: %u)\n", | 321 | curl_global_cleanup (); |
396 | errorCount); | 322 | return errorCount != 0; /* 0 == pass */ |
397 | curl_global_cleanup(); | ||
398 | return errorCount != 0; /* 0 == pass */ | ||
399 | } | 323 | } |
diff --git a/src/daemon/daemontest_long_header.c b/src/daemon/daemontest_long_header.c index 48635704..d0e26484 100644 --- a/src/daemon/daemontest_long_header.c +++ b/src/daemon/daemontest_long_header.c | |||
@@ -41,247 +41,196 @@ | |||
41 | 41 | ||
42 | static int oneone; | 42 | static int oneone; |
43 | 43 | ||
44 | static int apc_all(void * cls, | 44 | static int |
45 | const struct sockaddr * addr, | 45 | apc_all (void *cls, const struct sockaddr *addr, socklen_t addrlen) |
46 | socklen_t addrlen) { | 46 | { |
47 | return MHD_YES; | 47 | return MHD_YES; |
48 | } | 48 | } |
49 | 49 | ||
50 | struct CBC { | 50 | struct CBC |
51 | char * buf; | 51 | { |
52 | char *buf; | ||
52 | size_t pos; | 53 | size_t pos; |
53 | size_t size; | 54 | size_t size; |
54 | }; | 55 | }; |
55 | 56 | ||
56 | static size_t copyBuffer(void * ptr, | 57 | static size_t |
57 | size_t size, | 58 | copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx) |
58 | size_t nmemb, | 59 | { |
59 | void * ctx) { | ||
60 | return size * nmemb; | 60 | return size * nmemb; |
61 | } | 61 | } |
62 | 62 | ||
63 | static int ahc_echo(void * cls, | 63 | static int |
64 | struct MHD_Connection * connection, | 64 | ahc_echo (void *cls, |
65 | const char * url, | 65 | struct MHD_Connection *connection, |
66 | const char * method, | 66 | const char *url, |
67 | const char * version, | 67 | const char *method, |
68 | const char * upload_data, | 68 | const char *version, |
69 | unsigned int * upload_data_size) { | 69 | const char *upload_data, unsigned int *upload_data_size) |
70 | const char * me = cls; | 70 | { |
71 | struct MHD_Response * response; | 71 | const char *me = cls; |
72 | struct MHD_Response *response; | ||
72 | int ret; | 73 | int ret; |
73 | 74 | ||
74 | if (0 != strcmp(me, method)) | 75 | if (0 != strcmp (me, method)) |
75 | return MHD_NO; /* unexpected method */ | 76 | return MHD_NO; /* unexpected method */ |
76 | response = MHD_create_response_from_data(strlen(url), | 77 | response = MHD_create_response_from_data (strlen (url), |
77 | (void*) url, | 78 | (void *) url, MHD_NO, MHD_YES); |
78 | MHD_NO, | 79 | ret = MHD_queue_response (connection, MHD_HTTP_OK, response); |
79 | MHD_YES); | 80 | MHD_destroy_response (response); |
80 | ret = MHD_queue_response(connection, | ||
81 | MHD_HTTP_OK, | ||
82 | response); | ||
83 | MHD_destroy_response(response); | ||
84 | return ret; | 81 | return ret; |
85 | } | 82 | } |
86 | 83 | ||
87 | 84 | ||
88 | static int testLongUrlGet() { | 85 | static int |
89 | struct MHD_Daemon * d; | 86 | testLongUrlGet () |
90 | CURL * c; | 87 | { |
88 | struct MHD_Daemon *d; | ||
89 | CURL *c; | ||
91 | char buf[2048]; | 90 | char buf[2048]; |
92 | struct CBC cbc; | 91 | struct CBC cbc; |
93 | char * url; | 92 | char *url; |
94 | long code; | 93 | long code; |
95 | 94 | ||
96 | cbc.buf = buf; | 95 | cbc.buf = buf; |
97 | cbc.size = 2048; | 96 | cbc.size = 2048; |
98 | cbc.pos = 0; | 97 | cbc.pos = 0; |
99 | d = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY /* | MHD_USE_DEBUG */, | 98 | d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY /* | MHD_USE_DEBUG */ , |
100 | 1080, | 99 | 1080, |
101 | &apc_all, | 100 | &apc_all, |
102 | NULL, | 101 | NULL, |
103 | &ahc_echo, | 102 | &ahc_echo, |
104 | "GET", | 103 | "GET", |
105 | MHD_OPTION_CONNECTION_MEMORY_LIMIT, | 104 | MHD_OPTION_CONNECTION_MEMORY_LIMIT, |
106 | VERY_LONG / 2, | 105 | VERY_LONG / 2, MHD_OPTION_END); |
107 | MHD_OPTION_END); | ||
108 | if (d == NULL) | 106 | if (d == NULL) |
109 | return 1; | 107 | return 1; |
110 | c = curl_easy_init(); | 108 | c = curl_easy_init (); |
111 | url = malloc(VERY_LONG); | 109 | url = malloc (VERY_LONG); |
112 | memset(url, | 110 | memset (url, 'a', VERY_LONG); |
113 | 'a', | 111 | url[VERY_LONG - 1] = '\0'; |
114 | VERY_LONG); | 112 | memcpy (url, "http://localhost:1080/", strlen ("http://localhost:1080/")); |
115 | url[VERY_LONG-1] = '\0'; | 113 | curl_easy_setopt (c, CURLOPT_URL, url); |
116 | memcpy(url, | 114 | curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer); |
117 | "http://localhost:1080/", | 115 | curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc); |
118 | strlen("http://localhost:1080/")); | 116 | curl_easy_setopt (c, CURLOPT_FAILONERROR, 1); |
119 | curl_easy_setopt(c, | 117 | curl_easy_setopt (c, CURLOPT_TIMEOUT, 2L); |
120 | CURLOPT_URL, | 118 | curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 2L); |
121 | url); | ||
122 | curl_easy_setopt(c, | ||
123 | CURLOPT_WRITEFUNCTION, | ||
124 | ©Buffer); | ||
125 | curl_easy_setopt(c, | ||
126 | CURLOPT_WRITEDATA, | ||
127 | &cbc); | ||
128 | curl_easy_setopt(c, | ||
129 | CURLOPT_FAILONERROR, | ||
130 | 1); | ||
131 | curl_easy_setopt(c, | ||
132 | CURLOPT_TIMEOUT, | ||
133 | 2L); | ||
134 | curl_easy_setopt(c, | ||
135 | CURLOPT_CONNECTTIMEOUT, | ||
136 | 2L); | ||
137 | if (oneone) | 119 | if (oneone) |
138 | curl_easy_setopt(c, | 120 | curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); |
139 | CURLOPT_HTTP_VERSION, | ||
140 | CURL_HTTP_VERSION_1_1); | ||
141 | else | 121 | else |
142 | curl_easy_setopt(c, | 122 | curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); |
143 | CURLOPT_HTTP_VERSION, | 123 | // NOTE: use of CONNECTTIMEOUT without also |
144 | CURL_HTTP_VERSION_1_0); | ||
145 | // NOTE: use of CONNECTTIMEOUT without also | ||
146 | // setting NOSIGNAL results in really weird | 124 | // setting NOSIGNAL results in really weird |
147 | // crashes on my system! | 125 | // crashes on my system! |
148 | curl_easy_setopt(c, | 126 | curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1); |
149 | CURLOPT_NOSIGNAL, | 127 | if (CURLE_OK == curl_easy_perform (c)) |
150 | 1); | 128 | { |
151 | if (CURLE_OK == curl_easy_perform(c)) { | 129 | curl_easy_cleanup (c); |
152 | curl_easy_cleanup(c); | 130 | MHD_stop_daemon (d); |
153 | MHD_stop_daemon(d); | 131 | free (url); |
154 | free(url); | 132 | return 2; |
155 | return 2; | 133 | } |
156 | } | 134 | if (CURLE_OK != curl_easy_getinfo (c, CURLINFO_RESPONSE_CODE, &code)) |
157 | if (CURLE_OK != curl_easy_getinfo(c, | 135 | { |
158 | CURLINFO_RESPONSE_CODE, | 136 | curl_easy_cleanup (c); |
159 | &code)) { | 137 | MHD_stop_daemon (d); |
160 | curl_easy_cleanup(c); | 138 | free (url); |
161 | MHD_stop_daemon(d); | 139 | return 4; |
162 | free(url); | 140 | } |
163 | return 4; | 141 | curl_easy_cleanup (c); |
164 | } | 142 | MHD_stop_daemon (d); |
165 | curl_easy_cleanup(c); | 143 | free (url); |
166 | MHD_stop_daemon(d); | ||
167 | free(url); | ||
168 | if (code != MHD_HTTP_REQUEST_URI_TOO_LONG) | 144 | if (code != MHD_HTTP_REQUEST_URI_TOO_LONG) |
169 | return 8; | 145 | return 8; |
170 | return 0; | 146 | return 0; |
171 | } | 147 | } |
172 | 148 | ||
173 | 149 | ||
174 | static int testLongHeaderGet() { | 150 | static int |
175 | struct MHD_Daemon * d; | 151 | testLongHeaderGet () |
176 | CURL * c; | 152 | { |
153 | struct MHD_Daemon *d; | ||
154 | CURL *c; | ||
177 | char buf[2048]; | 155 | char buf[2048]; |
178 | struct CBC cbc; | 156 | struct CBC cbc; |
179 | char * url; | 157 | char *url; |
180 | long code; | 158 | long code; |
181 | struct curl_slist * header = NULL; | 159 | struct curl_slist *header = NULL; |
182 | 160 | ||
183 | cbc.buf = buf; | 161 | cbc.buf = buf; |
184 | cbc.size = 2048; | 162 | cbc.size = 2048; |
185 | cbc.pos = 0; | 163 | cbc.pos = 0; |
186 | d = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY /* | MHD_USE_DEBUG */, | 164 | d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY /* | MHD_USE_DEBUG */ , |
187 | 1080, | 165 | 1080, |
188 | &apc_all, | 166 | &apc_all, |
189 | NULL, | 167 | NULL, |
190 | &ahc_echo, | 168 | &ahc_echo, |
191 | "GET", | 169 | "GET", |
192 | MHD_OPTION_CONNECTION_MEMORY_LIMIT, | 170 | MHD_OPTION_CONNECTION_MEMORY_LIMIT, |
193 | VERY_LONG / 2, | 171 | VERY_LONG / 2, MHD_OPTION_END); |
194 | MHD_OPTION_END); | ||
195 | if (d == NULL) | 172 | if (d == NULL) |
196 | return 16; | 173 | return 16; |
197 | c = curl_easy_init(); | 174 | c = curl_easy_init (); |
198 | url = malloc(VERY_LONG); | 175 | url = malloc (VERY_LONG); |
199 | memset(url, | 176 | memset (url, 'a', VERY_LONG); |
200 | 'a', | 177 | url[VERY_LONG - 1] = '\0'; |
201 | VERY_LONG); | 178 | url[VERY_LONG / 2] = ':'; |
202 | url[VERY_LONG-1] = '\0'; | 179 | url[VERY_LONG / 2 + 1] = ':'; |
203 | url[VERY_LONG/2] = ':'; | 180 | header = curl_slist_append (header, url); |
204 | url[VERY_LONG/2+1] = ':'; | 181 | |
205 | header = curl_slist_append(header, | 182 | curl_easy_setopt (c, CURLOPT_HTTPHEADER, header); |
206 | url); | 183 | curl_easy_setopt (c, CURLOPT_URL, "http://localhost:1080/hello_world"); |
207 | 184 | curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer); | |
208 | curl_easy_setopt(c, | 185 | curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc); |
209 | CURLOPT_HTTPHEADER, | 186 | curl_easy_setopt (c, CURLOPT_FAILONERROR, 1); |
210 | header); | 187 | curl_easy_setopt (c, CURLOPT_TIMEOUT, 2L); |
211 | curl_easy_setopt(c, | 188 | curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 2L); |
212 | CURLOPT_URL, | ||
213 | "http://localhost:1080/hello_world"); | ||
214 | curl_easy_setopt(c, | ||
215 | CURLOPT_WRITEFUNCTION, | ||
216 | ©Buffer); | ||
217 | curl_easy_setopt(c, | ||
218 | CURLOPT_WRITEDATA, | ||
219 | &cbc); | ||
220 | curl_easy_setopt(c, | ||
221 | CURLOPT_FAILONERROR, | ||
222 | 1); | ||
223 | curl_easy_setopt(c, | ||
224 | CURLOPT_TIMEOUT, | ||
225 | 2L); | ||
226 | curl_easy_setopt(c, | ||
227 | CURLOPT_CONNECTTIMEOUT, | ||
228 | 2L); | ||
229 | if (oneone) | 189 | if (oneone) |
230 | curl_easy_setopt(c, | 190 | curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); |
231 | CURLOPT_HTTP_VERSION, | ||
232 | CURL_HTTP_VERSION_1_1); | ||
233 | else | 191 | else |
234 | curl_easy_setopt(c, | 192 | curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); |
235 | CURLOPT_HTTP_VERSION, | 193 | // NOTE: use of CONNECTTIMEOUT without also |
236 | CURL_HTTP_VERSION_1_0); | ||
237 | // NOTE: use of CONNECTTIMEOUT without also | ||
238 | // setting NOSIGNAL results in really weird | 194 | // setting NOSIGNAL results in really weird |
239 | // crashes on my system! | 195 | // crashes on my system! |
240 | curl_easy_setopt(c, | 196 | curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1); |
241 | CURLOPT_NOSIGNAL, | 197 | if (CURLE_OK == curl_easy_perform (c)) |
242 | 1); | 198 | { |
243 | if (CURLE_OK == curl_easy_perform(c)) { | 199 | curl_easy_cleanup (c); |
244 | curl_easy_cleanup(c); | 200 | MHD_stop_daemon (d); |
245 | MHD_stop_daemon(d); | 201 | curl_slist_free_all (header); |
246 | curl_slist_free_all(header); | 202 | free (url); |
247 | free(url); | 203 | return 32; |
248 | return 32; | 204 | } |
249 | } | 205 | if (CURLE_OK != curl_easy_getinfo (c, CURLINFO_RESPONSE_CODE, &code)) |
250 | if (CURLE_OK != curl_easy_getinfo(c, | 206 | { |
251 | CURLINFO_RESPONSE_CODE, | 207 | curl_slist_free_all (header); |
252 | &code)) { | 208 | curl_easy_cleanup (c); |
253 | curl_slist_free_all(header); | 209 | MHD_stop_daemon (d); |
254 | curl_easy_cleanup(c); | 210 | free (url); |
255 | MHD_stop_daemon(d); | 211 | return 64; |
256 | free(url); | 212 | } |
257 | return 64; | 213 | curl_slist_free_all (header); |
258 | } | 214 | curl_easy_cleanup (c); |
259 | curl_slist_free_all(header); | 215 | MHD_stop_daemon (d); |
260 | curl_easy_cleanup(c); | 216 | free (url); |
261 | MHD_stop_daemon(d); | ||
262 | free(url); | ||
263 | if (code != MHD_HTTP_REQUEST_ENTITY_TOO_LARGE) | 217 | if (code != MHD_HTTP_REQUEST_ENTITY_TOO_LARGE) |
264 | return 128; | 218 | return 128; |
265 | return 0; | 219 | return 0; |
266 | } | 220 | } |
267 | 221 | ||
268 | 222 | int | |
269 | 223 | main (int argc, char *const *argv) | |
270 | 224 | { | |
271 | |||
272 | int main(int argc, | ||
273 | char * const * argv) { | ||
274 | unsigned int errorCount = 0; | 225 | unsigned int errorCount = 0; |
275 | 226 | ||
276 | oneone = NULL != strstr(argv[0], "11"); | 227 | oneone = NULL != strstr (argv[0], "11"); |
277 | if (0 != curl_global_init(CURL_GLOBAL_WIN32)) | 228 | if (0 != curl_global_init (CURL_GLOBAL_WIN32)) |
278 | return 2; | 229 | return 2; |
279 | errorCount += testLongUrlGet(); | 230 | errorCount += testLongUrlGet (); |
280 | errorCount += testLongHeaderGet(); | 231 | errorCount += testLongHeaderGet (); |
281 | if (errorCount != 0) | 232 | if (errorCount != 0) |
282 | fprintf(stderr, | 233 | fprintf (stderr, "Error (code: %u)\n", errorCount); |
283 | "Error (code: %u)\n", | 234 | curl_global_cleanup (); |
284 | errorCount); | 235 | return errorCount != 0; /* 0 == pass */ |
285 | curl_global_cleanup(); | ||
286 | return errorCount != 0; /* 0 == pass */ | ||
287 | } | 236 | } |
diff --git a/src/daemon/daemontest_post.c b/src/daemon/daemontest_post.c index 2c020563..61850a24 100644 --- a/src/daemon/daemontest_post.c +++ b/src/daemon/daemontest_post.c | |||
@@ -41,246 +41,187 @@ | |||
41 | 41 | ||
42 | static int oneone; | 42 | static int oneone; |
43 | 43 | ||
44 | struct CBC { | 44 | struct CBC |
45 | char * buf; | 45 | { |
46 | char *buf; | ||
46 | size_t pos; | 47 | size_t pos; |
47 | size_t size; | 48 | size_t size; |
48 | }; | 49 | }; |
49 | 50 | ||
50 | static size_t copyBuffer(void * ptr, | 51 | static size_t |
51 | size_t size, | 52 | copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx) |
52 | size_t nmemb, | 53 | { |
53 | void * ctx) { | 54 | struct CBC *cbc = ctx; |
54 | struct CBC * cbc = ctx; | ||
55 | 55 | ||
56 | if (cbc->pos + size * nmemb > cbc->size) | 56 | if (cbc->pos + size * nmemb > cbc->size) |
57 | return 0; /* overflow */ | 57 | return 0; /* overflow */ |
58 | memcpy(&cbc->buf[cbc->pos], | 58 | memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb); |
59 | ptr, | ||
60 | size * nmemb); | ||
61 | cbc->pos += size * nmemb; | 59 | cbc->pos += size * nmemb; |
62 | return size * nmemb; | 60 | return size * nmemb; |
63 | } | 61 | } |
64 | 62 | ||
65 | static int ahc_echo(void * cls, | 63 | static int |
66 | struct MHD_Connection * connection, | 64 | ahc_echo (void *cls, |
67 | const char * url, | 65 | struct MHD_Connection *connection, |
68 | const char * method, | 66 | const char *url, |
69 | const char * version, | 67 | const char *method, |
70 | const char * upload_data, | 68 | const char *version, |
71 | unsigned int * upload_data_size) { | 69 | const char *upload_data, unsigned int *upload_data_size) |
72 | struct MHD_Response * response; | 70 | { |
71 | struct MHD_Response *response; | ||
73 | int ret; | 72 | int ret; |
74 | const char * r1; | 73 | const char *r1; |
75 | const char * r2; | 74 | const char *r2; |
76 | 75 | ||
77 | if (0 != strcmp("POST", method)) { | 76 | if (0 != strcmp ("POST", method)) |
78 | printf("METHOD: %s\n", method); | 77 | { |
79 | return MHD_NO; /* unexpected method */ | 78 | printf ("METHOD: %s\n", method); |
80 | } | 79 | return MHD_NO; /* unexpected method */ |
81 | r1 = MHD_lookup_connection_value(connection, | 80 | } |
82 | MHD_POSTDATA_KIND, | 81 | r1 = MHD_lookup_connection_value (connection, MHD_POSTDATA_KIND, "name"); |
83 | "name"); | 82 | r2 = MHD_lookup_connection_value (connection, MHD_POSTDATA_KIND, "project"); |
84 | r2 = MHD_lookup_connection_value(connection, | 83 | if ((r1 != NULL) && |
85 | MHD_POSTDATA_KIND, | 84 | (r2 != NULL) && |
86 | "project"); | 85 | (0 == strcmp ("daniel", r1)) && (0 == strcmp ("curl", r2))) |
87 | if ( (r1 != NULL) && | 86 | { |
88 | (r2 != NULL) && | 87 | response = MHD_create_response_from_data (strlen (url), |
89 | (0 == strcmp("daniel", | 88 | (void *) url, |
90 | r1)) && | 89 | MHD_NO, MHD_YES); |
91 | (0 == strcmp("curl", | 90 | ret = MHD_queue_response (connection, MHD_HTTP_OK, response); |
92 | r2)) ) { | 91 | MHD_destroy_response (response); |
93 | response = MHD_create_response_from_data(strlen(url), | 92 | return MHD_YES; /* done */ |
94 | (void*) url, | 93 | } |
95 | MHD_NO, | ||
96 | MHD_YES); | ||
97 | ret = MHD_queue_response(connection, | ||
98 | MHD_HTTP_OK, | ||
99 | response); | ||
100 | MHD_destroy_response(response); | ||
101 | return MHD_YES; /* done */ | ||
102 | } | ||
103 | return MHD_YES; | 94 | return MHD_YES; |
104 | } | 95 | } |
105 | 96 | ||
106 | 97 | ||
107 | static int testInternalPost() { | 98 | static int |
108 | struct MHD_Daemon * d; | 99 | testInternalPost () |
109 | CURL * c; | 100 | { |
101 | struct MHD_Daemon *d; | ||
102 | CURL *c; | ||
110 | char buf[2048]; | 103 | char buf[2048]; |
111 | struct CBC cbc; | 104 | struct CBC cbc; |
112 | 105 | ||
113 | cbc.buf = buf; | 106 | cbc.buf = buf; |
114 | cbc.size = 2048; | 107 | cbc.size = 2048; |
115 | cbc.pos = 0; | 108 | cbc.pos = 0; |
116 | d = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG, | 109 | d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG, |
117 | 1080, | 110 | 1080, NULL, NULL, &ahc_echo, NULL, MHD_OPTION_END); |
118 | NULL, | ||
119 | NULL, | ||
120 | &ahc_echo, | ||
121 | NULL, | ||
122 | MHD_OPTION_END); | ||
123 | if (d == NULL) | 111 | if (d == NULL) |
124 | return 1; | 112 | return 1; |
125 | c = curl_easy_init(); | 113 | c = curl_easy_init (); |
126 | curl_easy_setopt(c, | 114 | curl_easy_setopt (c, CURLOPT_URL, "http://localhost:1080/hello_world"); |
127 | CURLOPT_URL, | 115 | curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer); |
128 | "http://localhost:1080/hello_world"); | 116 | curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc); |
129 | curl_easy_setopt(c, | 117 | curl_easy_setopt (c, CURLOPT_POSTFIELDS, POST_DATA); |
130 | CURLOPT_WRITEFUNCTION, | 118 | curl_easy_setopt (c, CURLOPT_POSTFIELDSIZE, strlen (POST_DATA)); |
131 | ©Buffer); | 119 | curl_easy_setopt (c, CURLOPT_POST, 1L); |
132 | curl_easy_setopt(c, | 120 | curl_easy_setopt (c, CURLOPT_FAILONERROR, 1); |
133 | CURLOPT_WRITEDATA, | 121 | curl_easy_setopt (c, CURLOPT_TIMEOUT, 2L); |
134 | &cbc); | ||
135 | curl_easy_setopt(c, | ||
136 | CURLOPT_POSTFIELDS, | ||
137 | POST_DATA); | ||
138 | curl_easy_setopt(c, | ||
139 | CURLOPT_POSTFIELDSIZE, | ||
140 | strlen(POST_DATA)); | ||
141 | curl_easy_setopt(c, | ||
142 | CURLOPT_POST, | ||
143 | 1L); | ||
144 | curl_easy_setopt(c, | ||
145 | CURLOPT_FAILONERROR, | ||
146 | 1); | ||
147 | curl_easy_setopt(c, | ||
148 | CURLOPT_TIMEOUT, | ||
149 | 2L); | ||
150 | if (oneone) | 122 | if (oneone) |
151 | curl_easy_setopt(c, | 123 | curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); |
152 | CURLOPT_HTTP_VERSION, | ||
153 | CURL_HTTP_VERSION_1_1); | ||
154 | else | 124 | else |
155 | curl_easy_setopt(c, | 125 | curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); |
156 | CURLOPT_HTTP_VERSION, | 126 | curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 2L); |
157 | CURL_HTTP_VERSION_1_0); | ||
158 | curl_easy_setopt(c, | ||
159 | CURLOPT_CONNECTTIMEOUT, | ||
160 | 2L); | ||
161 | // NOTE: use of CONNECTTIMEOUT without also | 127 | // NOTE: use of CONNECTTIMEOUT without also |
162 | // setting NOSIGNAL results in really weird | 128 | // setting NOSIGNAL results in really weird |
163 | // crashes on my system! | 129 | // crashes on my system! |
164 | curl_easy_setopt(c, | 130 | curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1); |
165 | CURLOPT_NOSIGNAL, | 131 | if (CURLE_OK != curl_easy_perform (c)) |
166 | 1); | 132 | { |
167 | if (CURLE_OK != curl_easy_perform(c)) { | 133 | curl_easy_cleanup (c); |
168 | curl_easy_cleanup(c); | 134 | MHD_stop_daemon (d); |
169 | MHD_stop_daemon(d); | 135 | return 2; |
170 | return 2; | 136 | } |
171 | } | 137 | curl_easy_cleanup (c); |
172 | curl_easy_cleanup(c); | 138 | if (cbc.pos != strlen ("/hello_world")) |
173 | if (cbc.pos != strlen("/hello_world")) { | 139 | { |
174 | MHD_stop_daemon(d); | 140 | MHD_stop_daemon (d); |
175 | return 4; | 141 | return 4; |
176 | } | 142 | } |
177 | 143 | ||
178 | if (0 != strncmp("/hello_world", | 144 | if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world"))) |
179 | cbc.buf, | 145 | { |
180 | strlen("/hello_world"))) { | 146 | MHD_stop_daemon (d); |
181 | MHD_stop_daemon(d); | 147 | return 8; |
182 | return 8; | 148 | } |
183 | } | 149 | MHD_stop_daemon (d); |
184 | MHD_stop_daemon(d); | ||
185 | 150 | ||
186 | return 0; | 151 | return 0; |
187 | } | 152 | } |
188 | 153 | ||
189 | static int testMultithreadedPost() { | 154 | static int |
190 | struct MHD_Daemon * d; | 155 | testMultithreadedPost () |
191 | CURL * c; | 156 | { |
157 | struct MHD_Daemon *d; | ||
158 | CURL *c; | ||
192 | char buf[2048]; | 159 | char buf[2048]; |
193 | struct CBC cbc; | 160 | struct CBC cbc; |
194 | 161 | ||
195 | cbc.buf = buf; | 162 | cbc.buf = buf; |
196 | cbc.size = 2048; | 163 | cbc.size = 2048; |
197 | cbc.pos = 0; | 164 | cbc.pos = 0; |
198 | d = MHD_start_daemon(MHD_USE_THREAD_PER_CONNECTION |MHD_USE_DEBUG, | 165 | d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG, |
199 | 1081, | 166 | 1081, NULL, NULL, &ahc_echo, NULL, MHD_OPTION_END); |
200 | NULL, | ||
201 | NULL, | ||
202 | &ahc_echo, | ||
203 | NULL, | ||
204 | MHD_OPTION_END); | ||
205 | if (d == NULL) | 167 | if (d == NULL) |
206 | return 16; | 168 | return 16; |
207 | c = curl_easy_init(); | 169 | c = curl_easy_init (); |
208 | curl_easy_setopt(c, | 170 | curl_easy_setopt (c, CURLOPT_URL, "http://localhost:1081/hello_world"); |
209 | CURLOPT_URL, | 171 | curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer); |
210 | "http://localhost:1081/hello_world"); | 172 | curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc); |
211 | curl_easy_setopt(c, | 173 | curl_easy_setopt (c, CURLOPT_POSTFIELDS, POST_DATA); |
212 | CURLOPT_WRITEFUNCTION, | 174 | curl_easy_setopt (c, CURLOPT_POSTFIELDSIZE, strlen (POST_DATA)); |
213 | ©Buffer); | 175 | curl_easy_setopt (c, CURLOPT_POST, 1L); |
214 | curl_easy_setopt(c, | 176 | curl_easy_setopt (c, CURLOPT_FAILONERROR, 1); |
215 | CURLOPT_WRITEDATA, | 177 | curl_easy_setopt (c, CURLOPT_TIMEOUT, 2L); |
216 | &cbc); | ||
217 | curl_easy_setopt(c, | ||
218 | CURLOPT_POSTFIELDS, | ||
219 | POST_DATA); | ||
220 | curl_easy_setopt(c, | ||
221 | CURLOPT_POSTFIELDSIZE, | ||
222 | strlen(POST_DATA)); | ||
223 | curl_easy_setopt(c, | ||
224 | CURLOPT_POST, | ||
225 | 1L); | ||
226 | curl_easy_setopt(c, | ||
227 | CURLOPT_FAILONERROR, | ||
228 | 1); | ||
229 | curl_easy_setopt(c, | ||
230 | CURLOPT_TIMEOUT, | ||
231 | 2L); | ||
232 | if (oneone) | 178 | if (oneone) |
233 | curl_easy_setopt(c, | 179 | curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); |
234 | CURLOPT_HTTP_VERSION, | ||
235 | CURL_HTTP_VERSION_1_1); | ||
236 | else | 180 | else |
237 | curl_easy_setopt(c, | 181 | curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); |
238 | CURLOPT_HTTP_VERSION, | 182 | curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 2L); |
239 | CURL_HTTP_VERSION_1_0); | ||
240 | curl_easy_setopt(c, | ||
241 | CURLOPT_CONNECTTIMEOUT, | ||
242 | 2L); | ||
243 | // NOTE: use of CONNECTTIMEOUT without also | 183 | // NOTE: use of CONNECTTIMEOUT without also |
244 | // setting NOSIGNAL results in really weird | 184 | // setting NOSIGNAL results in really weird |
245 | // crashes on my system! | 185 | // crashes on my system! |
246 | curl_easy_setopt(c, | 186 | curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1); |
247 | CURLOPT_NOSIGNAL, | 187 | if (CURLE_OK != curl_easy_perform (c)) |
248 | 1); | 188 | { |
249 | if (CURLE_OK != curl_easy_perform(c)) { | 189 | curl_easy_cleanup (c); |
250 | curl_easy_cleanup(c); | 190 | MHD_stop_daemon (d); |
251 | MHD_stop_daemon(d); | 191 | return 32; |
252 | return 32; | 192 | } |
253 | } | 193 | curl_easy_cleanup (c); |
254 | curl_easy_cleanup(c); | 194 | if (cbc.pos != strlen ("/hello_world")) |
255 | if (cbc.pos != strlen("/hello_world")) { | 195 | { |
256 | MHD_stop_daemon(d); | 196 | MHD_stop_daemon (d); |
257 | return 64; | 197 | return 64; |
258 | } | 198 | } |
259 | if (0 != strncmp("/hello_world", | 199 | if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world"))) |
260 | cbc.buf, | 200 | { |
261 | strlen("/hello_world"))) { | 201 | MHD_stop_daemon (d); |
262 | MHD_stop_daemon(d); | 202 | return 128; |
263 | return 128; | 203 | } |
264 | } | 204 | MHD_stop_daemon (d); |
265 | MHD_stop_daemon(d); | ||
266 | 205 | ||
267 | return 0; | 206 | return 0; |
268 | } | 207 | } |
269 | 208 | ||
270 | 209 | ||
271 | static int testExternalPost() { | 210 | static int |
272 | struct MHD_Daemon * d; | 211 | testExternalPost () |
273 | CURL * c; | 212 | { |
213 | struct MHD_Daemon *d; | ||
214 | CURL *c; | ||
274 | char buf[2048]; | 215 | char buf[2048]; |
275 | struct CBC cbc; | 216 | struct CBC cbc; |
276 | CURLM * multi; | 217 | CURLM *multi; |
277 | CURLMcode mret; | 218 | CURLMcode mret; |
278 | fd_set rs; | 219 | fd_set rs; |
279 | fd_set ws; | 220 | fd_set ws; |
280 | fd_set es; | 221 | fd_set es; |
281 | int max; | 222 | int max; |
282 | int running; | 223 | int running; |
283 | struct CURLMsg * msg; | 224 | struct CURLMsg *msg; |
284 | time_t start; | 225 | time_t start; |
285 | struct timeval tv; | 226 | struct timeval tv; |
286 | 227 | ||
@@ -288,163 +229,124 @@ static int testExternalPost() { | |||
288 | cbc.buf = buf; | 229 | cbc.buf = buf; |
289 | cbc.size = 2048; | 230 | cbc.size = 2048; |
290 | cbc.pos = 0; | 231 | cbc.pos = 0; |
291 | d = MHD_start_daemon(MHD_USE_DEBUG, | 232 | d = MHD_start_daemon (MHD_USE_DEBUG, |
292 | 1082, | 233 | 1082, NULL, NULL, &ahc_echo, NULL, MHD_OPTION_END); |
293 | NULL, | ||
294 | NULL, | ||
295 | &ahc_echo, | ||
296 | NULL, | ||
297 | MHD_OPTION_END); | ||
298 | if (d == NULL) | 234 | if (d == NULL) |
299 | return 256; | 235 | return 256; |
300 | c = curl_easy_init(); | 236 | c = curl_easy_init (); |
301 | curl_easy_setopt(c, | 237 | curl_easy_setopt (c, CURLOPT_URL, "http://localhost:1082/hello_world"); |
302 | CURLOPT_URL, | 238 | curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer); |
303 | "http://localhost:1082/hello_world"); | 239 | curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc); |
304 | curl_easy_setopt(c, | 240 | curl_easy_setopt (c, CURLOPT_POSTFIELDS, POST_DATA); |
305 | CURLOPT_WRITEFUNCTION, | 241 | curl_easy_setopt (c, CURLOPT_POSTFIELDSIZE, strlen (POST_DATA)); |
306 | ©Buffer); | 242 | curl_easy_setopt (c, CURLOPT_POST, 1L); |
307 | curl_easy_setopt(c, | 243 | curl_easy_setopt (c, CURLOPT_FAILONERROR, 1); |
308 | CURLOPT_WRITEDATA, | 244 | curl_easy_setopt (c, CURLOPT_TIMEOUT, 5L); |
309 | &cbc); | ||
310 | curl_easy_setopt(c, | ||
311 | CURLOPT_POSTFIELDS, | ||
312 | POST_DATA); | ||
313 | curl_easy_setopt(c, | ||
314 | CURLOPT_POSTFIELDSIZE, | ||
315 | strlen(POST_DATA)); | ||
316 | curl_easy_setopt(c, | ||
317 | CURLOPT_POST, | ||
318 | 1L); | ||
319 | curl_easy_setopt(c, | ||
320 | CURLOPT_FAILONERROR, | ||
321 | 1); | ||
322 | curl_easy_setopt(c, | ||
323 | CURLOPT_TIMEOUT, | ||
324 | 5L); | ||
325 | if (oneone) | 245 | if (oneone) |
326 | curl_easy_setopt(c, | 246 | curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); |
327 | CURLOPT_HTTP_VERSION, | ||
328 | CURL_HTTP_VERSION_1_1); | ||
329 | else | 247 | else |
330 | curl_easy_setopt(c, | 248 | curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); |
331 | CURLOPT_HTTP_VERSION, | 249 | curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 5L); |
332 | CURL_HTTP_VERSION_1_0); | ||
333 | curl_easy_setopt(c, | ||
334 | CURLOPT_CONNECTTIMEOUT, | ||
335 | 5L); | ||
336 | // NOTE: use of CONNECTTIMEOUT without also | 250 | // NOTE: use of CONNECTTIMEOUT without also |
337 | // setting NOSIGNAL results in really weird | 251 | // setting NOSIGNAL results in really weird |
338 | // crashes on my system! | 252 | // crashes on my system! |
339 | curl_easy_setopt(c, | 253 | curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1); |
340 | CURLOPT_NOSIGNAL, | ||
341 | 1); | ||
342 | 254 | ||
343 | 255 | ||
344 | multi = curl_multi_init(); | 256 | multi = curl_multi_init (); |
345 | if (multi == NULL) { | 257 | if (multi == NULL) |
346 | curl_easy_cleanup(c); | 258 | { |
347 | MHD_stop_daemon(d); | 259 | curl_easy_cleanup (c); |
348 | return 512; | 260 | MHD_stop_daemon (d); |
349 | } | 261 | return 512; |
350 | mret = curl_multi_add_handle(multi, c); | 262 | } |
351 | if (mret != CURLM_OK) { | 263 | mret = curl_multi_add_handle (multi, c); |
352 | curl_multi_cleanup(multi); | 264 | if (mret != CURLM_OK) |
353 | curl_easy_cleanup(c); | 265 | { |
354 | MHD_stop_daemon(d); | 266 | curl_multi_cleanup (multi); |
355 | return 1024; | 267 | curl_easy_cleanup (c); |
356 | } | 268 | MHD_stop_daemon (d); |
357 | start = time(NULL); | 269 | return 1024; |
358 | while ( (time(NULL) - start < 5) && | 270 | } |
359 | (multi != NULL) ) { | 271 | start = time (NULL); |
360 | max = 0; | 272 | while ((time (NULL) - start < 5) && (multi != NULL)) |
361 | FD_ZERO(&rs); | 273 | { |
362 | FD_ZERO(&ws); | 274 | max = 0; |
363 | FD_ZERO(&es); | 275 | FD_ZERO (&rs); |
364 | curl_multi_perform(multi, &running); | 276 | FD_ZERO (&ws); |
365 | mret = curl_multi_fdset(multi, | 277 | FD_ZERO (&es); |
366 | &rs, | 278 | curl_multi_perform (multi, &running); |
367 | &ws, | 279 | mret = curl_multi_fdset (multi, &rs, &ws, &es, &max); |
368 | &es, | 280 | if (mret != CURLM_OK) |
369 | &max); | 281 | { |
370 | if (mret != CURLM_OK) { | 282 | curl_multi_remove_handle (multi, c); |
371 | curl_multi_remove_handle(multi, c); | 283 | curl_multi_cleanup (multi); |
372 | curl_multi_cleanup(multi); | 284 | curl_easy_cleanup (c); |
373 | curl_easy_cleanup(c); | 285 | MHD_stop_daemon (d); |
374 | MHD_stop_daemon(d); | 286 | return 2048; |
375 | return 2048; | 287 | } |
288 | if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max)) | ||
289 | { | ||
290 | curl_multi_remove_handle (multi, c); | ||
291 | curl_multi_cleanup (multi); | ||
292 | curl_easy_cleanup (c); | ||
293 | MHD_stop_daemon (d); | ||
294 | return 4096; | ||
295 | } | ||
296 | tv.tv_sec = 0; | ||
297 | tv.tv_usec = 1000; | ||
298 | select (max + 1, &rs, &ws, &es, &tv); | ||
299 | curl_multi_perform (multi, &running); | ||
300 | if (running == 0) | ||
301 | { | ||
302 | msg = curl_multi_info_read (multi, &running); | ||
303 | if (msg == NULL) | ||
304 | break; | ||
305 | if (msg->msg == CURLMSG_DONE) | ||
306 | { | ||
307 | if (msg->data.result != CURLE_OK) | ||
308 | printf ("%s failed at %s:%d: `%s'\n", | ||
309 | "curl_multi_perform", | ||
310 | __FILE__, | ||
311 | __LINE__, curl_easy_strerror (msg->data.result)); | ||
312 | curl_multi_remove_handle (multi, c); | ||
313 | curl_multi_cleanup (multi); | ||
314 | curl_easy_cleanup (c); | ||
315 | c = NULL; | ||
316 | multi = NULL; | ||
317 | } | ||
318 | } | ||
319 | MHD_run (d); | ||
376 | } | 320 | } |
377 | if (MHD_YES != MHD_get_fdset(d, | 321 | if (multi != NULL) |
378 | &rs, | 322 | { |
379 | &ws, | 323 | curl_multi_remove_handle (multi, c); |
380 | &es, | 324 | curl_easy_cleanup (c); |
381 | &max)) { | 325 | curl_multi_cleanup (multi); |
382 | curl_multi_remove_handle(multi, c); | ||
383 | curl_multi_cleanup(multi); | ||
384 | curl_easy_cleanup(c); | ||
385 | MHD_stop_daemon(d); | ||
386 | return 4096; | ||
387 | } | 326 | } |
388 | tv.tv_sec = 0; | 327 | MHD_stop_daemon (d); |
389 | tv.tv_usec = 1000; | 328 | if (cbc.pos != strlen ("/hello_world")) |
390 | select(max + 1, | ||
391 | &rs, | ||
392 | &ws, | ||
393 | &es, | ||
394 | &tv); | ||
395 | curl_multi_perform(multi, &running); | ||
396 | if (running == 0) { | ||
397 | msg = curl_multi_info_read(multi, | ||
398 | &running); | ||
399 | if (msg == NULL) | ||
400 | break; | ||
401 | if (msg->msg == CURLMSG_DONE) { | ||
402 | if (msg->data.result != CURLE_OK) | ||
403 | printf("%s failed at %s:%d: `%s'\n", | ||
404 | "curl_multi_perform", | ||
405 | __FILE__, | ||
406 | __LINE__, | ||
407 | curl_easy_strerror(msg->data.result)); | ||
408 | curl_multi_remove_handle(multi, c); | ||
409 | curl_multi_cleanup(multi); | ||
410 | curl_easy_cleanup(c); | ||
411 | c = NULL; | ||
412 | multi = NULL; | ||
413 | } | ||
414 | } | ||
415 | MHD_run(d); | ||
416 | } | ||
417 | if (multi != NULL) { | ||
418 | curl_multi_remove_handle(multi, c); | ||
419 | curl_easy_cleanup(c); | ||
420 | curl_multi_cleanup(multi); | ||
421 | } | ||
422 | MHD_stop_daemon(d); | ||
423 | if (cbc.pos != strlen("/hello_world")) | ||
424 | return 8192; | 329 | return 8192; |
425 | if (0 != strncmp("/hello_world", | 330 | if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world"))) |
426 | cbc.buf, | ||
427 | strlen("/hello_world"))) | ||
428 | return 16384; | 331 | return 16384; |
429 | return 0; | 332 | return 0; |
430 | } | 333 | } |
431 | 334 | ||
432 | 335 | ||
433 | 336 | ||
434 | int main(int argc, | 337 | int |
435 | char * const * argv) { | 338 | main (int argc, char *const *argv) |
339 | { | ||
436 | unsigned int errorCount = 0; | 340 | unsigned int errorCount = 0; |
437 | 341 | ||
438 | oneone = NULL != strstr(argv[0], "11"); | 342 | oneone = NULL != strstr (argv[0], "11"); |
439 | if (0 != curl_global_init(CURL_GLOBAL_WIN32)) | 343 | if (0 != curl_global_init (CURL_GLOBAL_WIN32)) |
440 | return 2; | 344 | return 2; |
441 | errorCount += testInternalPost(); | 345 | errorCount += testInternalPost (); |
442 | errorCount += testMultithreadedPost(); | 346 | errorCount += testMultithreadedPost (); |
443 | errorCount += testExternalPost(); | 347 | errorCount += testExternalPost (); |
444 | if (errorCount != 0) | 348 | if (errorCount != 0) |
445 | fprintf(stderr, | 349 | fprintf (stderr, "Error (code: %u)\n", errorCount); |
446 | "Error (code: %u)\n", | 350 | curl_global_cleanup (); |
447 | errorCount); | 351 | return errorCount != 0; /* 0 == pass */ |
448 | curl_global_cleanup(); | ||
449 | return errorCount != 0; /* 0 == pass */ | ||
450 | } | 352 | } |
diff --git a/src/daemon/daemontest_put.c b/src/daemon/daemontest_put.c index e2f03bdf..342161c8 100644 --- a/src/daemon/daemontest_put.c +++ b/src/daemon/daemontest_put.c | |||
@@ -34,87 +34,82 @@ | |||
34 | 34 | ||
35 | static int oneone; | 35 | static int oneone; |
36 | 36 | ||
37 | struct CBC { | 37 | struct CBC |
38 | char * buf; | 38 | { |
39 | char *buf; | ||
39 | size_t pos; | 40 | size_t pos; |
40 | size_t size; | 41 | size_t size; |
41 | }; | 42 | }; |
42 | 43 | ||
43 | static size_t putBuffer(void * stream, | 44 | static size_t |
44 | size_t size, | 45 | putBuffer (void *stream, size_t size, size_t nmemb, void *ptr) |
45 | size_t nmemb, | 46 | { |
46 | void * ptr) { | 47 | unsigned int *pos = ptr; |
47 | unsigned int * pos = ptr; | ||
48 | unsigned int wrt; | 48 | unsigned int wrt; |
49 | 49 | ||
50 | wrt = size * nmemb; | 50 | wrt = size * nmemb; |
51 | if (wrt > 8 - (*pos)) | 51 | if (wrt > 8 - (*pos)) |
52 | wrt = 8 - (*pos); | 52 | wrt = 8 - (*pos); |
53 | memcpy(stream, | 53 | memcpy (stream, &("Hello123"[*pos]), wrt); |
54 | &("Hello123"[*pos]), | ||
55 | wrt); | ||
56 | (*pos) += wrt; | 54 | (*pos) += wrt; |
57 | return wrt; | 55 | return wrt; |
58 | } | 56 | } |
59 | 57 | ||
60 | static size_t copyBuffer(void * ptr, | 58 | static size_t |
61 | size_t size, | 59 | copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx) |
62 | size_t nmemb, | 60 | { |
63 | void * ctx) { | 61 | struct CBC *cbc = ctx; |
64 | struct CBC * cbc = ctx; | ||
65 | 62 | ||
66 | if (cbc->pos + size * nmemb > cbc->size) | 63 | if (cbc->pos + size * nmemb > cbc->size) |
67 | return 0; /* overflow */ | 64 | return 0; /* overflow */ |
68 | memcpy(&cbc->buf[cbc->pos], | 65 | memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb); |
69 | ptr, | ||
70 | size * nmemb); | ||
71 | cbc->pos += size * nmemb; | 66 | cbc->pos += size * nmemb; |
72 | return size * nmemb; | 67 | return size * nmemb; |
73 | } | 68 | } |
74 | 69 | ||
75 | static int ahc_echo(void * cls, | 70 | static int |
76 | struct MHD_Connection * connection, | 71 | ahc_echo (void *cls, |
77 | const char * url, | 72 | struct MHD_Connection *connection, |
78 | const char * method, | 73 | const char *url, |
79 | const char * version, | 74 | const char *method, |
80 | const char * upload_data, | 75 | const char *version, |
81 | unsigned int * upload_data_size) { | 76 | const char *upload_data, unsigned int *upload_data_size) |
82 | int * done = cls; | 77 | { |
83 | struct MHD_Response * response; | 78 | int *done = cls; |
79 | struct MHD_Response *response; | ||
84 | int ret; | 80 | int ret; |
85 | 81 | ||
86 | if (0 != strcmp("PUT", method)) | 82 | if (0 != strcmp ("PUT", method)) |
87 | return MHD_NO; /* unexpected method */ | 83 | return MHD_NO; /* unexpected method */ |
88 | if ((*done) == 0) { | 84 | if ((*done) == 0) |
89 | if (*upload_data_size != 8) | 85 | { |
90 | return MHD_YES; /* not yet ready */ | 86 | if (*upload_data_size != 8) |
91 | if (0 == memcmp(upload_data, | 87 | return MHD_YES; /* not yet ready */ |
92 | "Hello123", | 88 | if (0 == memcmp (upload_data, "Hello123", 8)) |
93 | 8)) { | 89 | { |
94 | *upload_data_size = 0; | 90 | *upload_data_size = 0; |
95 | } else { | 91 | } |
96 | printf("Invalid upload data `%8s'!\n", | 92 | else |
97 | upload_data); | 93 | { |
98 | return MHD_NO; | 94 | printf ("Invalid upload data `%8s'!\n", upload_data); |
95 | return MHD_NO; | ||
96 | } | ||
97 | *done = 1; | ||
98 | return MHD_YES; | ||
99 | } | 99 | } |
100 | *done = 1; | 100 | response = MHD_create_response_from_data (strlen (url), |
101 | return MHD_YES; | 101 | (void *) url, MHD_NO, MHD_YES); |
102 | } | 102 | ret = MHD_queue_response (connection, MHD_HTTP_OK, response); |
103 | response = MHD_create_response_from_data(strlen(url), | 103 | MHD_destroy_response (response); |
104 | (void*) url, | ||
105 | MHD_NO, | ||
106 | MHD_YES); | ||
107 | ret = MHD_queue_response(connection, | ||
108 | MHD_HTTP_OK, | ||
109 | response); | ||
110 | MHD_destroy_response(response); | ||
111 | return ret; | 104 | return ret; |
112 | } | 105 | } |
113 | 106 | ||
114 | 107 | ||
115 | static int testInternalPut() { | 108 | static int |
116 | struct MHD_Daemon * d; | 109 | testInternalPut () |
117 | CURL * c; | 110 | { |
111 | struct MHD_Daemon *d; | ||
112 | CURL *c; | ||
118 | char buf[2048]; | 113 | char buf[2048]; |
119 | struct CBC cbc; | 114 | struct CBC cbc; |
120 | unsigned int pos = 0; | 115 | unsigned int pos = 0; |
@@ -123,85 +118,58 @@ static int testInternalPut() { | |||
123 | cbc.buf = buf; | 118 | cbc.buf = buf; |
124 | cbc.size = 2048; | 119 | cbc.size = 2048; |
125 | cbc.pos = 0; | 120 | cbc.pos = 0; |
126 | d = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG, | 121 | d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG, |
127 | 1080, | 122 | 1080, |
128 | NULL, | 123 | NULL, NULL, &ahc_echo, &done_flag, MHD_OPTION_END); |
129 | NULL, | ||
130 | &ahc_echo, | ||
131 | &done_flag, | ||
132 | MHD_OPTION_END); | ||
133 | if (d == NULL) | 124 | if (d == NULL) |
134 | return 1; | 125 | return 1; |
135 | c = curl_easy_init(); | 126 | c = curl_easy_init (); |
136 | curl_easy_setopt(c, | 127 | curl_easy_setopt (c, CURLOPT_URL, "http://localhost:1080/hello_world"); |
137 | CURLOPT_URL, | 128 | curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer); |
138 | "http://localhost:1080/hello_world"); | 129 | curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc); |
139 | curl_easy_setopt(c, | 130 | curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer); |
140 | CURLOPT_WRITEFUNCTION, | 131 | curl_easy_setopt (c, CURLOPT_READDATA, &pos); |
141 | ©Buffer); | 132 | curl_easy_setopt (c, CURLOPT_UPLOAD, 1L); |
142 | curl_easy_setopt(c, | 133 | curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L); |
143 | CURLOPT_WRITEDATA, | 134 | curl_easy_setopt (c, CURLOPT_FAILONERROR, 1); |
144 | &cbc); | 135 | curl_easy_setopt (c, CURLOPT_TIMEOUT, 15L); |
145 | curl_easy_setopt(c, | ||
146 | CURLOPT_READFUNCTION, | ||
147 | &putBuffer); | ||
148 | curl_easy_setopt(c, | ||
149 | CURLOPT_READDATA, | ||
150 | &pos); | ||
151 | curl_easy_setopt(c, | ||
152 | CURLOPT_UPLOAD, | ||
153 | 1L); | ||
154 | curl_easy_setopt(c, | ||
155 | CURLOPT_INFILESIZE_LARGE, | ||
156 | (curl_off_t) 8L); | ||
157 | curl_easy_setopt(c, | ||
158 | CURLOPT_FAILONERROR, | ||
159 | 1); | ||
160 | curl_easy_setopt(c, | ||
161 | CURLOPT_TIMEOUT, | ||
162 | 15L); | ||
163 | if (oneone) | 136 | if (oneone) |
164 | curl_easy_setopt(c, | 137 | curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); |
165 | CURLOPT_HTTP_VERSION, | ||
166 | CURL_HTTP_VERSION_1_1); | ||
167 | else | 138 | else |
168 | curl_easy_setopt(c, | 139 | curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); |
169 | CURLOPT_HTTP_VERSION, | 140 | curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L); |
170 | CURL_HTTP_VERSION_1_0); | ||
171 | curl_easy_setopt(c, | ||
172 | CURLOPT_CONNECTTIMEOUT, | ||
173 | 15L); | ||
174 | // NOTE: use of CONNECTTIMEOUT without also | 141 | // NOTE: use of CONNECTTIMEOUT without also |
175 | // setting NOSIGNAL results in really weird | 142 | // setting NOSIGNAL results in really weird |
176 | // crashes on my system! | 143 | // crashes on my system! |
177 | curl_easy_setopt(c, | 144 | curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1); |
178 | CURLOPT_NOSIGNAL, | 145 | if (CURLE_OK != curl_easy_perform (c)) |
179 | 1); | 146 | { |
180 | if (CURLE_OK != curl_easy_perform(c)) { | 147 | curl_easy_cleanup (c); |
181 | curl_easy_cleanup(c); | 148 | MHD_stop_daemon (d); |
182 | MHD_stop_daemon(d); | 149 | return 2; |
183 | return 2; | 150 | } |
184 | } | 151 | curl_easy_cleanup (c); |
185 | curl_easy_cleanup(c); | 152 | if (cbc.pos != strlen ("/hello_world")) |
186 | if (cbc.pos != strlen("/hello_world")) { | 153 | { |
187 | MHD_stop_daemon(d); | 154 | MHD_stop_daemon (d); |
188 | return 4; | 155 | return 4; |
189 | } | 156 | } |
190 | 157 | ||
191 | if (0 != strncmp("/hello_world", | 158 | if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world"))) |
192 | cbc.buf, | 159 | { |
193 | strlen("/hello_world"))) { | 160 | MHD_stop_daemon (d); |
194 | MHD_stop_daemon(d); | 161 | return 8; |
195 | return 8; | 162 | } |
196 | } | 163 | MHD_stop_daemon (d); |
197 | MHD_stop_daemon(d); | ||
198 | 164 | ||
199 | return 0; | 165 | return 0; |
200 | } | 166 | } |
201 | 167 | ||
202 | static int testMultithreadedPut() { | 168 | static int |
203 | struct MHD_Daemon * d; | 169 | testMultithreadedPut () |
204 | CURL * c; | 170 | { |
171 | struct MHD_Daemon *d; | ||
172 | CURL *c; | ||
205 | char buf[2048]; | 173 | char buf[2048]; |
206 | struct CBC cbc; | 174 | struct CBC cbc; |
207 | unsigned int pos = 0; | 175 | unsigned int pos = 0; |
@@ -210,94 +178,68 @@ static int testMultithreadedPut() { | |||
210 | cbc.buf = buf; | 178 | cbc.buf = buf; |
211 | cbc.size = 2048; | 179 | cbc.size = 2048; |
212 | cbc.pos = 0; | 180 | cbc.pos = 0; |
213 | d = MHD_start_daemon(MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG, | 181 | d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG, |
214 | 1081, | 182 | 1081, |
215 | NULL, NULL, | 183 | NULL, NULL, &ahc_echo, &done_flag, MHD_OPTION_END); |
216 | &ahc_echo, | ||
217 | &done_flag, | ||
218 | MHD_OPTION_END); | ||
219 | if (d == NULL) | 184 | if (d == NULL) |
220 | return 16; | 185 | return 16; |
221 | c = curl_easy_init(); | 186 | c = curl_easy_init (); |
222 | curl_easy_setopt(c, | 187 | curl_easy_setopt (c, CURLOPT_URL, "http://localhost:1081/hello_world"); |
223 | CURLOPT_URL, | 188 | curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer); |
224 | "http://localhost:1081/hello_world"); | 189 | curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc); |
225 | curl_easy_setopt(c, | 190 | curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer); |
226 | CURLOPT_WRITEFUNCTION, | 191 | curl_easy_setopt (c, CURLOPT_READDATA, &pos); |
227 | ©Buffer); | 192 | curl_easy_setopt (c, CURLOPT_UPLOAD, 1L); |
228 | curl_easy_setopt(c, | 193 | curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L); |
229 | CURLOPT_WRITEDATA, | 194 | curl_easy_setopt (c, CURLOPT_FAILONERROR, 1); |
230 | &cbc); | 195 | curl_easy_setopt (c, CURLOPT_TIMEOUT, 15L); |
231 | curl_easy_setopt(c, | ||
232 | CURLOPT_READFUNCTION, | ||
233 | &putBuffer); | ||
234 | curl_easy_setopt(c, | ||
235 | CURLOPT_READDATA, | ||
236 | &pos); | ||
237 | curl_easy_setopt(c, | ||
238 | CURLOPT_UPLOAD, | ||
239 | 1L); | ||
240 | curl_easy_setopt(c, | ||
241 | CURLOPT_INFILESIZE_LARGE, | ||
242 | (curl_off_t) 8L); | ||
243 | curl_easy_setopt(c, | ||
244 | CURLOPT_FAILONERROR, | ||
245 | 1); | ||
246 | curl_easy_setopt(c, | ||
247 | CURLOPT_TIMEOUT, | ||
248 | 15L); | ||
249 | if (oneone) | 196 | if (oneone) |
250 | curl_easy_setopt(c, | 197 | curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); |
251 | CURLOPT_HTTP_VERSION, | ||
252 | CURL_HTTP_VERSION_1_1); | ||
253 | else | 198 | else |
254 | curl_easy_setopt(c, | 199 | curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); |
255 | CURLOPT_HTTP_VERSION, | 200 | curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L); |
256 | CURL_HTTP_VERSION_1_0); | ||
257 | curl_easy_setopt(c, | ||
258 | CURLOPT_CONNECTTIMEOUT, | ||
259 | 15L); | ||
260 | // NOTE: use of CONNECTTIMEOUT without also | 201 | // NOTE: use of CONNECTTIMEOUT without also |
261 | // setting NOSIGNAL results in really weird | 202 | // setting NOSIGNAL results in really weird |
262 | // crashes on my system! | 203 | // crashes on my system! |
263 | curl_easy_setopt(c, | 204 | curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1); |
264 | CURLOPT_NOSIGNAL, | 205 | if (CURLE_OK != curl_easy_perform (c)) |
265 | 1); | 206 | { |
266 | if (CURLE_OK != curl_easy_perform(c)) { | 207 | curl_easy_cleanup (c); |
267 | curl_easy_cleanup(c); | 208 | MHD_stop_daemon (d); |
268 | MHD_stop_daemon(d); | 209 | return 32; |
269 | return 32; | 210 | } |
270 | } | 211 | curl_easy_cleanup (c); |
271 | curl_easy_cleanup(c); | 212 | if (cbc.pos != strlen ("/hello_world")) |
272 | if (cbc.pos != strlen("/hello_world")) { | 213 | { |
273 | MHD_stop_daemon(d); | 214 | MHD_stop_daemon (d); |
274 | return 64; | 215 | return 64; |
275 | } | 216 | } |
276 | if (0 != strncmp("/hello_world", | 217 | if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world"))) |
277 | cbc.buf, | 218 | { |
278 | strlen("/hello_world"))) { | 219 | MHD_stop_daemon (d); |
279 | MHD_stop_daemon(d); | 220 | return 128; |
280 | return 128; | 221 | } |
281 | } | 222 | MHD_stop_daemon (d); |
282 | MHD_stop_daemon(d); | ||
283 | 223 | ||
284 | return 0; | 224 | return 0; |
285 | } | 225 | } |
286 | 226 | ||
287 | 227 | ||
288 | static int testExternalPut() { | 228 | static int |
289 | struct MHD_Daemon * d; | 229 | testExternalPut () |
290 | CURL * c; | 230 | { |
231 | struct MHD_Daemon *d; | ||
232 | CURL *c; | ||
291 | char buf[2048]; | 233 | char buf[2048]; |
292 | struct CBC cbc; | 234 | struct CBC cbc; |
293 | CURLM * multi; | 235 | CURLM *multi; |
294 | CURLMcode mret; | 236 | CURLMcode mret; |
295 | fd_set rs; | 237 | fd_set rs; |
296 | fd_set ws; | 238 | fd_set ws; |
297 | fd_set es; | 239 | fd_set es; |
298 | int max; | 240 | int max; |
299 | int running; | 241 | int running; |
300 | struct CURLMsg * msg; | 242 | struct CURLMsg *msg; |
301 | time_t start; | 243 | time_t start; |
302 | struct timeval tv; | 244 | struct timeval tv; |
303 | unsigned int pos = 0; | 245 | unsigned int pos = 0; |
@@ -307,166 +249,126 @@ static int testExternalPut() { | |||
307 | cbc.buf = buf; | 249 | cbc.buf = buf; |
308 | cbc.size = 2048; | 250 | cbc.size = 2048; |
309 | cbc.pos = 0; | 251 | cbc.pos = 0; |
310 | d = MHD_start_daemon(MHD_USE_DEBUG, | 252 | d = MHD_start_daemon (MHD_USE_DEBUG, |
311 | 1082, | 253 | 1082, |
312 | NULL, | 254 | NULL, NULL, &ahc_echo, &done_flag, MHD_OPTION_END); |
313 | NULL, | ||
314 | &ahc_echo, | ||
315 | &done_flag, | ||
316 | MHD_OPTION_END); | ||
317 | if (d == NULL) | 255 | if (d == NULL) |
318 | return 256; | 256 | return 256; |
319 | c = curl_easy_init(); | 257 | c = curl_easy_init (); |
320 | curl_easy_setopt(c, | 258 | curl_easy_setopt (c, CURLOPT_URL, "http://localhost:1082/hello_world"); |
321 | CURLOPT_URL, | 259 | curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer); |
322 | "http://localhost:1082/hello_world"); | 260 | curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc); |
323 | curl_easy_setopt(c, | 261 | curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer); |
324 | CURLOPT_WRITEFUNCTION, | 262 | curl_easy_setopt (c, CURLOPT_READDATA, &pos); |
325 | ©Buffer); | 263 | curl_easy_setopt (c, CURLOPT_UPLOAD, 1L); |
326 | curl_easy_setopt(c, | 264 | curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L); |
327 | CURLOPT_WRITEDATA, | 265 | curl_easy_setopt (c, CURLOPT_FAILONERROR, 1); |
328 | &cbc); | 266 | curl_easy_setopt (c, CURLOPT_TIMEOUT, 15L); |
329 | curl_easy_setopt(c, | ||
330 | CURLOPT_READFUNCTION, | ||
331 | &putBuffer); | ||
332 | curl_easy_setopt(c, | ||
333 | CURLOPT_READDATA, | ||
334 | &pos); | ||
335 | curl_easy_setopt(c, | ||
336 | CURLOPT_UPLOAD, | ||
337 | 1L); | ||
338 | curl_easy_setopt(c, | ||
339 | CURLOPT_INFILESIZE_LARGE, | ||
340 | (curl_off_t) 8L); | ||
341 | curl_easy_setopt(c, | ||
342 | CURLOPT_FAILONERROR, | ||
343 | 1); | ||
344 | curl_easy_setopt(c, | ||
345 | CURLOPT_TIMEOUT, | ||
346 | 15L); | ||
347 | if (oneone) | 267 | if (oneone) |
348 | curl_easy_setopt(c, | 268 | curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); |
349 | CURLOPT_HTTP_VERSION, | ||
350 | CURL_HTTP_VERSION_1_1); | ||
351 | else | 269 | else |
352 | curl_easy_setopt(c, | 270 | curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); |
353 | CURLOPT_HTTP_VERSION, | 271 | curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L); |
354 | CURL_HTTP_VERSION_1_0); | ||
355 | curl_easy_setopt(c, | ||
356 | CURLOPT_CONNECTTIMEOUT, | ||
357 | 15L); | ||
358 | // NOTE: use of CONNECTTIMEOUT without also | 272 | // NOTE: use of CONNECTTIMEOUT without also |
359 | // setting NOSIGNAL results in really weird | 273 | // setting NOSIGNAL results in really weird |
360 | // crashes on my system! | 274 | // crashes on my system! |
361 | curl_easy_setopt(c, | 275 | curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1); |
362 | CURLOPT_NOSIGNAL, | ||
363 | 1); | ||
364 | 276 | ||
365 | 277 | ||
366 | multi = curl_multi_init(); | 278 | multi = curl_multi_init (); |
367 | if (multi == NULL) { | 279 | if (multi == NULL) |
368 | curl_easy_cleanup(c); | 280 | { |
369 | MHD_stop_daemon(d); | 281 | curl_easy_cleanup (c); |
370 | return 512; | 282 | MHD_stop_daemon (d); |
371 | } | 283 | return 512; |
372 | mret = curl_multi_add_handle(multi, c); | 284 | } |
373 | if (mret != CURLM_OK) { | 285 | mret = curl_multi_add_handle (multi, c); |
374 | curl_multi_cleanup(multi); | 286 | if (mret != CURLM_OK) |
375 | curl_easy_cleanup(c); | 287 | { |
376 | MHD_stop_daemon(d); | 288 | curl_multi_cleanup (multi); |
377 | return 1024; | 289 | curl_easy_cleanup (c); |
378 | } | 290 | MHD_stop_daemon (d); |
379 | start = time(NULL); | 291 | return 1024; |
380 | while ( (time(NULL) - start < 5) && | 292 | } |
381 | (multi != NULL) ) { | 293 | start = time (NULL); |
382 | max = 0; | 294 | while ((time (NULL) - start < 5) && (multi != NULL)) |
383 | FD_ZERO(&rs); | 295 | { |
384 | FD_ZERO(&ws); | 296 | max = 0; |
385 | FD_ZERO(&es); | 297 | FD_ZERO (&rs); |
386 | curl_multi_perform(multi, &running); | 298 | FD_ZERO (&ws); |
387 | mret = curl_multi_fdset(multi, | 299 | FD_ZERO (&es); |
388 | &rs, | 300 | curl_multi_perform (multi, &running); |
389 | &ws, | 301 | mret = curl_multi_fdset (multi, &rs, &ws, &es, &max); |
390 | &es, | 302 | if (mret != CURLM_OK) |
391 | &max); | 303 | { |
392 | if (mret != CURLM_OK) { | 304 | curl_multi_remove_handle (multi, c); |
393 | curl_multi_remove_handle(multi, c); | 305 | curl_multi_cleanup (multi); |
394 | curl_multi_cleanup(multi); | 306 | curl_easy_cleanup (c); |
395 | curl_easy_cleanup(c); | 307 | MHD_stop_daemon (d); |
396 | MHD_stop_daemon(d); | 308 | return 2048; |
397 | return 2048; | 309 | } |
310 | if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max)) | ||
311 | { | ||
312 | curl_multi_remove_handle (multi, c); | ||
313 | curl_multi_cleanup (multi); | ||
314 | curl_easy_cleanup (c); | ||
315 | MHD_stop_daemon (d); | ||
316 | return 4096; | ||
317 | } | ||
318 | tv.tv_sec = 0; | ||
319 | tv.tv_usec = 1000; | ||
320 | select (max + 1, &rs, &ws, &es, &tv); | ||
321 | curl_multi_perform (multi, &running); | ||
322 | if (running == 0) | ||
323 | { | ||
324 | msg = curl_multi_info_read (multi, &running); | ||
325 | if (msg == NULL) | ||
326 | break; | ||
327 | if (msg->msg == CURLMSG_DONE) | ||
328 | { | ||
329 | if (msg->data.result != CURLE_OK) | ||
330 | printf ("%s failed at %s:%d: `%s'\n", | ||
331 | "curl_multi_perform", | ||
332 | __FILE__, | ||
333 | __LINE__, curl_easy_strerror (msg->data.result)); | ||
334 | curl_multi_remove_handle (multi, c); | ||
335 | curl_multi_cleanup (multi); | ||
336 | curl_easy_cleanup (c); | ||
337 | c = NULL; | ||
338 | multi = NULL; | ||
339 | } | ||
340 | } | ||
341 | MHD_run (d); | ||
398 | } | 342 | } |
399 | if (MHD_YES != MHD_get_fdset(d, | 343 | if (multi != NULL) |
400 | &rs, | 344 | { |
401 | &ws, | 345 | curl_multi_remove_handle (multi, c); |
402 | &es, | 346 | curl_easy_cleanup (c); |
403 | &max)) { | 347 | curl_multi_cleanup (multi); |
404 | curl_multi_remove_handle(multi, c); | ||
405 | curl_multi_cleanup(multi); | ||
406 | curl_easy_cleanup(c); | ||
407 | MHD_stop_daemon(d); | ||
408 | return 4096; | ||
409 | } | 348 | } |
410 | tv.tv_sec = 0; | 349 | MHD_stop_daemon (d); |
411 | tv.tv_usec = 1000; | 350 | if (cbc.pos != strlen ("/hello_world")) |
412 | select(max + 1, | ||
413 | &rs, | ||
414 | &ws, | ||
415 | &es, | ||
416 | &tv); | ||
417 | curl_multi_perform(multi, &running); | ||
418 | if (running == 0) { | ||
419 | msg = curl_multi_info_read(multi, | ||
420 | &running); | ||
421 | if (msg == NULL) | ||
422 | break; | ||
423 | if (msg->msg == CURLMSG_DONE) { | ||
424 | if (msg->data.result != CURLE_OK) | ||
425 | printf("%s failed at %s:%d: `%s'\n", | ||
426 | "curl_multi_perform", | ||
427 | __FILE__, | ||
428 | __LINE__, | ||
429 | curl_easy_strerror(msg->data.result)); | ||
430 | curl_multi_remove_handle(multi, c); | ||
431 | curl_multi_cleanup(multi); | ||
432 | curl_easy_cleanup(c); | ||
433 | c = NULL; | ||
434 | multi = NULL; | ||
435 | } | ||
436 | } | ||
437 | MHD_run(d); | ||
438 | } | ||
439 | if (multi != NULL) { | ||
440 | curl_multi_remove_handle(multi, c); | ||
441 | curl_easy_cleanup(c); | ||
442 | curl_multi_cleanup(multi); | ||
443 | } | ||
444 | MHD_stop_daemon(d); | ||
445 | if (cbc.pos != strlen("/hello_world")) | ||
446 | return 8192; | 351 | return 8192; |
447 | if (0 != strncmp("/hello_world", | 352 | if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world"))) |
448 | cbc.buf, | ||
449 | strlen("/hello_world"))) | ||
450 | return 16384; | 353 | return 16384; |
451 | return 0; | 354 | return 0; |
452 | } | 355 | } |
453 | 356 | ||
454 | 357 | ||
455 | 358 | ||
456 | int main(int argc, | 359 | int |
457 | char * const * argv) { | 360 | main (int argc, char *const *argv) |
361 | { | ||
458 | unsigned int errorCount = 0; | 362 | unsigned int errorCount = 0; |
459 | 363 | ||
460 | oneone = NULL != strstr(argv[0], "11"); | 364 | oneone = NULL != strstr (argv[0], "11"); |
461 | if (0 != curl_global_init(CURL_GLOBAL_WIN32)) | 365 | if (0 != curl_global_init (CURL_GLOBAL_WIN32)) |
462 | return 2; | 366 | return 2; |
463 | errorCount += testInternalPut(); | 367 | errorCount += testInternalPut (); |
464 | errorCount += testMultithreadedPut(); | 368 | errorCount += testMultithreadedPut (); |
465 | errorCount += testExternalPut(); | 369 | errorCount += testExternalPut (); |
466 | if (errorCount != 0) | 370 | if (errorCount != 0) |
467 | fprintf(stderr, | 371 | fprintf (stderr, "Error (code: %u)\n", errorCount); |
468 | "Error (code: %u)\n", | 372 | curl_global_cleanup (); |
469 | errorCount); | 373 | return errorCount != 0; /* 0 == pass */ |
470 | curl_global_cleanup(); | ||
471 | return errorCount != 0; /* 0 == pass */ | ||
472 | } | 374 | } |
diff --git a/src/daemon/fileserver_example.c b/src/daemon/fileserver_example.c index 989ab7d5..6f39f491 100644 --- a/src/daemon/fileserver_example.c +++ b/src/daemon/fileserver_example.c | |||
@@ -37,78 +37,69 @@ | |||
37 | 37 | ||
38 | #define PAGE "<html><head><title>File not found</title></head><body>File not found</body></html>" | 38 | #define PAGE "<html><head><title>File not found</title></head><body>File not found</body></html>" |
39 | 39 | ||
40 | static int file_reader(void * cls, | 40 | static int |
41 | size_t pos, | 41 | file_reader (void *cls, size_t pos, char *buf, int max) |
42 | char * buf, | 42 | { |
43 | int max) { | 43 | FILE *file = cls; |
44 | FILE * file = cls; | ||
45 | 44 | ||
46 | fseek(file, pos, SEEK_SET); | 45 | fseek (file, pos, SEEK_SET); |
47 | return fread(buf, | 46 | return fread (buf, 1, max, file); |
48 | 1, | ||
49 | max, | ||
50 | file); | ||
51 | } | 47 | } |
52 | 48 | ||
53 | static int ahc_echo(void * cls, | 49 | static int |
54 | struct MHD_Connection * connection, | 50 | ahc_echo (void *cls, |
55 | const char * url, | 51 | struct MHD_Connection *connection, |
56 | const char * method, | 52 | const char *url, |
57 | const char * upload_data, | 53 | const char *method, |
58 | const char * version, | 54 | const char *upload_data, |
59 | unsigned int * upload_data_size) { | 55 | const char *version, unsigned int *upload_data_size) |
60 | struct MHD_Response * response; | 56 | { |
57 | struct MHD_Response *response; | ||
61 | int ret; | 58 | int ret; |
62 | FILE * file; | 59 | FILE *file; |
63 | struct stat buf; | 60 | struct stat buf; |
64 | 61 | ||
65 | if (0 != strcmp(method, "GET")) | 62 | if (0 != strcmp (method, "GET")) |
66 | return MHD_NO; /* unexpected method */ | 63 | return MHD_NO; /* unexpected method */ |
67 | file = fopen(&url[1], "r"); | 64 | file = fopen (&url[1], "r"); |
68 | if (file == NULL) { | 65 | if (file == NULL) |
69 | response = MHD_create_response_from_data(strlen(PAGE), | 66 | { |
70 | (void*) PAGE, | 67 | response = MHD_create_response_from_data (strlen (PAGE), |
71 | MHD_NO, | 68 | (void *) PAGE, |
72 | MHD_NO); | 69 | MHD_NO, MHD_NO); |
73 | ret = MHD_queue_response(connection, | 70 | ret = MHD_queue_response (connection, MHD_HTTP_NOT_FOUND, response); |
74 | MHD_HTTP_NOT_FOUND, | 71 | MHD_destroy_response (response); |
75 | response); | 72 | } |
76 | MHD_destroy_response(response); | 73 | else |
77 | } else { | 74 | { |
78 | stat(&url[1], | 75 | stat (&url[1], &buf); |
79 | &buf); | 76 | response = MHD_create_response_from_callback (buf.st_size, |
80 | response = MHD_create_response_from_callback(buf.st_size, | 77 | &file_reader, |
81 | &file_reader, | 78 | file, |
82 | file, | 79 | (MHD_ContentReaderFreeCallback) |
83 | (MHD_ContentReaderFreeCallback) &fclose); | 80 | & fclose); |
84 | ret = MHD_queue_response(connection, | 81 | ret = MHD_queue_response (connection, MHD_HTTP_OK, response); |
85 | MHD_HTTP_OK, | 82 | MHD_destroy_response (response); |
86 | response); | 83 | } |
87 | MHD_destroy_response(response); | ||
88 | } | ||
89 | return ret; | 84 | return ret; |
90 | } | 85 | } |
91 | 86 | ||
92 | int main(int argc, | 87 | int |
93 | char * const * argv) { | 88 | main (int argc, char *const *argv) |
94 | struct MHD_Daemon * d; | 89 | { |
90 | struct MHD_Daemon *d; | ||
95 | 91 | ||
96 | if (argc != 3) { | 92 | if (argc != 3) |
97 | printf("%s PORT SECONDS-TO-RUN\n", | 93 | { |
98 | argv[0]); | 94 | printf ("%s PORT SECONDS-TO-RUN\n", argv[0]); |
99 | return 1; | 95 | return 1; |
100 | } | 96 | } |
101 | d = MHD_start_daemon(MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG, | 97 | d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG, |
102 | atoi(argv[1]), | 98 | atoi (argv[1]), |
103 | NULL, | 99 | NULL, NULL, &ahc_echo, PAGE, MHD_OPTION_END); |
104 | NULL, | ||
105 | &ahc_echo, | ||
106 | PAGE, | ||
107 | MHD_OPTION_END); | ||
108 | if (d == NULL) | 100 | if (d == NULL) |
109 | return 1; | 101 | return 1; |
110 | sleep(atoi(argv[2])); | 102 | sleep (atoi (argv[2])); |
111 | MHD_stop_daemon(d); | 103 | MHD_stop_daemon (d); |
112 | return 0; | 104 | return 0; |
113 | } | 105 | } |
114 | |||
diff --git a/src/daemon/internal.c b/src/daemon/internal.c index ef67affc..6f674470 100644 --- a/src/daemon/internal.c +++ b/src/daemon/internal.c | |||
@@ -32,15 +32,14 @@ | |||
32 | * fprintf-like helper function for logging debug | 32 | * fprintf-like helper function for logging debug |
33 | * messages. | 33 | * messages. |
34 | */ | 34 | */ |
35 | void MHD_DLOG(const struct MHD_Daemon * daemon, | 35 | void |
36 | const char * format, | 36 | MHD_DLOG (const struct MHD_Daemon *daemon, const char *format, ...) |
37 | ...) { | 37 | { |
38 | va_list va; | 38 | va_list va; |
39 | 39 | ||
40 | if ( (daemon->options & MHD_USE_DEBUG) == 0) | 40 | if ((daemon->options & MHD_USE_DEBUG) == 0) |
41 | return; | 41 | return; |
42 | va_start(va, format); | 42 | va_start (va, format); |
43 | VFPRINTF(stderr, format, va); | 43 | VFPRINTF (stderr, format, va); |
44 | va_end(va); | 44 | va_end (va); |
45 | } | 45 | } |
46 | |||
diff --git a/src/daemon/internal.h b/src/daemon/internal.h index 8aa08243..8bc33c29 100644 --- a/src/daemon/internal.h +++ b/src/daemon/internal.h | |||
@@ -62,59 +62,60 @@ | |||
62 | * fprintf-like helper function for logging debug | 62 | * fprintf-like helper function for logging debug |
63 | * messages. | 63 | * messages. |
64 | */ | 64 | */ |
65 | void MHD_DLOG(const struct MHD_Daemon * daemon, | 65 | void MHD_DLOG (const struct MHD_Daemon *daemon, const char *format, ...); |
66 | const char * format, | ||
67 | ...); | ||
68 | 66 | ||
69 | 67 | ||
70 | /** | 68 | /** |
71 | * Header or cookie in HTTP request or response. | 69 | * Header or cookie in HTTP request or response. |
72 | */ | 70 | */ |
73 | struct MHD_HTTP_Header { | 71 | struct MHD_HTTP_Header |
74 | struct MHD_HTTP_Header * next; | 72 | { |
73 | struct MHD_HTTP_Header *next; | ||
75 | 74 | ||
76 | char * header; | 75 | char *header; |
77 | 76 | ||
78 | char * value; | 77 | char *value; |
79 | 78 | ||
80 | enum MHD_ValueKind kind; | 79 | enum MHD_ValueKind kind; |
81 | }; | 80 | }; |
82 | 81 | ||
83 | 82 | ||
84 | struct MHD_Access_Handler { | 83 | struct MHD_Access_Handler |
85 | struct MHD_Access_Handler * next; | 84 | { |
85 | struct MHD_Access_Handler *next; | ||
86 | 86 | ||
87 | char * uri_prefix; | 87 | char *uri_prefix; |
88 | 88 | ||
89 | MHD_AccessHandlerCallback dh; | 89 | MHD_AccessHandlerCallback dh; |
90 | 90 | ||
91 | void * dh_cls; | 91 | void *dh_cls; |
92 | }; | 92 | }; |
93 | 93 | ||
94 | 94 | ||
95 | /** | 95 | /** |
96 | * Representation of a response. | 96 | * Representation of a response. |
97 | */ | 97 | */ |
98 | struct MHD_Response { | 98 | struct MHD_Response |
99 | { | ||
99 | 100 | ||
100 | /** | 101 | /** |
101 | * Headers to send for the response. Initially | 102 | * Headers to send for the response. Initially |
102 | * the linked list is created in inverse order; | 103 | * the linked list is created in inverse order; |
103 | * the order should be inverted before sending! | 104 | * the order should be inverted before sending! |
104 | */ | 105 | */ |
105 | struct MHD_HTTP_Header * first_header; | 106 | struct MHD_HTTP_Header *first_header; |
106 | 107 | ||
107 | /** | 108 | /** |
108 | * Buffer pointing to data that we are supposed | 109 | * Buffer pointing to data that we are supposed |
109 | * to send as a response. | 110 | * to send as a response. |
110 | */ | 111 | */ |
111 | char * data; | 112 | char *data; |
112 | 113 | ||
113 | /** | 114 | /** |
114 | * Closure to give to the content reader | 115 | * Closure to give to the content reader |
115 | * free callback. | 116 | * free callback. |
116 | */ | 117 | */ |
117 | void * crc_cls; | 118 | void *crc_cls; |
118 | 119 | ||
119 | /** | 120 | /** |
120 | * How do we get more data? NULL if we are | 121 | * How do we get more data? NULL if we are |
@@ -165,27 +166,28 @@ struct MHD_Response { | |||
165 | 166 | ||
166 | 167 | ||
167 | 168 | ||
168 | struct MHD_Connection { | 169 | struct MHD_Connection |
170 | { | ||
169 | 171 | ||
170 | /** | 172 | /** |
171 | * This is a linked list. | 173 | * This is a linked list. |
172 | */ | 174 | */ |
173 | struct MHD_Connection * next; | 175 | struct MHD_Connection *next; |
174 | 176 | ||
175 | /** | 177 | /** |
176 | * Reference to the MHD_Daemon struct. | 178 | * Reference to the MHD_Daemon struct. |
177 | */ | 179 | */ |
178 | struct MHD_Daemon * daemon; | 180 | struct MHD_Daemon *daemon; |
179 | 181 | ||
180 | /** | 182 | /** |
181 | * Linked list of parsed headers. | 183 | * Linked list of parsed headers. |
182 | */ | 184 | */ |
183 | struct MHD_HTTP_Header * headers_received; | 185 | struct MHD_HTTP_Header *headers_received; |
184 | 186 | ||
185 | /** | 187 | /** |
186 | * Response to transmit (initially NULL). | 188 | * Response to transmit (initially NULL). |
187 | */ | 189 | */ |
188 | struct MHD_Response * response; | 190 | struct MHD_Response *response; |
189 | 191 | ||
190 | /** | 192 | /** |
191 | * The memory pool is created whenever we first read | 193 | * The memory pool is created whenever we first read |
@@ -197,43 +199,43 @@ struct MHD_Connection { | |||
197 | * connections) and the IP address (which persists | 199 | * connections) and the IP address (which persists |
198 | * across individual requests). | 200 | * across individual requests). |
199 | */ | 201 | */ |
200 | struct MemoryPool * pool; | 202 | struct MemoryPool *pool; |
201 | 203 | ||
202 | /** | 204 | /** |
203 | * Request method. Should be GET/POST/etc. Allocated | 205 | * Request method. Should be GET/POST/etc. Allocated |
204 | * in pool. | 206 | * in pool. |
205 | */ | 207 | */ |
206 | char * method; | 208 | char *method; |
207 | 209 | ||
208 | /** | 210 | /** |
209 | * Requested URL (everything after "GET" only). Allocated | 211 | * Requested URL (everything after "GET" only). Allocated |
210 | * in pool. | 212 | * in pool. |
211 | */ | 213 | */ |
212 | char * url; | 214 | char *url; |
213 | 215 | ||
214 | /** | 216 | /** |
215 | * HTTP version string (i.e. http/1.1). Allocated | 217 | * HTTP version string (i.e. http/1.1). Allocated |
216 | * in pool. | 218 | * in pool. |
217 | */ | 219 | */ |
218 | char * version; | 220 | char *version; |
219 | 221 | ||
220 | /** | 222 | /** |
221 | * Buffer for reading requests. Allocated | 223 | * Buffer for reading requests. Allocated |
222 | * in pool. | 224 | * in pool. |
223 | */ | 225 | */ |
224 | char * read_buffer; | 226 | char *read_buffer; |
225 | 227 | ||
226 | /** | 228 | /** |
227 | * Buffer for writing response (headers only). Allocated | 229 | * Buffer for writing response (headers only). Allocated |
228 | * in pool. | 230 | * in pool. |
229 | */ | 231 | */ |
230 | char * write_buffer; | 232 | char *write_buffer; |
231 | 233 | ||
232 | /** | 234 | /** |
233 | * Foreign address (of length addr_len). MALLOCED (not | 235 | * Foreign address (of length addr_len). MALLOCED (not |
234 | * in pool!). | 236 | * in pool!). |
235 | */ | 237 | */ |
236 | struct sockaddr_in * addr; | 238 | struct sockaddr_in *addr; |
237 | 239 | ||
238 | /** | 240 | /** |
239 | * Thread for this connection (if we are using | 241 | * Thread for this connection (if we are using |
@@ -342,20 +344,21 @@ struct MHD_Connection { | |||
342 | 344 | ||
343 | 345 | ||
344 | 346 | ||
345 | struct MHD_Daemon { | 347 | struct MHD_Daemon |
348 | { | ||
346 | 349 | ||
347 | struct MHD_Access_Handler * handlers; | 350 | struct MHD_Access_Handler *handlers; |
348 | 351 | ||
349 | struct MHD_Access_Handler default_handler; | 352 | struct MHD_Access_Handler default_handler; |
350 | 353 | ||
351 | /** | 354 | /** |
352 | * Linked list of our current connections. | 355 | * Linked list of our current connections. |
353 | */ | 356 | */ |
354 | struct MHD_Connection * connections; | 357 | struct MHD_Connection *connections; |
355 | 358 | ||
356 | MHD_AcceptPolicyCallback apc; | 359 | MHD_AcceptPolicyCallback apc; |
357 | 360 | ||
358 | void * apc_cls; | 361 | void *apc_cls; |
359 | 362 | ||
360 | /** | 363 | /** |
361 | * PID of the select thread (if we have internal select) | 364 | * PID of the select thread (if we have internal select) |
@@ -390,7 +393,7 @@ struct MHD_Daemon { | |||
390 | /** | 393 | /** |
391 | * Listen port. | 394 | * Listen port. |
392 | */ | 395 | */ |
393 | unsigned short port; | 396 | unsigned short port; |
394 | 397 | ||
395 | }; | 398 | }; |
396 | 399 | ||
diff --git a/src/daemon/memorypool.c b/src/daemon/memorypool.c index d8e835e8..37cc50c1 100644 --- a/src/daemon/memorypool.c +++ b/src/daemon/memorypool.c | |||
@@ -26,12 +26,13 @@ | |||
26 | 26 | ||
27 | #include "memorypool.h" | 27 | #include "memorypool.h" |
28 | 28 | ||
29 | struct MemoryPool { | 29 | struct MemoryPool |
30 | { | ||
30 | 31 | ||
31 | /** | 32 | /** |
32 | * Pointer to the pool's memory | 33 | * Pointer to the pool's memory |
33 | */ | 34 | */ |
34 | char * memory; | 35 | char *memory; |
35 | 36 | ||
36 | /** | 37 | /** |
37 | * Size of the pool. | 38 | * Size of the pool. |
@@ -59,25 +60,30 @@ struct MemoryPool { | |||
59 | * | 60 | * |
60 | * @param max maximum size of the pool | 61 | * @param max maximum size of the pool |
61 | */ | 62 | */ |
62 | struct MemoryPool * MHD_pool_create(unsigned int max) { | 63 | struct MemoryPool * |
63 | struct MemoryPool * pool; | 64 | MHD_pool_create (unsigned int max) |
65 | { | ||
66 | struct MemoryPool *pool; | ||
64 | 67 | ||
65 | pool = malloc(sizeof(struct MemoryPool)); | 68 | pool = malloc (sizeof (struct MemoryPool)); |
66 | if (pool == NULL) | 69 | if (pool == NULL) |
67 | return NULL; | 70 | return NULL; |
68 | pool->memory = MMAP(NULL, max, PROT_READ | PROT_WRITE, | 71 | pool->memory = MMAP (NULL, max, PROT_READ | PROT_WRITE, |
69 | MAP_ANONYMOUS, -1, 0); | 72 | MAP_ANONYMOUS, -1, 0); |
70 | if ( (pool->memory == MAP_FAILED) || | 73 | if ((pool->memory == MAP_FAILED) || (pool->memory == NULL)) |
71 | (pool->memory == NULL) ) { | 74 | { |
72 | pool->memory = malloc(max); | 75 | pool->memory = malloc (max); |
73 | if (pool->memory == NULL) { | 76 | if (pool->memory == NULL) |
74 | free(pool); | 77 | { |
75 | return NULL; | 78 | free (pool); |
79 | return NULL; | ||
80 | } | ||
81 | pool->is_mmap = 0; | ||
82 | } | ||
83 | else | ||
84 | { | ||
85 | pool->is_mmap = 1; | ||
76 | } | 86 | } |
77 | pool->is_mmap = 0; | ||
78 | } else { | ||
79 | pool->is_mmap = 1; | ||
80 | } | ||
81 | pool->pos = 0; | 87 | pool->pos = 0; |
82 | pool->end = max; | 88 | pool->end = max; |
83 | pool->size = max; | 89 | pool->size = max; |
@@ -87,14 +93,16 @@ struct MemoryPool * MHD_pool_create(unsigned int max) { | |||
87 | /** | 93 | /** |
88 | * Destroy a memory pool. | 94 | * Destroy a memory pool. |
89 | */ | 95 | */ |
90 | void MHD_pool_destroy(struct MemoryPool * pool) { | 96 | void |
97 | MHD_pool_destroy (struct MemoryPool *pool) | ||
98 | { | ||
91 | if (pool == NULL) | 99 | if (pool == NULL) |
92 | return; | 100 | return; |
93 | if (pool->is_mmap == 0) | 101 | if (pool->is_mmap == 0) |
94 | free(pool->memory); | 102 | free (pool->memory); |
95 | else | 103 | else |
96 | MUNMAP(pool->memory, pool->size); | 104 | MUNMAP (pool->memory, pool->size); |
97 | free(pool); | 105 | free (pool); |
98 | } | 106 | } |
99 | 107 | ||
100 | /** | 108 | /** |
@@ -102,21 +110,23 @@ void MHD_pool_destroy(struct MemoryPool * pool) { | |||
102 | * @return NULL if the pool cannot support size more | 110 | * @return NULL if the pool cannot support size more |
103 | * bytes | 111 | * bytes |
104 | */ | 112 | */ |
105 | void * MHD_pool_allocate(struct MemoryPool * pool, | 113 | void * |
106 | unsigned int size, | 114 | MHD_pool_allocate (struct MemoryPool *pool, unsigned int size, int from_end) |
107 | int from_end) { | 115 | { |
108 | void * ret; | 116 | void *ret; |
109 | 117 | ||
110 | if ( (pool->pos + size > pool->end) || | 118 | if ((pool->pos + size > pool->end) || (pool->pos + size < pool->pos)) |
111 | (pool->pos + size < pool->pos) ) | ||
112 | return NULL; | 119 | return NULL; |
113 | if (from_end == MHD_YES) { | 120 | if (from_end == MHD_YES) |
114 | ret = &pool->memory[pool->end - size]; | 121 | { |
115 | pool->end -= size; | 122 | ret = &pool->memory[pool->end - size]; |
116 | } else { | 123 | pool->end -= size; |
117 | ret = &pool->memory[pool->pos]; | 124 | } |
118 | pool->pos += size; | 125 | else |
119 | } | 126 | { |
127 | ret = &pool->memory[pool->pos]; | ||
128 | pool->pos += size; | ||
129 | } | ||
120 | return ret; | 130 | return ret; |
121 | } | 131 | } |
122 | 132 | ||
@@ -136,43 +146,40 @@ void * MHD_pool_allocate(struct MemoryPool * pool, | |||
136 | * NULL if the pool cannot support new_size | 146 | * NULL if the pool cannot support new_size |
137 | * bytes (old continues to be valid for old_size) | 147 | * bytes (old continues to be valid for old_size) |
138 | */ | 148 | */ |
139 | void * MHD_pool_reallocate(struct MemoryPool * pool, | 149 | void * |
140 | void * old, | 150 | MHD_pool_reallocate (struct MemoryPool *pool, |
141 | unsigned int old_size, | 151 | void *old, unsigned int old_size, unsigned int new_size) |
142 | unsigned int new_size) { | 152 | { |
143 | void * ret; | 153 | void *ret; |
144 | 154 | ||
145 | if ( (pool->end < old_size) || | 155 | if ((pool->end < old_size) || (pool->end < new_size)) |
146 | (pool->end < new_size) ) | 156 | return NULL; /* unsatisfiable or bogus request */ |
147 | return NULL; /* unsatisfiable or bogus request */ | 157 | |
148 | 158 | if ((pool->pos >= old_size) && (&pool->memory[pool->pos - old_size] == old)) | |
149 | if ( (pool->pos >= old_size) && | 159 | { |
150 | (&pool->memory[pool->pos - old_size] == old) ) { | 160 | /* was the previous allocation - optimize! */ |
151 | /* was the previous allocation - optimize! */ | 161 | if (pool->pos + new_size - old_size <= pool->end) |
152 | if (pool->pos + new_size - old_size <= pool->end) { | 162 | { |
153 | /* fits */ | 163 | /* fits */ |
154 | pool->pos += new_size - old_size; | 164 | pool->pos += new_size - old_size; |
155 | if (new_size < old_size) /* shrinking - zero again! */ | 165 | if (new_size < old_size) /* shrinking - zero again! */ |
156 | memset(&pool->memory[pool->pos], | 166 | memset (&pool->memory[pool->pos], 0, old_size - new_size); |
157 | 0, | 167 | return old; |
158 | old_size - new_size); | 168 | } |
159 | return old; | 169 | /* does not fit */ |
170 | return NULL; | ||
160 | } | 171 | } |
161 | /* does not fit */ | ||
162 | return NULL; | ||
163 | } | ||
164 | if (new_size <= old_size) | 172 | if (new_size <= old_size) |
165 | return old; /* cannot shrink, no need to move */ | 173 | return old; /* cannot shrink, no need to move */ |
166 | if ( (pool->pos + new_size >= pool->pos) && | 174 | if ((pool->pos + new_size >= pool->pos) && |
167 | (pool->pos + new_size <= pool->end) ) { | 175 | (pool->pos + new_size <= pool->end)) |
168 | /* fits */ | 176 | { |
169 | ret = &pool->memory[pool->pos]; | 177 | /* fits */ |
170 | memcpy(ret, | 178 | ret = &pool->memory[pool->pos]; |
171 | old, | 179 | memcpy (ret, old, old_size); |
172 | old_size); | 180 | pool->pos += new_size; |
173 | pool->pos += new_size; | 181 | return ret; |
174 | return ret; | 182 | } |
175 | } | ||
176 | /* does not fit */ | 183 | /* does not fit */ |
177 | return NULL; | 184 | return NULL; |
178 | } | 185 | } |
diff --git a/src/daemon/memorypool.h b/src/daemon/memorypool.h index 693b03f6..92e09a51 100644 --- a/src/daemon/memorypool.h +++ b/src/daemon/memorypool.h | |||
@@ -43,12 +43,12 @@ struct MemoryPool; | |||
43 | * | 43 | * |
44 | * @param max maximum size of the pool | 44 | * @param max maximum size of the pool |
45 | */ | 45 | */ |
46 | struct MemoryPool * MHD_pool_create(unsigned int max); | 46 | struct MemoryPool *MHD_pool_create (unsigned int max); |
47 | 47 | ||
48 | /** | 48 | /** |
49 | * Destroy a memory pool. | 49 | * Destroy a memory pool. |
50 | */ | 50 | */ |
51 | void MHD_pool_destroy(struct MemoryPool * pool); | 51 | void MHD_pool_destroy (struct MemoryPool *pool); |
52 | 52 | ||
53 | /** | 53 | /** |
54 | * Allocate size bytes from the pool. | 54 | * Allocate size bytes from the pool. |
@@ -59,9 +59,8 @@ void MHD_pool_destroy(struct MemoryPool * pool); | |||
59 | * @return NULL if the pool cannot support size more | 59 | * @return NULL if the pool cannot support size more |
60 | * bytes | 60 | * bytes |
61 | */ | 61 | */ |
62 | void * MHD_pool_allocate(struct MemoryPool * pool, | 62 | void *MHD_pool_allocate (struct MemoryPool *pool, |
63 | unsigned int size, | 63 | unsigned int size, int from_end); |
64 | int from_end); | ||
65 | 64 | ||
66 | /** | 65 | /** |
67 | * Reallocate a block of memory obtained from the pool. | 66 | * Reallocate a block of memory obtained from the pool. |
@@ -79,9 +78,8 @@ void * MHD_pool_allocate(struct MemoryPool * pool, | |||
79 | * NULL if the pool cannot support new_size | 78 | * NULL if the pool cannot support new_size |
80 | * bytes (old continues to be valid for old_size) | 79 | * bytes (old continues to be valid for old_size) |
81 | */ | 80 | */ |
82 | void * MHD_pool_reallocate(struct MemoryPool * pool, | 81 | void *MHD_pool_reallocate (struct MemoryPool *pool, |
83 | void * old, | 82 | void *old, |
84 | unsigned int old_size, | 83 | unsigned int old_size, unsigned int new_size); |
85 | unsigned int new_size); | ||
86 | 84 | ||
87 | #endif | 85 | #endif |
diff --git a/src/daemon/minimal_example.c b/src/daemon/minimal_example.c index 10b54aac..8de0064e 100644 --- a/src/daemon/minimal_example.c +++ b/src/daemon/minimal_example.c | |||
@@ -35,50 +35,43 @@ | |||
35 | 35 | ||
36 | #define PAGE "<html><head><title>libmicrohttpd demo</title></head><body>libmicrohttpd demo</body></html>" | 36 | #define PAGE "<html><head><title>libmicrohttpd demo</title></head><body>libmicrohttpd demo</body></html>" |
37 | 37 | ||
38 | static int ahc_echo(void * cls, | 38 | static int |
39 | struct MHD_Connection * connection, | 39 | ahc_echo (void *cls, |
40 | const char * url, | 40 | struct MHD_Connection *connection, |
41 | const char * method, | 41 | const char *url, |
42 | const char * upload_data, | 42 | const char *method, |
43 | const char * version, | 43 | const char *upload_data, |
44 | unsigned int * upload_data_size) { | 44 | const char *version, unsigned int *upload_data_size) |
45 | const char * me = cls; | 45 | { |
46 | struct MHD_Response * response; | 46 | const char *me = cls; |
47 | struct MHD_Response *response; | ||
47 | int ret; | 48 | int ret; |
48 | 49 | ||
49 | if (0 != strcmp(method, "GET")) | 50 | if (0 != strcmp (method, "GET")) |
50 | return MHD_NO; /* unexpected method */ | 51 | return MHD_NO; /* unexpected method */ |
51 | response = MHD_create_response_from_data(strlen(me), | 52 | response = MHD_create_response_from_data (strlen (me), |
52 | (void*) me, | 53 | (void *) me, MHD_NO, MHD_NO); |
53 | MHD_NO, | 54 | ret = MHD_queue_response (connection, MHD_HTTP_OK, response); |
54 | MHD_NO); | 55 | MHD_destroy_response (response); |
55 | ret = MHD_queue_response(connection, | ||
56 | MHD_HTTP_OK, | ||
57 | response); | ||
58 | MHD_destroy_response(response); | ||
59 | return ret; | 56 | return ret; |
60 | } | 57 | } |
61 | 58 | ||
62 | int main(int argc, | 59 | int |
63 | char * const * argv) { | 60 | main (int argc, char *const *argv) |
64 | struct MHD_Daemon * d; | 61 | { |
62 | struct MHD_Daemon *d; | ||
65 | 63 | ||
66 | if (argc != 3) { | 64 | if (argc != 3) |
67 | printf("%s PORT SECONDS-TO-RUN\n", | 65 | { |
68 | argv[0]); | 66 | printf ("%s PORT SECONDS-TO-RUN\n", argv[0]); |
69 | return 1; | 67 | return 1; |
70 | } | 68 | } |
71 | d = MHD_start_daemon(MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG, | 69 | d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG, |
72 | atoi(argv[1]), | 70 | atoi (argv[1]), |
73 | NULL, | 71 | NULL, NULL, &ahc_echo, PAGE, MHD_OPTION_END); |
74 | NULL, | ||
75 | &ahc_echo, | ||
76 | PAGE, | ||
77 | MHD_OPTION_END); | ||
78 | if (d == NULL) | 72 | if (d == NULL) |
79 | return 1; | 73 | return 1; |
80 | sleep(atoi(argv[2])); | 74 | sleep (atoi (argv[2])); |
81 | MHD_stop_daemon(d); | 75 | MHD_stop_daemon (d); |
82 | return 0; | 76 | return 0; |
83 | } | 77 | } |
84 | |||
diff --git a/src/daemon/plibc.h b/src/daemon/plibc.h index 65c431d5..4af3552d 100644 --- a/src/daemon/plibc.h +++ b/src/daemon/plibc.h | |||
@@ -29,21 +29,22 @@ | |||
29 | #define _PLIBC_H_ | 29 | #define _PLIBC_H_ |
30 | 30 | ||
31 | #ifndef SIGALRM | 31 | #ifndef SIGALRM |
32 | #define SIGALRM 14 | 32 | #define SIGALRM 14 |
33 | #endif | 33 | #endif |
34 | 34 | ||
35 | #ifdef __cplusplus | 35 | #ifdef __cplusplus |
36 | extern "C" { | 36 | extern "C" |
37 | { | ||
37 | #endif | 38 | #endif |
38 | 39 | ||
39 | #ifdef Q_OS_WIN32 | 40 | #ifdef Q_OS_WIN32 |
40 | #define WINDOWS 1 | 41 | #define WINDOWS 1 |
41 | #endif | 42 | #endif |
42 | 43 | ||
43 | #ifdef WINDOWS | 44 | #ifdef WINDOWS |
44 | 45 | ||
45 | #if ENABLE_NLS | 46 | #if ENABLE_NLS |
46 | #include "langinfo.h" | 47 | #include "langinfo.h" |
47 | #endif | 48 | #endif |
48 | 49 | ||
49 | #include <windows.h> | 50 | #include <windows.h> |
@@ -75,8 +76,8 @@ extern "C" { | |||
75 | #define int64_t long long | 76 | #define int64_t long long |
76 | #define int32_t long | 77 | #define int32_t long |
77 | 78 | ||
78 | struct stat64 | 79 | struct stat64 |
79 | { | 80 | { |
80 | _dev_t st_dev; | 81 | _dev_t st_dev; |
81 | _ino_t st_ino; | 82 | _ino_t st_ino; |
82 | _mode_t st_mode; | 83 | _mode_t st_mode; |
@@ -88,112 +89,112 @@ struct stat64 | |||
88 | __time64_t st_atime; | 89 | __time64_t st_atime; |
89 | __time64_t st_mtime; | 90 | __time64_t st_mtime; |
90 | __time64_t st_ctime; | 91 | __time64_t st_ctime; |
91 | }; | 92 | }; |
92 | 93 | ||
93 | #ifndef pid_t | 94 | #ifndef pid_t |
94 | #define pid_t int | 95 | #define pid_t int |
95 | #endif | 96 | #endif |
96 | 97 | ||
97 | #ifndef WEXITSTATUS | 98 | #ifndef WEXITSTATUS |
98 | #define WEXITSTATUS(status) (((status) & 0xff00) >> 8) | 99 | #define WEXITSTATUS(status) (((status) & 0xff00) >> 8) |
99 | #endif | 100 | #endif |
100 | 101 | ||
101 | /* Thanks to the Cygwin project */ | 102 | /* Thanks to the Cygwin project */ |
102 | #define ENOCSI 43 /* No CSI structure available */ | 103 | #define ENOCSI 43 /* No CSI structure available */ |
103 | #define EL2HLT 44 /* Level 2 halted */ | 104 | #define EL2HLT 44 /* Level 2 halted */ |
104 | #ifndef EDEADLK | 105 | #ifndef EDEADLK |
105 | #define EDEADLK 45 /* Deadlock condition */ | 106 | #define EDEADLK 45 /* Deadlock condition */ |
106 | #endif | 107 | #endif |
107 | #ifndef ENOLCK | 108 | #ifndef ENOLCK |
108 | #define ENOLCK 46 /* No record locks available */ | 109 | #define ENOLCK 46 /* No record locks available */ |
109 | #endif | 110 | #endif |
110 | #define EBADE 50 /* Invalid exchange */ | 111 | #define EBADE 50 /* Invalid exchange */ |
111 | #define EBADR 51 /* Invalid request descriptor */ | 112 | #define EBADR 51 /* Invalid request descriptor */ |
112 | #define EXFULL 52 /* Exchange full */ | 113 | #define EXFULL 52 /* Exchange full */ |
113 | #define ENOANO 53 /* No anode */ | 114 | #define ENOANO 53 /* No anode */ |
114 | #define EBADRQC 54 /* Invalid request code */ | 115 | #define EBADRQC 54 /* Invalid request code */ |
115 | #define EBADSLT 55 /* Invalid slot */ | 116 | #define EBADSLT 55 /* Invalid slot */ |
116 | #ifndef EDEADLOCK | 117 | #ifndef EDEADLOCK |
117 | #define EDEADLOCK EDEADLK /* File locking deadlock error */ | 118 | #define EDEADLOCK EDEADLK /* File locking deadlock error */ |
118 | #endif | 119 | #endif |
119 | #define EBFONT 57 /* Bad font file fmt */ | 120 | #define EBFONT 57 /* Bad font file fmt */ |
120 | #define ENOSTR 60 /* Device not a stream */ | 121 | #define ENOSTR 60 /* Device not a stream */ |
121 | #define ENODATA 61 /* No data (for no delay io) */ | 122 | #define ENODATA 61 /* No data (for no delay io) */ |
122 | #define ETIME 62 /* Timer expired */ | 123 | #define ETIME 62 /* Timer expired */ |
123 | #define ENOSR 63 /* Out of streams resources */ | 124 | #define ENOSR 63 /* Out of streams resources */ |
124 | #define ENONET 64 /* Machine is not on the network */ | 125 | #define ENONET 64 /* Machine is not on the network */ |
125 | #define ENOPKG 65 /* Package not installed */ | 126 | #define ENOPKG 65 /* Package not installed */ |
126 | #define EREMOTE 66 /* The object is remote */ | 127 | #define EREMOTE 66 /* The object is remote */ |
127 | #define ENOLINK 67 /* The link has been severed */ | 128 | #define ENOLINK 67 /* The link has been severed */ |
128 | #define EADV 68 /* Advertise error */ | 129 | #define EADV 68 /* Advertise error */ |
129 | #define ESRMNT 69 /* Srmount error */ | 130 | #define ESRMNT 69 /* Srmount error */ |
130 | #define ECOMM 70 /* Communication error on send */ | 131 | #define ECOMM 70 /* Communication error on send */ |
131 | #define EPROTO 71 /* Protocol error */ | 132 | #define EPROTO 71 /* Protocol error */ |
132 | #define EMULTIHOP 74 /* Multihop attempted */ | 133 | #define EMULTIHOP 74 /* Multihop attempted */ |
133 | #define ELBIN 75 /* Inode is remote (not really error) */ | 134 | #define ELBIN 75 /* Inode is remote (not really error) */ |
134 | #define EDOTDOT 76 /* Cross mount point (not really error) */ | 135 | #define EDOTDOT 76 /* Cross mount point (not really error) */ |
135 | #define EBADMSG 77 /* Trying to read unreadable message */ | 136 | #define EBADMSG 77 /* Trying to read unreadable message */ |
136 | #define ENOTUNIQ 80 /* Given log. name not unique */ | 137 | #define ENOTUNIQ 80 /* Given log. name not unique */ |
137 | #define EBADFD 81 /* f.d. invalid for this operation */ | 138 | #define EBADFD 81 /* f.d. invalid for this operation */ |
138 | #define EREMCHG 82 /* Remote address changed */ | 139 | #define EREMCHG 82 /* Remote address changed */ |
139 | #define ELIBACC 83 /* Can't access a needed shared lib */ | 140 | #define ELIBACC 83 /* Can't access a needed shared lib */ |
140 | #define ELIBBAD 84 /* Accessing a corrupted shared lib */ | 141 | #define ELIBBAD 84 /* Accessing a corrupted shared lib */ |
141 | #define ELIBSCN 85 /* .lib section in a.out corrupted */ | 142 | #define ELIBSCN 85 /* .lib section in a.out corrupted */ |
142 | #define ELIBMAX 86 /* Attempting to link in too many libs */ | 143 | #define ELIBMAX 86 /* Attempting to link in too many libs */ |
143 | #define ELIBEXEC 87 /* Attempting to exec a shared library */ | 144 | #define ELIBEXEC 87 /* Attempting to exec a shared library */ |
144 | #ifndef ENOSYS | 145 | #ifndef ENOSYS |
145 | #define ENOSYS 88 /* Function not implemented */ | 146 | #define ENOSYS 88 /* Function not implemented */ |
146 | #endif | 147 | #endif |
147 | #define ENMFILE 89 /* No more files */ | 148 | #define ENMFILE 89 /* No more files */ |
148 | #ifndef ENOTEMPTY | 149 | #ifndef ENOTEMPTY |
149 | #define ENOTEMPTY 90 /* Directory not empty */ | 150 | #define ENOTEMPTY 90 /* Directory not empty */ |
150 | #endif | 151 | #endif |
151 | #ifndef ENAMETOOLONG | 152 | #ifndef ENAMETOOLONG |
152 | #define ENAMETOOLONG 91 /* File or path name too long */ | 153 | #define ENAMETOOLONG 91 /* File or path name too long */ |
153 | #endif | 154 | #endif |
154 | #define ELOOP 92 /* Too many symbolic links */ | 155 | #define ELOOP 92 /* Too many symbolic links */ |
155 | #define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ | 156 | #define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ |
156 | #define EPFNOSUPPORT 96 /* Protocol family not supported */ | 157 | #define EPFNOSUPPORT 96 /* Protocol family not supported */ |
157 | #define ECONNRESET 104 /* Connection reset by peer */ | 158 | #define ECONNRESET 104 /* Connection reset by peer */ |
158 | #define ENOBUFS 105 /* No buffer space available */ | 159 | #define ENOBUFS 105 /* No buffer space available */ |
159 | #define EAFNOSUPPORT 106 /* Address family not supported by protocol family */ | 160 | #define EAFNOSUPPORT 106 /* Address family not supported by protocol family */ |
160 | #define EPROTOTYPE 107 /* Protocol wrong type for socket */ | 161 | #define EPROTOTYPE 107 /* Protocol wrong type for socket */ |
161 | #define ENOTSOCK 108 /* Socket operation on non-socket */ | 162 | #define ENOTSOCK 108 /* Socket operation on non-socket */ |
162 | #define ENOPROTOOPT 109 /* Protocol not available */ | 163 | #define ENOPROTOOPT 109 /* Protocol not available */ |
163 | #define ESHUTDOWN 110 /* Can't send after socket shutdown */ | 164 | #define ESHUTDOWN 110 /* Can't send after socket shutdown */ |
164 | #define ECONNREFUSED 111 /* Connection refused */ | 165 | #define ECONNREFUSED 111 /* Connection refused */ |
165 | #define EADDRINUSE 112 /* Address already in use */ | 166 | #define EADDRINUSE 112 /* Address already in use */ |
166 | #define ECONNABORTED 113 /* Connection aborted */ | 167 | #define ECONNABORTED 113 /* Connection aborted */ |
167 | #define ENETUNREACH 114 /* Network is unreachable */ | 168 | #define ENETUNREACH 114 /* Network is unreachable */ |
168 | #define ENETDOWN 115 /* Network interface is not configured */ | 169 | #define ENETDOWN 115 /* Network interface is not configured */ |
169 | #ifndef ETIMEDOUT | 170 | #ifndef ETIMEDOUT |
170 | #define ETIMEDOUT 116 /* Connection timed out */ | 171 | #define ETIMEDOUT 116 /* Connection timed out */ |
171 | #endif | 172 | #endif |
172 | #define EHOSTDOWN 117 /* Host is down */ | 173 | #define EHOSTDOWN 117 /* Host is down */ |
173 | #define EHOSTUNREACH 118 /* Host is unreachable */ | 174 | #define EHOSTUNREACH 118 /* Host is unreachable */ |
174 | #define EINPROGRESS 119 /* Connection already in progress */ | 175 | #define EINPROGRESS 119 /* Connection already in progress */ |
175 | #define EALREADY 120 /* Socket already connected */ | 176 | #define EALREADY 120 /* Socket already connected */ |
176 | #define EDESTADDRREQ 121 /* Destination address required */ | 177 | #define EDESTADDRREQ 121 /* Destination address required */ |
177 | #define EMSGSIZE 122 /* Message too long */ | 178 | #define EMSGSIZE 122 /* Message too long */ |
178 | #define EPROTONOSUPPORT 123 /* Unknown protocol */ | 179 | #define EPROTONOSUPPORT 123 /* Unknown protocol */ |
179 | #define ESOCKTNOSUPPORT 124 /* Socket type not supported */ | 180 | #define ESOCKTNOSUPPORT 124 /* Socket type not supported */ |
180 | #define EADDRNOTAVAIL 125 /* Address not available */ | 181 | #define EADDRNOTAVAIL 125 /* Address not available */ |
181 | #define ENETRESET 126 /* Connection aborted by network */ | 182 | #define ENETRESET 126 /* Connection aborted by network */ |
182 | #define EISCONN 127 /* Socket is already connected */ | 183 | #define EISCONN 127 /* Socket is already connected */ |
183 | #define ENOTCONN 128 /* Socket is not connected */ | 184 | #define ENOTCONN 128 /* Socket is not connected */ |
184 | #define ETOOMANYREFS 129 /* Too many references: cannot splice */ | 185 | #define ETOOMANYREFS 129 /* Too many references: cannot splice */ |
185 | #define EPROCLIM 130 /* Too many processes */ | 186 | #define EPROCLIM 130 /* Too many processes */ |
186 | #define EUSERS 131 /* Too many users */ | 187 | #define EUSERS 131 /* Too many users */ |
187 | #define EDQUOT 132 /* Disk quota exceeded */ | 188 | #define EDQUOT 132 /* Disk quota exceeded */ |
188 | #define ESTALE 133 /* Unknown error */ | 189 | #define ESTALE 133 /* Unknown error */ |
189 | #ifndef ENOTSUP | 190 | #ifndef ENOTSUP |
190 | #define ENOTSUP 134 /* Not supported */ | 191 | #define ENOTSUP 134 /* Not supported */ |
191 | #endif | 192 | #endif |
192 | #define ENOMEDIUM 135 /* No medium (in tape drive) */ | 193 | #define ENOMEDIUM 135 /* No medium (in tape drive) */ |
193 | #define ENOSHARE 136 /* No such host or network path */ | 194 | #define ENOSHARE 136 /* No such host or network path */ |
194 | #define ECASECLASH 137 /* Filename exists with different case */ | 195 | #define ECASECLASH 137 /* Filename exists with different case */ |
195 | #define EWOULDBLOCK EAGAIN /* Operation would block */ | 196 | #define EWOULDBLOCK EAGAIN /* Operation would block */ |
196 | #define EOVERFLOW 139 /* Value too large for defined data type */ | 197 | #define EOVERFLOW 139 /* Value too large for defined data type */ |
197 | 198 | ||
198 | #undef HOST_NOT_FOUND | 199 | #undef HOST_NOT_FOUND |
199 | #define HOST_NOT_FOUND 1 | 200 | #define HOST_NOT_FOUND 1 |
@@ -207,65 +208,65 @@ struct stat64 | |||
207 | #define PROT_READ 0x1 | 208 | #define PROT_READ 0x1 |
208 | #define PROT_WRITE 0x2 | 209 | #define PROT_WRITE 0x2 |
209 | #define MAP_SHARED 0x1 | 210 | #define MAP_SHARED 0x1 |
210 | #define MAP_PRIVATE 0x2 /* unsupported */ | 211 | #define MAP_PRIVATE 0x2 /* unsupported */ |
211 | #define MAP_FIXED 0x10 | 212 | #define MAP_FIXED 0x10 |
212 | #define MAP_FAILED ((void *)-1) | 213 | #define MAP_FAILED ((void *)-1) |
213 | 214 | ||
214 | struct statfs | 215 | struct statfs |
215 | { | 216 | { |
216 | long f_type; /* type of filesystem (see below) */ | 217 | long f_type; /* type of filesystem (see below) */ |
217 | long f_bsize; /* optimal transfer block size */ | 218 | long f_bsize; /* optimal transfer block size */ |
218 | long f_blocks; /* total data blocks in file system */ | 219 | long f_blocks; /* total data blocks in file system */ |
219 | long f_bfree; /* free blocks in fs */ | 220 | long f_bfree; /* free blocks in fs */ |
220 | long f_bavail; /* free blocks avail to non-superuser */ | 221 | long f_bavail; /* free blocks avail to non-superuser */ |
221 | long f_files; /* total file nodes in file system */ | 222 | long f_files; /* total file nodes in file system */ |
222 | long f_ffree; /* free file nodes in fs */ | 223 | long f_ffree; /* free file nodes in fs */ |
223 | long f_fsid; /* file system id */ | 224 | long f_fsid; /* file system id */ |
224 | long f_namelen; /* maximum length of filenames */ | 225 | long f_namelen; /* maximum length of filenames */ |
225 | long f_spare[6]; /* spare for later */ | 226 | long f_spare[6]; /* spare for later */ |
226 | }; | 227 | }; |
227 | 228 | ||
228 | /* Taken from the Wine project <http://www.winehq.org> | 229 | /* Taken from the Wine project <http://www.winehq.org> |
229 | /wine/include/winternl.h */ | 230 | /wine/include/winternl.h */ |
230 | enum SYSTEM_INFORMATION_CLASS | 231 | enum SYSTEM_INFORMATION_CLASS |
231 | { | 232 | { |
232 | SystemBasicInformation = 0, | 233 | SystemBasicInformation = 0, |
233 | Unknown1, | 234 | Unknown1, |
234 | SystemPerformanceInformation = 2, | 235 | SystemPerformanceInformation = 2, |
235 | SystemTimeOfDayInformation = 3, /* was SystemTimeInformation */ | 236 | SystemTimeOfDayInformation = 3, /* was SystemTimeInformation */ |
236 | Unknown4, | 237 | Unknown4, |
237 | SystemProcessInformation = 5, | 238 | SystemProcessInformation = 5, |
238 | Unknown6, | 239 | Unknown6, |
239 | Unknown7, | 240 | Unknown7, |
240 | SystemProcessorPerformanceInformation = 8, | 241 | SystemProcessorPerformanceInformation = 8, |
241 | Unknown9, | 242 | Unknown9, |
242 | Unknown10, | 243 | Unknown10, |
243 | SystemDriverInformation, | 244 | SystemDriverInformation, |
244 | Unknown12, | 245 | Unknown12, |
245 | Unknown13, | 246 | Unknown13, |
246 | Unknown14, | 247 | Unknown14, |
247 | Unknown15, | 248 | Unknown15, |
248 | SystemHandleList, | 249 | SystemHandleList, |
249 | Unknown17, | 250 | Unknown17, |
250 | Unknown18, | 251 | Unknown18, |
251 | Unknown19, | 252 | Unknown19, |
252 | Unknown20, | 253 | Unknown20, |
253 | SystemCacheInformation, | 254 | SystemCacheInformation, |
254 | Unknown22, | 255 | Unknown22, |
255 | SystemInterruptInformation = 23, | 256 | SystemInterruptInformation = 23, |
256 | SystemExceptionInformation = 33, | 257 | SystemExceptionInformation = 33, |
257 | SystemRegistryQuotaInformation = 37, | 258 | SystemRegistryQuotaInformation = 37, |
258 | SystemLookasideInformation = 45 | 259 | SystemLookasideInformation = 45 |
259 | }; | 260 | }; |
260 | 261 | ||
261 | typedef struct | 262 | typedef struct |
262 | { | 263 | { |
263 | LARGE_INTEGER IdleTime; | 264 | LARGE_INTEGER IdleTime; |
264 | LARGE_INTEGER KernelTime; | 265 | LARGE_INTEGER KernelTime; |
265 | LARGE_INTEGER UserTime; | 266 | LARGE_INTEGER UserTime; |
266 | LARGE_INTEGER Reserved1[2]; | 267 | LARGE_INTEGER Reserved1[2]; |
267 | ULONG Reserved2; | 268 | ULONG Reserved2; |
268 | } SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION; | 269 | } SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION; |
269 | 270 | ||
270 | #define sleep(secs) (Sleep(secs * 1000)) | 271 | #define sleep(secs) (Sleep(secs * 1000)) |
271 | 272 | ||
@@ -282,11 +283,11 @@ typedef struct | |||
282 | #define SHUT_RDWR SD_BOTH | 283 | #define SHUT_RDWR SD_BOTH |
283 | 284 | ||
284 | /* Operations for flock() */ | 285 | /* Operations for flock() */ |
285 | #define LOCK_SH 1 /* shared lock */ | 286 | #define LOCK_SH 1 /* shared lock */ |
286 | #define LOCK_EX 2 /* exclusive lock */ | 287 | #define LOCK_EX 2 /* exclusive lock */ |
287 | #define LOCK_NB 4 /* or'd with one of the above to prevent | 288 | #define LOCK_NB 4 /* or'd with one of the above to prevent |
288 | blocking */ | 289 | blocking */ |
289 | #define LOCK_UN 8 /* remove lock */ | 290 | #define LOCK_UN 8 /* remove lock */ |
290 | 291 | ||
291 | /* Not supported under MinGW */ | 292 | /* Not supported under MinGW */ |
292 | #define S_IRGRP 0 | 293 | #define S_IRGRP 0 |
@@ -308,272 +309,273 @@ typedef struct | |||
308 | */ | 309 | */ |
309 | #define index(s, c) strchr(s, c) | 310 | #define index(s, c) strchr(s, c) |
310 | 311 | ||
311 | BOOL _plibc_CreateShortcut(const char *pszSrc, const char *pszDest); | 312 | BOOL _plibc_CreateShortcut (const char *pszSrc, const char *pszDest); |
312 | BOOL _plibc_DereferenceShortcut(char *pszShortcut); | 313 | BOOL _plibc_DereferenceShortcut (char *pszShortcut); |
313 | char *plibc_ChooseDir(char *pszTitle, unsigned long ulFlags); | 314 | char *plibc_ChooseDir (char *pszTitle, unsigned long ulFlags); |
314 | char *plibc_ChooseFile(char *pszTitle, unsigned long ulFlags); | 315 | char *plibc_ChooseFile (char *pszTitle, unsigned long ulFlags); |
315 | long QueryRegistry(HKEY hMainKey, char *pszKey, char *pszSubKey, | 316 | long QueryRegistry (HKEY hMainKey, char *pszKey, char *pszSubKey, |
316 | char *pszBuffer, long *pdLength); | 317 | char *pszBuffer, long *pdLength); |
317 | 318 | ||
318 | BOOL __win_IsHandleMarkedAsBlocking(SOCKET hHandle); | 319 | BOOL __win_IsHandleMarkedAsBlocking (SOCKET hHandle); |
319 | void __win_SetHandleBlockingMode(SOCKET s, BOOL bBlocking); | 320 | void __win_SetHandleBlockingMode (SOCKET s, BOOL bBlocking); |
320 | void __win_DiscardHandleBlockingMode(SOCKET s); | 321 | void __win_DiscardHandleBlockingMode (SOCKET s); |
321 | int _win_isSocketValid(int s); | 322 | int _win_isSocketValid (int s); |
322 | int plibc_conv_to_win_path(const char *pszUnix, char *pszWindows); | 323 | int plibc_conv_to_win_path (const char *pszUnix, char *pszWindows); |
323 | 324 | ||
324 | typedef void (*TPanicProc) (int, char *); | 325 | typedef void (*TPanicProc) (int, char *); |
325 | void plibc_set_panic_proc(TPanicProc proc); | 326 | void plibc_set_panic_proc (TPanicProc proc); |
326 | 327 | ||
327 | int flock(int fd, int operation); | 328 | int flock (int fd, int operation); |
328 | int fsync(int fildes); | 329 | int fsync (int fildes); |
329 | int inet_pton(int af, const char *src, void *dst); | 330 | int inet_pton (int af, const char *src, void *dst); |
330 | int inet_pton4(const char *src, u_char *dst, int pton); | 331 | int inet_pton4 (const char *src, u_char * dst, int pton); |
331 | #if USE_IPV6 | 332 | #if USE_IPV6 |
332 | int inet_pton6(const char *src, u_char *dst); | 333 | int inet_pton6 (const char *src, u_char * dst); |
333 | #endif | 334 | #endif |
334 | int truncate(const char *fname, int distance); | 335 | int truncate (const char *fname, int distance); |
335 | int statfs(const char *path, struct statfs *buf); | 336 | int statfs (const char *path, struct statfs *buf); |
336 | const char *hstrerror(int err); | 337 | const char *hstrerror (int err); |
337 | void gettimeofday(struct timeval *tp, void *tzp); | 338 | void gettimeofday (struct timeval *tp, void *tzp); |
338 | int mkstemp(char *tmplate); | 339 | int mkstemp (char *tmplate); |
339 | char *strptime (const char *buf, const char *format, struct tm *tm); | 340 | char *strptime (const char *buf, const char *format, struct tm *tm); |
340 | char *ctime(const time_t *clock); | 341 | char *ctime (const time_t * clock); |
341 | char *ctime_r(const time_t *clock, char *buf); | 342 | char *ctime_r (const time_t * clock, char *buf); |
342 | int plibc_init(char *pszOrg, char *pszApp); | 343 | int plibc_init (char *pszOrg, char *pszApp); |
343 | void plibc_shutdown(); | 344 | void plibc_shutdown (); |
344 | int plibc_initialized(); | 345 | int plibc_initialized (); |
345 | int plibc_conv_to_win_path_ex(const char *pszUnix, char *pszWindows, int derefLinks); | 346 | int plibc_conv_to_win_path_ex (const char *pszUnix, char *pszWindows, |
346 | void _SetErrnoFromWinError(long lWinError, char *pszCaller, int iLine); | 347 | int derefLinks); |
347 | void SetErrnoFromWinsockError(long lWinError); | 348 | void _SetErrnoFromWinError (long lWinError, char *pszCaller, int iLine); |
348 | void SetHErrnoFromWinError(long lWinError); | 349 | void SetErrnoFromWinsockError (long lWinError); |
349 | void SetErrnoFromHRESULT(HRESULT hRes); | 350 | void SetHErrnoFromWinError (long lWinError); |
350 | FILE *_win_fopen(const char *filename, const char *mode); | 351 | void SetErrnoFromHRESULT (HRESULT hRes); |
351 | DIR *_win_opendir(const char *dirname); | 352 | FILE *_win_fopen (const char *filename, const char *mode); |
352 | int _win_open(const char *filename, int oflag, ...); | 353 | DIR *_win_opendir (const char *dirname); |
354 | int _win_open (const char *filename, int oflag, ...); | ||
353 | #ifdef ENABLE_NLS | 355 | #ifdef ENABLE_NLS |
354 | char *_win_bindtextdomain(const char *domainname, const char *dirname); | 356 | char *_win_bindtextdomain (const char *domainname, const char *dirname); |
355 | #endif | 357 | #endif |
356 | int _win_chdir(const char *path); | 358 | int _win_chdir (const char *path); |
357 | int _win_close(int fd); | 359 | int _win_close (int fd); |
358 | int _win_creat(const char *path, mode_t mode); | 360 | int _win_creat (const char *path, mode_t mode); |
359 | int _win_fstat(int handle, struct stat *buffer); | 361 | int _win_fstat (int handle, struct stat *buffer); |
360 | int _win_pipe(int *phandles); | 362 | int _win_pipe (int *phandles); |
361 | int _win_rmdir(const char *path); | 363 | int _win_rmdir (const char *path); |
362 | int _win_access( const char *path, int mode ); | 364 | int _win_access (const char *path, int mode); |
363 | int _win_chmod(const char *filename, int pmode); | 365 | int _win_chmod (const char *filename, int pmode); |
364 | char *realpath(const char *file_name, char *resolved_name); | 366 | char *realpath (const char *file_name, char *resolved_name); |
365 | long _win_random(void); | 367 | long _win_random (void); |
366 | int _win_remove(const char *path); | 368 | int _win_remove (const char *path); |
367 | int _win_rename(const char *oldname, const char *newname); | 369 | int _win_rename (const char *oldname, const char *newname); |
368 | int _win_stat(const char *path, struct stat *buffer); | 370 | int _win_stat (const char *path, struct stat *buffer); |
369 | int _win_stat64(const char *path, struct stat64 *buffer); | 371 | int _win_stat64 (const char *path, struct stat64 *buffer); |
370 | int _win_unlink(const char *filename); | 372 | int _win_unlink (const char *filename); |
371 | int _win_write(int fildes, const void *buf, size_t nbyte); | 373 | int _win_write (int fildes, const void *buf, size_t nbyte); |
372 | int _win_read(int fildes, void *buf, size_t nbyte); | 374 | int _win_read (int fildes, void *buf, size_t nbyte); |
373 | size_t _win_fwrite(const void *buffer, size_t size, size_t count, FILE *stream); | 375 | size_t _win_fwrite (const void *buffer, size_t size, size_t count, |
374 | size_t _win_fread( void *buffer, size_t size, size_t count, FILE *stream ); | 376 | FILE * stream); |
375 | int _win_symlink(const char *path1, const char *path2); | 377 | size_t _win_fread (void *buffer, size_t size, size_t count, FILE * stream); |
376 | void *_win_mmap(void *start, size_t len, int access, int flags, int fd, | 378 | int _win_symlink (const char *path1, const char *path2); |
377 | unsigned long long offset); | 379 | void *_win_mmap (void *start, size_t len, int access, int flags, int fd, |
378 | int _win_munmap(void *start, size_t length); | 380 | unsigned long long offset); |
379 | int _win_lstat(const char *path, struct stat *buf); | 381 | int _win_munmap (void *start, size_t length); |
380 | int _win_lstat64(const char *path, struct stat64 *buf); | 382 | int _win_lstat (const char *path, struct stat *buf); |
381 | int _win_readlink(const char *path, char *buf, size_t bufsize); | 383 | int _win_lstat64 (const char *path, struct stat64 *buf); |
382 | int _win_accept(SOCKET s, struct sockaddr *addr, int *addrlen); | 384 | int _win_readlink (const char *path, char *buf, size_t bufsize); |
383 | int _win_printf(const char *format,...); | 385 | int _win_accept (SOCKET s, struct sockaddr *addr, int *addrlen); |
384 | int _win_fprintf(FILE *f,const char *format,...); | 386 | int _win_printf (const char *format, ...); |
385 | int _win_vprintf(const char *format, va_list ap); | 387 | int _win_fprintf (FILE * f, const char *format, ...); |
386 | int _win_vfprintf(FILE *stream, const char *format, va_list arg_ptr); | 388 | int _win_vprintf (const char *format, va_list ap); |
387 | int _win_vsprintf(char *dest,const char *format, va_list arg_ptr); | 389 | int _win_vfprintf (FILE * stream, const char *format, va_list arg_ptr); |
388 | int _win_vsnprintf(char* str, size_t size, const char *format, va_list arg_ptr); | 390 | int _win_vsprintf (char *dest, const char *format, va_list arg_ptr); |
389 | int _win_snprintf(char *str,size_t size,const char *format,...); | 391 | int _win_vsnprintf (char *str, size_t size, const char *format, |
390 | int _win_sprintf(char *dest,const char *format,...); | 392 | va_list arg_ptr); |
391 | int _win_vsscanf(const char* str, const char* format, va_list arg_ptr); | 393 | int _win_snprintf (char *str, size_t size, const char *format, ...); |
392 | int _win_sscanf(const char *str, const char *format, ...); | 394 | int _win_sprintf (char *dest, const char *format, ...); |
393 | int _win_vfscanf(FILE *stream, const char *format, va_list arg_ptr); | 395 | int _win_vsscanf (const char *str, const char *format, va_list arg_ptr); |
394 | int _win_vscanf(const char *format, va_list arg_ptr); | 396 | int _win_sscanf (const char *str, const char *format, ...); |
395 | int _win_scanf(const char *format, ...); | 397 | int _win_vfscanf (FILE * stream, const char *format, va_list arg_ptr); |
396 | int _win_fscanf(FILE *stream, const char *format, ...); | 398 | int _win_vscanf (const char *format, va_list arg_ptr); |
397 | pid_t _win_waitpid(pid_t pid, int *stat_loc, int options); | 399 | int _win_scanf (const char *format, ...); |
398 | int _win_bind(SOCKET s, const struct sockaddr *name, int namelen); | 400 | int _win_fscanf (FILE * stream, const char *format, ...); |
399 | int _win_connect(SOCKET s,const struct sockaddr *name, int namelen); | 401 | pid_t _win_waitpid (pid_t pid, int *stat_loc, int options); |
400 | int _win_getpeername(SOCKET s, struct sockaddr *name, | 402 | int _win_bind (SOCKET s, const struct sockaddr *name, int namelen); |
401 | int *namelen); | 403 | int _win_connect (SOCKET s, const struct sockaddr *name, int namelen); |
402 | int _win_getsockname(SOCKET s, struct sockaddr *name, | 404 | int _win_getpeername (SOCKET s, struct sockaddr *name, int *namelen); |
403 | int *namelen); | 405 | int _win_getsockname (SOCKET s, struct sockaddr *name, int *namelen); |
404 | int _win_getsockopt(SOCKET s, int level, int optname, char *optval, | 406 | int _win_getsockopt (SOCKET s, int level, int optname, char *optval, |
405 | int *optlen); | 407 | int *optlen); |
406 | int _win_listen(SOCKET s, int backlog); | 408 | int _win_listen (SOCKET s, int backlog); |
407 | int _win_recv(SOCKET s, char *buf, int len, int flags); | 409 | int _win_recv (SOCKET s, char *buf, int len, int flags); |
408 | int _win_recvfrom(SOCKET s, void *buf, int len, int flags, | 410 | int _win_recvfrom (SOCKET s, void *buf, int len, int flags, |
409 | struct sockaddr *from, int *fromlen); | 411 | struct sockaddr *from, int *fromlen); |
410 | int _win_select(int max_fd, fd_set * rfds, fd_set * wfds, fd_set * efds, | 412 | int _win_select (int max_fd, fd_set * rfds, fd_set * wfds, fd_set * efds, |
411 | const struct timeval *tv); | 413 | const struct timeval *tv); |
412 | int _win_send(SOCKET s, const char *buf, int len, int flags); | 414 | int _win_send (SOCKET s, const char *buf, int len, int flags); |
413 | int _win_sendto(SOCKET s, const char *buf, int len, int flags, | 415 | int _win_sendto (SOCKET s, const char *buf, int len, int flags, |
414 | const struct sockaddr *to, int tolen); | 416 | const struct sockaddr *to, int tolen); |
415 | int _win_setsockopt(SOCKET s, int level, int optname, const void *optval, | 417 | int _win_setsockopt (SOCKET s, int level, int optname, const void *optval, |
416 | int optlen); | 418 | int optlen); |
417 | int _win_shutdown(SOCKET s, int how); | 419 | int _win_shutdown (SOCKET s, int how); |
418 | SOCKET _win_socket(int af, int type, int protocol); | 420 | SOCKET _win_socket (int af, int type, int protocol); |
419 | struct hostent *_win_gethostbyaddr(const char *addr, int len, int type); | 421 | struct hostent *_win_gethostbyaddr (const char *addr, int len, int type); |
420 | struct hostent *_win_gethostbyname(const char *name); | 422 | struct hostent *_win_gethostbyname (const char *name); |
421 | char *_win_strerror(int errnum); | 423 | char *_win_strerror (int errnum); |
422 | int IsWinNT(); | 424 | int IsWinNT (); |
423 | 425 | ||
424 | #if !HAVE_STRNDUP | 426 | #if !HAVE_STRNDUP |
425 | char *strndup (const char *s, size_t n); | 427 | char *strndup (const char *s, size_t n); |
426 | #endif | 428 | #endif |
427 | #if !HAVE_STRNLEN | 429 | #if !HAVE_STRNLEN |
428 | size_t strnlen (const char *str, size_t maxlen); | 430 | size_t strnlen (const char *str, size_t maxlen); |
429 | #endif | 431 | #endif |
430 | 432 | ||
431 | #define strcasecmp(a, b) stricmp(a, b) | 433 | #define strcasecmp(a, b) stricmp(a, b) |
432 | #define strncasecmp(a, b, c) strnicmp(a, b, c) | 434 | #define strncasecmp(a, b, c) strnicmp(a, b, c) |
433 | 435 | ||
434 | #endif /* WINDOWS */ | 436 | #endif /* WINDOWS */ |
435 | 437 | ||
436 | #ifndef WINDOWS | 438 | #ifndef WINDOWS |
437 | #define DIR_SEPARATOR '/' | 439 | #define DIR_SEPARATOR '/' |
438 | #define DIR_SEPARATOR_STR "/" | 440 | #define DIR_SEPARATOR_STR "/" |
439 | #define PATH_SEPARATOR ';' | 441 | #define PATH_SEPARATOR ';' |
440 | #define PATH_SEPARATOR_STR ";" | 442 | #define PATH_SEPARATOR_STR ";" |
441 | #define NEWLINE "\n" | 443 | #define NEWLINE "\n" |
442 | 444 | ||
443 | #ifdef ENABLE_NLS | 445 | #ifdef ENABLE_NLS |
444 | #define BINDTEXTDOMAIN(d, n) bindtextdomain(d, n) | 446 | #define BINDTEXTDOMAIN(d, n) bindtextdomain(d, n) |
445 | #endif | 447 | #endif |
446 | #define CREAT(p, m) creat(p, m) | 448 | #define CREAT(p, m) creat(p, m) |
447 | #undef FOPEN | 449 | #undef FOPEN |
448 | #define FOPEN(f, m) fopen(f, m) | 450 | #define FOPEN(f, m) fopen(f, m) |
449 | #define OPENDIR(d) opendir(d) | 451 | #define OPENDIR(d) opendir(d) |
450 | #define OPEN(f) open(f) | 452 | #define OPEN(f) open(f) |
451 | #define CHDIR(d) chdir(d) | 453 | #define CHDIR(d) chdir(d) |
452 | #define CLOSE(f) close(f) | 454 | #define CLOSE(f) close(f) |
453 | #define RMDIR(f) rmdir(f) | 455 | #define RMDIR(f) rmdir(f) |
454 | #define ACCESS(p, m) access(p, m) | 456 | #define ACCESS(p, m) access(p, m) |
455 | #define CHMOD(f, p) chmod(f, p) | 457 | #define CHMOD(f, p) chmod(f, p) |
456 | #define FSTAT(h, b) fstat(h, b) | 458 | #define FSTAT(h, b) fstat(h, b) |
457 | #define PIPE(h) pipe(h) | 459 | #define PIPE(h) pipe(h) |
458 | #define REMOVE(p) remove(p) | 460 | #define REMOVE(p) remove(p) |
459 | #define RENAME(o, n) rename(o, n) | 461 | #define RENAME(o, n) rename(o, n) |
460 | #define STAT(p, b) stat(p, b) | 462 | #define STAT(p, b) stat(p, b) |
461 | #define STAT64(p, b) stat64(p, b) | 463 | #define STAT64(p, b) stat64(p, b) |
462 | #define UNLINK(f) unlink(f) | 464 | #define UNLINK(f) unlink(f) |
463 | #define WRITE(f, b, n) write(f, b, n) | 465 | #define WRITE(f, b, n) write(f, b, n) |
464 | #define READ(f, b, n) read(f, b, n) | 466 | #define READ(f, b, n) read(f, b, n) |
465 | #define GN_FREAD(b, s, c, f) fread(b, s, c, f) | 467 | #define GN_FREAD(b, s, c, f) fread(b, s, c, f) |
466 | #define GN_FWRITE(b, s, c, f) fwrite(b, s, c, f) | 468 | #define GN_FWRITE(b, s, c, f) fwrite(b, s, c, f) |
467 | #define SYMLINK(a, b) symlink(a, b) | 469 | #define SYMLINK(a, b) symlink(a, b) |
468 | #define MMAP(s, l, p, f, d, o) mmap(s, l, p, f, d, o) | 470 | #define MMAP(s, l, p, f, d, o) mmap(s, l, p, f, d, o) |
469 | #define MUNMAP(s, l) munmap(s, l) | 471 | #define MUNMAP(s, l) munmap(s, l) |
470 | #define STRERROR(i) strerror(i) | 472 | #define STRERROR(i) strerror(i) |
471 | #define RANDOM() random() | 473 | #define RANDOM() random() |
472 | #define READLINK(p, b, s) readlink(p, b, s) | 474 | #define READLINK(p, b, s) readlink(p, b, s) |
473 | #define LSTAT(p, b) lstat(p, b) | 475 | #define LSTAT(p, b) lstat(p, b) |
474 | #define LSTAT64(p, b) lstat64(p, b) | 476 | #define LSTAT64(p, b) lstat64(p, b) |
475 | #define PRINTF printf | 477 | #define PRINTF printf |
476 | #define FPRINTF fprintf | 478 | #define FPRINTF fprintf |
477 | #define VPRINTF(f, a) vprintf(f, a) | 479 | #define VPRINTF(f, a) vprintf(f, a) |
478 | #define VFPRINTF(s, f, a) vfprintf(s, f, a) | 480 | #define VFPRINTF(s, f, a) vfprintf(s, f, a) |
479 | #define VSPRINTF(d, f, a) vsprintf(d, f, a) | 481 | #define VSPRINTF(d, f, a) vsprintf(d, f, a) |
480 | #define VSNPRINTF(str, size, fmt, a) vsnprintf(str, size, fmt, a) | 482 | #define VSNPRINTF(str, size, fmt, a) vsnprintf(str, size, fmt, a) |
481 | #define _REAL_SNPRINTF snprintf | 483 | #define _REAL_SNPRINTF snprintf |
482 | #define SPRINTF sprintf | 484 | #define SPRINTF sprintf |
483 | #define VSSCANF(s, f, a) vsscanf(s, f, a) | 485 | #define VSSCANF(s, f, a) vsscanf(s, f, a) |
484 | #define SSCANF sscanf | 486 | #define SSCANF sscanf |
485 | #define VFSCANF(s, f, a) vfscanf(s, f, a) | 487 | #define VFSCANF(s, f, a) vfscanf(s, f, a) |
486 | #define VSCANF(f, a) vscanf(f, a) | 488 | #define VSCANF(f, a) vscanf(f, a) |
487 | #define SCANF scanf | 489 | #define SCANF scanf |
488 | #define FSCANF fscanf | 490 | #define FSCANF fscanf |
489 | #define WAITPID(p, s, o) waitpid(p, s, o) | 491 | #define WAITPID(p, s, o) waitpid(p, s, o) |
490 | #define ACCEPT(s, a, l) accept(s, a, l) | 492 | #define ACCEPT(s, a, l) accept(s, a, l) |
491 | #define BIND(s, n, l) bind(s, n, l) | 493 | #define BIND(s, n, l) bind(s, n, l) |
492 | #define CONNECT(s, n, l) connect(s, n, l) | 494 | #define CONNECT(s, n, l) connect(s, n, l) |
493 | #define GETPEERNAME(s, n, l) getpeername(s, n, l) | 495 | #define GETPEERNAME(s, n, l) getpeername(s, n, l) |
494 | #define GETSOCKNAME(s, n, l) getsockname(s, n, l) | 496 | #define GETSOCKNAME(s, n, l) getsockname(s, n, l) |
495 | #define GETSOCKOPT(s, l, o, v, p) getsockopt(s, l, o, v, p) | 497 | #define GETSOCKOPT(s, l, o, v, p) getsockopt(s, l, o, v, p) |
496 | #define LISTEN(s, b) listen(s, b) | 498 | #define LISTEN(s, b) listen(s, b) |
497 | #define RECV(s, b, l, f) recv(s, b, l, f) | 499 | #define RECV(s, b, l, f) recv(s, b, l, f) |
498 | #define RECVFROM(s, b, l, f, r, o) recvfrom(s, b, l, f, r, o) | 500 | #define RECVFROM(s, b, l, f, r, o) recvfrom(s, b, l, f, r, o) |
499 | #define SELECT(n, r, w, e, t) select(n, r, w, e, t) | 501 | #define SELECT(n, r, w, e, t) select(n, r, w, e, t) |
500 | #define SEND(s, b, l, f) send(s, b, l, f) | 502 | #define SEND(s, b, l, f) send(s, b, l, f) |
501 | #define SENDTO(s, b, l, f, o, n) sendto(s, b, l, f, o, n) | 503 | #define SENDTO(s, b, l, f, o, n) sendto(s, b, l, f, o, n) |
502 | #define SETSOCKOPT(s, l, o, v, n) setsockopt(s, l, o, v, n) | 504 | #define SETSOCKOPT(s, l, o, v, n) setsockopt(s, l, o, v, n) |
503 | #define SHUTDOWN(s, h) shutdown(s, h) | 505 | #define SHUTDOWN(s, h) shutdown(s, h) |
504 | #define SOCKET(a, t, p) socket(a, t, p) | 506 | #define SOCKET(a, t, p) socket(a, t, p) |
505 | #define GETHOSTBYADDR(a, l, t) gethostbyname(a, l, t) | 507 | #define GETHOSTBYADDR(a, l, t) gethostbyname(a, l, t) |
506 | #define GETHOSTBYNAME(n) gethostbyname(n) | 508 | #define GETHOSTBYNAME(n) gethostbyname(n) |
507 | #else | 509 | #else |
508 | #define DIR_SEPARATOR '\\' | 510 | #define DIR_SEPARATOR '\\' |
509 | #define DIR_SEPARATOR_STR "\\" | 511 | #define DIR_SEPARATOR_STR "\\" |
510 | #define PATH_SEPARATOR ':' | 512 | #define PATH_SEPARATOR ':' |
511 | #define PATH_SEPARATOR_STR ":" | 513 | #define PATH_SEPARATOR_STR ":" |
512 | #define NEWLINE "\r\n" | 514 | #define NEWLINE "\r\n" |
513 | 515 | ||
514 | #ifdef ENABLE_NLS | 516 | #ifdef ENABLE_NLS |
515 | #define BINDTEXTDOMAIN(d, n) _win_bindtextdomain(d, n) | 517 | #define BINDTEXTDOMAIN(d, n) _win_bindtextdomain(d, n) |
516 | #endif | 518 | #endif |
517 | #define CREAT(p, m) _win_creat(p, m) | 519 | #define CREAT(p, m) _win_creat(p, m) |
518 | #define FOPEN(f, m) _win_fopen(f, m) | 520 | #define FOPEN(f, m) _win_fopen(f, m) |
519 | #define OPENDIR(d) _win_opendir(d) | 521 | #define OPENDIR(d) _win_opendir(d) |
520 | #define OPEN(f) _win_open(f) | 522 | #define OPEN(f) _win_open(f) |
521 | #define CHDIR(d) _win_chdir(d) | 523 | #define CHDIR(d) _win_chdir(d) |
522 | #define CLOSE(f) _win_close(f) | 524 | #define CLOSE(f) _win_close(f) |
523 | #define FSTAT(h, b) _win_fstat(h, b) | 525 | #define FSTAT(h, b) _win_fstat(h, b) |
524 | #define RMDIR(f) _win_rmdir(f) | 526 | #define RMDIR(f) _win_rmdir(f) |
525 | #define ACCESS(p, m) _win_access(p, m) | 527 | #define ACCESS(p, m) _win_access(p, m) |
526 | #define CHMOD(f, p) _win_chmod(f, p) | 528 | #define CHMOD(f, p) _win_chmod(f, p) |
527 | #define PIPE(h) _win_pipe(h) | 529 | #define PIPE(h) _win_pipe(h) |
528 | #define RANDOM() _win_random() | 530 | #define RANDOM() _win_random() |
529 | #define REMOVE(p) _win_remove(p) | 531 | #define REMOVE(p) _win_remove(p) |
530 | #define RENAME(o, n) _win_rename(o, n) | 532 | #define RENAME(o, n) _win_rename(o, n) |
531 | #define STAT(p, b) _win_stat(p, b) | 533 | #define STAT(p, b) _win_stat(p, b) |
532 | #define STAT64(p, b) _win_stat64(p, b) | 534 | #define STAT64(p, b) _win_stat64(p, b) |
533 | #define UNLINK(f) _win_unlink(f) | 535 | #define UNLINK(f) _win_unlink(f) |
534 | #define WRITE(f, b, n) _win_write(f, b, n) | 536 | #define WRITE(f, b, n) _win_write(f, b, n) |
535 | #define READ(f, b, n) _win_read(f, b, n) | 537 | #define READ(f, b, n) _win_read(f, b, n) |
536 | #define GN_FREAD(b, s, c, f) _win_fread(b, s, c, f) | 538 | #define GN_FREAD(b, s, c, f) _win_fread(b, s, c, f) |
537 | #define GN_FWRITE(b, s, c, f) _win_fwrite(b, s, c, f) | 539 | #define GN_FWRITE(b, s, c, f) _win_fwrite(b, s, c, f) |
538 | #define SYMLINK(a, b) _win_symlink(a, b) | 540 | #define SYMLINK(a, b) _win_symlink(a, b) |
539 | #define MMAP(s, l, p, f, d, o) _win_mmap(s, l, p, f, d, o) | 541 | #define MMAP(s, l, p, f, d, o) _win_mmap(s, l, p, f, d, o) |
540 | #define MUNMAP(s, l) _win_munmap(s, l) | 542 | #define MUNMAP(s, l) _win_munmap(s, l) |
541 | #define STRERROR(i) _win_strerror(i) | 543 | #define STRERROR(i) _win_strerror(i) |
542 | #define READLINK(p, b, s) _win_readlink(p, b, s) | 544 | #define READLINK(p, b, s) _win_readlink(p, b, s) |
543 | #define LSTAT(p, b) _win_lstat(p, b) | 545 | #define LSTAT(p, b) _win_lstat(p, b) |
544 | #define LSTAT64(p, b) _win_lstat64(p, b) | 546 | #define LSTAT64(p, b) _win_lstat64(p, b) |
545 | #define PRINTF(f, ...) _win_printf(f , __VA_ARGS__) | 547 | #define PRINTF(f, ...) _win_printf(f , __VA_ARGS__) |
546 | #define FPRINTF(fil, fmt, ...) _win_fprintf(fil, fmt, __VA_ARGS__) | 548 | #define FPRINTF(fil, fmt, ...) _win_fprintf(fil, fmt, __VA_ARGS__) |
547 | #define VPRINTF(f, a) _win_vprintf(f, a) | 549 | #define VPRINTF(f, a) _win_vprintf(f, a) |
548 | #define VFPRINTF(s, f, a) _win_vfprintf(s, f, a) | 550 | #define VFPRINTF(s, f, a) _win_vfprintf(s, f, a) |
549 | #define VSPRINTF(d, f, a) _win_vsprintf(d, f, a) | 551 | #define VSPRINTF(d, f, a) _win_vsprintf(d, f, a) |
550 | #define VSNPRINTF(str, size, fmt, a) _win_vsnprintf(str, size, fmt, a) | 552 | #define VSNPRINTF(str, size, fmt, a) _win_vsnprintf(str, size, fmt, a) |
551 | #define _REAL_SNPRINTF(str, size, fmt, ...) _win_snprintf(str, size, fmt, __VA_ARGS__) | 553 | #define _REAL_SNPRINTF(str, size, fmt, ...) _win_snprintf(str, size, fmt, __VA_ARGS__) |
552 | #define SPRINTF(d, f, ...) _win_sprintf(d, f, __VA_ARGS__) | 554 | #define SPRINTF(d, f, ...) _win_sprintf(d, f, __VA_ARGS__) |
553 | #define VSSCANF(s, f, a) _win_vsscanf(s, f, a) | 555 | #define VSSCANF(s, f, a) _win_vsscanf(s, f, a) |
554 | #define SSCANF(s, f, ...) _win_sscanf(s, f, __VA_ARGS__) | 556 | #define SSCANF(s, f, ...) _win_sscanf(s, f, __VA_ARGS__) |
555 | #define VFSCANF(s, f, a) _win_vfscanf(s, f, a) | 557 | #define VFSCANF(s, f, a) _win_vfscanf(s, f, a) |
556 | #define VSCANF(f, a) _win_vscanf(f, a) | 558 | #define VSCANF(f, a) _win_vscanf(f, a) |
557 | #define SCANF(f, ...) _win_scanf(f, __VA_ARGS__) | 559 | #define SCANF(f, ...) _win_scanf(f, __VA_ARGS__) |
558 | #define FSCANF(s, f, ...) _win_fscanf(s, f, __VA_ARGS__) | 560 | #define FSCANF(s, f, ...) _win_fscanf(s, f, __VA_ARGS__) |
559 | #define WAITPID(p, s, o) _win_waitpid(p, s, o) | 561 | #define WAITPID(p, s, o) _win_waitpid(p, s, o) |
560 | #define ACCEPT(s, a, l) _win_accept(s, a, l) | 562 | #define ACCEPT(s, a, l) _win_accept(s, a, l) |
561 | #define BIND(s, n, l) _win_bind(s, n, l) | 563 | #define BIND(s, n, l) _win_bind(s, n, l) |
562 | #define CONNECT(s, n, l) _win_connect(s, n, l) | 564 | #define CONNECT(s, n, l) _win_connect(s, n, l) |
563 | #define GETPEERNAME(s, n, l) _win_getpeername(s, n, l) | 565 | #define GETPEERNAME(s, n, l) _win_getpeername(s, n, l) |
564 | #define GETSOCKNAME(s, n, l) _win_getsockname(s, n, l) | 566 | #define GETSOCKNAME(s, n, l) _win_getsockname(s, n, l) |
565 | #define GETSOCKOPT(s, l, o, v, p) _win_getsockopt(s, l, o, v, p) | 567 | #define GETSOCKOPT(s, l, o, v, p) _win_getsockopt(s, l, o, v, p) |
566 | #define LISTEN(s, b) _win_listen(s, b) | 568 | #define LISTEN(s, b) _win_listen(s, b) |
567 | #define RECV(s, b, l, f) _win_recv(s, b, l, f) | 569 | #define RECV(s, b, l, f) _win_recv(s, b, l, f) |
568 | #define RECVFROM(s, b, l, f, r, o) _win_recvfrom(s, b, l, f, r, o) | 570 | #define RECVFROM(s, b, l, f, r, o) _win_recvfrom(s, b, l, f, r, o) |
569 | #define SELECT(n, r, w, e, t) _win_select(n, r, w, e, t) | 571 | #define SELECT(n, r, w, e, t) _win_select(n, r, w, e, t) |
570 | #define SEND(s, b, l, f) _win_send(s, b, l, f) | 572 | #define SEND(s, b, l, f) _win_send(s, b, l, f) |
571 | #define SENDTO(s, b, l, f, o, n) _win_sendto(s, b, l, f, o, n) | 573 | #define SENDTO(s, b, l, f, o, n) _win_sendto(s, b, l, f, o, n) |
572 | #define SETSOCKOPT(s, l, o, v, n) _win_setsockopt(s, l, o, v, n) | 574 | #define SETSOCKOPT(s, l, o, v, n) _win_setsockopt(s, l, o, v, n) |
573 | #define SHUTDOWN(s, h) _win_shutdown(s, h) | 575 | #define SHUTDOWN(s, h) _win_shutdown(s, h) |
574 | #define SOCKET(a, t, p) _win_socket(a, t, p) | 576 | #define SOCKET(a, t, p) _win_socket(a, t, p) |
575 | #define GETHOSTBYADDR(a, l, t) _win_gethostbyname(a, l, t) | 577 | #define GETHOSTBYADDR(a, l, t) _win_gethostbyname(a, l, t) |
576 | #define GETHOSTBYNAME(n) _win_gethostbyname(n) | 578 | #define GETHOSTBYNAME(n) _win_gethostbyname(n) |
577 | #endif | 579 | #endif |
578 | 580 | ||
579 | 581 | ||
@@ -582,6 +584,6 @@ size_t strnlen (const char *str, size_t maxlen); | |||
582 | #endif | 584 | #endif |
583 | 585 | ||
584 | 586 | ||
585 | #endif //_PLIBC_H_ | 587 | #endif //_PLIBC_H_ |
586 | 588 | ||
587 | /* end of plibc.h */ | 589 | /* end of plibc.h */ |
diff --git a/src/daemon/response.c b/src/daemon/response.c index 0326a15b..412bf2ea 100644 --- a/src/daemon/response.c +++ b/src/daemon/response.c | |||
@@ -34,26 +34,25 @@ | |||
34 | * @return MHD_NO on error (i.e. invalid header or content format). | 34 | * @return MHD_NO on error (i.e. invalid header or content format). |
35 | */ | 35 | */ |
36 | int | 36 | int |
37 | MHD_add_response_header(struct MHD_Response * response, | 37 | MHD_add_response_header (struct MHD_Response *response, |
38 | const char * header, | 38 | const char *header, const char *content) |
39 | const char * content) { | 39 | { |
40 | struct MHD_HTTP_Header * hdr; | 40 | struct MHD_HTTP_Header *hdr; |
41 | 41 | ||
42 | if ( (response == NULL) || | 42 | if ((response == NULL) || |
43 | (header == NULL) || | 43 | (header == NULL) || |
44 | (content == NULL) || | 44 | (content == NULL) || |
45 | (strlen(header) == 0) || | 45 | (strlen (header) == 0) || |
46 | (strlen(content) == 0) || | 46 | (strlen (content) == 0) || |
47 | (NULL != strstr(header, "\t")) || | 47 | (NULL != strstr (header, "\t")) || |
48 | (NULL != strstr(header, "\r")) || | 48 | (NULL != strstr (header, "\r")) || |
49 | (NULL != strstr(header, "\n")) || | 49 | (NULL != strstr (header, "\n")) || |
50 | (NULL != strstr(content, "\t")) || | 50 | (NULL != strstr (content, "\t")) || |
51 | (NULL != strstr(content, "\r")) || | 51 | (NULL != strstr (content, "\r")) || (NULL != strstr (content, "\n"))) |
52 | (NULL != strstr(content, "\n")) ) | ||
53 | return MHD_NO; | 52 | return MHD_NO; |
54 | hdr = malloc(sizeof(struct MHD_HTTP_Header)); | 53 | hdr = malloc (sizeof (struct MHD_HTTP_Header)); |
55 | hdr->header = strdup(header); | 54 | hdr->header = strdup (header); |
56 | hdr->value = strdup(content); | 55 | hdr->value = strdup (content); |
57 | hdr->kind = MHD_HEADER_KIND; | 56 | hdr->kind = MHD_HEADER_KIND; |
58 | hdr->next = response->first_header; | 57 | hdr->next = response->first_header; |
59 | response->first_header = hdr; | 58 | response->first_header = hdr; |
@@ -66,32 +65,33 @@ MHD_add_response_header(struct MHD_Response * response, | |||
66 | * @return MHD_NO on error (no such header known) | 65 | * @return MHD_NO on error (no such header known) |
67 | */ | 66 | */ |
68 | int | 67 | int |
69 | MHD_del_response_header(struct MHD_Response * response, | 68 | MHD_del_response_header (struct MHD_Response *response, |
70 | const char * header, | 69 | const char *header, const char *content) |
71 | const char * content) { | 70 | { |
72 | struct MHD_HTTP_Header * pos; | 71 | struct MHD_HTTP_Header *pos; |
73 | struct MHD_HTTP_Header * prev; | 72 | struct MHD_HTTP_Header *prev; |
74 | 73 | ||
75 | if ( (header == NULL) || | 74 | if ((header == NULL) || (content == NULL)) |
76 | (content == NULL) ) | ||
77 | return MHD_NO; | 75 | return MHD_NO; |
78 | prev = NULL; | 76 | prev = NULL; |
79 | pos = response->first_header; | 77 | pos = response->first_header; |
80 | while (pos != NULL) { | 78 | while (pos != NULL) |
81 | if ( (0 == strcmp(header, pos->header)) && | 79 | { |
82 | (0 == strcmp(content, pos->value)) ) { | 80 | if ((0 == strcmp (header, pos->header)) && |
83 | free(pos->header); | 81 | (0 == strcmp (content, pos->value))) |
84 | free(pos->value); | 82 | { |
85 | if (prev == NULL) | 83 | free (pos->header); |
86 | response->first_header = pos->next; | 84 | free (pos->value); |
87 | else | 85 | if (prev == NULL) |
88 | prev->next = pos->next; | 86 | response->first_header = pos->next; |
89 | free(pos); | 87 | else |
90 | return MHD_YES; | 88 | prev->next = pos->next; |
89 | free (pos); | ||
90 | return MHD_YES; | ||
91 | } | ||
92 | prev = pos; | ||
93 | pos = pos->next; | ||
91 | } | 94 | } |
92 | prev = pos; | ||
93 | pos = pos->next; | ||
94 | } | ||
95 | return MHD_NO; | 95 | return MHD_NO; |
96 | } | 96 | } |
97 | 97 | ||
@@ -104,22 +104,21 @@ MHD_del_response_header(struct MHD_Response * response, | |||
104 | * @return number of entries iterated over | 104 | * @return number of entries iterated over |
105 | */ | 105 | */ |
106 | int | 106 | int |
107 | MHD_get_response_headers(struct MHD_Response * response, | 107 | MHD_get_response_headers (struct MHD_Response *response, |
108 | MHD_KeyValueIterator iterator, | 108 | MHD_KeyValueIterator iterator, void *iterator_cls) |
109 | void * iterator_cls) { | 109 | { |
110 | struct MHD_HTTP_Header * pos; | 110 | struct MHD_HTTP_Header *pos; |
111 | int numHeaders = 0; | 111 | int numHeaders = 0; |
112 | pos = response->first_header; | 112 | pos = response->first_header; |
113 | while (pos != NULL) { | 113 | while (pos != NULL) |
114 | numHeaders++; | 114 | { |
115 | if ( (iterator != NULL) && | 115 | numHeaders++; |
116 | (MHD_YES != iterator(iterator_cls, | 116 | if ((iterator != NULL) && |
117 | pos->kind, | 117 | (MHD_YES != iterator (iterator_cls, |
118 | pos->header, | 118 | pos->kind, pos->header, pos->value))) |
119 | pos->value)) ) | 119 | break; |
120 | break; | 120 | pos = pos->next; |
121 | pos = pos->next; | 121 | } |
122 | } | ||
123 | return numHeaders; | 122 | return numHeaders; |
124 | } | 123 | } |
125 | 124 | ||
@@ -131,16 +130,16 @@ MHD_get_response_headers(struct MHD_Response * response, | |||
131 | * @return NULL if header does not exist | 130 | * @return NULL if header does not exist |
132 | */ | 131 | */ |
133 | const char * | 132 | const char * |
134 | MHD_get_response_header(struct MHD_Response * response, | 133 | MHD_get_response_header (struct MHD_Response *response, const char *key) |
135 | const char * key) { | 134 | { |
136 | struct MHD_HTTP_Header * pos; | 135 | struct MHD_HTTP_Header *pos; |
137 | pos = response->first_header; | 136 | pos = response->first_header; |
138 | while (pos != NULL) { | 137 | while (pos != NULL) |
139 | if (0 == strcmp(key, | 138 | { |
140 | pos->header)) | 139 | if (0 == strcmp (key, pos->header)) |
141 | return pos->value; | 140 | return pos->value; |
142 | pos = pos->next; | 141 | pos = pos->next; |
143 | } | 142 | } |
144 | return NULL; | 143 | return NULL; |
145 | } | 144 | } |
146 | 145 | ||
@@ -156,29 +155,30 @@ MHD_get_response_header(struct MHD_Response * response, | |||
156 | * @return NULL on error (i.e. invalid arguments, out of memory) | 155 | * @return NULL on error (i.e. invalid arguments, out of memory) |
157 | */ | 156 | */ |
158 | struct MHD_Response * | 157 | struct MHD_Response * |
159 | MHD_create_response_from_callback(size_t size, | 158 | MHD_create_response_from_callback (size_t size, |
160 | MHD_ContentReaderCallback crc, | 159 | MHD_ContentReaderCallback crc, |
161 | void * crc_cls, | 160 | void *crc_cls, |
162 | MHD_ContentReaderFreeCallback crfc) { | 161 | MHD_ContentReaderFreeCallback crfc) |
163 | struct MHD_Response * retVal; | 162 | { |
163 | struct MHD_Response *retVal; | ||
164 | 164 | ||
165 | if (crc == NULL) | 165 | if (crc == NULL) |
166 | return NULL; | 166 | return NULL; |
167 | retVal = malloc(sizeof(struct MHD_Response)); | 167 | retVal = malloc (sizeof (struct MHD_Response)); |
168 | memset(retVal, | 168 | memset (retVal, 0, sizeof (struct MHD_Response)); |
169 | 0, | 169 | retVal->data = malloc (MHD_BUF_INC_SIZE); |
170 | sizeof(struct MHD_Response)); | 170 | if (retVal->data == NULL) |
171 | retVal->data = malloc(MHD_BUF_INC_SIZE); | 171 | { |
172 | if (retVal->data == NULL) { | 172 | free (retVal); |
173 | free(retVal); | 173 | return NULL; |
174 | return NULL; | 174 | } |
175 | } | ||
176 | retVal->data_buffer_size = MHD_BUF_INC_SIZE; | 175 | retVal->data_buffer_size = MHD_BUF_INC_SIZE; |
177 | if (pthread_mutex_init(&retVal->mutex, NULL) != 0) { | 176 | if (pthread_mutex_init (&retVal->mutex, NULL) != 0) |
178 | free(retVal->data); | 177 | { |
179 | free(retVal); | 178 | free (retVal->data); |
180 | return NULL; | 179 | free (retVal); |
181 | } | 180 | return NULL; |
181 | } | ||
182 | retVal->crc = crc; | 182 | retVal->crc = crc; |
183 | retVal->crfc = crfc; | 183 | retVal->crfc = crfc; |
184 | retVal->crc_cls = crc_cls; | 184 | retVal->crc_cls = crc_cls; |
@@ -200,33 +200,28 @@ MHD_create_response_from_callback(size_t size, | |||
200 | * @return NULL on error (i.e. invalid arguments, out of memory) | 200 | * @return NULL on error (i.e. invalid arguments, out of memory) |
201 | */ | 201 | */ |
202 | struct MHD_Response * | 202 | struct MHD_Response * |
203 | MHD_create_response_from_data(size_t size, | 203 | MHD_create_response_from_data (size_t size, |
204 | void * data, | 204 | void *data, int must_free, int must_copy) |
205 | int must_free, | 205 | { |
206 | int must_copy) { | 206 | struct MHD_Response *retVal; |
207 | struct MHD_Response * retVal; | 207 | void *tmp; |
208 | void * tmp; | ||
209 | 208 | ||
210 | if ( (data == NULL) && | 209 | if ((data == NULL) && (size > 0)) |
211 | (size > 0) ) | ||
212 | return NULL; | 210 | return NULL; |
213 | retVal = malloc(sizeof(struct MHD_Response)); | 211 | retVal = malloc (sizeof (struct MHD_Response)); |
214 | memset(retVal, | 212 | memset (retVal, 0, sizeof (struct MHD_Response)); |
215 | 0, | 213 | if (pthread_mutex_init (&retVal->mutex, NULL) != 0) |
216 | sizeof(struct MHD_Response)); | 214 | { |
217 | if (pthread_mutex_init(&retVal->mutex, NULL) != 0) { | 215 | free (retVal); |
218 | free(retVal); | 216 | return NULL; |
219 | return NULL; | 217 | } |
220 | } | 218 | if ((must_copy) && (size > 0)) |
221 | if ( (must_copy) && | 219 | { |
222 | (size > 0) ) { | 220 | tmp = malloc (size); |
223 | tmp = malloc(size); | 221 | memcpy (tmp, data, size); |
224 | memcpy(tmp, | 222 | must_free = 1; |
225 | data, | 223 | data = tmp; |
226 | size); | 224 | } |
227 | must_free = 1; | ||
228 | data = tmp; | ||
229 | } | ||
230 | retVal->crc = NULL; | 225 | retVal->crc = NULL; |
231 | retVal->crfc = must_free ? &free : NULL; | 226 | retVal->crfc = must_free ? &free : NULL; |
232 | retVal->crc_cls = must_free ? data : NULL; | 227 | retVal->crc_cls = must_free ? data : NULL; |
@@ -244,38 +239,42 @@ MHD_create_response_from_data(size_t size, | |||
244 | * necessarily be freed immediatley. | 239 | * necessarily be freed immediatley. |
245 | */ | 240 | */ |
246 | void | 241 | void |
247 | MHD_destroy_response(struct MHD_Response * response) { | 242 | MHD_destroy_response (struct MHD_Response *response) |
248 | struct MHD_HTTP_Header * pos; | 243 | { |
244 | struct MHD_HTTP_Header *pos; | ||
249 | 245 | ||
250 | if (response == NULL) | 246 | if (response == NULL) |
251 | return; | ||
252 | pthread_mutex_lock(&response->mutex); | ||
253 | if (0 != --response->reference_count) { | ||
254 | pthread_mutex_unlock(&response->mutex); | ||
255 | return; | 247 | return; |
256 | } | 248 | pthread_mutex_lock (&response->mutex); |
257 | pthread_mutex_unlock(&response->mutex); | 249 | if (0 != --response->reference_count) |
258 | pthread_mutex_destroy(&response->mutex); | 250 | { |
251 | pthread_mutex_unlock (&response->mutex); | ||
252 | return; | ||
253 | } | ||
254 | pthread_mutex_unlock (&response->mutex); | ||
255 | pthread_mutex_destroy (&response->mutex); | ||
259 | if (response->crfc != NULL) | 256 | if (response->crfc != NULL) |
260 | response->crfc(response->crc_cls); | 257 | response->crfc (response->crc_cls); |
261 | while (response->first_header != NULL) { | 258 | while (response->first_header != NULL) |
262 | pos = response->first_header; | 259 | { |
263 | response->first_header = pos->next; | 260 | pos = response->first_header; |
264 | free(pos->header); | 261 | response->first_header = pos->next; |
265 | free(pos->value); | 262 | free (pos->header); |
266 | free(pos); | 263 | free (pos->value); |
267 | } | 264 | free (pos); |
268 | if (response->crc != NULL) | 265 | } |
269 | free(response->data); | 266 | if (response->crc != NULL) |
270 | free(response); | 267 | free (response->data); |
268 | free (response); | ||
271 | } | 269 | } |
272 | 270 | ||
273 | 271 | ||
274 | void | 272 | void |
275 | MHD_increment_response_rc(struct MHD_Response * response) { | 273 | MHD_increment_response_rc (struct MHD_Response *response) |
276 | pthread_mutex_lock(&response->mutex); | 274 | { |
275 | pthread_mutex_lock (&response->mutex); | ||
277 | response->reference_count++; | 276 | response->reference_count++; |
278 | pthread_mutex_unlock(&response->mutex); | 277 | pthread_mutex_unlock (&response->mutex); |
279 | } | 278 | } |
280 | 279 | ||
281 | 280 | ||
diff --git a/src/daemon/response.h b/src/daemon/response.h index ab582f00..a31ba30f 100644 --- a/src/daemon/response.h +++ b/src/daemon/response.h | |||
@@ -32,7 +32,7 @@ | |||
32 | * Increment response RC. Should this be part of the | 32 | * Increment response RC. Should this be part of the |
33 | * public API? | 33 | * public API? |
34 | */ | 34 | */ |
35 | void MHD_increment_response_rc(struct MHD_Response * response); | 35 | void MHD_increment_response_rc (struct MHD_Response *response); |
36 | 36 | ||
37 | 37 | ||
38 | #endif | 38 | #endif |
diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h index e678d4b1..eb96e807 100644 --- a/src/include/microhttpd.h +++ b/src/include/microhttpd.h | |||
@@ -52,8 +52,9 @@ | |||
52 | #endif | 52 | #endif |
53 | 53 | ||
54 | #ifdef __cplusplus | 54 | #ifdef __cplusplus |
55 | extern "C" { | 55 | extern "C" |
56 | #if 0 /* keep Emacsens' auto-indent happy */ | 56 | { |
57 | #if 0 /* keep Emacsens' auto-indent happy */ | ||
57 | } | 58 | } |
58 | #endif | 59 | #endif |
59 | #endif | 60 | #endif |
@@ -216,7 +217,8 @@ extern "C" { | |||
216 | * implemented or not supported on the target platform (i.e. no | 217 | * implemented or not supported on the target platform (i.e. no |
217 | * support for SSL, threads or IPv6). | 218 | * support for SSL, threads or IPv6). |
218 | */ | 219 | */ |
219 | enum MHD_FLAG { | 220 | enum MHD_FLAG |
221 | { | ||
220 | /** | 222 | /** |
221 | * No options selected. | 223 | * No options selected. |
222 | */ | 224 | */ |
@@ -256,7 +258,8 @@ enum MHD_FLAG { | |||
256 | * MHD options. Passed in the varargs portion | 258 | * MHD options. Passed in the varargs portion |
257 | * of MHD_start_daemon. | 259 | * of MHD_start_daemon. |
258 | */ | 260 | */ |
259 | enum MHD_OPTION { | 261 | enum MHD_OPTION |
262 | { | ||
260 | 263 | ||
261 | /** | 264 | /** |
262 | * No more options / last option. This is used | 265 | * No more options / last option. This is used |
@@ -282,7 +285,8 @@ enum MHD_OPTION { | |||
282 | * The MHD_ValueKind specifies the source of | 285 | * The MHD_ValueKind specifies the source of |
283 | * the key-value pairs in the HTTP protocol. | 286 | * the key-value pairs in the HTTP protocol. |
284 | */ | 287 | */ |
285 | enum MHD_ValueKind { | 288 | enum MHD_ValueKind |
289 | { | ||
286 | 290 | ||
287 | /** | 291 | /** |
288 | * Response header | 292 | * Response header |
@@ -344,9 +348,9 @@ struct MHD_Response; | |||
344 | * @return MHD_YES if connection is allowed, MHD_NO if not | 348 | * @return MHD_YES if connection is allowed, MHD_NO if not |
345 | */ | 349 | */ |
346 | typedef int | 350 | typedef int |
347 | (*MHD_AcceptPolicyCallback)(void * cls, | 351 | (*MHD_AcceptPolicyCallback) (void *cls, |
348 | const struct sockaddr * addr, | 352 | const struct sockaddr * addr, |
349 | socklen_t addrlen); | 353 | socklen_t addrlen); |
350 | 354 | ||
351 | /** | 355 | /** |
352 | * A client has requested the given url using the given method ("GET", | 356 | * A client has requested the given url using the given method ("GET", |
@@ -372,13 +376,13 @@ typedef int | |||
372 | * error while handling the request | 376 | * error while handling the request |
373 | */ | 377 | */ |
374 | typedef int | 378 | typedef int |
375 | (*MHD_AccessHandlerCallback)(void * cls, | 379 | (*MHD_AccessHandlerCallback) (void *cls, |
376 | struct MHD_Connection * connection, | 380 | struct MHD_Connection * connection, |
377 | const char * url, | 381 | const char *url, |
378 | const char * method, | 382 | const char *method, |
379 | const char * version, | 383 | const char *version, |
380 | const char * upload_data, | 384 | const char *upload_data, |
381 | unsigned int * upload_data_size); | 385 | unsigned int *upload_data_size); |
382 | 386 | ||
383 | /** | 387 | /** |
384 | * Iterator over key-value pairs. This iterator | 388 | * Iterator over key-value pairs. This iterator |
@@ -391,10 +395,9 @@ typedef int | |||
391 | * MHD_NO to abort the iteration | 395 | * MHD_NO to abort the iteration |
392 | */ | 396 | */ |
393 | typedef int | 397 | typedef int |
394 | (*MHD_KeyValueIterator)(void * cls, | 398 | (*MHD_KeyValueIterator) (void *cls, |
395 | enum MHD_ValueKind kind, | 399 | enum MHD_ValueKind kind, |
396 | const char * key, | 400 | const char *key, const char *value); |
397 | const char * value); | ||
398 | 401 | ||
399 | /** | 402 | /** |
400 | * Callback used by libmicrohttpd in order to obtain content. The | 403 | * Callback used by libmicrohttpd in order to obtain content. The |
@@ -423,10 +426,7 @@ typedef int | |||
423 | * with the client). | 426 | * with the client). |
424 | */ | 427 | */ |
425 | typedef int | 428 | typedef int |
426 | (*MHD_ContentReaderCallback)(void * cls, | 429 | (*MHD_ContentReaderCallback) (void *cls, size_t pos, char *buf, int max); |
427 | size_t pos, | ||
428 | char * buf, | ||
429 | int max); | ||
430 | 430 | ||
431 | /** | 431 | /** |
432 | * This method is called by libmicrohttpd if we | 432 | * This method is called by libmicrohttpd if we |
@@ -434,8 +434,7 @@ typedef int | |||
434 | * be used to free resources associated with the | 434 | * be used to free resources associated with the |
435 | * content reader. | 435 | * content reader. |
436 | */ | 436 | */ |
437 | typedef void | 437 | typedef void (*MHD_ContentReaderFreeCallback) (void *cls); |
438 | (*MHD_ContentReaderFreeCallback)(void * cls); | ||
439 | 438 | ||
440 | /** | 439 | /** |
441 | * Start a webserver on the given port. | 440 | * Start a webserver on the given port. |
@@ -452,22 +451,19 @@ typedef void | |||
452 | * terminated with MHD_OPTION_END). | 451 | * terminated with MHD_OPTION_END). |
453 | * @return NULL on error, handle to daemon on success | 452 | * @return NULL on error, handle to daemon on success |
454 | */ | 453 | */ |
455 | struct MHD_Daemon * | 454 | struct MHD_Daemon *MHD_start_daemon (unsigned int flags, |
456 | MHD_start_daemon(unsigned int flags, | 455 | unsigned short port, |
457 | unsigned short port, | 456 | MHD_AcceptPolicyCallback apc, |
458 | MHD_AcceptPolicyCallback apc, | 457 | void *apc_cls, |
459 | void * apc_cls, | 458 | MHD_AccessHandlerCallback dh, |
460 | MHD_AccessHandlerCallback dh, | 459 | void *dh_cls, ...); |
461 | void * dh_cls, | ||
462 | ...); | ||
463 | 460 | ||
464 | 461 | ||
465 | 462 | ||
466 | /** | 463 | /** |
467 | * Shutdown an http daemon. | 464 | * Shutdown an http daemon. |
468 | */ | 465 | */ |
469 | void | 466 | void MHD_stop_daemon (struct MHD_Daemon *daemon); |
470 | MHD_stop_daemon(struct MHD_Daemon * daemon); | ||
471 | 467 | ||
472 | 468 | ||
473 | /** | 469 | /** |
@@ -478,11 +474,9 @@ MHD_stop_daemon(struct MHD_Daemon * daemon); | |||
478 | * options for this call. | 474 | * options for this call. |
479 | */ | 475 | */ |
480 | int | 476 | int |
481 | MHD_get_fdset(struct MHD_Daemon * daemon, | 477 | MHD_get_fdset (struct MHD_Daemon *daemon, |
482 | fd_set * read_fd_set, | 478 | fd_set * read_fd_set, |
483 | fd_set * write_fd_set, | 479 | fd_set * write_fd_set, fd_set * except_fd_set, int *max_fd); |
484 | fd_set * except_fd_set, | ||
485 | int * max_fd); | ||
486 | 480 | ||
487 | /** | 481 | /** |
488 | * Run webserver operations (without blocking unless | 482 | * Run webserver operations (without blocking unless |
@@ -494,8 +488,7 @@ MHD_get_fdset(struct MHD_Daemon * daemon, | |||
494 | * daemon was not started with the right | 488 | * daemon was not started with the right |
495 | * options for this call. | 489 | * options for this call. |
496 | */ | 490 | */ |
497 | int | 491 | int MHD_run (struct MHD_Daemon *daemon); |
498 | MHD_run(struct MHD_Daemon * daemon); | ||
499 | 492 | ||
500 | 493 | ||
501 | /** | 494 | /** |
@@ -506,10 +499,9 @@ MHD_run(struct MHD_Daemon * daemon); | |||
506 | * already exists | 499 | * already exists |
507 | */ | 500 | */ |
508 | int | 501 | int |
509 | MHD_register_handler(struct MHD_Daemon * daemon, | 502 | MHD_register_handler (struct MHD_Daemon *daemon, |
510 | const char * uri_prefix, | 503 | const char *uri_prefix, |
511 | MHD_AccessHandlerCallback dh, | 504 | MHD_AccessHandlerCallback dh, void *dh_cls); |
512 | void * dh_cls); | ||
513 | 505 | ||
514 | /** | 506 | /** |
515 | * Unregister an access handler for the URIs beginning with | 507 | * Unregister an access handler for the URIs beginning with |
@@ -520,10 +512,9 @@ MHD_register_handler(struct MHD_Daemon * daemon, | |||
520 | * is not known for this daemon | 512 | * is not known for this daemon |
521 | */ | 513 | */ |
522 | int | 514 | int |
523 | MHD_unregister_handler(struct MHD_Daemon * daemon, | 515 | MHD_unregister_handler (struct MHD_Daemon *daemon, |
524 | const char * uri_prefix, | 516 | const char *uri_prefix, |
525 | MHD_AccessHandlerCallback dh, | 517 | MHD_AccessHandlerCallback dh, void *dh_cls); |
526 | void * dh_cls); | ||
527 | 518 | ||
528 | /** | 519 | /** |
529 | * Get all of the headers from the request. | 520 | * Get all of the headers from the request. |
@@ -534,10 +525,9 @@ MHD_unregister_handler(struct MHD_Daemon * daemon, | |||
534 | * @return number of entries iterated over | 525 | * @return number of entries iterated over |
535 | */ | 526 | */ |
536 | int | 527 | int |
537 | MHD_get_connection_values(struct MHD_Connection * connection, | 528 | MHD_get_connection_values (struct MHD_Connection *connection, |
538 | enum MHD_ValueKind kind, | 529 | enum MHD_ValueKind kind, |
539 | MHD_KeyValueIterator iterator, | 530 | MHD_KeyValueIterator iterator, void *iterator_cls); |
540 | void * iterator_cls); | ||
541 | 531 | ||
542 | /** | 532 | /** |
543 | * Get a particular header value. If multiple | 533 | * Get a particular header value. If multiple |
@@ -546,10 +536,9 @@ MHD_get_connection_values(struct MHD_Connection * connection, | |||
546 | * @param key the header to look for | 536 | * @param key the header to look for |
547 | * @return NULL if no such item was found | 537 | * @return NULL if no such item was found |
548 | */ | 538 | */ |
549 | const char * | 539 | const char *MHD_lookup_connection_value (struct MHD_Connection *connection, |
550 | MHD_lookup_connection_value(struct MHD_Connection * connection, | 540 | enum MHD_ValueKind kind, |
551 | enum MHD_ValueKind kind, | 541 | const char *key); |
552 | const char * key); | ||
553 | 542 | ||
554 | /** | 543 | /** |
555 | * Queue a response to be transmitted to the client (as soon as | 544 | * Queue a response to be transmitted to the client (as soon as |
@@ -562,11 +551,10 @@ MHD_lookup_connection_value(struct MHD_Connection * connection, | |||
562 | * MHD_YES on success or if message has been queued | 551 | * MHD_YES on success or if message has been queued |
563 | */ | 552 | */ |
564 | int | 553 | int |
565 | MHD_queue_response(struct MHD_Connection * connection, | 554 | MHD_queue_response (struct MHD_Connection *connection, |
566 | unsigned int status_code, | 555 | unsigned int status_code, struct MHD_Response *response); |
567 | struct MHD_Response * response); | 556 | |
568 | 557 | ||
569 | |||
570 | /** | 558 | /** |
571 | * Create a response object. The response object can be extended with | 559 | * Create a response object. The response object can be extended with |
572 | * header information and then be used any number of times. | 560 | * header information and then be used any number of times. |
@@ -577,11 +565,11 @@ MHD_queue_response(struct MHD_Connection * connection, | |||
577 | * @param crfc callback to call to free crc_cls resources | 565 | * @param crfc callback to call to free crc_cls resources |
578 | * @return NULL on error (i.e. invalid arguments, out of memory) | 566 | * @return NULL on error (i.e. invalid arguments, out of memory) |
579 | */ | 567 | */ |
580 | struct MHD_Response * | 568 | struct MHD_Response *MHD_create_response_from_callback (size_t size, |
581 | MHD_create_response_from_callback(size_t size, | 569 | MHD_ContentReaderCallback |
582 | MHD_ContentReaderCallback crc, | 570 | crc, void *crc_cls, |
583 | void * crc_cls, | 571 | MHD_ContentReaderFreeCallback |
584 | MHD_ContentReaderFreeCallback crfc); | 572 | crfc); |
585 | 573 | ||
586 | /** | 574 | /** |
587 | * Create a response object. The response object can be extended with | 575 | * Create a response object. The response object can be extended with |
@@ -595,11 +583,10 @@ MHD_create_response_from_callback(size_t size, | |||
595 | * this call returns | 583 | * this call returns |
596 | * @return NULL on error (i.e. invalid arguments, out of memory) | 584 | * @return NULL on error (i.e. invalid arguments, out of memory) |
597 | */ | 585 | */ |
598 | struct MHD_Response * | 586 | struct MHD_Response *MHD_create_response_from_data (size_t size, |
599 | MHD_create_response_from_data(size_t size, | 587 | void *data, |
600 | void * data, | 588 | int must_free, |
601 | int must_free, | 589 | int must_copy); |
602 | int must_copy); | ||
603 | 590 | ||
604 | /** | 591 | /** |
605 | * Destroy a response object and associated resources. Note that | 592 | * Destroy a response object and associated resources. Note that |
@@ -607,8 +594,7 @@ MHD_create_response_from_data(size_t size, | |||
607 | * is still in the queue for some clients, so the memory may not | 594 | * is still in the queue for some clients, so the memory may not |
608 | * necessarily be freed immediatley. | 595 | * necessarily be freed immediatley. |
609 | */ | 596 | */ |
610 | void | 597 | void MHD_destroy_response (struct MHD_Response *response); |
611 | MHD_destroy_response(struct MHD_Response * response); | ||
612 | 598 | ||
613 | /** | 599 | /** |
614 | * Add a header line to the response. | 600 | * Add a header line to the response. |
@@ -616,9 +602,8 @@ MHD_destroy_response(struct MHD_Response * response); | |||
616 | * @return MHD_NO on error (i.e. invalid header or content format). | 602 | * @return MHD_NO on error (i.e. invalid header or content format). |
617 | */ | 603 | */ |
618 | int | 604 | int |
619 | MHD_add_response_header(struct MHD_Response * response, | 605 | MHD_add_response_header (struct MHD_Response *response, |
620 | const char * header, | 606 | const char *header, const char *content); |
621 | const char * content); | ||
622 | 607 | ||
623 | /** | 608 | /** |
624 | * Delete a header line from the response. | 609 | * Delete a header line from the response. |
@@ -626,9 +611,8 @@ MHD_add_response_header(struct MHD_Response * response, | |||
626 | * @return MHD_NO on error (no such header known) | 611 | * @return MHD_NO on error (no such header known) |
627 | */ | 612 | */ |
628 | int | 613 | int |
629 | MHD_del_response_header(struct MHD_Response * response, | 614 | MHD_del_response_header (struct MHD_Response *response, |
630 | const char * header, | 615 | const char *header, const char *content); |
631 | const char * content); | ||
632 | 616 | ||
633 | /** | 617 | /** |
634 | * Get all of the headers added to a response. | 618 | * Get all of the headers added to a response. |
@@ -639,9 +623,8 @@ MHD_del_response_header(struct MHD_Response * response, | |||
639 | * @return number of entries iterated over | 623 | * @return number of entries iterated over |
640 | */ | 624 | */ |
641 | int | 625 | int |
642 | MHD_get_response_headers(struct MHD_Response * response, | 626 | MHD_get_response_headers (struct MHD_Response *response, |
643 | MHD_KeyValueIterator iterator, | 627 | MHD_KeyValueIterator iterator, void *iterator_cls); |
644 | void * iterator_cls); | ||
645 | 628 | ||
646 | 629 | ||
647 | /** | 630 | /** |
@@ -650,12 +633,11 @@ MHD_get_response_headers(struct MHD_Response * response, | |||
650 | * @param key which header to get | 633 | * @param key which header to get |
651 | * @return NULL if header does not exist | 634 | * @return NULL if header does not exist |
652 | */ | 635 | */ |
653 | const char * | 636 | const char *MHD_get_response_header (struct MHD_Response *response, |
654 | MHD_get_response_header(struct MHD_Response * response, | 637 | const char *key); |
655 | const char * key); | ||
656 | 638 | ||
657 | 639 | ||
658 | #if 0 /* keep Emacsens' auto-indent happy */ | 640 | #if 0 /* keep Emacsens' auto-indent happy */ |
659 | { | 641 | { |
660 | #endif | 642 | #endif |
661 | #ifdef __cplusplus | 643 | #ifdef __cplusplus |