aboutsummaryrefslogtreecommitdiff
path: root/src/daemon/connection.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/daemon/connection.c')
-rw-r--r--src/daemon/connection.c69
1 files changed, 50 insertions, 19 deletions
diff --git a/src/daemon/connection.c b/src/daemon/connection.c
index 272fb802..ec261963 100644
--- a/src/daemon/connection.c
+++ b/src/daemon/connection.c
@@ -41,6 +41,12 @@
41#define HTTP_100_CONTINUE "HTTP/1.1 100 Continue\r\n\r\n" 41#define HTTP_100_CONTINUE "HTTP/1.1 100 Continue\r\n\r\n"
42 42
43/** 43/**
44 * Response used when the request (http header) is too big to
45 * be processed.
46 */
47#define REQUEST_TOO_BIG ""
48
49/**
44 * Get all of the headers from the request. 50 * Get all of the headers from the request.
45 * 51 *
46 * @param iterator callback to call on each header; 52 * @param iterator callback to call on each header;
@@ -146,16 +152,14 @@ MHD_connection_get_fdset(struct MHD_Connection * connection,
146 fd = connection->socket_fd; 152 fd = connection->socket_fd;
147 if (fd == -1) 153 if (fd == -1)
148 return MHD_YES; 154 return MHD_YES;
149 if ( (connection->read_close == 0) && 155 if ( (connection->read_close == MHD_NO) &&
150 ( (connection->headersReceived == 0) || 156 ( (connection->headersReceived == 0) ||
151 (connection->readLoc < connection->read_buffer_size) ) ) { 157 (connection->readLoc < connection->read_buffer_size) ) ) {
152 FD_SET(fd, read_fd_set); 158 FD_SET(fd, read_fd_set);
153 if (fd > *max_fd) 159 if (fd > *max_fd)
154 *max_fd = fd; 160 *max_fd = fd;
155 } else { 161 } else {
156 162 if ( (connection->read_close == MHD_NO) &&
157
158 if ( (connection->read_close == 0) &&
159 ( (connection->headersReceived == 1) && 163 ( (connection->headersReceived == 1) &&
160 (connection->post_processed == MHD_NO) && 164 (connection->post_processed == MHD_NO) &&
161 (connection->readLoc == connection->read_buffer_size) ) ) { 165 (connection->readLoc == connection->read_buffer_size) ) ) {
@@ -188,17 +192,32 @@ MHD_connection_get_fdset(struct MHD_Connection * connection,
188 192
189/** 193/**
190 * We ran out of memory processing the 194 * We ran out of memory processing the
191 * header. Handle it properly. 195 * header. Handle it properly by stopping to read data
196 * and sending a HTTP 413 or HTTP 414 response.
197 *
198 * @param status_code the response code to send (413 or 414)
192 */ 199 */
193static void 200static void
194MHD_excessive_header_handler(struct MHD_Connection * connection) { 201MHD_excessive_data_handler(struct MHD_Connection * connection,
202 unsigned int status_code) {
203 struct MHD_Response * response;
204
195 /* die, header far too long to be reasonable; 205 /* die, header far too long to be reasonable;
196 FIXME: send proper response to client 206 FIXME: send proper response to client
197 (stop reading, queue proper response) */ 207 (stop reading, queue proper response) */
208 connection->read_close = MHD_YES;
209 connection->headersReceived = MHD_YES;
210 connection->bodyReceived = MHD_YES;
198 MHD_DLOG(connection->daemon, 211 MHD_DLOG(connection->daemon,
199 "Received excessively long header line, closing connection.\n"); 212 "Received excessively long header, closing connection.\n");
200 CLOSE(connection->socket_fd); 213 response = MHD_create_response_from_data(strlen(REQUEST_TOO_BIG),
201 connection->socket_fd = -1; 214 REQUEST_TOO_BIG,
215 MHD_NO,
216 MHD_NO);
217 MHD_queue_response(connection,
218 status_code,
219 response);
220 MHD_destroy_response(response);
202} 221}
203 222
204/** 223/**
@@ -230,7 +249,10 @@ MHD_get_next_header_line(struct MHD_Connection * connection) {
230 connection->read_buffer_size, 249 connection->read_buffer_size,
231 connection->read_buffer_size * 2 + MHD_BUF_INC_SIZE); 250 connection->read_buffer_size * 2 + MHD_BUF_INC_SIZE);
232 if (rbuf == NULL) { 251 if (rbuf == NULL) {
233 MHD_excessive_header_handler(connection); 252 MHD_excessive_data_handler(connection,
253 (connection->url != NULL)
254 ? MHD_HTTP_REQUEST_ENTITY_TOO_LARGE
255 : MHD_HTTP_REQUEST_URI_TOO_LONG);
234 } else { 256 } else {
235 connection->read_buffer_size = connection->read_buffer_size * 2 + MHD_BUF_INC_SIZE; 257 connection->read_buffer_size = connection->read_buffer_size * 2 + MHD_BUF_INC_SIZE;
236 connection->read_buffer = rbuf; 258 connection->read_buffer = rbuf;
@@ -265,7 +287,8 @@ MHD_connection_add_header(struct MHD_Connection * connection,
265 if (hdr == NULL) { 287 if (hdr == NULL) {
266 MHD_DLOG(connection->daemon, 288 MHD_DLOG(connection->daemon,
267 "Not enough memory to allocate header record!\n"); 289 "Not enough memory to allocate header record!\n");
268 MHD_excessive_header_handler(connection); 290 MHD_excessive_data_handler(connection,
291 MHD_HTTP_REQUEST_ENTITY_TOO_LARGE);
269 return MHD_NO; 292 return MHD_NO;
270 } 293 }
271 hdr->next = connection->headers_received; 294 hdr->next = connection->headers_received;
@@ -360,7 +383,8 @@ MHD_parse_cookie_header(struct MHD_Connection * connection) {
360 if (cpy == NULL) { 383 if (cpy == NULL) {
361 MHD_DLOG(connection->daemon, 384 MHD_DLOG(connection->daemon,
362 "Not enough memory to parse cookies!\n"); 385 "Not enough memory to parse cookies!\n");
363 MHD_excessive_header_handler(connection); 386 MHD_excessive_data_handler(connection,
387 MHD_HTTP_REQUEST_ENTITY_TOO_LARGE);
364 return MHD_NO; 388 return MHD_NO;
365 } 389 }
366 memcpy(cpy, 390 memcpy(cpy,
@@ -483,7 +507,8 @@ MHD_parse_connection_headers(struct MHD_Connection * connection) {
483 strlen(last)+1, 507 strlen(last)+1,
484 strlen(line) + strlen(last) + 1); 508 strlen(line) + strlen(last) + 1);
485 if (last == NULL) { 509 if (last == NULL) {
486 MHD_excessive_header_handler(connection); 510 MHD_excessive_data_handler(connection,
511 MHD_HTTP_REQUEST_ENTITY_TOO_LARGE);
487 break; 512 break;
488 } 513 }
489 tmp = line; 514 tmp = line;
@@ -620,8 +645,10 @@ MHD_test_post_data(struct MHD_Connection * connection) {
620 const char * encoding; 645 const char * encoding;
621 void * buf; 646 void * buf;
622 647
623 if (0 != strcasecmp(connection->method, 648 if ( (connection->method == NULL) ||
624 MHD_HTTP_METHOD_POST)) 649 (connection->response != NULL) ||
650 (0 != strcasecmp(connection->method,
651 MHD_HTTP_METHOD_POST)) )
625 return MHD_NO; 652 return MHD_NO;
626 encoding = MHD_lookup_connection_value(connection, 653 encoding = MHD_lookup_connection_value(connection,
627 MHD_HEADER_KIND, 654 MHD_HEADER_KIND,
@@ -711,6 +738,8 @@ MHD_call_connection_handler(struct MHD_Connection * connection) {
711 struct MHD_Access_Handler * ah; 738 struct MHD_Access_Handler * ah;
712 unsigned int processed; 739 unsigned int processed;
713 740
741 if (connection->response != NULL)
742 return; /* already queued a response */
714 if (connection->headersReceived == 0) 743 if (connection->headersReceived == 0)
715 abort(); /* bad timing... */ 744 abort(); /* bad timing... */
716 ah = MHD_find_access_handler(connection); 745 ah = MHD_find_access_handler(connection);
@@ -778,7 +807,8 @@ MHD_connection_handle_read(struct MHD_Connection * connection) {
778 if (tmp == NULL) { 807 if (tmp == NULL) {
779 MHD_DLOG(connection->daemon, 808 MHD_DLOG(connection->daemon,
780 "Not enough memory for reading headers!\n"); 809 "Not enough memory for reading headers!\n");
781 MHD_excessive_header_handler(connection); 810 MHD_excessive_data_handler(connection,
811 MHD_HTTP_REQUEST_ENTITY_TOO_LARGE);
782 return MHD_NO; 812 return MHD_NO;
783 } 813 }
784 connection->read_buffer = tmp; 814 connection->read_buffer = tmp;
@@ -824,8 +854,9 @@ MHD_connection_handle_read(struct MHD_Connection * connection) {
824 (connection->uploadSize == connection->readLoc) ) 854 (connection->uploadSize == connection->readLoc) )
825 if (MHD_NO == MHD_parse_post_data(connection)) 855 if (MHD_NO == MHD_parse_post_data(connection))
826 connection->post_processed = MHD_NO; 856 connection->post_processed = MHD_NO;
827 if ( (connection->post_processed == MHD_NO) || 857 if ( ( (connection->post_processed == MHD_NO) ||
828 (connection->read_buffer_size == connection->readLoc) ) 858 (connection->read_buffer_size == connection->readLoc) ) &&
859 (connection->method != NULL) )
829 MHD_call_connection_handler(connection); 860 MHD_call_connection_handler(connection);
830 } 861 }
831 return MHD_YES; 862 return MHD_YES;
@@ -1065,7 +1096,7 @@ MHD_connection_handle_write(struct MHD_Connection * connection) {
1065 connection->messagePos = 0; 1096 connection->messagePos = 0;
1066 connection->method = NULL; 1097 connection->method = NULL;
1067 connection->url = NULL; 1098 connection->url = NULL;
1068 if ( (connection->read_close != 0) || 1099 if ( (connection->read_close == MHD_YES) ||
1069 (0 != strcasecmp(MHD_HTTP_VERSION_1_1, 1100 (0 != strcasecmp(MHD_HTTP_VERSION_1_1,
1070 connection->version)) ) { 1101 connection->version)) ) {
1071 /* closed for reading => close for good! */ 1102 /* closed for reading => close for good! */