diff options
Diffstat (limited to 'src/lib')
81 files changed, 6732 insertions, 6555 deletions
diff --git a/src/lib/action_continue.c b/src/lib/action_continue.c index 20c351ad..9d98940b 100644 --- a/src/lib/action_continue.c +++ b/src/lib/action_continue.c | |||
@@ -35,11 +35,11 @@ | |||
35 | */ | 35 | */ |
36 | static enum MHD_StatusCode | 36 | static enum MHD_StatusCode |
37 | cont_action (void *cls, | 37 | cont_action (void *cls, |
38 | struct MHD_Request *request) | 38 | struct MHD_Request *request) |
39 | { | 39 | { |
40 | (void) cls; | 40 | (void) cls; |
41 | (void) request; | 41 | (void) request; |
42 | /* not sure yet, but this function body may | 42 | /* not sure yet, but this function body may |
43 | just legitimately stay empty... */ | 43 | just legitimately stay empty... */ |
44 | return MHD_SC_OK; | 44 | return MHD_SC_OK; |
45 | } | 45 | } |
diff --git a/src/lib/action_from_response.c b/src/lib/action_from_response.c index 43f33cb5..6253fb22 100644 --- a/src/lib/action_from_response.c +++ b/src/lib/action_from_response.c | |||
@@ -36,7 +36,7 @@ | |||
36 | */ | 36 | */ |
37 | static enum MHD_StatusCode | 37 | static enum MHD_StatusCode |
38 | response_action (void *cls, | 38 | response_action (void *cls, |
39 | struct MHD_Request *request) | 39 | struct MHD_Request *request) |
40 | { | 40 | { |
41 | struct MHD_Response *response = cls; | 41 | struct MHD_Response *response = cls; |
42 | struct MHD_Daemon *daemon = request->daemon; | 42 | struct MHD_Daemon *daemon = request->daemon; |
@@ -49,14 +49,15 @@ response_action (void *cls, | |||
49 | #ifdef UPGRADE_SUPPORT | 49 | #ifdef UPGRADE_SUPPORT |
50 | if ( (NULL != response->upgrade_handler) && | 50 | if ( (NULL != response->upgrade_handler) && |
51 | daemon->disallow_upgrade ) | 51 | daemon->disallow_upgrade ) |
52 | { | 52 | { |
53 | #ifdef HAVE_MESSAGES | 53 | #ifdef HAVE_MESSAGES |
54 | MHD_DLOG (daemon, | 54 | MHD_DLOG (daemon, |
55 | MHD_SC_UPGRADE_ON_DAEMON_WITH_UPGRADE_DISALLOWED, | 55 | MHD_SC_UPGRADE_ON_DAEMON_WITH_UPGRADE_DISALLOWED, |
56 | _("Attempted 'upgrade' connection on daemon without MHD_ALLOW_UPGRADE option!\n")); | 56 | _ ( |
57 | "Attempted 'upgrade' connection on daemon without MHD_ALLOW_UPGRADE option!\n")); | ||
57 | #endif | 58 | #endif |
58 | return MHD_SC_UPGRADE_ON_DAEMON_WITH_UPGRADE_DISALLOWED; | 59 | return MHD_SC_UPGRADE_ON_DAEMON_WITH_UPGRADE_DISALLOWED; |
59 | } | 60 | } |
60 | #endif /* UPGRADE_SUPPORT */ | 61 | #endif /* UPGRADE_SUPPORT */ |
61 | request->response = response; | 62 | request->response = response; |
62 | #if defined(_MHD_HAVE_SENDFILE) | 63 | #if defined(_MHD_HAVE_SENDFILE) |
@@ -74,21 +75,21 @@ response_action (void *cls, | |||
74 | (MHD_HTTP_OK > response->status_code) || | 75 | (MHD_HTTP_OK > response->status_code) || |
75 | (MHD_HTTP_NO_CONTENT == response->status_code) || | 76 | (MHD_HTTP_NO_CONTENT == response->status_code) || |
76 | (MHD_HTTP_NOT_MODIFIED == response->status_code) ) | 77 | (MHD_HTTP_NOT_MODIFIED == response->status_code) ) |
77 | { | 78 | { |
78 | /* if this is a "HEAD" request, or a status code for | 79 | /* if this is a "HEAD" request, or a status code for |
79 | which a body is not allowed, pretend that we | 80 | which a body is not allowed, pretend that we |
80 | have already sent the full message body. */ | 81 | have already sent the full message body. */ |
81 | request->response_write_position = response->total_size; | 82 | request->response_write_position = response->total_size; |
82 | } | 83 | } |
83 | if ( (MHD_REQUEST_HEADERS_PROCESSED == request->state) && | 84 | if ( (MHD_REQUEST_HEADERS_PROCESSED == request->state) && |
84 | ( (MHD_METHOD_POST == request->method) || | 85 | ( (MHD_METHOD_POST == request->method) || |
85 | (MHD_METHOD_PUT == request->method) ) ) | 86 | (MHD_METHOD_PUT == request->method) ) ) |
86 | { | 87 | { |
87 | /* response was queued "early", refuse to read body / footers or | 88 | /* response was queued "early", refuse to read body / footers or |
88 | further requests! */ | 89 | further requests! */ |
89 | request->connection->read_closed = true; | 90 | request->connection->read_closed = true; |
90 | request->state = MHD_REQUEST_FOOTERS_RECEIVED; | 91 | request->state = MHD_REQUEST_FOOTERS_RECEIVED; |
91 | } | 92 | } |
92 | if (! request->in_idle) | 93 | if (! request->in_idle) |
93 | (void) MHD_request_handle_idle_ (request); | 94 | (void) MHD_request_handle_idle_ (request); |
94 | return MHD_SC_OK; | 95 | return MHD_SC_OK; |
@@ -114,16 +115,16 @@ response_action (void *cls, | |||
114 | */ | 115 | */ |
115 | _MHD_EXTERN const struct MHD_Action * | 116 | _MHD_EXTERN const struct MHD_Action * |
116 | MHD_action_from_response (struct MHD_Response *response, | 117 | MHD_action_from_response (struct MHD_Response *response, |
117 | enum MHD_Bool destroy_after_use) | 118 | enum MHD_Bool destroy_after_use) |
118 | { | 119 | { |
119 | response->action.action = &response_action; | 120 | response->action.action = &response_action; |
120 | response->action.action_cls = response; | 121 | response->action.action_cls = response; |
121 | if (! destroy_after_use) | 122 | if (! destroy_after_use) |
122 | { | 123 | { |
123 | MHD_mutex_lock_chk_ (&response->mutex); | 124 | MHD_mutex_lock_chk_ (&response->mutex); |
124 | response->reference_count++; | 125 | response->reference_count++; |
125 | MHD_mutex_unlock_chk_ (&response->mutex); | 126 | MHD_mutex_unlock_chk_ (&response->mutex); |
126 | } | 127 | } |
127 | return &response->action; | 128 | return &response->action; |
128 | } | 129 | } |
129 | 130 | ||
diff --git a/src/lib/action_parse_post.c b/src/lib/action_parse_post.c index c60e793d..53757933 100644 --- a/src/lib/action_parse_post.c +++ b/src/lib/action_parse_post.c | |||
@@ -52,8 +52,8 @@ | |||
52 | */ | 52 | */ |
53 | const struct MHD_Action * | 53 | const struct MHD_Action * |
54 | MHD_action_parse_post (size_t buffer_size, | 54 | MHD_action_parse_post (size_t buffer_size, |
55 | MHD_PostDataIterator iter, | 55 | MHD_PostDataIterator iter, |
56 | void *iter_cls) | 56 | void *iter_cls) |
57 | { | 57 | { |
58 | return NULL; /* not yet implemented */ | 58 | return NULL; /* not yet implemented */ |
59 | } | 59 | } |
diff --git a/src/lib/action_process_upload.c b/src/lib/action_process_upload.c index cafd5d3c..0e9722cd 100644 --- a/src/lib/action_process_upload.c +++ b/src/lib/action_process_upload.c | |||
@@ -49,13 +49,13 @@ struct UploadAction | |||
49 | * | 49 | * |
50 | * @param cls the `struct UploadAction` with the | 50 | * @param cls the `struct UploadAction` with the |
51 | * function we are to call for upload data | 51 | * function we are to call for upload data |
52 | * @param request the request for which we are to process | 52 | * @param request the request for which we are to process |
53 | * upload data | 53 | * upload data |
54 | * @return #MHD_SC_OK on success | 54 | * @return #MHD_SC_OK on success |
55 | */ | 55 | */ |
56 | static enum MHD_StatusCode | 56 | static enum MHD_StatusCode |
57 | upload_action (void *cls, | 57 | upload_action (void *cls, |
58 | struct MHD_Request *request) | 58 | struct MHD_Request *request) |
59 | { | 59 | { |
60 | struct UploadAction *ua = cls; | 60 | struct UploadAction *ua = cls; |
61 | 61 | ||
@@ -75,7 +75,7 @@ upload_action (void *cls, | |||
75 | */ | 75 | */ |
76 | const struct MHD_Action * | 76 | const struct MHD_Action * |
77 | MHD_action_process_upload (MHD_UploadCallback uc, | 77 | MHD_action_process_upload (MHD_UploadCallback uc, |
78 | void *uc_cls) | 78 | void *uc_cls) |
79 | { | 79 | { |
80 | struct UploadAction *ua; | 80 | struct UploadAction *ua; |
81 | 81 | ||
@@ -90,5 +90,3 @@ MHD_action_process_upload (MHD_UploadCallback uc, | |||
90 | 90 | ||
91 | 91 | ||
92 | /* end of action_process_upload.c */ | 92 | /* end of action_process_upload.c */ |
93 | |||
94 | |||
diff --git a/src/lib/action_suspend.c b/src/lib/action_suspend.c index bf5adc34..c176e494 100644 --- a/src/lib/action_suspend.c +++ b/src/lib/action_suspend.c | |||
@@ -35,7 +35,7 @@ | |||
35 | */ | 35 | */ |
36 | static enum MHD_StatusCode | 36 | static enum MHD_StatusCode |
37 | suspend_action (void *cls, | 37 | suspend_action (void *cls, |
38 | struct MHD_Request *request) | 38 | struct MHD_Request *request) |
39 | { | 39 | { |
40 | (void) cls; | 40 | (void) cls; |
41 | struct MHD_Connection *connection = request->connection; | 41 | struct MHD_Connection *connection = request->connection; |
@@ -43,24 +43,24 @@ suspend_action (void *cls, | |||
43 | 43 | ||
44 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); | 44 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); |
45 | if (connection->resuming) | 45 | if (connection->resuming) |
46 | { | 46 | { |
47 | /* suspending again while we didn't even complete resuming yet */ | 47 | /* suspending again while we didn't even complete resuming yet */ |
48 | connection->resuming = false; | 48 | connection->resuming = false; |
49 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); | 49 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); |
50 | return MHD_SC_OK; | 50 | return MHD_SC_OK; |
51 | } | 51 | } |
52 | if (daemon->threading_mode != MHD_TM_THREAD_PER_CONNECTION) | 52 | if (daemon->threading_mode != MHD_TM_THREAD_PER_CONNECTION) |
53 | { | 53 | { |
54 | if (connection->connection_timeout == | 54 | if (connection->connection_timeout == |
55 | daemon->connection_default_timeout) | 55 | daemon->connection_default_timeout) |
56 | XDLL_remove (daemon->normal_timeout_head, | 56 | XDLL_remove (daemon->normal_timeout_head, |
57 | daemon->normal_timeout_tail, | 57 | daemon->normal_timeout_tail, |
58 | connection); | 58 | connection); |
59 | else | 59 | else |
60 | XDLL_remove (daemon->manual_timeout_head, | 60 | XDLL_remove (daemon->manual_timeout_head, |
61 | daemon->manual_timeout_tail, | 61 | daemon->manual_timeout_tail, |
62 | connection); | 62 | connection); |
63 | } | 63 | } |
64 | DLL_remove (daemon->connections_head, | 64 | DLL_remove (daemon->connections_head, |
65 | daemon->connections_tail, | 65 | daemon->connections_tail, |
66 | connection); | 66 | connection); |
@@ -71,25 +71,25 @@ suspend_action (void *cls, | |||
71 | connection->suspended = true; | 71 | connection->suspended = true; |
72 | #ifdef EPOLL_SUPPORT | 72 | #ifdef EPOLL_SUPPORT |
73 | if (MHD_ELS_EPOLL == daemon->event_loop_syscall) | 73 | if (MHD_ELS_EPOLL == daemon->event_loop_syscall) |
74 | { | ||
75 | if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) | ||
76 | { | ||
77 | EDLL_remove (daemon->eready_head, | ||
78 | daemon->eready_tail, | ||
79 | connection); | ||
80 | connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL; | ||
81 | } | ||
82 | if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) | ||
74 | { | 83 | { |
75 | if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) | 84 | if (0 != epoll_ctl (daemon->epoll_fd, |
76 | { | 85 | EPOLL_CTL_DEL, |
77 | EDLL_remove (daemon->eready_head, | 86 | connection->socket_fd, |
78 | daemon->eready_tail, | 87 | NULL)) |
79 | connection); | 88 | MHD_PANIC (_ ("Failed to remove FD from epoll set\n")); |
80 | connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL; | 89 | connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET; |
81 | } | ||
82 | if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) | ||
83 | { | ||
84 | if (0 != epoll_ctl (daemon->epoll_fd, | ||
85 | EPOLL_CTL_DEL, | ||
86 | connection->socket_fd, | ||
87 | NULL)) | ||
88 | MHD_PANIC (_("Failed to remove FD from epoll set\n")); | ||
89 | connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET; | ||
90 | } | ||
91 | connection->epoll_state |= MHD_EPOLL_STATE_SUSPENDED; | ||
92 | } | 90 | } |
91 | connection->epoll_state |= MHD_EPOLL_STATE_SUSPENDED; | ||
92 | } | ||
93 | #endif | 93 | #endif |
94 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); | 94 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); |
95 | return MHD_SC_OK; | 95 | return MHD_SC_OK; |
diff --git a/src/lib/base64.c b/src/lib/base64.c index 3dc7a142..d7d1ec92 100644 --- a/src/lib/base64.c +++ b/src/lib/base64.c | |||
@@ -9,45 +9,46 @@ | |||
9 | #include "base64.h" | 9 | #include "base64.h" |
10 | 10 | ||
11 | static const char base64_digits[] = | 11 | static const char base64_digits[] = |
12 | { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 12 | { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
13 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 13 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
14 | 0, 0, 0, 0, 0, 62, 0, 0, 0, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, | 14 | 0, 0, 0, 0, 0, 62, 0, 0, 0, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, |
15 | 0, 0, 0, -1, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, | 15 | 0, 0, 0, -1, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, |
16 | 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0, 0, 26, | 16 | 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0, 0, 26, |
17 | 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, | 17 | 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, |
18 | 45, 46, 47, 48, 49, 50, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 18 | 45, 46, 47, 48, 49, 50, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
19 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 19 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
20 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 20 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
21 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 21 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
22 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 22 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
23 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; | 23 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; |
24 | 24 | ||
25 | 25 | ||
26 | char * | 26 | char * |
27 | BASE64Decode(const char* src) | 27 | BASE64Decode (const char*src) |
28 | { | 28 | { |
29 | size_t in_len = strlen (src); | 29 | size_t in_len = strlen (src); |
30 | char* dest; | 30 | char*dest; |
31 | char* result; | 31 | char*result; |
32 | 32 | ||
33 | if (in_len % 4) | 33 | if (in_len % 4) |
34 | { | 34 | { |
35 | /* Wrong base64 string length */ | 35 | /* Wrong base64 string length */ |
36 | return NULL; | 36 | return NULL; |
37 | } | 37 | } |
38 | result = dest = malloc(in_len / 4 * 3 + 1); | 38 | result = dest = malloc (in_len / 4 * 3 + 1); |
39 | if (NULL == result) | 39 | if (NULL == result) |
40 | return NULL; /* out of memory */ | 40 | return NULL; /* out of memory */ |
41 | while (*src) { | 41 | while (*src) |
42 | char a = base64_digits[(unsigned char)*(src++)]; | 42 | { |
43 | char b = base64_digits[(unsigned char)*(src++)]; | 43 | char a = base64_digits[(unsigned char) *(src++)]; |
44 | char c = base64_digits[(unsigned char)*(src++)]; | 44 | char b = base64_digits[(unsigned char) *(src++)]; |
45 | char d = base64_digits[(unsigned char)*(src++)]; | 45 | char c = base64_digits[(unsigned char) *(src++)]; |
46 | char d = base64_digits[(unsigned char) *(src++)]; | ||
46 | *(dest++) = (a << 2) | ((b & 0x30) >> 4); | 47 | *(dest++) = (a << 2) | ((b & 0x30) >> 4); |
47 | if (c == (char)-1) | 48 | if (c == (char) -1) |
48 | break; | 49 | break; |
49 | *(dest++) = ((b & 0x0f) << 4) | ((c & 0x3c) >> 2); | 50 | *(dest++) = ((b & 0x0f) << 4) | ((c & 0x3c) >> 2); |
50 | if (d == (char)-1) | 51 | if (d == (char) -1) |
51 | break; | 52 | break; |
52 | *(dest++) = ((c & 0x03) << 6) | d; | 53 | *(dest++) = ((c & 0x03) << 6) | d; |
53 | } | 54 | } |
diff --git a/src/lib/base64.h b/src/lib/base64.h index ba96ca0c..65042c0b 100644 --- a/src/lib/base64.h +++ b/src/lib/base64.h | |||
@@ -12,6 +12,6 @@ | |||
12 | #include "platform.h" | 12 | #include "platform.h" |
13 | 13 | ||
14 | char * | 14 | char * |
15 | BASE64Decode(const char* src); | 15 | BASE64Decode (const char*src); |
16 | 16 | ||
17 | #endif /* !BASE64_H */ | 17 | #endif /* !BASE64_H */ |
diff --git a/src/lib/connection_add.c b/src/lib/connection_add.c index cd933d06..aaf04712 100644 --- a/src/lib/connection_add.c +++ b/src/lib/connection_add.c | |||
@@ -53,14 +53,14 @@ thread_main_connection_upgrade (struct MHD_Connection *con) | |||
53 | with the socket; */ | 53 | with the socket; */ |
54 | if ( (NULL != daemon->tls_api) && | 54 | if ( (NULL != daemon->tls_api) && |
55 | (MHD_ELS_POLL != daemon->event_loop_syscall) ) | 55 | (MHD_ELS_POLL != daemon->event_loop_syscall) ) |
56 | { | 56 | { |
57 | MHD_daemon_upgrade_connection_with_select_ (con); | 57 | MHD_daemon_upgrade_connection_with_select_ (con); |
58 | } | 58 | } |
59 | #ifdef HAVE_POLL | 59 | #ifdef HAVE_POLL |
60 | else if (NULL != daemon->tls_api) | 60 | else if (NULL != daemon->tls_api) |
61 | { | 61 | { |
62 | MHD_daemon_upgrade_connection_with_poll_ (con); | 62 | MHD_daemon_upgrade_connection_with_poll_ (con); |
63 | } | 63 | } |
64 | #endif | 64 | #endif |
65 | /* end HTTPS */ | 65 | /* end HTTPS */ |
66 | #endif /* HTTPS_SUPPORT */ | 66 | #endif /* HTTPS_SUPPORT */ |
@@ -111,342 +111,344 @@ thread_main_handle_connection (void *data) | |||
111 | #endif /* ! HAVE_POLL */ | 111 | #endif /* ! HAVE_POLL */ |
112 | bool was_suspended = false; | 112 | bool was_suspended = false; |
113 | 113 | ||
114 | MHD_thread_init_(&con->pid); | 114 | MHD_thread_init_ (&con->pid); |
115 | 115 | ||
116 | while ( (! daemon->shutdown) && | 116 | while ( (! daemon->shutdown) && |
117 | (MHD_REQUEST_CLOSED != con->request.state) ) | 117 | (MHD_REQUEST_CLOSED != con->request.state) ) |
118 | { | 118 | { |
119 | const time_t timeout = daemon->connection_default_timeout; | 119 | const time_t timeout = daemon->connection_default_timeout; |
120 | #ifdef UPGRADE_SUPPORT | 120 | #ifdef UPGRADE_SUPPORT |
121 | struct MHD_UpgradeResponseHandle * const urh = con->request.urh; | 121 | struct MHD_UpgradeResponseHandle *const urh = con->request.urh; |
122 | #else /* ! UPGRADE_SUPPORT */ | 122 | #else /* ! UPGRADE_SUPPORT */ |
123 | static const void * const urh = NULL; | 123 | static const void *const urh = NULL; |
124 | #endif /* ! UPGRADE_SUPPORT */ | 124 | #endif /* ! UPGRADE_SUPPORT */ |
125 | 125 | ||
126 | if ( (con->suspended) && | 126 | if ( (con->suspended) && |
127 | (NULL == urh) ) | 127 | (NULL == urh) ) |
128 | { | ||
129 | /* Connection was suspended, wait for resume. */ | ||
130 | was_suspended = true; | ||
131 | if (! use_poll) | ||
132 | { | ||
133 | FD_ZERO (&rs); | ||
134 | if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc), | ||
135 | &rs, | ||
136 | NULL, | ||
137 | FD_SETSIZE)) | ||
128 | { | 138 | { |
129 | /* Connection was suspended, wait for resume. */ | ||
130 | was_suspended = true; | ||
131 | if (! use_poll) | ||
132 | { | ||
133 | FD_ZERO (&rs); | ||
134 | if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc), | ||
135 | &rs, | ||
136 | NULL, | ||
137 | FD_SETSIZE)) | ||
138 | { | ||
139 | #ifdef HAVE_MESSAGES | 139 | #ifdef HAVE_MESSAGES |
140 | MHD_DLOG (con->daemon, | 140 | MHD_DLOG (con->daemon, |
141 | MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE, | 141 | MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE, |
142 | _("Failed to add FD to fd_set\n")); | 142 | _ ("Failed to add FD to fd_set\n")); |
143 | #endif | 143 | #endif |
144 | goto exit; | 144 | goto exit; |
145 | } | 145 | } |
146 | if (0 > MHD_SYS_select_ (MHD_itc_r_fd_ (daemon->itc) + 1, | 146 | if (0 > MHD_SYS_select_ (MHD_itc_r_fd_ (daemon->itc) + 1, |
147 | &rs, | 147 | &rs, |
148 | NULL, | 148 | NULL, |
149 | NULL, | 149 | NULL, |
150 | NULL)) | 150 | NULL)) |
151 | { | 151 | { |
152 | const int err = MHD_socket_get_error_(); | 152 | const int err = MHD_socket_get_error_ (); |
153 | 153 | ||
154 | if (MHD_SCKT_ERR_IS_EINTR_(err)) | 154 | if (MHD_SCKT_ERR_IS_EINTR_ (err)) |
155 | continue; | 155 | continue; |
156 | #ifdef HAVE_MESSAGES | 156 | #ifdef HAVE_MESSAGES |
157 | MHD_DLOG (con->daemon, | 157 | MHD_DLOG (con->daemon, |
158 | MHD_SC_UNEXPECTED_SELECT_ERROR, | 158 | MHD_SC_UNEXPECTED_SELECT_ERROR, |
159 | _("Error during select (%d): `%s'\n"), | 159 | _ ("Error during select (%d): `%s'\n"), |
160 | err, | 160 | err, |
161 | MHD_socket_strerr_ (err)); | 161 | MHD_socket_strerr_ (err)); |
162 | #endif | 162 | #endif |
163 | break; | 163 | break; |
164 | } | 164 | } |
165 | } | 165 | } |
166 | #ifdef HAVE_POLL | 166 | #ifdef HAVE_POLL |
167 | else /* use_poll */ | 167 | else /* use_poll */ |
168 | { | 168 | { |
169 | p[0].events = POLLIN; | 169 | p[0].events = POLLIN; |
170 | p[0].fd = MHD_itc_r_fd_ (daemon->itc); | 170 | p[0].fd = MHD_itc_r_fd_ (daemon->itc); |
171 | p[0].revents = 0; | 171 | p[0].revents = 0; |
172 | if (0 > MHD_sys_poll_ (p, | 172 | if (0 > MHD_sys_poll_ (p, |
173 | 1, | 173 | 1, |
174 | -1)) | 174 | -1)) |
175 | { | 175 | { |
176 | if (MHD_SCKT_LAST_ERR_IS_(MHD_SCKT_EINTR_)) | 176 | if (MHD_SCKT_LAST_ERR_IS_ (MHD_SCKT_EINTR_)) |
177 | continue; | 177 | continue; |
178 | #ifdef HAVE_MESSAGES | 178 | #ifdef HAVE_MESSAGES |
179 | MHD_DLOG (con->daemon, | 179 | MHD_DLOG (con->daemon, |
180 | MHD_SC_UNEXPECTED_POLL_ERROR, | 180 | MHD_SC_UNEXPECTED_POLL_ERROR, |
181 | _("Error during poll: `%s'\n"), | 181 | _ ("Error during poll: `%s'\n"), |
182 | MHD_socket_last_strerr_ ()); | 182 | MHD_socket_last_strerr_ ()); |
183 | #endif | 183 | #endif |
184 | break; | 184 | break; |
185 | } | 185 | } |
186 | } | 186 | } |
187 | #endif /* HAVE_POLL */ | 187 | #endif /* HAVE_POLL */ |
188 | MHD_itc_clear_ (daemon->itc); | 188 | MHD_itc_clear_ (daemon->itc); |
189 | continue; /* Check again for resume. */ | 189 | continue; /* Check again for resume. */ |
190 | } /* End of "suspended" branch. */ | 190 | } /* End of "suspended" branch. */ |
191 | 191 | ||
192 | if (was_suspended) | 192 | if (was_suspended) |
193 | { | 193 | { |
194 | MHD_connection_update_last_activity_ (con); /* Reset timeout timer. */ | 194 | MHD_connection_update_last_activity_ (con); /* Reset timeout timer. */ |
195 | /* Process response queued during suspend and update states. */ | 195 | /* Process response queued during suspend and update states. */ |
196 | MHD_request_handle_idle_ (&con->request); | 196 | MHD_request_handle_idle_ (&con->request); |
197 | was_suspended = false; | 197 | was_suspended = false; |
198 | } | 198 | } |
199 | 199 | ||
200 | tvp = NULL; | 200 | tvp = NULL; |
201 | 201 | ||
202 | if ( (MHD_EVENT_LOOP_INFO_BLOCK == con->request.event_loop_info) | 202 | if ( (MHD_EVENT_LOOP_INFO_BLOCK == con->request.event_loop_info) |
203 | #ifdef HTTPS_SUPPORT | 203 | #ifdef HTTPS_SUPPORT |
204 | || ( (con->tls_read_ready) && | 204 | || ( (con->tls_read_ready) && |
205 | (MHD_EVENT_LOOP_INFO_READ == con->request.event_loop_info) ) | 205 | (MHD_EVENT_LOOP_INFO_READ == con->request.event_loop_info) ) |
206 | #endif /* HTTPS_SUPPORT */ | 206 | #endif /* HTTPS_SUPPORT */ |
207 | ) | 207 | ) |
208 | { | 208 | { |
209 | /* do not block: more data may be inside of TLS buffers waiting or | 209 | /* do not block: more data may be inside of TLS buffers waiting or |
210 | * application must provide response data */ | 210 | * application must provide response data */ |
211 | tv.tv_sec = 0; | 211 | tv.tv_sec = 0; |
212 | tv.tv_usec = 0; | 212 | tv.tv_usec = 0; |
213 | tvp = &tv; | 213 | tvp = &tv; |
214 | } | 214 | } |
215 | if ( (NULL == tvp) && | 215 | if ( (NULL == tvp) && |
216 | (timeout > 0) ) | 216 | (timeout > 0) ) |
217 | { | 217 | { |
218 | now = MHD_monotonic_sec_counter(); | 218 | now = MHD_monotonic_sec_counter (); |
219 | if (now - con->last_activity > timeout) | 219 | if (now - con->last_activity > timeout) |
220 | tv.tv_sec = 0; | 220 | tv.tv_sec = 0; |
221 | else | 221 | else |
222 | { | 222 | { |
223 | const time_t seconds_left = timeout - (now - con->last_activity); | 223 | const time_t seconds_left = timeout - (now - con->last_activity); |
224 | #if !defined(_WIN32) || defined(__CYGWIN__) | 224 | #if ! defined(_WIN32) || defined(__CYGWIN__) |
225 | tv.tv_sec = seconds_left; | 225 | tv.tv_sec = seconds_left; |
226 | #else /* _WIN32 && !__CYGWIN__ */ | 226 | #else /* _WIN32 && !__CYGWIN__ */ |
227 | if (seconds_left > TIMEVAL_TV_SEC_MAX) | 227 | if (seconds_left > TIMEVAL_TV_SEC_MAX) |
228 | tv.tv_sec = TIMEVAL_TV_SEC_MAX; | 228 | tv.tv_sec = TIMEVAL_TV_SEC_MAX; |
229 | else | 229 | else |
230 | tv.tv_sec = (_MHD_TIMEVAL_TV_SEC_TYPE) seconds_left; | 230 | tv.tv_sec = (_MHD_TIMEVAL_TV_SEC_TYPE) seconds_left; |
231 | #endif /* _WIN32 && ! __CYGWIN__ */ | 231 | #endif /* _WIN32 && ! __CYGWIN__ */ |
232 | } | 232 | } |
233 | tv.tv_usec = 0; | 233 | tv.tv_usec = 0; |
234 | tvp = &tv; | 234 | tvp = &tv; |
235 | } | 235 | } |
236 | if (! use_poll) | 236 | if (! use_poll) |
237 | { | 237 | { |
238 | /* use select */ | 238 | /* use select */ |
239 | bool err_state = false; | 239 | bool err_state = false; |
240 | 240 | ||
241 | FD_ZERO (&rs); | 241 | FD_ZERO (&rs); |
242 | FD_ZERO (&ws); | 242 | FD_ZERO (&ws); |
243 | FD_ZERO (&es); | 243 | FD_ZERO (&es); |
244 | maxsock = MHD_INVALID_SOCKET; | 244 | maxsock = MHD_INVALID_SOCKET; |
245 | switch (con->request.event_loop_info) | 245 | switch (con->request.event_loop_info) |
246 | { | 246 | { |
247 | case MHD_EVENT_LOOP_INFO_READ: | 247 | case MHD_EVENT_LOOP_INFO_READ: |
248 | if (! MHD_add_to_fd_set_ (con->socket_fd, | 248 | if (! MHD_add_to_fd_set_ (con->socket_fd, |
249 | &rs, | 249 | &rs, |
250 | &maxsock, | 250 | &maxsock, |
251 | FD_SETSIZE)) | 251 | FD_SETSIZE)) |
252 | err_state = true; | 252 | err_state = true; |
253 | break; | 253 | break; |
254 | case MHD_EVENT_LOOP_INFO_WRITE: | 254 | case MHD_EVENT_LOOP_INFO_WRITE: |
255 | if (! MHD_add_to_fd_set_ (con->socket_fd, | 255 | if (! MHD_add_to_fd_set_ (con->socket_fd, |
256 | &ws, | 256 | &ws, |
257 | &maxsock, | 257 | &maxsock, |
258 | FD_SETSIZE)) | 258 | FD_SETSIZE)) |
259 | err_state = true; | 259 | err_state = true; |
260 | break; | 260 | break; |
261 | case MHD_EVENT_LOOP_INFO_BLOCK: | 261 | case MHD_EVENT_LOOP_INFO_BLOCK: |
262 | if (! MHD_add_to_fd_set_ (con->socket_fd, | 262 | if (! MHD_add_to_fd_set_ (con->socket_fd, |
263 | &es, | 263 | &es, |
264 | &maxsock, | 264 | &maxsock, |
265 | FD_SETSIZE)) | 265 | FD_SETSIZE)) |
266 | err_state = true; | 266 | err_state = true; |
267 | break; | 267 | break; |
268 | case MHD_EVENT_LOOP_INFO_CLEANUP: | 268 | case MHD_EVENT_LOOP_INFO_CLEANUP: |
269 | /* how did we get here!? */ | 269 | /* how did we get here!? */ |
270 | goto exit; | 270 | goto exit; |
271 | } | 271 | } |
272 | #if WINDOWS | 272 | #if WINDOWS |
273 | if (MHD_ITC_IS_VALID_(daemon->itc) ) | 273 | if (MHD_ITC_IS_VALID_ (daemon->itc) ) |
274 | { | 274 | { |
275 | if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc), | 275 | if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc), |
276 | &rs, | 276 | &rs, |
277 | &maxsock, | 277 | &maxsock, |
278 | FD_SETSIZE)) | 278 | FD_SETSIZE)) |
279 | err_state = 1; | 279 | err_state = 1; |
280 | } | 280 | } |
281 | #endif | 281 | #endif |
282 | if (err_state) | 282 | if (err_state) |
283 | { | 283 | { |
284 | #ifdef HAVE_MESSAGES | 284 | #ifdef HAVE_MESSAGES |
285 | MHD_DLOG (con->daemon, | 285 | MHD_DLOG (con->daemon, |
286 | MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE, | 286 | MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE, |
287 | _("Failed to add FD to fd_set\n")); | 287 | _ ("Failed to add FD to fd_set\n")); |
288 | #endif | 288 | #endif |
289 | goto exit; | 289 | goto exit; |
290 | } | 290 | } |
291 | 291 | ||
292 | num_ready = MHD_SYS_select_ (maxsock + 1, | 292 | num_ready = MHD_SYS_select_ (maxsock + 1, |
293 | &rs, | 293 | &rs, |
294 | &ws, | 294 | &ws, |
295 | &es, | 295 | &es, |
296 | tvp); | 296 | tvp); |
297 | if (num_ready < 0) | 297 | if (num_ready < 0) |
298 | { | 298 | { |
299 | const int err = MHD_socket_get_error_(); | 299 | const int err = MHD_socket_get_error_ (); |
300 | 300 | ||
301 | if (MHD_SCKT_ERR_IS_EINTR_(err)) | 301 | if (MHD_SCKT_ERR_IS_EINTR_ (err)) |
302 | continue; | 302 | continue; |
303 | #ifdef HAVE_MESSAGES | 303 | #ifdef HAVE_MESSAGES |
304 | MHD_DLOG (con->daemon, | 304 | MHD_DLOG (con->daemon, |
305 | MHD_SC_UNEXPECTED_SELECT_ERROR, | 305 | MHD_SC_UNEXPECTED_SELECT_ERROR, |
306 | _("Error during select (%d): `%s'\n"), | 306 | _ ("Error during select (%d): `%s'\n"), |
307 | err, | 307 | err, |
308 | MHD_socket_strerr_ (err)); | 308 | MHD_socket_strerr_ (err)); |
309 | #endif | 309 | #endif |
310 | break; | 310 | break; |
311 | } | 311 | } |
312 | #if WINDOWS | 312 | #if WINDOWS |
313 | /* Clear ITC before other processing so additional | 313 | /* Clear ITC before other processing so additional |
314 | * signals will trigger select() again */ | 314 | * signals will trigger select() again */ |
315 | if ( (MHD_ITC_IS_VALID_(daemon->itc)) && | 315 | if ( (MHD_ITC_IS_VALID_ (daemon->itc)) && |
316 | (FD_ISSET (MHD_itc_r_fd_ (daemon->itc), | 316 | (FD_ISSET (MHD_itc_r_fd_ (daemon->itc), |
317 | &rs)) ) | 317 | &rs)) ) |
318 | MHD_itc_clear_ (daemon->itc); | 318 | MHD_itc_clear_ (daemon->itc); |
319 | #endif | 319 | #endif |
320 | if (MHD_NO == | 320 | if (MHD_NO == |
321 | MHD_connection_call_handlers_ (con, | 321 | MHD_connection_call_handlers_ (con, |
322 | FD_ISSET (con->socket_fd, | 322 | FD_ISSET (con->socket_fd, |
323 | &rs), | 323 | &rs), |
324 | FD_ISSET (con->socket_fd, | 324 | FD_ISSET (con->socket_fd, |
325 | &ws), | 325 | &ws), |
326 | FD_ISSET (con->socket_fd, | 326 | FD_ISSET (con->socket_fd, |
327 | &es)) ) | 327 | &es)) ) |
328 | goto exit; | 328 | goto exit; |
329 | } | 329 | } |
330 | #ifdef HAVE_POLL | 330 | #ifdef HAVE_POLL |
331 | else | 331 | else |
332 | { | 332 | { |
333 | /* use poll */ | 333 | /* use poll */ |
334 | memset (&p, | 334 | memset (&p, |
335 | 0, | 335 | 0, |
336 | sizeof (p)); | 336 | sizeof (p)); |
337 | p[0].fd = con->socket_fd; | 337 | p[0].fd = con->socket_fd; |
338 | switch (con->request.event_loop_info) | 338 | switch (con->request.event_loop_info) |
339 | { | 339 | { |
340 | case MHD_EVENT_LOOP_INFO_READ: | 340 | case MHD_EVENT_LOOP_INFO_READ: |
341 | p[0].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC; | 341 | p[0].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC; |
342 | break; | 342 | break; |
343 | case MHD_EVENT_LOOP_INFO_WRITE: | 343 | case MHD_EVENT_LOOP_INFO_WRITE: |
344 | p[0].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC; | 344 | p[0].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC; |
345 | break; | 345 | break; |
346 | case MHD_EVENT_LOOP_INFO_BLOCK: | 346 | case MHD_EVENT_LOOP_INFO_BLOCK: |
347 | p[0].events |= MHD_POLL_EVENTS_ERR_DISC; | 347 | p[0].events |= MHD_POLL_EVENTS_ERR_DISC; |
348 | break; | 348 | break; |
349 | case MHD_EVENT_LOOP_INFO_CLEANUP: | 349 | case MHD_EVENT_LOOP_INFO_CLEANUP: |
350 | /* how did we get here!? */ | 350 | /* how did we get here!? */ |
351 | goto exit; | 351 | goto exit; |
352 | } | 352 | } |
353 | #if WINDOWS | 353 | #if WINDOWS |
354 | extra_slot = 0; | 354 | extra_slot = 0; |
355 | if (MHD_ITC_IS_VALID_(daemon->itc)) | 355 | if (MHD_ITC_IS_VALID_ (daemon->itc)) |
356 | { | 356 | { |
357 | p[1].events |= POLLIN; | 357 | p[1].events |= POLLIN; |
358 | p[1].fd = MHD_itc_r_fd_ (daemon->itc); | 358 | p[1].fd = MHD_itc_r_fd_ (daemon->itc); |
359 | p[1].revents = 0; | 359 | p[1].revents = 0; |
360 | extra_slot = 1; | 360 | extra_slot = 1; |
361 | } | 361 | } |
362 | #endif | 362 | #endif |
363 | if (MHD_sys_poll_ (p, | 363 | if (MHD_sys_poll_ (p, |
364 | #if WINDOWS | 364 | #if WINDOWS |
365 | 1 + extra_slot, | 365 | 1 + extra_slot, |
366 | #else | 366 | #else |
367 | 1, | 367 | 1, |
368 | #endif | 368 | #endif |
369 | (NULL == tvp) ? -1 : tv.tv_sec * 1000) < 0) | 369 | (NULL == tvp) ? -1 : tv.tv_sec * 1000) < 0) |
370 | { | 370 | { |
371 | if (MHD_SCKT_LAST_ERR_IS_(MHD_SCKT_EINTR_)) | 371 | if (MHD_SCKT_LAST_ERR_IS_ (MHD_SCKT_EINTR_)) |
372 | continue; | 372 | continue; |
373 | #ifdef HAVE_MESSAGES | 373 | #ifdef HAVE_MESSAGES |
374 | MHD_DLOG (con->daemon, | 374 | MHD_DLOG (con->daemon, |
375 | MHD_SC_UNEXPECTED_POLL_ERROR, | 375 | MHD_SC_UNEXPECTED_POLL_ERROR, |
376 | _("Error during poll: `%s'\n"), | 376 | _ ("Error during poll: `%s'\n"), |
377 | MHD_socket_last_strerr_ ()); | 377 | MHD_socket_last_strerr_ ()); |
378 | #endif | 378 | #endif |
379 | break; | 379 | break; |
380 | } | 380 | } |
381 | #if WINDOWS | 381 | #if WINDOWS |
382 | /* Clear ITC before other processing so additional | 382 | /* Clear ITC before other processing so additional |
383 | * signals will trigger poll() again */ | 383 | * signals will trigger poll() again */ |
384 | if ( (MHD_ITC_IS_VALID_(daemon->itc)) && | 384 | if ( (MHD_ITC_IS_VALID_ (daemon->itc)) && |
385 | (0 != (p[1].revents & (POLLERR | POLLHUP | POLLIN))) ) | 385 | (0 != (p[1].revents & (POLLERR | POLLHUP | POLLIN))) ) |
386 | MHD_itc_clear_ (daemon->itc); | 386 | MHD_itc_clear_ (daemon->itc); |
387 | #endif | 387 | #endif |
388 | if (MHD_NO == | 388 | if (MHD_NO == |
389 | MHD_connection_call_handlers_ (con, | 389 | MHD_connection_call_handlers_ (con, |
390 | 0 != (p[0].revents & POLLIN), | 390 | (0 != (p[0].revents & POLLIN)), |
391 | 0 != (p[0].revents & POLLOUT), | 391 | (0 != (p[0].revents & POLLOUT)), |
392 | 0 != (p[0].revents & (POLLERR | MHD_POLL_REVENTS_ERR_DISC)))) | 392 | (0 != (p[0].revents & (POLLERR |
393 | goto exit; | 393 | | |
394 | } | 394 | MHD_POLL_REVENTS_ERR_DISC))) )) |
395 | goto exit; | ||
396 | } | ||
395 | #endif | 397 | #endif |
396 | #ifdef UPGRADE_SUPPORT | 398 | #ifdef UPGRADE_SUPPORT |
397 | if (MHD_REQUEST_UPGRADE == con->request.state) | 399 | if (MHD_REQUEST_UPGRADE == con->request.state) |
398 | { | 400 | { |
399 | /* Normal HTTP processing is finished, | 401 | /* Normal HTTP processing is finished, |
400 | * notify application. */ | 402 | * notify application. */ |
401 | if (NULL != con->request.response->termination_cb) | 403 | if (NULL != con->request.response->termination_cb) |
402 | con->request.response->termination_cb | 404 | con->request.response->termination_cb |
403 | (con->request.response->termination_cb_cls, | 405 | (con->request.response->termination_cb_cls, |
404 | MHD_REQUEST_TERMINATED_COMPLETED_OK, | 406 | MHD_REQUEST_TERMINATED_COMPLETED_OK, |
405 | con->request.client_context); | 407 | con->request.client_context); |
406 | thread_main_connection_upgrade (con); | 408 | thread_main_connection_upgrade (con); |
407 | /* MHD_connection_finish_forward_() was called by thread_main_connection_upgrade(). */ | 409 | /* MHD_connection_finish_forward_() was called by thread_main_connection_upgrade(). */ |
408 | 410 | ||
409 | /* "Upgraded" data will not be used in this thread from this point. */ | 411 | /* "Upgraded" data will not be used in this thread from this point. */ |
410 | con->request.urh->clean_ready = true; | 412 | con->request.urh->clean_ready = true; |
411 | /* If 'urh->was_closed' set to true, connection will be | 413 | /* If 'urh->was_closed' set to true, connection will be |
412 | * moved immediately to cleanup list. Otherwise connection | 414 | * moved immediately to cleanup list. Otherwise connection |
413 | * will stay in suspended list until 'urh' will be marked | 415 | * will stay in suspended list until 'urh' will be marked |
414 | * with 'was_closed' by application. */ | 416 | * with 'was_closed' by application. */ |
415 | MHD_request_resume (&con->request); | 417 | MHD_request_resume (&con->request); |
416 | 418 | ||
417 | /* skip usual clean up */ | 419 | /* skip usual clean up */ |
418 | return (MHD_THRD_RTRN_TYPE_) 0; | 420 | return (MHD_THRD_RTRN_TYPE_) 0; |
419 | } | ||
420 | #endif /* UPGRADE_SUPPORT */ | ||
421 | } | 421 | } |
422 | #endif /* UPGRADE_SUPPORT */ | ||
423 | } | ||
422 | #if DEBUG_CLOSE | 424 | #if DEBUG_CLOSE |
423 | #ifdef HAVE_MESSAGES | 425 | #ifdef HAVE_MESSAGES |
424 | MHD_DLOG (con->daemon, | 426 | MHD_DLOG (con->daemon, |
425 | MHD_SC_THREAD_TERMINATING, | 427 | MHD_SC_THREAD_TERMINATING, |
426 | _("Processing thread terminating. Closing connection\n")); | 428 | _ ("Processing thread terminating. Closing connection\n")); |
427 | #endif | 429 | #endif |
428 | #endif | 430 | #endif |
429 | if (MHD_REQUEST_CLOSED != con->request.state) | 431 | if (MHD_REQUEST_CLOSED != con->request.state) |
430 | MHD_connection_close_ (con, | 432 | MHD_connection_close_ (con, |
431 | (daemon->shutdown) ? | 433 | (daemon->shutdown) ? |
432 | MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN: | 434 | MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN : |
433 | MHD_REQUEST_TERMINATED_WITH_ERROR); | 435 | MHD_REQUEST_TERMINATED_WITH_ERROR); |
434 | MHD_request_handle_idle_ (&con->request); | 436 | MHD_request_handle_idle_ (&con->request); |
435 | exit: | 437 | exit: |
436 | if (NULL != con->request.response) | 438 | if (NULL != con->request.response) |
437 | { | 439 | { |
438 | MHD_response_queue_for_destroy (con->request.response); | 440 | MHD_response_queue_for_destroy (con->request.response); |
439 | con->request.response = NULL; | 441 | con->request.response = NULL; |
440 | } | 442 | } |
441 | 443 | ||
442 | if (MHD_INVALID_SOCKET != con->socket_fd) | 444 | if (MHD_INVALID_SOCKET != con->socket_fd) |
443 | { | 445 | { |
444 | shutdown (con->socket_fd, | 446 | shutdown (con->socket_fd, |
445 | SHUT_WR); | 447 | SHUT_WR); |
446 | /* 'socket_fd' can be used in other thread to signal shutdown. | 448 | /* 'socket_fd' can be used in other thread to signal shutdown. |
447 | * To avoid data races, do not close socket here. Daemon will | 449 | * To avoid data races, do not close socket here. Daemon will |
448 | * use more connections only after cleanup anyway. */ | 450 | * use more connections only after cleanup anyway. */ |
449 | } | 451 | } |
450 | return (MHD_THRD_RTRN_TYPE_) 0; | 452 | return (MHD_THRD_RTRN_TYPE_) 0; |
451 | } | 453 | } |
452 | 454 | ||
@@ -469,9 +471,9 @@ recv_param_adapter (struct MHD_Connection *connection, | |||
469 | 471 | ||
470 | if ( (MHD_INVALID_SOCKET == connection->socket_fd) || | 472 | if ( (MHD_INVALID_SOCKET == connection->socket_fd) || |
471 | (MHD_REQUEST_CLOSED == connection->request.state) ) | 473 | (MHD_REQUEST_CLOSED == connection->request.state) ) |
472 | { | 474 | { |
473 | return MHD_ERR_NOTCONN_; | 475 | return MHD_ERR_NOTCONN_; |
474 | } | 476 | } |
475 | if (i > MHD_SCKT_SEND_MAX_SIZE_) | 477 | if (i > MHD_SCKT_SEND_MAX_SIZE_) |
476 | i = MHD_SCKT_SEND_MAX_SIZE_; /* return value limit */ | 478 | i = MHD_SCKT_SEND_MAX_SIZE_; /* return value limit */ |
477 | 479 | ||
@@ -479,25 +481,25 @@ recv_param_adapter (struct MHD_Connection *connection, | |||
479 | other, | 481 | other, |
480 | i); | 482 | i); |
481 | if (0 > ret) | 483 | if (0 > ret) |
484 | { | ||
485 | const int err = MHD_socket_get_error_ (); | ||
486 | if (MHD_SCKT_ERR_IS_EAGAIN_ (err)) | ||
482 | { | 487 | { |
483 | const int err = MHD_socket_get_error_ (); | ||
484 | if (MHD_SCKT_ERR_IS_EAGAIN_ (err)) | ||
485 | { | ||
486 | #ifdef EPOLL_SUPPORT | 488 | #ifdef EPOLL_SUPPORT |
487 | /* Got EAGAIN --- no longer read-ready */ | 489 | /* Got EAGAIN --- no longer read-ready */ |
488 | connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY; | 490 | connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY; |
489 | #endif /* EPOLL_SUPPORT */ | 491 | #endif /* EPOLL_SUPPORT */ |
490 | return MHD_ERR_AGAIN_; | 492 | return MHD_ERR_AGAIN_; |
491 | } | ||
492 | if (MHD_SCKT_ERR_IS_EINTR_ (err)) | ||
493 | return MHD_ERR_AGAIN_; | ||
494 | if (MHD_SCKT_ERR_IS_ (err, MHD_SCKT_ECONNRESET_)) | ||
495 | return MHD_ERR_CONNRESET_; | ||
496 | /* Treat any other error as hard error. */ | ||
497 | return MHD_ERR_NOTCONN_; | ||
498 | } | 493 | } |
494 | if (MHD_SCKT_ERR_IS_EINTR_ (err)) | ||
495 | return MHD_ERR_AGAIN_; | ||
496 | if (MHD_SCKT_ERR_IS_ (err, MHD_SCKT_ECONNRESET_)) | ||
497 | return MHD_ERR_CONNRESET_; | ||
498 | /* Treat any other error as hard error. */ | ||
499 | return MHD_ERR_NOTCONN_; | ||
500 | } | ||
499 | #ifdef EPOLL_SUPPORT | 501 | #ifdef EPOLL_SUPPORT |
500 | else if (i > (size_t)ret) | 502 | else if (i > (size_t) ret) |
501 | connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY; | 503 | connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY; |
502 | #endif /* EPOLL_SUPPORT */ | 504 | #endif /* EPOLL_SUPPORT */ |
503 | return ret; | 505 | return ret; |
@@ -522,9 +524,9 @@ send_param_adapter (struct MHD_Connection *connection, | |||
522 | 524 | ||
523 | if ( (MHD_INVALID_SOCKET == connection->socket_fd) || | 525 | if ( (MHD_INVALID_SOCKET == connection->socket_fd) || |
524 | (MHD_REQUEST_CLOSED == connection->request.state) ) | 526 | (MHD_REQUEST_CLOSED == connection->request.state) ) |
525 | { | 527 | { |
526 | return MHD_ERR_NOTCONN_; | 528 | return MHD_ERR_NOTCONN_; |
527 | } | 529 | } |
528 | if (i > MHD_SCKT_SEND_MAX_SIZE_) | 530 | if (i > MHD_SCKT_SEND_MAX_SIZE_) |
529 | i = MHD_SCKT_SEND_MAX_SIZE_; /* return value limit */ | 531 | i = MHD_SCKT_SEND_MAX_SIZE_; /* return value limit */ |
530 | 532 | ||
@@ -532,26 +534,26 @@ send_param_adapter (struct MHD_Connection *connection, | |||
532 | other, | 534 | other, |
533 | i); | 535 | i); |
534 | if (0 > ret) | 536 | if (0 > ret) |
535 | { | 537 | { |
536 | const int err = MHD_socket_get_error_(); | 538 | const int err = MHD_socket_get_error_ (); |
537 | 539 | ||
538 | if (MHD_SCKT_ERR_IS_EAGAIN_(err)) | 540 | if (MHD_SCKT_ERR_IS_EAGAIN_ (err)) |
539 | { | 541 | { |
540 | #ifdef EPOLL_SUPPORT | 542 | #ifdef EPOLL_SUPPORT |
541 | /* EAGAIN --- no longer write-ready */ | 543 | /* EAGAIN --- no longer write-ready */ |
542 | connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY; | 544 | connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY; |
543 | #endif /* EPOLL_SUPPORT */ | 545 | #endif /* EPOLL_SUPPORT */ |
544 | return MHD_ERR_AGAIN_; | 546 | return MHD_ERR_AGAIN_; |
545 | } | ||
546 | if (MHD_SCKT_ERR_IS_EINTR_ (err)) | ||
547 | return MHD_ERR_AGAIN_; | ||
548 | if (MHD_SCKT_ERR_IS_ (err, MHD_SCKT_ECONNRESET_)) | ||
549 | return MHD_ERR_CONNRESET_; | ||
550 | /* Treat any other error as hard error. */ | ||
551 | return MHD_ERR_NOTCONN_; | ||
552 | } | 547 | } |
548 | if (MHD_SCKT_ERR_IS_EINTR_ (err)) | ||
549 | return MHD_ERR_AGAIN_; | ||
550 | if (MHD_SCKT_ERR_IS_ (err, MHD_SCKT_ECONNRESET_)) | ||
551 | return MHD_ERR_CONNRESET_; | ||
552 | /* Treat any other error as hard error. */ | ||
553 | return MHD_ERR_NOTCONN_; | ||
554 | } | ||
553 | #ifdef EPOLL_SUPPORT | 555 | #ifdef EPOLL_SUPPORT |
554 | else if (i > (size_t)ret) | 556 | else if (i > (size_t) ret) |
555 | connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY; | 557 | connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY; |
556 | #endif /* EPOLL_SUPPORT */ | 558 | #endif /* EPOLL_SUPPORT */ |
557 | return ret; | 559 | return ret; |
@@ -582,11 +584,11 @@ send_param_adapter (struct MHD_Connection *connection, | |||
582 | */ | 584 | */ |
583 | static enum MHD_StatusCode | 585 | static enum MHD_StatusCode |
584 | internal_add_connection (struct MHD_Daemon *daemon, | 586 | internal_add_connection (struct MHD_Daemon *daemon, |
585 | MHD_socket client_socket, | 587 | MHD_socket client_socket, |
586 | const struct sockaddr *addr, | 588 | const struct sockaddr *addr, |
587 | socklen_t addrlen, | 589 | socklen_t addrlen, |
588 | bool external_add, | 590 | bool external_add, |
589 | bool non_blck) | 591 | bool non_blck) |
590 | { | 592 | { |
591 | enum MHD_StatusCode sc; | 593 | enum MHD_StatusCode sc; |
592 | struct MHD_Connection *connection; | 594 | struct MHD_Connection *connection; |
@@ -594,78 +596,78 @@ internal_add_connection (struct MHD_Daemon *daemon, | |||
594 | 596 | ||
595 | /* Direct add to master daemon could happen only with "external" add mode. */ | 597 | /* Direct add to master daemon could happen only with "external" add mode. */ |
596 | mhd_assert ( (NULL == daemon->worker_pool) || | 598 | mhd_assert ( (NULL == daemon->worker_pool) || |
597 | (external_add) ); | 599 | (external_add) ); |
598 | if ( (external_add) && | 600 | if ( (external_add) && |
599 | (NULL != daemon->worker_pool) ) | 601 | (NULL != daemon->worker_pool) ) |
600 | { | 602 | { |
601 | unsigned int i; | 603 | unsigned int i; |
602 | 604 | ||
603 | /* have a pool, try to find a pool with capacity; we use the | 605 | /* have a pool, try to find a pool with capacity; we use the |
604 | socket as the initial offset into the pool for load | 606 | socket as the initial offset into the pool for load |
605 | balancing */ | 607 | balancing */ |
606 | for (i = 0; i < daemon->worker_pool_size; ++i) | 608 | for (i = 0; i < daemon->worker_pool_size; ++i) |
607 | { | 609 | { |
608 | struct MHD_Daemon * const worker = | 610 | struct MHD_Daemon *const worker = |
609 | &daemon->worker_pool[(i + client_socket) % daemon->worker_pool_size]; | 611 | &daemon->worker_pool[(i + client_socket) % daemon->worker_pool_size]; |
610 | if (worker->connections < worker->global_connection_limit) | 612 | if (worker->connections < worker->global_connection_limit) |
611 | return internal_add_connection (worker, | 613 | return internal_add_connection (worker, |
612 | client_socket, | 614 | client_socket, |
613 | addr, | 615 | addr, |
614 | addrlen, | 616 | addrlen, |
615 | true, | 617 | true, |
616 | non_blck); | 618 | non_blck); |
617 | } | 619 | } |
618 | /* all pools are at their connection limit, must refuse */ | 620 | /* all pools are at their connection limit, must refuse */ |
619 | MHD_socket_close_chk_ (client_socket); | 621 | MHD_socket_close_chk_ (client_socket); |
620 | #if ENFILE | 622 | #if ENFILE |
621 | errno = ENFILE; | 623 | errno = ENFILE; |
622 | #endif | 624 | #endif |
623 | return MHD_SC_LIMIT_CONNECTIONS_REACHED; | 625 | return MHD_SC_LIMIT_CONNECTIONS_REACHED; |
624 | } | 626 | } |
625 | 627 | ||
626 | if ( (! MHD_SCKT_FD_FITS_FDSET_(client_socket, | 628 | if ( (! MHD_SCKT_FD_FITS_FDSET_ (client_socket, |
627 | NULL)) && | 629 | NULL)) && |
628 | (MHD_ELS_SELECT == daemon->event_loop_syscall) ) | 630 | (MHD_ELS_SELECT == daemon->event_loop_syscall) ) |
629 | { | 631 | { |
630 | #ifdef HAVE_MESSAGES | 632 | #ifdef HAVE_MESSAGES |
631 | MHD_DLOG (daemon, | 633 | MHD_DLOG (daemon, |
632 | MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE, | 634 | MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE, |
633 | _("Socket descriptor larger than FD_SETSIZE: %d > %d\n"), | 635 | _ ("Socket descriptor larger than FD_SETSIZE: %d > %d\n"), |
634 | (int) client_socket, | 636 | (int) client_socket, |
635 | (int) FD_SETSIZE); | 637 | (int) FD_SETSIZE); |
636 | #endif | 638 | #endif |
637 | MHD_socket_close_chk_ (client_socket); | 639 | MHD_socket_close_chk_ (client_socket); |
638 | #if EINVAL | 640 | #if EINVAL |
639 | errno = EINVAL; | 641 | errno = EINVAL; |
640 | #endif | 642 | #endif |
641 | return MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE; | 643 | return MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE; |
642 | } | 644 | } |
643 | 645 | ||
644 | #ifdef MHD_socket_nosignal_ | 646 | #ifdef MHD_socket_nosignal_ |
645 | if (! MHD_socket_nosignal_ (client_socket)) | 647 | if (! MHD_socket_nosignal_ (client_socket)) |
646 | { | 648 | { |
647 | #ifdef HAVE_MESSAGES | 649 | #ifdef HAVE_MESSAGES |
648 | MHD_DLOG (daemon, | 650 | MHD_DLOG (daemon, |
649 | MHD_SC_ACCEPT_CONFIGURE_NOSIGPIPE_FAILED, | 651 | MHD_SC_ACCEPT_CONFIGURE_NOSIGPIPE_FAILED, |
650 | _("Failed to set SO_NOSIGPIPE on accepted socket: %s\n"), | 652 | _ ("Failed to set SO_NOSIGPIPE on accepted socket: %s\n"), |
651 | MHD_socket_last_strerr_()); | 653 | MHD_socket_last_strerr_ ()); |
652 | #endif | 654 | #endif |
653 | #ifndef MSG_NOSIGNAL | 655 | #ifndef MSG_NOSIGNAL |
654 | /* Cannot use socket as it can produce SIGPIPE. */ | 656 | /* Cannot use socket as it can produce SIGPIPE. */ |
655 | #ifdef ENOTSOCK | 657 | #ifdef ENOTSOCK |
656 | errno = ENOTSOCK; | 658 | errno = ENOTSOCK; |
657 | #endif /* ENOTSOCK */ | 659 | #endif /* ENOTSOCK */ |
658 | return MHD_SC_ACCEPT_CONFIGURE_NOSIGPIPE_FAILED; | 660 | return MHD_SC_ACCEPT_CONFIGURE_NOSIGPIPE_FAILED; |
659 | #endif /* ! MSG_NOSIGNAL */ | 661 | #endif /* ! MSG_NOSIGNAL */ |
660 | } | 662 | } |
661 | #endif /* MHD_socket_nosignal_ */ | 663 | #endif /* MHD_socket_nosignal_ */ |
662 | 664 | ||
663 | 665 | ||
664 | #ifdef HAVE_MESSAGES | 666 | #ifdef HAVE_MESSAGES |
665 | #if DEBUG_CONNECT | 667 | #if DEBUG_CONNECT |
666 | MHD_DLOG (daemon, | 668 | MHD_DLOG (daemon, |
667 | MHD_SC_CONNECTION_ACCEPTED, | 669 | MHD_SC_CONNECTION_ACCEPTED, |
668 | _("Accepted connection on socket %d\n"), | 670 | _ ("Accepted connection on socket %d\n"), |
669 | client_socket); | 671 | client_socket); |
670 | #endif | 672 | #endif |
671 | #endif | 673 | #endif |
@@ -673,82 +675,83 @@ internal_add_connection (struct MHD_Daemon *daemon, | |||
673 | (MHD_NO == MHD_ip_limit_add (daemon, | 675 | (MHD_NO == MHD_ip_limit_add (daemon, |
674 | addr, | 676 | addr, |
675 | addrlen)) ) | 677 | addrlen)) ) |
676 | { | 678 | { |
677 | /* above connection limit - reject */ | 679 | /* above connection limit - reject */ |
678 | #ifdef HAVE_MESSAGES | 680 | #ifdef HAVE_MESSAGES |
679 | MHD_DLOG (daemon, | 681 | MHD_DLOG (daemon, |
680 | MHD_SC_LIMIT_CONNECTIONS_REACHED, | 682 | MHD_SC_LIMIT_CONNECTIONS_REACHED, |
681 | _("Server reached connection limit. Closing inbound connection.\n")); | 683 | _ ( |
684 | "Server reached connection limit. Closing inbound connection.\n")); | ||
682 | #endif | 685 | #endif |
683 | MHD_socket_close_chk_ (client_socket); | 686 | MHD_socket_close_chk_ (client_socket); |
684 | #if ENFILE | 687 | #if ENFILE |
685 | errno = ENFILE; | 688 | errno = ENFILE; |
686 | #endif | 689 | #endif |
687 | return MHD_SC_LIMIT_CONNECTIONS_REACHED; | 690 | return MHD_SC_LIMIT_CONNECTIONS_REACHED; |
688 | } | 691 | } |
689 | 692 | ||
690 | /* apply connection acceptance policy if present */ | 693 | /* apply connection acceptance policy if present */ |
691 | if ( (NULL != daemon->accept_policy_cb) && | 694 | if ( (NULL != daemon->accept_policy_cb) && |
692 | (MHD_NO == | 695 | (MHD_NO == |
693 | daemon->accept_policy_cb (daemon->accept_policy_cb_cls, | 696 | daemon->accept_policy_cb (daemon->accept_policy_cb_cls, |
694 | addr, | 697 | addr, |
695 | addrlen)) ) | 698 | addrlen)) ) |
696 | { | 699 | { |
697 | #if DEBUG_CLOSE | 700 | #if DEBUG_CLOSE |
698 | #ifdef HAVE_MESSAGES | 701 | #ifdef HAVE_MESSAGES |
699 | MHD_DLOG (daemon, | 702 | MHD_DLOG (daemon, |
700 | MHD_SC_ACCEPT_POLICY_REJECTED, | 703 | MHD_SC_ACCEPT_POLICY_REJECTED, |
701 | _("Connection rejected by application. Closing connection.\n")); | 704 | _ ("Connection rejected by application. Closing connection.\n")); |
702 | #endif | 705 | #endif |
703 | #endif | 706 | #endif |
704 | MHD_socket_close_chk_ (client_socket); | 707 | MHD_socket_close_chk_ (client_socket); |
705 | MHD_ip_limit_del (daemon, | 708 | MHD_ip_limit_del (daemon, |
706 | addr, | 709 | addr, |
707 | addrlen); | 710 | addrlen); |
708 | #if EACCESS | 711 | #if EACCESS |
709 | errno = EACCESS; | 712 | errno = EACCESS; |
710 | #endif | 713 | #endif |
711 | return MHD_SC_ACCEPT_POLICY_REJECTED; | 714 | return MHD_SC_ACCEPT_POLICY_REJECTED; |
712 | } | 715 | } |
713 | 716 | ||
714 | if (NULL == | 717 | if (NULL == |
715 | (connection = MHD_calloc_ (1, | 718 | (connection = MHD_calloc_ (1, |
716 | sizeof (struct MHD_Connection)))) | 719 | sizeof (struct MHD_Connection)))) |
717 | { | 720 | { |
718 | eno = errno; | 721 | eno = errno; |
719 | #ifdef HAVE_MESSAGES | 722 | #ifdef HAVE_MESSAGES |
720 | MHD_DLOG (daemon, | 723 | MHD_DLOG (daemon, |
721 | MHD_SC_CONNECTION_MALLOC_FAILURE, | 724 | MHD_SC_CONNECTION_MALLOC_FAILURE, |
722 | "Error allocating memory: %s\n", | 725 | "Error allocating memory: %s\n", |
723 | MHD_strerror_ (errno)); | 726 | MHD_strerror_ (errno)); |
724 | #endif | 727 | #endif |
725 | MHD_socket_close_chk_ (client_socket); | 728 | MHD_socket_close_chk_ (client_socket); |
726 | MHD_ip_limit_del (daemon, | 729 | MHD_ip_limit_del (daemon, |
727 | addr, | 730 | addr, |
728 | addrlen); | 731 | addrlen); |
729 | errno = eno; | 732 | errno = eno; |
730 | return MHD_SC_CONNECTION_MALLOC_FAILURE; | 733 | return MHD_SC_CONNECTION_MALLOC_FAILURE; |
731 | } | 734 | } |
732 | connection->pool | 735 | connection->pool |
733 | = MHD_pool_create (daemon->connection_memory_limit_b); | 736 | = MHD_pool_create (daemon->connection_memory_limit_b); |
734 | if (NULL == connection->pool) | 737 | if (NULL == connection->pool) |
735 | { | 738 | { |
736 | #ifdef HAVE_MESSAGES | 739 | #ifdef HAVE_MESSAGES |
737 | MHD_DLOG (daemon, | 740 | MHD_DLOG (daemon, |
738 | MHD_SC_POOL_MALLOC_FAILURE, | 741 | MHD_SC_POOL_MALLOC_FAILURE, |
739 | _("Error allocating memory: %s\n"), | 742 | _ ("Error allocating memory: %s\n"), |
740 | MHD_strerror_ (errno)); | 743 | MHD_strerror_ (errno)); |
741 | #endif | 744 | #endif |
742 | MHD_socket_close_chk_ (client_socket); | 745 | MHD_socket_close_chk_ (client_socket); |
743 | MHD_ip_limit_del (daemon, | 746 | MHD_ip_limit_del (daemon, |
744 | addr, | 747 | addr, |
745 | addrlen); | 748 | addrlen); |
746 | free (connection); | 749 | free (connection); |
747 | #if ENOMEM | 750 | #if ENOMEM |
748 | errno = ENOMEM; | 751 | errno = ENOMEM; |
749 | #endif | 752 | #endif |
750 | return MHD_SC_POOL_MALLOC_FAILURE; | 753 | return MHD_SC_POOL_MALLOC_FAILURE; |
751 | } | 754 | } |
752 | 755 | ||
753 | connection->connection_timeout = daemon->connection_default_timeout; | 756 | connection->connection_timeout = daemon->connection_default_timeout; |
754 | memcpy (&connection->addr, | 757 | memcpy (&connection->addr, |
@@ -758,148 +761,151 @@ internal_add_connection (struct MHD_Daemon *daemon, | |||
758 | connection->socket_fd = client_socket; | 761 | connection->socket_fd = client_socket; |
759 | connection->sk_nonblck = non_blck; | 762 | connection->sk_nonblck = non_blck; |
760 | connection->daemon = daemon; | 763 | connection->daemon = daemon; |
761 | connection->last_activity = MHD_monotonic_sec_counter(); | 764 | connection->last_activity = MHD_monotonic_sec_counter (); |
762 | 765 | ||
763 | #ifdef HTTPS_SUPPORT | 766 | #ifdef HTTPS_SUPPORT |
764 | if (NULL != daemon->tls_api) | 767 | if (NULL != daemon->tls_api) |
768 | { | ||
769 | connection->tls_cs | ||
770 | = daemon->tls_api->setup_connection (daemon->tls_api->cls, | ||
771 | NULL /* FIXME */); | ||
772 | if (NULL == connection->tls_cs) | ||
765 | { | 773 | { |
766 | connection->tls_cs | 774 | eno = EINVAL; |
767 | = daemon->tls_api->setup_connection (daemon->tls_api->cls, | 775 | sc = -1; // FIXME! |
768 | NULL /* FIXME */); | 776 | goto cleanup; |
769 | if (NULL == connection->tls_cs) | ||
770 | { | ||
771 | eno = EINVAL; | ||
772 | sc = -1; // FIXME! | ||
773 | goto cleanup; | ||
774 | } | ||
775 | } | 777 | } |
778 | } | ||
776 | else | 779 | else |
777 | #endif /* ! HTTPS_SUPPORT */ | 780 | #endif /* ! HTTPS_SUPPORT */ |
778 | { | 781 | { |
779 | /* set default connection handlers */ | 782 | /* set default connection handlers */ |
780 | connection->recv_cls = &recv_param_adapter; | 783 | connection->recv_cls = &recv_param_adapter; |
781 | connection->send_cls = &send_param_adapter; | 784 | connection->send_cls = &send_param_adapter; |
782 | } | 785 | } |
783 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); | 786 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); |
784 | /* Firm check under lock. */ | 787 | /* Firm check under lock. */ |
785 | if (daemon->connections >= daemon->global_connection_limit) | 788 | if (daemon->connections >= daemon->global_connection_limit) |
786 | { | 789 | { |
787 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); | 790 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); |
788 | /* above connection limit - reject */ | 791 | /* above connection limit - reject */ |
789 | #ifdef HAVE_MESSAGES | 792 | #ifdef HAVE_MESSAGES |
790 | MHD_DLOG (daemon, | 793 | MHD_DLOG (daemon, |
791 | MHD_SC_LIMIT_CONNECTIONS_REACHED, | 794 | MHD_SC_LIMIT_CONNECTIONS_REACHED, |
792 | _("Server reached connection limit. Closing inbound connection.\n")); | 795 | _ ( |
796 | "Server reached connection limit. Closing inbound connection.\n")); | ||
793 | #endif | 797 | #endif |
794 | #if ENFILE | 798 | #if ENFILE |
795 | eno = ENFILE; | 799 | eno = ENFILE; |
796 | #endif | 800 | #endif |
797 | sc = MHD_SC_LIMIT_CONNECTIONS_REACHED; | 801 | sc = MHD_SC_LIMIT_CONNECTIONS_REACHED; |
798 | goto cleanup; | 802 | goto cleanup; |
799 | } | 803 | } |
800 | daemon->connections++; | 804 | daemon->connections++; |
801 | if (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) | 805 | if (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) |
802 | { | 806 | { |
803 | XDLL_insert (daemon->normal_timeout_head, | 807 | XDLL_insert (daemon->normal_timeout_head, |
804 | daemon->normal_timeout_tail, | 808 | daemon->normal_timeout_tail, |
805 | connection); | 809 | connection); |
806 | } | 810 | } |
807 | DLL_insert (daemon->connections_head, | 811 | DLL_insert (daemon->connections_head, |
808 | daemon->connections_tail, | 812 | daemon->connections_tail, |
809 | connection); | 813 | connection); |
810 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); | 814 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); |
811 | 815 | ||
812 | if (NULL != daemon->notify_connection_cb) | 816 | if (NULL != daemon->notify_connection_cb) |
813 | daemon->notify_connection_cb (daemon->notify_connection_cb_cls, | 817 | daemon->notify_connection_cb (daemon->notify_connection_cb_cls, |
814 | connection, | 818 | connection, |
815 | MHD_CONNECTION_NOTIFY_STARTED); | 819 | MHD_CONNECTION_NOTIFY_STARTED); |
816 | 820 | ||
817 | /* attempt to create handler thread */ | 821 | /* attempt to create handler thread */ |
818 | if (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode) | 822 | if (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode) |
823 | { | ||
824 | if (! MHD_create_named_thread_ (&connection->pid, | ||
825 | "MHD-connection", | ||
826 | daemon->thread_stack_limit_b, | ||
827 | &thread_main_handle_connection, | ||
828 | connection)) | ||
819 | { | 829 | { |
820 | if (! MHD_create_named_thread_ (&connection->pid, | 830 | eno = errno; |
821 | "MHD-connection", | ||
822 | daemon->thread_stack_limit_b, | ||
823 | &thread_main_handle_connection, | ||
824 | connection)) | ||
825 | { | ||
826 | eno = errno; | ||
827 | #ifdef HAVE_MESSAGES | 831 | #ifdef HAVE_MESSAGES |
828 | MHD_DLOG (daemon, | 832 | MHD_DLOG (daemon, |
829 | MHD_SC_THREAD_LAUNCH_FAILURE, | 833 | MHD_SC_THREAD_LAUNCH_FAILURE, |
830 | "Failed to create a thread: %s\n", | 834 | "Failed to create a thread: %s\n", |
831 | MHD_strerror_ (eno)); | 835 | MHD_strerror_ (eno)); |
832 | #endif | 836 | #endif |
833 | sc = MHD_SC_THREAD_LAUNCH_FAILURE; | 837 | sc = MHD_SC_THREAD_LAUNCH_FAILURE; |
834 | goto cleanup; | 838 | goto cleanup; |
835 | } | ||
836 | } | 839 | } |
840 | } | ||
837 | else | 841 | else |
838 | { | 842 | { |
839 | connection->pid = daemon->pid; | 843 | connection->pid = daemon->pid; |
840 | } | 844 | } |
841 | #ifdef EPOLL_SUPPORT | 845 | #ifdef EPOLL_SUPPORT |
842 | if (MHD_ELS_EPOLL == daemon->event_loop_syscall) | 846 | if (MHD_ELS_EPOLL == daemon->event_loop_syscall) |
843 | { | 847 | { |
844 | if ( (! daemon->enable_turbo) || | 848 | if ( (! daemon->enable_turbo) || |
845 | (external_add)) | 849 | (external_add)) |
846 | { /* Do not manipulate EReady DL-list in 'external_add' mode. */ | 850 | { /* Do not manipulate EReady DL-list in 'external_add' mode. */ |
847 | struct epoll_event event; | 851 | struct epoll_event event; |
848 | 852 | ||
849 | event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET; | 853 | event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET; |
850 | event.data.ptr = connection; | 854 | event.data.ptr = connection; |
851 | if (0 != epoll_ctl (daemon->epoll_fd, | 855 | if (0 != epoll_ctl (daemon->epoll_fd, |
852 | EPOLL_CTL_ADD, | 856 | EPOLL_CTL_ADD, |
853 | client_socket, | 857 | client_socket, |
854 | &event)) | 858 | &event)) |
855 | { | 859 | { |
856 | eno = errno; | 860 | eno = errno; |
857 | #ifdef HAVE_MESSAGES | 861 | #ifdef HAVE_MESSAGES |
858 | MHD_DLOG (daemon, | 862 | MHD_DLOG (daemon, |
859 | MHD_SC_EPOLL_CTL_ADD_FAILED, | 863 | MHD_SC_EPOLL_CTL_ADD_FAILED, |
860 | _("Call to epoll_ctl failed: %s\n"), | 864 | _ ("Call to epoll_ctl failed: %s\n"), |
861 | MHD_socket_last_strerr_ ()); | 865 | MHD_socket_last_strerr_ ()); |
862 | #endif | 866 | #endif |
863 | sc = MHD_SC_EPOLL_CTL_ADD_FAILED; | 867 | sc = MHD_SC_EPOLL_CTL_ADD_FAILED; |
864 | goto cleanup; | 868 | goto cleanup; |
865 | } | 869 | } |
866 | connection->epoll_state |= MHD_EPOLL_STATE_IN_EPOLL_SET; | 870 | connection->epoll_state |= MHD_EPOLL_STATE_IN_EPOLL_SET; |
867 | } | 871 | } |
868 | else | 872 | else |
869 | { | 873 | { |
870 | connection->epoll_state |= MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_WRITE_READY | 874 | connection->epoll_state |= MHD_EPOLL_STATE_READ_READY |
871 | | MHD_EPOLL_STATE_IN_EREADY_EDLL; | 875 | | MHD_EPOLL_STATE_WRITE_READY |
872 | EDLL_insert (daemon->eready_head, | 876 | | MHD_EPOLL_STATE_IN_EREADY_EDLL; |
873 | daemon->eready_tail, | 877 | EDLL_insert (daemon->eready_head, |
874 | connection); | 878 | daemon->eready_tail, |
875 | } | 879 | connection); |
876 | } | 880 | } |
881 | } | ||
877 | else /* This 'else' is combined with next 'if'. */ | 882 | else /* This 'else' is combined with next 'if'. */ |
878 | #endif | 883 | #endif |
879 | if ( (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) && | 884 | if ( (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) && |
880 | (external_add) && | 885 | (external_add) && |
881 | (MHD_ITC_IS_VALID_(daemon->itc)) && | 886 | (MHD_ITC_IS_VALID_ (daemon->itc)) && |
882 | (! MHD_itc_activate_ (daemon->itc, | 887 | (! MHD_itc_activate_ (daemon->itc, |
883 | "n")) ) | 888 | "n")) ) |
884 | { | 889 | { |
885 | #ifdef HAVE_MESSAGES | 890 | #ifdef HAVE_MESSAGES |
886 | MHD_DLOG (daemon, | 891 | MHD_DLOG (daemon, |
887 | MHD_SC_ITC_USE_FAILED, | 892 | MHD_SC_ITC_USE_FAILED, |
888 | _("Failed to signal new connection via inter-thread communication channel (not necessarily fatal, continuing anyway).")); | 893 | _ ( |
894 | "Failed to signal new connection via inter-thread communication channel (not necessarily fatal, continuing anyway).")); | ||
889 | #endif | 895 | #endif |
890 | } | 896 | } |
891 | return MHD_SC_OK; | 897 | return MHD_SC_OK; |
892 | 898 | ||
893 | cleanup: | 899 | cleanup: |
894 | if (NULL != daemon->notify_connection_cb) | 900 | if (NULL != daemon->notify_connection_cb) |
895 | daemon->notify_connection_cb (daemon->notify_connection_cb_cls, | 901 | daemon->notify_connection_cb (daemon->notify_connection_cb_cls, |
896 | connection, | 902 | connection, |
897 | MHD_CONNECTION_NOTIFY_CLOSED); | 903 | MHD_CONNECTION_NOTIFY_CLOSED); |
898 | #ifdef HTTPS_SUPPORT | 904 | #ifdef HTTPS_SUPPORT |
899 | if ( (NULL != daemon->tls_api) && | 905 | if ( (NULL != daemon->tls_api) && |
900 | (NULL != connection->tls_cs) ) | 906 | (NULL != connection->tls_cs) ) |
901 | daemon->tls_api->teardown_connection (daemon->tls_api->cls, | 907 | daemon->tls_api->teardown_connection (daemon->tls_api->cls, |
902 | connection->tls_cs); | 908 | connection->tls_cs); |
903 | #endif /* HTTPS_SUPPORT */ | 909 | #endif /* HTTPS_SUPPORT */ |
904 | MHD_socket_close_chk_ (client_socket); | 910 | MHD_socket_close_chk_ (client_socket); |
905 | MHD_ip_limit_del (daemon, | 911 | MHD_ip_limit_del (daemon, |
@@ -907,14 +913,14 @@ internal_add_connection (struct MHD_Daemon *daemon, | |||
907 | addrlen); | 913 | addrlen); |
908 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); | 914 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); |
909 | if (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) | 915 | if (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) |
910 | { | 916 | { |
911 | XDLL_remove (daemon->normal_timeout_head, | 917 | XDLL_remove (daemon->normal_timeout_head, |
912 | daemon->normal_timeout_tail, | 918 | daemon->normal_timeout_tail, |
913 | connection); | 919 | connection); |
914 | } | 920 | } |
915 | DLL_remove (daemon->connections_head, | 921 | DLL_remove (daemon->connections_head, |
916 | daemon->connections_tail, | 922 | daemon->connections_tail, |
917 | connection); | 923 | connection); |
918 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); | 924 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); |
919 | MHD_pool_destroy (connection->pool); | 925 | MHD_pool_destroy (connection->pool); |
920 | free (connection); | 926 | free (connection); |
@@ -954,42 +960,42 @@ internal_add_connection (struct MHD_Daemon *daemon, | |||
954 | */ | 960 | */ |
955 | enum MHD_StatusCode | 961 | enum MHD_StatusCode |
956 | MHD_daemon_add_connection (struct MHD_Daemon *daemon, | 962 | MHD_daemon_add_connection (struct MHD_Daemon *daemon, |
957 | MHD_socket client_socket, | 963 | MHD_socket client_socket, |
958 | const struct sockaddr *addr, | 964 | const struct sockaddr *addr, |
959 | socklen_t addrlen) | 965 | socklen_t addrlen) |
960 | { | 966 | { |
961 | bool sk_nonbl; | 967 | bool sk_nonbl; |
962 | 968 | ||
963 | if (! MHD_socket_nonblocking_ (client_socket)) | 969 | if (! MHD_socket_nonblocking_ (client_socket)) |
964 | { | 970 | { |
965 | #ifdef HAVE_MESSAGES | 971 | #ifdef HAVE_MESSAGES |
966 | MHD_DLOG (daemon, | 972 | MHD_DLOG (daemon, |
967 | MHD_SC_ACCEPT_CONFIGURE_NONBLOCKING_FAILED, | 973 | MHD_SC_ACCEPT_CONFIGURE_NONBLOCKING_FAILED, |
968 | _("Failed to set nonblocking mode on new client socket: %s\n"), | 974 | _ ("Failed to set nonblocking mode on new client socket: %s\n"), |
969 | MHD_socket_last_strerr_()); | 975 | MHD_socket_last_strerr_ ()); |
970 | #endif | 976 | #endif |
971 | sk_nonbl = false; | 977 | sk_nonbl = false; |
972 | } | 978 | } |
973 | else | 979 | else |
974 | { | 980 | { |
975 | sk_nonbl = true; | 981 | sk_nonbl = true; |
976 | } | 982 | } |
977 | 983 | ||
978 | if ( (daemon->enable_turbo) && | 984 | if ( (daemon->enable_turbo) && |
979 | (! MHD_socket_noninheritable_ (client_socket)) ) | 985 | (! MHD_socket_noninheritable_ (client_socket)) ) |
980 | { | 986 | { |
981 | #ifdef HAVE_MESSAGES | 987 | #ifdef HAVE_MESSAGES |
982 | MHD_DLOG (daemon, | 988 | MHD_DLOG (daemon, |
983 | MHD_SC_ACCEPT_CONFIGURE_NOINHERIT_FAILED, | 989 | MHD_SC_ACCEPT_CONFIGURE_NOINHERIT_FAILED, |
984 | _("Failed to set noninheritable mode on new client socket.\n")); | 990 | _ ("Failed to set noninheritable mode on new client socket.\n")); |
985 | #endif | 991 | #endif |
986 | } | 992 | } |
987 | return internal_add_connection (daemon, | 993 | return internal_add_connection (daemon, |
988 | client_socket, | 994 | client_socket, |
989 | addr, | 995 | addr, |
990 | addrlen, | 996 | addrlen, |
991 | true, | 997 | true, |
992 | sk_nonbl); | 998 | sk_nonbl); |
993 | } | 999 | } |
994 | 1000 | ||
995 | 1001 | ||
@@ -1033,94 +1039,98 @@ MHD_accept_connection_ (struct MHD_Daemon *daemon) | |||
1033 | #endif /* ! USE_ACCEPT4 */ | 1039 | #endif /* ! USE_ACCEPT4 */ |
1034 | if ( (MHD_INVALID_SOCKET == s) || | 1040 | if ( (MHD_INVALID_SOCKET == s) || |
1035 | (addrlen <= 0) ) | 1041 | (addrlen <= 0) ) |
1036 | { | 1042 | { |
1037 | const int err = MHD_socket_get_error_ (); | 1043 | const int err = MHD_socket_get_error_ (); |
1038 | 1044 | ||
1039 | /* This could be a common occurance with multiple worker threads */ | 1045 | /* This could be a common occurance with multiple worker threads */ |
1040 | if (MHD_SCKT_ERR_IS_ (err, | 1046 | if (MHD_SCKT_ERR_IS_ (err, |
1041 | MHD_SCKT_EINVAL_)) | 1047 | MHD_SCKT_EINVAL_)) |
1042 | return MHD_SC_DAEMON_ALREADY_SHUTDOWN; /* can happen during shutdown, let's hope this is the cause... */ | 1048 | return MHD_SC_DAEMON_ALREADY_SHUTDOWN; /* can happen during shutdown, let's hope this is the cause... */ |
1043 | if (MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_(err)) | 1049 | if (MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_ (err)) |
1044 | return MHD_SC_ACCEPT_FAST_DISCONNECT; /* do not print error if client just disconnected early */ | 1050 | return MHD_SC_ACCEPT_FAST_DISCONNECT; /* do not print error if client just disconnected early */ |
1045 | if (MHD_SCKT_ERR_IS_EAGAIN_ (err) ) | 1051 | if (MHD_SCKT_ERR_IS_EAGAIN_ (err) ) |
1046 | return MHD_SC_ACCEPT_FAILED_EAGAIN; | 1052 | return MHD_SC_ACCEPT_FAILED_EAGAIN; |
1047 | if (MHD_INVALID_SOCKET != s) | 1053 | if (MHD_INVALID_SOCKET != s) |
1048 | { | 1054 | { |
1049 | MHD_socket_close_chk_ (s); | 1055 | MHD_socket_close_chk_ (s); |
1050 | } | 1056 | } |
1051 | if ( MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err) ) | 1057 | if ( MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err) ) |
1052 | { | 1058 | { |
1053 | /* system/process out of resources */ | 1059 | /* system/process out of resources */ |
1054 | if (0 == daemon->connections) | 1060 | if (0 == daemon->connections) |
1055 | { | 1061 | { |
1056 | #ifdef HAVE_MESSAGES | 1062 | #ifdef HAVE_MESSAGES |
1057 | /* Not setting 'at_limit' flag, as there is no way it | 1063 | /* Not setting 'at_limit' flag, as there is no way it |
1058 | would ever be cleared. Instead trying to produce | 1064 | would ever be cleared. Instead trying to produce |
1059 | bit fat ugly warning. */ | 1065 | bit fat ugly warning. */ |
1060 | MHD_DLOG (daemon, | 1066 | MHD_DLOG (daemon, |
1061 | MHD_SC_ACCEPT_SYSTEM_LIMIT_REACHED_INSTANTLY, | 1067 | MHD_SC_ACCEPT_SYSTEM_LIMIT_REACHED_INSTANTLY, |
1062 | _("Hit process or system resource limit at FIRST connection. This is really bad as there is no sane way to proceed. Will try busy waiting for system resources to become magically available.\n")); | 1068 | _ ( |
1069 | "Hit process or system resource limit at FIRST connection. This is really bad as there is no sane way to proceed. Will try busy waiting for system resources to become magically available.\n")); | ||
1063 | #endif | 1070 | #endif |
1064 | return MHD_SC_ACCEPT_SYSTEM_LIMIT_REACHED_INSTANTLY; | 1071 | return MHD_SC_ACCEPT_SYSTEM_LIMIT_REACHED_INSTANTLY; |
1065 | } | 1072 | } |
1066 | else | 1073 | else |
1067 | { | 1074 | { |
1068 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); | 1075 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); |
1069 | daemon->at_limit = true; | 1076 | daemon->at_limit = true; |
1070 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); | 1077 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); |
1071 | #ifdef HAVE_MESSAGES | 1078 | #ifdef HAVE_MESSAGES |
1072 | MHD_DLOG (daemon, | 1079 | MHD_DLOG (daemon, |
1073 | MHD_SC_ACCEPT_SYSTEM_LIMIT_REACHED, | 1080 | MHD_SC_ACCEPT_SYSTEM_LIMIT_REACHED, |
1074 | _("Hit process or system resource limit at %u connections, temporarily suspending accept(). Consider setting a lower MHD_OPTION_CONNECTION_LIMIT.\n"), | 1081 | _ ( |
1075 | (unsigned int) daemon->connections); | 1082 | "Hit process or system resource limit at %u connections, temporarily suspending accept(). Consider setting a lower MHD_OPTION_CONNECTION_LIMIT.\n"), |
1083 | (unsigned int) daemon->connections); | ||
1076 | #endif | 1084 | #endif |
1077 | return MHD_SC_ACCEPT_SYSTEM_LIMIT_REACHED; | 1085 | return MHD_SC_ACCEPT_SYSTEM_LIMIT_REACHED; |
1078 | } | 1086 | } |
1079 | } | 1087 | } |
1080 | #ifdef HAVE_MESSAGES | 1088 | #ifdef HAVE_MESSAGES |
1081 | MHD_DLOG (daemon, | 1089 | MHD_DLOG (daemon, |
1082 | MHD_SC_ACCEPT_FAILED_UNEXPECTEDLY, | 1090 | MHD_SC_ACCEPT_FAILED_UNEXPECTEDLY, |
1083 | _("Error accepting connection: %s\n"), | 1091 | _ ("Error accepting connection: %s\n"), |
1084 | MHD_socket_strerr_(err)); | 1092 | MHD_socket_strerr_ (err)); |
1085 | #endif | 1093 | #endif |
1086 | return MHD_SC_ACCEPT_FAILED_UNEXPECTEDLY; | 1094 | return MHD_SC_ACCEPT_FAILED_UNEXPECTEDLY; |
1087 | } | 1095 | } |
1088 | #if !defined(USE_ACCEPT4) || !defined(HAVE_SOCK_NONBLOCK) | 1096 | #if ! defined(USE_ACCEPT4) || ! defined(HAVE_SOCK_NONBLOCK) |
1089 | if (! MHD_socket_nonblocking_ (s)) | 1097 | if (! MHD_socket_nonblocking_ (s)) |
1090 | { | 1098 | { |
1091 | #ifdef HAVE_MESSAGES | 1099 | #ifdef HAVE_MESSAGES |
1092 | MHD_DLOG (daemon, | 1100 | MHD_DLOG (daemon, |
1093 | MHD_SC_ACCEPT_CONFIGURE_NONBLOCKING_FAILED, | 1101 | MHD_SC_ACCEPT_CONFIGURE_NONBLOCKING_FAILED, |
1094 | _("Failed to set nonblocking mode on incoming connection socket: %s\n"), | 1102 | _ ( |
1095 | MHD_socket_last_strerr_()); | 1103 | "Failed to set nonblocking mode on incoming connection socket: %s\n"), |
1104 | MHD_socket_last_strerr_ ()); | ||
1096 | #endif | 1105 | #endif |
1097 | } | 1106 | } |
1098 | else | 1107 | else |
1099 | sk_nonbl = true; | 1108 | sk_nonbl = true; |
1100 | #endif /* !USE_ACCEPT4 || !HAVE_SOCK_NONBLOCK */ | 1109 | #endif /* !USE_ACCEPT4 || !HAVE_SOCK_NONBLOCK */ |
1101 | #if !defined(USE_ACCEPT4) || !defined(SOCK_CLOEXEC) | 1110 | #if ! defined(USE_ACCEPT4) || ! defined(SOCK_CLOEXEC) |
1102 | if (! MHD_socket_noninheritable_ (s)) | 1111 | if (! MHD_socket_noninheritable_ (s)) |
1103 | { | 1112 | { |
1104 | #ifdef HAVE_MESSAGES | 1113 | #ifdef HAVE_MESSAGES |
1105 | MHD_DLOG (daemon, | 1114 | MHD_DLOG (daemon, |
1106 | MHD_SC_ACCEPT_CONFIGURE_NOINHERIT_FAILED, | 1115 | MHD_SC_ACCEPT_CONFIGURE_NOINHERIT_FAILED, |
1107 | _("Failed to set noninheritable mode on incoming connection socket.\n")); | 1116 | _ ( |
1117 | "Failed to set noninheritable mode on incoming connection socket.\n")); | ||
1108 | #endif | 1118 | #endif |
1109 | } | 1119 | } |
1110 | #endif /* !USE_ACCEPT4 || !SOCK_CLOEXEC */ | 1120 | #endif /* !USE_ACCEPT4 || !SOCK_CLOEXEC */ |
1111 | #ifdef HAVE_MESSAGES | 1121 | #ifdef HAVE_MESSAGES |
1112 | #if DEBUG_CONNECT | 1122 | #if DEBUG_CONNECT |
1113 | MHD_DLOG (daemon, | 1123 | MHD_DLOG (daemon, |
1114 | MHD_SC_CONNECTION_ACCEPTED, | 1124 | MHD_SC_CONNECTION_ACCEPTED, |
1115 | _("Accepted connection on socket %d\n"), | 1125 | _ ("Accepted connection on socket %d\n"), |
1116 | s); | 1126 | s); |
1117 | #endif | 1127 | #endif |
1118 | #endif | 1128 | #endif |
1119 | return internal_add_connection (daemon, | 1129 | return internal_add_connection (daemon, |
1120 | s, | 1130 | s, |
1121 | addr, | 1131 | addr, |
1122 | addrlen, | 1132 | addrlen, |
1123 | false, | 1133 | false, |
1124 | sk_nonbl); | 1134 | sk_nonbl); |
1125 | } | 1135 | } |
1126 | 1136 | ||
diff --git a/src/lib/connection_add.h b/src/lib/connection_add.h index 6957fd77..de8abd9a 100644 --- a/src/lib/connection_add.h +++ b/src/lib/connection_add.h | |||
@@ -32,10 +32,10 @@ | |||
32 | * that process daemon's select()/poll()/etc. | 32 | * that process daemon's select()/poll()/etc. |
33 | * | 33 | * |
34 | * @param daemon handle with the listen socket | 34 | * @param daemon handle with the listen socket |
35 | * @return #MHD_SC_OK on success | 35 | * @return #MHD_SC_OK on success |
36 | */ | 36 | */ |
37 | enum MHD_StatusCode | 37 | enum MHD_StatusCode |
38 | MHD_accept_connection_ (struct MHD_Daemon *daemon) | 38 | MHD_accept_connection_ (struct MHD_Daemon *daemon) |
39 | MHD_NONNULL (1); | 39 | MHD_NONNULL (1); |
40 | 40 | ||
41 | #endif | 41 | #endif |
diff --git a/src/lib/connection_call_handlers.c b/src/lib/connection_call_handlers.c index af8860d6..c4fb448e 100644 --- a/src/lib/connection_call_handlers.c +++ b/src/lib/connection_call_handlers.c | |||
@@ -56,7 +56,8 @@ | |||
56 | * minimal. | 56 | * minimal. |
57 | */ | 57 | */ |
58 | #ifdef HAVE_MESSAGES | 58 | #ifdef HAVE_MESSAGES |
59 | #define REQUEST_TOO_BIG "<html><head><title>Request too big</title></head><body>Your HTTP header was too big for the memory constraints of this webserver.</body></html>" | 59 | #define REQUEST_TOO_BIG \ |
60 | "<html><head><title>Request too big</title></head><body>Your HTTP header was too big for the memory constraints of this webserver.</body></html>" | ||
60 | #else | 61 | #else |
61 | #define REQUEST_TOO_BIG "" | 62 | #define REQUEST_TOO_BIG "" |
62 | #endif | 63 | #endif |
@@ -69,7 +70,8 @@ | |||
69 | * minimal. | 70 | * minimal. |
70 | */ | 71 | */ |
71 | #ifdef HAVE_MESSAGES | 72 | #ifdef HAVE_MESSAGES |
72 | #define REQUEST_LACKS_HOST "<html><head><title>"Host:" header required</title></head><body>In HTTP 1.1, requests must include a "Host:" header, and your HTTP 1.1 request lacked such a header.</body></html>" | 73 | #define REQUEST_LACKS_HOST \ |
74 | "<html><head><title>"Host:" header required</title></head><body>In HTTP 1.1, requests must include a "Host:" header, and your HTTP 1.1 request lacked such a header.</body></html>" | ||
73 | #else | 75 | #else |
74 | #define REQUEST_LACKS_HOST "" | 76 | #define REQUEST_LACKS_HOST "" |
75 | #endif | 77 | #endif |
@@ -82,7 +84,8 @@ | |||
82 | * minimal. | 84 | * minimal. |
83 | */ | 85 | */ |
84 | #ifdef HAVE_MESSAGES | 86 | #ifdef HAVE_MESSAGES |
85 | #define REQUEST_MALFORMED "<html><head><title>Request malformed</title></head><body>Your HTTP request was syntactically incorrect.</body></html>" | 87 | #define REQUEST_MALFORMED \ |
88 | "<html><head><title>Request malformed</title></head><body>Your HTTP request was syntactically incorrect.</body></html>" | ||
86 | #else | 89 | #else |
87 | #define REQUEST_MALFORMED "" | 90 | #define REQUEST_MALFORMED "" |
88 | #endif | 91 | #endif |
@@ -94,7 +97,8 @@ | |||
94 | * minimal. | 97 | * minimal. |
95 | */ | 98 | */ |
96 | #ifdef HAVE_MESSAGES | 99 | #ifdef HAVE_MESSAGES |
97 | #define INTERNAL_ERROR "<html><head><title>Internal server error</title></head><body>Please ask the developer of this Web server to carefully read the GNU libmicrohttpd documentation about connection management and blocking.</body></html>" | 100 | #define INTERNAL_ERROR \ |
101 | "<html><head><title>Internal server error</title></head><body>Please ask the developer of this Web server to carefully read the GNU libmicrohttpd documentation about connection management and blocking.</body></html>" | ||
98 | #else | 102 | #else |
99 | #define INTERNAL_ERROR "" | 103 | #define INTERNAL_ERROR "" |
100 | #endif | 104 | #endif |
@@ -128,17 +132,18 @@ MHD_conn_init_static_ (void) | |||
128 | #ifdef SF_FLAGS | 132 | #ifdef SF_FLAGS |
129 | long sys_page_size = sysconf (_SC_PAGESIZE); | 133 | long sys_page_size = sysconf (_SC_PAGESIZE); |
130 | if (0 > sys_page_size) | 134 | if (0 > sys_page_size) |
131 | { /* Failed to get page size. */ | 135 | { /* Failed to get page size. */ |
132 | freebsd_sendfile_flags_ = SF_NODISKIO; | 136 | freebsd_sendfile_flags_ = SF_NODISKIO; |
133 | freebsd_sendfile_flags_thd_p_c_ = SF_NODISKIO; | 137 | freebsd_sendfile_flags_thd_p_c_ = SF_NODISKIO; |
134 | } | 138 | } |
135 | else | 139 | else |
136 | { | 140 | { |
137 | freebsd_sendfile_flags_ = | 141 | freebsd_sendfile_flags_ = |
138 | SF_FLAGS((uint16_t)(MHD_SENFILE_CHUNK_ / sys_page_size), SF_NODISKIO); | 142 | SF_FLAGS ((uint16_t) (MHD_SENFILE_CHUNK_ / sys_page_size), SF_NODISKIO); |
139 | freebsd_sendfile_flags_thd_p_c_ = | 143 | freebsd_sendfile_flags_thd_p_c_ = |
140 | SF_FLAGS((uint16_t)(MHD_SENFILE_CHUNK_THR_P_C_ / sys_page_size), SF_NODISKIO); | 144 | SF_FLAGS ((uint16_t) (MHD_SENFILE_CHUNK_THR_P_C_ / sys_page_size), |
141 | } | 145 | SF_NODISKIO); |
146 | } | ||
142 | #endif /* SF_FLAGS */ | 147 | #endif /* SF_FLAGS */ |
143 | } | 148 | } |
144 | #endif /* HAVE_FREEBSD_SENDFILE */ | 149 | #endif /* HAVE_FREEBSD_SENDFILE */ |
@@ -161,13 +166,13 @@ MHD_conn_init_static_ (void) | |||
161 | */ | 166 | */ |
162 | static void | 167 | static void |
163 | connection_close_error (struct MHD_Connection *connection, | 168 | connection_close_error (struct MHD_Connection *connection, |
164 | enum MHD_StatusCode sc, | 169 | enum MHD_StatusCode sc, |
165 | const char *emsg) | 170 | const char *emsg) |
166 | { | 171 | { |
167 | #ifdef HAVE_MESSAGES | 172 | #ifdef HAVE_MESSAGES |
168 | if (NULL != emsg) | 173 | if (NULL != emsg) |
169 | MHD_DLOG (connection->daemon, | 174 | MHD_DLOG (connection->daemon, |
170 | sc, | 175 | sc, |
171 | emsg); | 176 | emsg); |
172 | #else /* ! HAVE_MESSAGES */ | 177 | #else /* ! HAVE_MESSAGES */ |
173 | (void) emsg; /* Mute compiler warning. */ | 178 | (void) emsg; /* Mute compiler warning. */ |
@@ -209,8 +214,8 @@ try_grow_read_buffer (struct MHD_Request *request) | |||
209 | if (0 == request->read_buffer_size) | 214 | if (0 == request->read_buffer_size) |
210 | new_size = daemon->connection_memory_limit_b / 2; | 215 | new_size = daemon->connection_memory_limit_b / 2; |
211 | else | 216 | else |
212 | new_size = request->read_buffer_size + | 217 | new_size = request->read_buffer_size |
213 | daemon->connection_memory_increment_b; | 218 | + daemon->connection_memory_increment_b; |
214 | buf = MHD_pool_reallocate (request->connection->pool, | 219 | buf = MHD_pool_reallocate (request->connection->pool, |
215 | request->read_buffer, | 220 | request->read_buffer, |
216 | request->read_buffer_size, | 221 | request->read_buffer_size, |
@@ -245,16 +250,16 @@ MHD_request_handle_read_ (struct MHD_Request *request) | |||
245 | struct MHD_TLS_Plugin *tls; | 250 | struct MHD_TLS_Plugin *tls; |
246 | 251 | ||
247 | if ( (NULL != (tls = daemon->tls_api)) && | 252 | if ( (NULL != (tls = daemon->tls_api)) && |
248 | (! tls->handshake (tls->cls, | 253 | (! tls->handshake (tls->cls, |
249 | connection->tls_cs)) ) | 254 | connection->tls_cs)) ) |
250 | return; | 255 | return; |
251 | } | 256 | } |
252 | #endif /* HTTPS_SUPPORT */ | 257 | #endif /* HTTPS_SUPPORT */ |
253 | 258 | ||
254 | /* make sure "read" has a reasonable number of bytes | 259 | /* make sure "read" has a reasonable number of bytes |
255 | in buffer to use per system call (if possible) */ | 260 | in buffer to use per system call (if possible) */ |
256 | if (request->read_buffer_offset + | 261 | if (request->read_buffer_offset |
257 | daemon->connection_memory_increment_b > | 262 | + daemon->connection_memory_increment_b > |
258 | request->read_buffer_size) | 263 | request->read_buffer_size) |
259 | try_grow_read_buffer (request); | 264 | try_grow_read_buffer (request); |
260 | 265 | ||
@@ -263,82 +268,84 @@ MHD_request_handle_read_ (struct MHD_Request *request) | |||
263 | bytes_read = connection->recv_cls (connection, | 268 | bytes_read = connection->recv_cls (connection, |
264 | &request->read_buffer | 269 | &request->read_buffer |
265 | [request->read_buffer_offset], | 270 | [request->read_buffer_offset], |
266 | request->read_buffer_size - | 271 | request->read_buffer_size |
267 | request->read_buffer_offset); | 272 | - request->read_buffer_offset); |
268 | if (bytes_read < 0) | 273 | if (bytes_read < 0) |
274 | { | ||
275 | if (MHD_ERR_AGAIN_ == bytes_read) | ||
276 | return; /* No new data to process. */ | ||
277 | if (MHD_ERR_CONNRESET_ == bytes_read) | ||
269 | { | 278 | { |
270 | if (MHD_ERR_AGAIN_ == bytes_read) | ||
271 | return; /* No new data to process. */ | ||
272 | if (MHD_ERR_CONNRESET_ == bytes_read) | ||
273 | { | ||
274 | CONNECTION_CLOSE_ERROR (connection, | ||
275 | (MHD_REQUEST_INIT == request->state) | ||
276 | ? MHD_SC_CONNECTION_CLOSED | ||
277 | : MHD_SC_CONNECTION_RESET_CLOSED, | ||
278 | (MHD_REQUEST_INIT == request->state) | ||
279 | ? NULL | ||
280 | : _("Socket disconnected while reading request.\n")); | ||
281 | return; | ||
282 | } | ||
283 | CONNECTION_CLOSE_ERROR (connection, | 279 | CONNECTION_CLOSE_ERROR (connection, |
284 | (MHD_REQUEST_INIT == request->state) | ||
285 | ? MHD_SC_CONNECTION_CLOSED | ||
286 | : MHD_SC_CONNECTION_READ_FAIL_CLOSED, | ||
287 | (MHD_REQUEST_INIT == request->state) | 280 | (MHD_REQUEST_INIT == request->state) |
288 | ? NULL | 281 | ? MHD_SC_CONNECTION_CLOSED |
289 | : _("Connection socket is closed due to error when reading request.\n")); | 282 | : MHD_SC_CONNECTION_RESET_CLOSED, |
283 | (MHD_REQUEST_INIT == request->state) | ||
284 | ? NULL | ||
285 | : _ ( | ||
286 | "Socket disconnected while reading request.\n")); | ||
290 | return; | 287 | return; |
291 | } | 288 | } |
289 | CONNECTION_CLOSE_ERROR (connection, | ||
290 | (MHD_REQUEST_INIT == request->state) | ||
291 | ? MHD_SC_CONNECTION_CLOSED | ||
292 | : MHD_SC_CONNECTION_READ_FAIL_CLOSED, | ||
293 | (MHD_REQUEST_INIT == request->state) | ||
294 | ? NULL | ||
295 | : _ ( | ||
296 | "Connection socket is closed due to error when reading request.\n")); | ||
297 | return; | ||
298 | } | ||
292 | 299 | ||
293 | if (0 == bytes_read) | 300 | if (0 == bytes_read) |
294 | { /* Remote side closed connection. */ | 301 | { /* Remote side closed connection. */ |
295 | connection->read_closed = true; | 302 | connection->read_closed = true; |
296 | MHD_connection_close_ (connection, | 303 | MHD_connection_close_ (connection, |
297 | MHD_REQUEST_TERMINATED_CLIENT_ABORT); | 304 | MHD_REQUEST_TERMINATED_CLIENT_ABORT); |
298 | return; | 305 | return; |
299 | } | 306 | } |
300 | request->read_buffer_offset += bytes_read; | 307 | request->read_buffer_offset += bytes_read; |
301 | MHD_connection_update_last_activity_ (connection); | 308 | MHD_connection_update_last_activity_ (connection); |
302 | #if DEBUG_STATES | 309 | #if DEBUG_STATES |
303 | MHD_DLOG (daemon, | 310 | MHD_DLOG (daemon, |
304 | MHD_SC_STATE_MACHINE_STATUS_REPORT, | 311 | MHD_SC_STATE_MACHINE_STATUS_REPORT, |
305 | _("In function %s handling connection at state: %s\n"), | 312 | _ ("In function %s handling connection at state: %s\n"), |
306 | __FUNCTION__, | 313 | __FUNCTION__, |
307 | MHD_state_to_string (request->state)); | 314 | MHD_state_to_string (request->state)); |
308 | #endif | 315 | #endif |
309 | switch (request->state) | 316 | switch (request->state) |
317 | { | ||
318 | case MHD_REQUEST_INIT: | ||
319 | case MHD_REQUEST_URL_RECEIVED: | ||
320 | case MHD_REQUEST_HEADER_PART_RECEIVED: | ||
321 | case MHD_REQUEST_HEADERS_RECEIVED: | ||
322 | case MHD_REQUEST_HEADERS_PROCESSED: | ||
323 | case MHD_REQUEST_CONTINUE_SENDING: | ||
324 | case MHD_REQUEST_CONTINUE_SENT: | ||
325 | case MHD_REQUEST_BODY_RECEIVED: | ||
326 | case MHD_REQUEST_FOOTER_PART_RECEIVED: | ||
327 | /* nothing to do but default action */ | ||
328 | if (connection->read_closed) | ||
310 | { | 329 | { |
311 | case MHD_REQUEST_INIT: | 330 | MHD_connection_close_ (connection, |
312 | case MHD_REQUEST_URL_RECEIVED: | 331 | MHD_REQUEST_TERMINATED_READ_ERROR); |
313 | case MHD_REQUEST_HEADER_PART_RECEIVED: | 332 | } |
314 | case MHD_REQUEST_HEADERS_RECEIVED: | 333 | return; |
315 | case MHD_REQUEST_HEADERS_PROCESSED: | 334 | case MHD_REQUEST_CLOSED: |
316 | case MHD_REQUEST_CONTINUE_SENDING: | 335 | return; |
317 | case MHD_REQUEST_CONTINUE_SENT: | ||
318 | case MHD_REQUEST_BODY_RECEIVED: | ||
319 | case MHD_REQUEST_FOOTER_PART_RECEIVED: | ||
320 | /* nothing to do but default action */ | ||
321 | if (connection->read_closed) | ||
322 | { | ||
323 | MHD_connection_close_ (connection, | ||
324 | MHD_REQUEST_TERMINATED_READ_ERROR); | ||
325 | } | ||
326 | return; | ||
327 | case MHD_REQUEST_CLOSED: | ||
328 | return; | ||
329 | #ifdef UPGRADE_SUPPORT | 336 | #ifdef UPGRADE_SUPPORT |
330 | case MHD_REQUEST_UPGRADE: | 337 | case MHD_REQUEST_UPGRADE: |
331 | mhd_assert (0); | 338 | mhd_assert (0); |
332 | return; | 339 | return; |
333 | #endif /* UPGRADE_SUPPORT */ | 340 | #endif /* UPGRADE_SUPPORT */ |
334 | default: | 341 | default: |
335 | /* shrink read buffer to how much is actually used */ | 342 | /* shrink read buffer to how much is actually used */ |
336 | MHD_pool_reallocate (connection->pool, | 343 | MHD_pool_reallocate (connection->pool, |
337 | request->read_buffer, | 344 | request->read_buffer, |
338 | request->read_buffer_size + 1, | 345 | request->read_buffer_size + 1, |
339 | request->read_buffer_offset); | 346 | request->read_buffer_offset); |
340 | break; | 347 | break; |
341 | } | 348 | } |
342 | return; | 349 | return; |
343 | } | 350 | } |
344 | 351 | ||
@@ -361,9 +368,9 @@ sendfile_adapter (struct MHD_Connection *connection) | |||
361 | uint64_t left; | 368 | uint64_t left; |
362 | uint64_t offsetu64; | 369 | uint64_t offsetu64; |
363 | #ifndef HAVE_SENDFILE64 | 370 | #ifndef HAVE_SENDFILE64 |
364 | const uint64_t max_off_t = (uint64_t)OFF_T_MAX; | 371 | const uint64_t max_off_t = (uint64_t) OFF_T_MAX; |
365 | #else /* HAVE_SENDFILE64 */ | 372 | #else /* HAVE_SENDFILE64 */ |
366 | const uint64_t max_off_t = (uint64_t)OFF64_T_MAX; | 373 | const uint64_t max_off_t = (uint64_t) OFF64_T_MAX; |
367 | #endif /* HAVE_SENDFILE64 */ | 374 | #endif /* HAVE_SENDFILE64 */ |
368 | #ifdef MHD_LINUX_SOLARIS_SENDFILE | 375 | #ifdef MHD_LINUX_SOLARIS_SENDFILE |
369 | #ifndef HAVE_SENDFILE64 | 376 | #ifndef HAVE_SENDFILE64 |
@@ -379,8 +386,10 @@ sendfile_adapter (struct MHD_Connection *connection) | |||
379 | #ifdef HAVE_DARWIN_SENDFILE | 386 | #ifdef HAVE_DARWIN_SENDFILE |
380 | off_t len; | 387 | off_t len; |
381 | #endif /* HAVE_DARWIN_SENDFILE */ | 388 | #endif /* HAVE_DARWIN_SENDFILE */ |
382 | const bool used_thr_p_c = (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode); | 389 | const bool used_thr_p_c = (MHD_TM_THREAD_PER_CONNECTION == |
383 | const size_t chunk_size = used_thr_p_c ? MHD_SENFILE_CHUNK_THR_P_C_ : MHD_SENFILE_CHUNK_; | 390 | daemon->threading_mode); |
391 | const size_t chunk_size = used_thr_p_c ? MHD_SENFILE_CHUNK_THR_P_C_ : | ||
392 | MHD_SENFILE_CHUNK_; | ||
384 | size_t send_size = 0; | 393 | size_t send_size = 0; |
385 | 394 | ||
386 | mhd_assert (MHD_resp_sender_sendfile == request->resp_sender); | 395 | mhd_assert (MHD_resp_sender_sendfile == request->resp_sender); |
@@ -390,10 +399,10 @@ sendfile_adapter (struct MHD_Connection *connection) | |||
390 | * use 128KiB chunks (2MiB for thread-per-connection). */ | 399 | * use 128KiB chunks (2MiB for thread-per-connection). */ |
391 | send_size = (left > chunk_size) ? chunk_size : (size_t) left; | 400 | send_size = (left > chunk_size) ? chunk_size : (size_t) left; |
392 | if (max_off_t < offsetu64) | 401 | if (max_off_t < offsetu64) |
393 | { /* Retry to send with standard 'send()'. */ | 402 | { /* Retry to send with standard 'send()'. */ |
394 | request->resp_sender = MHD_resp_sender_std; | 403 | request->resp_sender = MHD_resp_sender_std; |
395 | return MHD_ERR_AGAIN_; | 404 | return MHD_ERR_AGAIN_; |
396 | } | 405 | } |
397 | #ifdef MHD_LINUX_SOLARIS_SENDFILE | 406 | #ifdef MHD_LINUX_SOLARIS_SENDFILE |
398 | #ifndef HAVE_SENDFILE64 | 407 | #ifndef HAVE_SENDFILE64 |
399 | offset = (off_t) offsetu64; | 408 | offset = (off_t) offsetu64; |
@@ -409,54 +418,54 @@ sendfile_adapter (struct MHD_Connection *connection) | |||
409 | send_size); | 418 | send_size); |
410 | #endif /* HAVE_SENDFILE64 */ | 419 | #endif /* HAVE_SENDFILE64 */ |
411 | if (0 > ret) | 420 | if (0 > ret) |
412 | { | 421 | { |
413 | const int err = MHD_socket_get_error_(); | 422 | const int err = MHD_socket_get_error_ (); |
414 | 423 | ||
415 | if (MHD_SCKT_ERR_IS_EAGAIN_(err)) | 424 | if (MHD_SCKT_ERR_IS_EAGAIN_ (err)) |
416 | { | 425 | { |
417 | #ifdef EPOLL_SUPPORT | 426 | #ifdef EPOLL_SUPPORT |
418 | /* EAGAIN --- no longer write-ready */ | 427 | /* EAGAIN --- no longer write-ready */ |
419 | connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY; | 428 | connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY; |
420 | #endif /* EPOLL_SUPPORT */ | 429 | #endif /* EPOLL_SUPPORT */ |
421 | return MHD_ERR_AGAIN_; | 430 | return MHD_ERR_AGAIN_; |
422 | } | 431 | } |
423 | if (MHD_SCKT_ERR_IS_EINTR_ (err)) | 432 | if (MHD_SCKT_ERR_IS_EINTR_ (err)) |
424 | return MHD_ERR_AGAIN_; | 433 | return MHD_ERR_AGAIN_; |
425 | #ifdef HAVE_LINUX_SENDFILE | 434 | #ifdef HAVE_LINUX_SENDFILE |
426 | if (MHD_SCKT_ERR_IS_(err, | 435 | if (MHD_SCKT_ERR_IS_ (err, |
427 | MHD_SCKT_EBADF_)) | 436 | MHD_SCKT_EBADF_)) |
428 | return MHD_ERR_BADF_; | 437 | return MHD_ERR_BADF_; |
429 | /* sendfile() failed with EINVAL if mmap()-like operations are not | 438 | /* sendfile() failed with EINVAL if mmap()-like operations are not |
430 | supported for FD or other 'unusual' errors occurred, so we should try | 439 | supported for FD or other 'unusual' errors occurred, so we should try |
431 | to fall back to 'SEND'; see also this thread for info on | 440 | to fall back to 'SEND'; see also this thread for info on |
432 | odd libc/Linux behavior with sendfile: | 441 | odd libc/Linux behavior with sendfile: |
433 | http://lists.gnu.org/archive/html/libmicrohttpd/2011-02/msg00015.html */ | 442 | http://lists.gnu.org/archive/html/libmicrohttpd/2011-02/msg00015.html */ |
443 | request->resp_sender = MHD_resp_sender_std; | ||
444 | return MHD_ERR_AGAIN_; | ||
445 | #else /* HAVE_SOLARIS_SENDFILE */ | ||
446 | if ( (EAFNOSUPPORT == err) || | ||
447 | (EINVAL == err) || | ||
448 | (EOPNOTSUPP == err) ) | ||
449 | { /* Retry with standard file reader. */ | ||
434 | request->resp_sender = MHD_resp_sender_std; | 450 | request->resp_sender = MHD_resp_sender_std; |
435 | return MHD_ERR_AGAIN_; | 451 | return MHD_ERR_AGAIN_; |
436 | #else /* HAVE_SOLARIS_SENDFILE */ | ||
437 | if ( (EAFNOSUPPORT == err) || | ||
438 | (EINVAL == err) || | ||
439 | (EOPNOTSUPP == err) ) | ||
440 | { /* Retry with standard file reader. */ | ||
441 | request->resp_sender = MHD_resp_sender_std; | ||
442 | return MHD_ERR_AGAIN_; | ||
443 | } | ||
444 | if ( (ENOTCONN == err) || | ||
445 | (EPIPE == err) ) | ||
446 | { | ||
447 | return MHD_ERR_CONNRESET_; | ||
448 | } | ||
449 | return MHD_ERR_BADF_; /* Fail hard */ | ||
450 | #endif /* HAVE_SOLARIS_SENDFILE */ | ||
451 | } | 452 | } |
453 | if ( (ENOTCONN == err) || | ||
454 | (EPIPE == err) ) | ||
455 | { | ||
456 | return MHD_ERR_CONNRESET_; | ||
457 | } | ||
458 | return MHD_ERR_BADF_; /* Fail hard */ | ||
459 | #endif /* HAVE_SOLARIS_SENDFILE */ | ||
460 | } | ||
452 | #ifdef EPOLL_SUPPORT | 461 | #ifdef EPOLL_SUPPORT |
453 | else if (send_size > (size_t)ret) | 462 | else if (send_size > (size_t) ret) |
454 | connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY; | 463 | connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY; |
455 | #endif /* EPOLL_SUPPORT */ | 464 | #endif /* EPOLL_SUPPORT */ |
456 | #elif defined(HAVE_FREEBSD_SENDFILE) | 465 | #elif defined(HAVE_FREEBSD_SENDFILE) |
457 | #ifdef SF_FLAGS | 466 | #ifdef SF_FLAGS |
458 | flags = used_thr_p_c ? | 467 | flags = used_thr_p_c ? |
459 | freebsd_sendfile_flags_thd_p_c_ : freebsd_sendfile_flags_; | 468 | freebsd_sendfile_flags_thd_p_c_ : freebsd_sendfile_flags_; |
460 | #endif /* SF_FLAGS */ | 469 | #endif /* SF_FLAGS */ |
461 | if (0 != sendfile (file_fd, | 470 | if (0 != sendfile (file_fd, |
462 | connection->socket_fd, | 471 | connection->socket_fd, |
@@ -465,26 +474,26 @@ sendfile_adapter (struct MHD_Connection *connection) | |||
465 | NULL, | 474 | NULL, |
466 | &sent_bytes, | 475 | &sent_bytes, |
467 | flags)) | 476 | flags)) |
477 | { | ||
478 | const int err = MHD_socket_get_error_ (); | ||
479 | if (MHD_SCKT_ERR_IS_EAGAIN_ (err) || | ||
480 | MHD_SCKT_ERR_IS_EINTR_ (err) || | ||
481 | (EBUSY == err) ) | ||
468 | { | 482 | { |
469 | const int err = MHD_socket_get_error_(); | 483 | mhd_assert (SSIZE_MAX >= sent_bytes); |
470 | if (MHD_SCKT_ERR_IS_EAGAIN_(err) || | 484 | if (0 != sent_bytes) |
471 | MHD_SCKT_ERR_IS_EINTR_(err) || | 485 | return (ssize_t) sent_bytes; |
472 | EBUSY == err) | ||
473 | { | ||
474 | mhd_assert (SSIZE_MAX >= sent_bytes); | ||
475 | if (0 != sent_bytes) | ||
476 | return (ssize_t)sent_bytes; | ||
477 | 486 | ||
478 | return MHD_ERR_AGAIN_; | ||
479 | } | ||
480 | /* Some unrecoverable error. Possibly file FD is not suitable | ||
481 | * for sendfile(). Retry with standard send(). */ | ||
482 | request->resp_sender = MHD_resp_sender_std; | ||
483 | return MHD_ERR_AGAIN_; | 487 | return MHD_ERR_AGAIN_; |
484 | } | 488 | } |
489 | /* Some unrecoverable error. Possibly file FD is not suitable | ||
490 | * for sendfile(). Retry with standard send(). */ | ||
491 | request->resp_sender = MHD_resp_sender_std; | ||
492 | return MHD_ERR_AGAIN_; | ||
493 | } | ||
485 | mhd_assert (0 < sent_bytes); | 494 | mhd_assert (0 < sent_bytes); |
486 | mhd_assert (SSIZE_MAX >= sent_bytes); | 495 | mhd_assert (SSIZE_MAX >= sent_bytes); |
487 | ret = (ssize_t)sent_bytes; | 496 | ret = (ssize_t) sent_bytes; |
488 | #elif defined(HAVE_DARWIN_SENDFILE) | 497 | #elif defined(HAVE_DARWIN_SENDFILE) |
489 | len = (off_t) send_size; /* chunk always fit */ | 498 | len = (off_t) send_size; /* chunk always fit */ |
490 | if (0 != sendfile (file_fd, | 499 | if (0 != sendfile (file_fd, |
@@ -493,35 +502,35 @@ sendfile_adapter (struct MHD_Connection *connection) | |||
493 | &len, | 502 | &len, |
494 | NULL, | 503 | NULL, |
495 | 0)) | 504 | 0)) |
505 | { | ||
506 | const int err = MHD_socket_get_error_ (); | ||
507 | if (MHD_SCKT_ERR_IS_EAGAIN_ (err) || | ||
508 | MHD_SCKT_ERR_IS_EINTR_ (err)) | ||
496 | { | 509 | { |
497 | const int err = MHD_socket_get_error_(); | 510 | mhd_assert (0 <= len); |
498 | if (MHD_SCKT_ERR_IS_EAGAIN_(err) || | 511 | mhd_assert (SSIZE_MAX >= len); |
499 | MHD_SCKT_ERR_IS_EINTR_(err)) | 512 | mhd_assert (send_size >= (size_t) len); |
500 | { | 513 | if (0 != len) |
501 | mhd_assert (0 <= len); | 514 | return (ssize_t) len; |
502 | mhd_assert (SSIZE_MAX >= len); | ||
503 | mhd_assert (send_size >= (size_t)len); | ||
504 | if (0 != len) | ||
505 | return (ssize_t)len; | ||
506 | 515 | ||
507 | return MHD_ERR_AGAIN_; | 516 | return MHD_ERR_AGAIN_; |
508 | } | 517 | } |
509 | if (ENOTCONN == err || | 518 | if ((ENOTCONN == err) || |
510 | EPIPE == err) | 519 | (EPIPE == err) ) |
511 | return MHD_ERR_CONNRESET_; | 520 | return MHD_ERR_CONNRESET_; |
512 | if (ENOTSUP == err || | 521 | if ((ENOTSUP == err) || |
513 | EOPNOTSUPP == err) | 522 | (EOPNOTSUPP == err) ) |
514 | { /* This file FD is not suitable for sendfile(). | 523 | { /* This file FD is not suitable for sendfile(). |
515 | * Retry with standard send(). */ | 524 | * Retry with standard send(). */ |
516 | request->resp_sender = MHD_resp_sender_std; | 525 | request->resp_sender = MHD_resp_sender_std; |
517 | return MHD_ERR_AGAIN_; | 526 | return MHD_ERR_AGAIN_; |
518 | } | ||
519 | return MHD_ERR_BADF_; /* Return hard error. */ | ||
520 | } | 527 | } |
528 | return MHD_ERR_BADF_; /* Return hard error. */ | ||
529 | } | ||
521 | mhd_assert (0 <= len); | 530 | mhd_assert (0 <= len); |
522 | mhd_assert (SSIZE_MAX >= len); | 531 | mhd_assert (SSIZE_MAX >= len); |
523 | mhd_assert (send_size >= (size_t)len); | 532 | mhd_assert (send_size >= (size_t) len); |
524 | ret = (ssize_t)len; | 533 | ret = (ssize_t) len; |
525 | #endif /* HAVE_FREEBSD_SENDFILE */ | 534 | #endif /* HAVE_FREEBSD_SENDFILE */ |
526 | return ret; | 535 | return ret; |
527 | } | 536 | } |
@@ -547,7 +556,7 @@ check_write_done (struct MHD_Request *request, | |||
547 | request->write_buffer_send_offset = 0; | 556 | request->write_buffer_send_offset = 0; |
548 | request->state = next_state; | 557 | request->state = next_state; |
549 | MHD_pool_reallocate (request->connection->pool, | 558 | MHD_pool_reallocate (request->connection->pool, |
550 | request->write_buffer, | 559 | request->write_buffer, |
551 | request->write_buffer_size, | 560 | request->write_buffer_size, |
552 | 0); | 561 | 0); |
553 | request->write_buffer = NULL; | 562 | request->write_buffer = NULL; |
@@ -579,47 +588,48 @@ try_ready_normal_body (struct MHD_Request *request) | |||
579 | (request->response_write_position == response->total_size) ) | 588 | (request->response_write_position == response->total_size) ) |
580 | return true; /* 0-byte response is always ready */ | 589 | return true; /* 0-byte response is always ready */ |
581 | if ( (response->data_start <= | 590 | if ( (response->data_start <= |
582 | request->response_write_position) && | 591 | request->response_write_position) && |
583 | (response->data_size + response->data_start > | 592 | (response->data_size + response->data_start > |
584 | request->response_write_position) ) | 593 | request->response_write_position) ) |
585 | return true; /* response already ready */ | 594 | return true; /* response already ready */ |
586 | #if defined(_MHD_HAVE_SENDFILE) | 595 | #if defined(_MHD_HAVE_SENDFILE) |
587 | if (MHD_resp_sender_sendfile == request->resp_sender) | 596 | if (MHD_resp_sender_sendfile == request->resp_sender) |
588 | { | 597 | { |
589 | /* will use sendfile, no need to bother response crc */ | 598 | /* will use sendfile, no need to bother response crc */ |
590 | return true; | 599 | return true; |
591 | } | 600 | } |
592 | #endif /* _MHD_HAVE_SENDFILE */ | 601 | #endif /* _MHD_HAVE_SENDFILE */ |
593 | 602 | ||
594 | ret = response->crc (response->crc_cls, | 603 | ret = response->crc (response->crc_cls, |
595 | request->response_write_position, | 604 | request->response_write_position, |
596 | response->data, | 605 | response->data, |
597 | (size_t) MHD_MIN ((uint64_t) response->data_buffer_size, | 606 | (size_t) MHD_MIN ((uint64_t) response->data_buffer_size, |
598 | response->total_size - | 607 | response->total_size |
599 | request->response_write_position)); | 608 | - request->response_write_position)); |
600 | if ( (((ssize_t) MHD_CONTENT_READER_END_OF_STREAM) == ret) || | 609 | if ( (((ssize_t) MHD_CONTENT_READER_END_OF_STREAM) == ret) || |
601 | (((ssize_t) MHD_CONTENT_READER_END_WITH_ERROR) == ret) ) | 610 | (((ssize_t) MHD_CONTENT_READER_END_WITH_ERROR) == ret) ) |
602 | { | 611 | { |
603 | /* either error or http 1.0 transfer, close socket! */ | 612 | /* either error or http 1.0 transfer, close socket! */ |
604 | response->total_size = request->response_write_position; | 613 | response->total_size = request->response_write_position; |
605 | MHD_mutex_unlock_chk_ (&response->mutex); | 614 | MHD_mutex_unlock_chk_ (&response->mutex); |
606 | if ( ((ssize_t)MHD_CONTENT_READER_END_OF_STREAM) == ret) | 615 | if ( ((ssize_t) MHD_CONTENT_READER_END_OF_STREAM) == ret) |
607 | MHD_connection_close_ (connection, | 616 | MHD_connection_close_ (connection, |
608 | MHD_REQUEST_TERMINATED_COMPLETED_OK); | 617 | MHD_REQUEST_TERMINATED_COMPLETED_OK); |
609 | else | 618 | else |
610 | CONNECTION_CLOSE_ERROR (connection, | 619 | CONNECTION_CLOSE_ERROR (connection, |
611 | MHD_SC_APPLICATION_DATA_GENERATION_FAILURE_CLOSED, | 620 | MHD_SC_APPLICATION_DATA_GENERATION_FAILURE_CLOSED, |
612 | _("Closing connection (application reported error generating data)\n")); | 621 | _ ( |
613 | return false; | 622 | "Closing connection (application reported error generating data)\n")); |
614 | } | 623 | return false; |
624 | } | ||
615 | response->data_start = request->response_write_position; | 625 | response->data_start = request->response_write_position; |
616 | response->data_size = ret; | 626 | response->data_size = ret; |
617 | if (0 == ret) | 627 | if (0 == ret) |
618 | { | 628 | { |
619 | request->state = MHD_REQUEST_NORMAL_BODY_UNREADY; | 629 | request->state = MHD_REQUEST_NORMAL_BODY_UNREADY; |
620 | MHD_mutex_unlock_chk_ (&response->mutex); | 630 | MHD_mutex_unlock_chk_ (&response->mutex); |
621 | return false; | 631 | return false; |
622 | } | 632 | } |
623 | return true; | 633 | return true; |
624 | } | 634 | } |
625 | 635 | ||
@@ -647,93 +657,94 @@ try_ready_chunked_body (struct MHD_Request *request) | |||
647 | if (NULL == response->crc) | 657 | if (NULL == response->crc) |
648 | return true; | 658 | return true; |
649 | if (0 == request->write_buffer_size) | 659 | if (0 == request->write_buffer_size) |
650 | { | 660 | { |
651 | size = MHD_MIN (daemon->connection_memory_limit_b, | 661 | size = MHD_MIN (daemon->connection_memory_limit_b, |
652 | 2 * (0xFFFFFF + sizeof(cbuf) + 2)); | 662 | 2 * (0xFFFFFF + sizeof(cbuf) + 2)); |
653 | do | 663 | do |
654 | { | 664 | { |
655 | size /= 2; | 665 | size /= 2; |
656 | if (size < 128) | 666 | if (size < 128) |
657 | { | 667 | { |
658 | MHD_mutex_unlock_chk_ (&response->mutex); | 668 | MHD_mutex_unlock_chk_ (&response->mutex); |
659 | /* not enough memory */ | 669 | /* not enough memory */ |
660 | CONNECTION_CLOSE_ERROR (connection, | 670 | CONNECTION_CLOSE_ERROR (connection, |
661 | MHD_SC_CONNECTION_POOL_MALLOC_FAILURE, | 671 | MHD_SC_CONNECTION_POOL_MALLOC_FAILURE, |
662 | _("Closing connection (out of memory)\n")); | 672 | _ ("Closing connection (out of memory)\n")); |
663 | return false; | 673 | return false; |
664 | } | 674 | } |
665 | buf = MHD_pool_allocate (connection->pool, | 675 | buf = MHD_pool_allocate (connection->pool, |
666 | size, | 676 | size, |
667 | MHD_NO); | 677 | MHD_NO); |
668 | } | 678 | } |
669 | while (NULL == buf); | 679 | while (NULL == buf); |
670 | request->write_buffer_size = size; | 680 | request->write_buffer_size = size; |
671 | request->write_buffer = buf; | 681 | request->write_buffer = buf; |
672 | } | 682 | } |
673 | 683 | ||
674 | if (0 == response->total_size) | 684 | if (0 == response->total_size) |
675 | ret = 0; /* response must be empty, don't bother calling crc */ | 685 | ret = 0; /* response must be empty, don't bother calling crc */ |
676 | else if ( (response->data_start <= | 686 | else if ( (response->data_start <= |
677 | request->response_write_position) && | 687 | request->response_write_position) && |
678 | (response->data_start + response->data_size > | 688 | (response->data_start + response->data_size > |
679 | request->response_write_position) ) | 689 | request->response_write_position) ) |
680 | { | 690 | { |
681 | /* difference between response_write_position and data_start is less | 691 | /* difference between response_write_position and data_start is less |
682 | than data_size which is size_t type, no need to check for overflow */ | 692 | than data_size which is size_t type, no need to check for overflow */ |
683 | const size_t data_write_offset | 693 | const size_t data_write_offset |
684 | = (size_t)(request->response_write_position - response->data_start); | 694 | = (size_t) (request->response_write_position - response->data_start); |
685 | /* buffer already ready, use what is there for the chunk */ | 695 | /* buffer already ready, use what is there for the chunk */ |
686 | ret = response->data_size - data_write_offset; | 696 | ret = response->data_size - data_write_offset; |
687 | if ( ((size_t) ret) > request->write_buffer_size - sizeof (cbuf) - 2 ) | 697 | if ( ((size_t) ret) > request->write_buffer_size - sizeof (cbuf) - 2 ) |
688 | ret = request->write_buffer_size - sizeof (cbuf) - 2; | 698 | ret = request->write_buffer_size - sizeof (cbuf) - 2; |
689 | memcpy (&request->write_buffer[sizeof (cbuf)], | 699 | memcpy (&request->write_buffer[sizeof (cbuf)], |
690 | &response->data[data_write_offset], | 700 | &response->data[data_write_offset], |
691 | ret); | 701 | ret); |
692 | } | 702 | } |
693 | else | 703 | else |
694 | { | 704 | { |
695 | /* buffer not in range, try to fill it */ | 705 | /* buffer not in range, try to fill it */ |
696 | ret = response->crc (response->crc_cls, | 706 | ret = response->crc (response->crc_cls, |
697 | request->response_write_position, | 707 | request->response_write_position, |
698 | &request->write_buffer[sizeof (cbuf)], | 708 | &request->write_buffer[sizeof (cbuf)], |
699 | request->write_buffer_size - sizeof (cbuf) - 2); | 709 | request->write_buffer_size - sizeof (cbuf) - 2); |
700 | } | 710 | } |
701 | if ( ((ssize_t) MHD_CONTENT_READER_END_WITH_ERROR) == ret) | 711 | if ( ((ssize_t) MHD_CONTENT_READER_END_WITH_ERROR) == ret) |
702 | { | 712 | { |
703 | /* error, close socket! */ | 713 | /* error, close socket! */ |
704 | response->total_size = request->response_write_position; | 714 | response->total_size = request->response_write_position; |
705 | MHD_mutex_unlock_chk_ (&response->mutex); | 715 | MHD_mutex_unlock_chk_ (&response->mutex); |
706 | CONNECTION_CLOSE_ERROR (connection, | 716 | CONNECTION_CLOSE_ERROR (connection, |
707 | MHD_SC_APPLICATION_DATA_GENERATION_FAILURE_CLOSED, | 717 | MHD_SC_APPLICATION_DATA_GENERATION_FAILURE_CLOSED, |
708 | _("Closing connection (application error generating response)\n")); | 718 | _ ( |
709 | return false; | 719 | "Closing connection (application error generating response)\n")); |
710 | } | 720 | return false; |
721 | } | ||
711 | if ( (((ssize_t) MHD_CONTENT_READER_END_OF_STREAM) == ret) || | 722 | if ( (((ssize_t) MHD_CONTENT_READER_END_OF_STREAM) == ret) || |
712 | (0 == response->total_size) ) | 723 | (0 == response->total_size) ) |
713 | { | 724 | { |
714 | /* end of message, signal other side! */ | 725 | /* end of message, signal other side! */ |
715 | memcpy (request->write_buffer, | 726 | memcpy (request->write_buffer, |
716 | "0\r\n", | 727 | "0\r\n", |
717 | 3); | 728 | 3); |
718 | request->write_buffer_append_offset = 3; | 729 | request->write_buffer_append_offset = 3; |
719 | request->write_buffer_send_offset = 0; | 730 | request->write_buffer_send_offset = 0; |
720 | response->total_size = request->response_write_position; | 731 | response->total_size = request->response_write_position; |
721 | return true; | 732 | return true; |
722 | } | 733 | } |
723 | if (0 == ret) | 734 | if (0 == ret) |
724 | { | 735 | { |
725 | request->state = MHD_REQUEST_CHUNKED_BODY_UNREADY; | 736 | request->state = MHD_REQUEST_CHUNKED_BODY_UNREADY; |
726 | MHD_mutex_unlock_chk_ (&response->mutex); | 737 | MHD_mutex_unlock_chk_ (&response->mutex); |
727 | return false; | 738 | return false; |
728 | } | 739 | } |
729 | if (ret > 0xFFFFFF) | 740 | if (ret > 0xFFFFFF) |
730 | ret = 0xFFFFFF; | 741 | ret = 0xFFFFFF; |
731 | cblen = MHD_snprintf_(cbuf, | 742 | cblen = MHD_snprintf_ (cbuf, |
732 | sizeof (cbuf), | 743 | sizeof (cbuf), |
733 | "%X\r\n", | 744 | "%X\r\n", |
734 | (unsigned int) ret); | 745 | (unsigned int) ret); |
735 | mhd_assert(cblen > 0); | 746 | mhd_assert (cblen > 0); |
736 | mhd_assert((size_t)cblen < sizeof(cbuf)); | 747 | mhd_assert ((size_t) cblen < sizeof(cbuf)); |
737 | memcpy (&request->write_buffer[sizeof (cbuf) - cblen], | 748 | memcpy (&request->write_buffer[sizeof (cbuf) - cblen], |
738 | cbuf, | 749 | cbuf, |
739 | cblen); | 750 | cblen); |
@@ -768,221 +779,224 @@ MHD_request_handle_write_ (struct MHD_Request *request) | |||
768 | struct MHD_TLS_Plugin *tls; | 779 | struct MHD_TLS_Plugin *tls; |
769 | 780 | ||
770 | if ( (NULL != (tls = daemon->tls_api)) && | 781 | if ( (NULL != (tls = daemon->tls_api)) && |
771 | (! tls->handshake (tls->cls, | 782 | (! tls->handshake (tls->cls, |
772 | connection->tls_cs)) ) | 783 | connection->tls_cs)) ) |
773 | return; | 784 | return; |
774 | } | 785 | } |
775 | #endif /* HTTPS_SUPPORT */ | 786 | #endif /* HTTPS_SUPPORT */ |
776 | 787 | ||
777 | #if DEBUG_STATES | 788 | #if DEBUG_STATES |
778 | MHD_DLOG (daemon, | 789 | MHD_DLOG (daemon, |
779 | MHD_SC_STATE_MACHINE_STATUS_REPORT, | 790 | MHD_SC_STATE_MACHINE_STATUS_REPORT, |
780 | _("In function %s handling connection at state: %s\n"), | 791 | _ ("In function %s handling connection at state: %s\n"), |
781 | __FUNCTION__, | 792 | __FUNCTION__, |
782 | MHD_state_to_string (request->state)); | 793 | MHD_state_to_string (request->state)); |
783 | #endif | 794 | #endif |
784 | switch (request->state) | 795 | switch (request->state) |
785 | { | 796 | { |
786 | case MHD_REQUEST_INIT: | 797 | case MHD_REQUEST_INIT: |
787 | case MHD_REQUEST_URL_RECEIVED: | 798 | case MHD_REQUEST_URL_RECEIVED: |
788 | case MHD_REQUEST_HEADER_PART_RECEIVED: | 799 | case MHD_REQUEST_HEADER_PART_RECEIVED: |
789 | case MHD_REQUEST_HEADERS_RECEIVED: | 800 | case MHD_REQUEST_HEADERS_RECEIVED: |
790 | mhd_assert (0); | 801 | mhd_assert (0); |
791 | return; | 802 | return; |
792 | case MHD_REQUEST_HEADERS_PROCESSED: | 803 | case MHD_REQUEST_HEADERS_PROCESSED: |
793 | return; | 804 | return; |
794 | case MHD_REQUEST_CONTINUE_SENDING: | 805 | case MHD_REQUEST_CONTINUE_SENDING: |
795 | ret = connection->send_cls (connection, | 806 | ret = connection->send_cls (connection, |
796 | &HTTP_100_CONTINUE | 807 | &HTTP_100_CONTINUE |
797 | [request->continue_message_write_offset], | 808 | [request->continue_message_write_offset], |
798 | MHD_STATICSTR_LEN_ (HTTP_100_CONTINUE) - | 809 | MHD_STATICSTR_LEN_ (HTTP_100_CONTINUE) |
799 | request->continue_message_write_offset); | 810 | - request->continue_message_write_offset); |
800 | if (ret < 0) | 811 | if (ret < 0) |
801 | { | 812 | { |
802 | if (MHD_ERR_AGAIN_ == ret) | 813 | if (MHD_ERR_AGAIN_ == ret) |
803 | return; | 814 | return; |
804 | #ifdef HAVE_MESSAGES | 815 | #ifdef HAVE_MESSAGES |
805 | MHD_DLOG (daemon, | 816 | MHD_DLOG (daemon, |
806 | MHD_SC_CONNECTION_WRITE_FAIL_CLOSED, | 817 | MHD_SC_CONNECTION_WRITE_FAIL_CLOSED, |
807 | _("Failed to send data in request for %s.\n"), | 818 | _ ("Failed to send data in request for %s.\n"), |
808 | request->url); | 819 | request->url); |
809 | #endif | 820 | #endif |
810 | CONNECTION_CLOSE_ERROR (connection, | 821 | CONNECTION_CLOSE_ERROR (connection, |
811 | MHD_SC_CONNECTION_WRITE_FAIL_CLOSED, | 822 | MHD_SC_CONNECTION_WRITE_FAIL_CLOSED, |
812 | NULL); | 823 | NULL); |
813 | return; | ||
814 | } | ||
815 | request->continue_message_write_offset += ret; | ||
816 | MHD_connection_update_last_activity_ (connection); | ||
817 | return; | ||
818 | case MHD_REQUEST_CONTINUE_SENT: | ||
819 | case MHD_REQUEST_BODY_RECEIVED: | ||
820 | case MHD_REQUEST_FOOTER_PART_RECEIVED: | ||
821 | case MHD_REQUEST_FOOTERS_RECEIVED: | ||
822 | mhd_assert (0); | ||
823 | return; | 824 | return; |
824 | case MHD_REQUEST_HEADERS_SENDING: | 825 | } |
825 | ret = connection->send_cls (connection, | 826 | request->continue_message_write_offset += ret; |
826 | &request->write_buffer | 827 | MHD_connection_update_last_activity_ (connection); |
827 | [request->write_buffer_send_offset], | 828 | return; |
828 | request->write_buffer_append_offset - | 829 | case MHD_REQUEST_CONTINUE_SENT: |
829 | request->write_buffer_send_offset); | 830 | case MHD_REQUEST_BODY_RECEIVED: |
830 | if (ret < 0) | 831 | case MHD_REQUEST_FOOTER_PART_RECEIVED: |
831 | { | 832 | case MHD_REQUEST_FOOTERS_RECEIVED: |
832 | if (MHD_ERR_AGAIN_ == ret) | 833 | mhd_assert (0); |
833 | return; | 834 | return; |
834 | CONNECTION_CLOSE_ERROR (connection, | 835 | case MHD_REQUEST_HEADERS_SENDING: |
835 | MHD_SC_CONNECTION_WRITE_FAIL_CLOSED, | 836 | ret = connection->send_cls (connection, |
836 | _("Connection was closed while sending response headers.\n")); | 837 | &request->write_buffer |
837 | return; | 838 | [request->write_buffer_send_offset], |
838 | } | 839 | request->write_buffer_append_offset |
839 | request->write_buffer_send_offset += ret; | 840 | - request->write_buffer_send_offset); |
840 | MHD_connection_update_last_activity_ (connection); | 841 | if (ret < 0) |
841 | if (MHD_REQUEST_HEADERS_SENDING != request->state) | 842 | { |
843 | if (MHD_ERR_AGAIN_ == ret) | ||
842 | return; | 844 | return; |
843 | check_write_done (request, | 845 | CONNECTION_CLOSE_ERROR (connection, |
844 | MHD_REQUEST_HEADERS_SENT); | 846 | MHD_SC_CONNECTION_WRITE_FAIL_CLOSED, |
847 | _ ( | ||
848 | "Connection was closed while sending response headers.\n")); | ||
845 | return; | 849 | return; |
846 | case MHD_REQUEST_HEADERS_SENT: | 850 | } |
851 | request->write_buffer_send_offset += ret; | ||
852 | MHD_connection_update_last_activity_ (connection); | ||
853 | if (MHD_REQUEST_HEADERS_SENDING != request->state) | ||
847 | return; | 854 | return; |
848 | case MHD_REQUEST_NORMAL_BODY_READY: | 855 | check_write_done (request, |
849 | response = request->response; | 856 | MHD_REQUEST_HEADERS_SENT); |
850 | if (request->response_write_position < | 857 | return; |
851 | request->response->total_size) | 858 | case MHD_REQUEST_HEADERS_SENT: |
852 | { | 859 | return; |
853 | uint64_t data_write_offset; | 860 | case MHD_REQUEST_NORMAL_BODY_READY: |
854 | 861 | response = request->response; | |
855 | if (NULL != response->crc) | 862 | if (request->response_write_position < |
856 | MHD_mutex_lock_chk_ (&response->mutex); | 863 | request->response->total_size) |
857 | if (! try_ready_normal_body (request)) | 864 | { |
858 | { | 865 | uint64_t data_write_offset; |
859 | /* mutex was already unlocked by try_ready_normal_body */ | 866 | |
860 | return; | 867 | if (NULL != response->crc) |
861 | } | 868 | MHD_mutex_lock_chk_ (&response->mutex); |
869 | if (! try_ready_normal_body (request)) | ||
870 | { | ||
871 | /* mutex was already unlocked by try_ready_normal_body */ | ||
872 | return; | ||
873 | } | ||
862 | #if defined(_MHD_HAVE_SENDFILE) | 874 | #if defined(_MHD_HAVE_SENDFILE) |
863 | if (MHD_resp_sender_sendfile == request->resp_sender) | 875 | if (MHD_resp_sender_sendfile == request->resp_sender) |
864 | { | 876 | { |
865 | ret = sendfile_adapter (connection); | 877 | ret = sendfile_adapter (connection); |
866 | } | 878 | } |
867 | else | 879 | else |
868 | #else /* ! _MHD_HAVE_SENDFILE */ | 880 | #else /* ! _MHD_HAVE_SENDFILE */ |
869 | if (1) | 881 | if (1) |
870 | #endif /* ! _MHD_HAVE_SENDFILE */ | 882 | #endif /* ! _MHD_HAVE_SENDFILE */ |
871 | { | 883 | { |
872 | data_write_offset = request->response_write_position | 884 | data_write_offset = request->response_write_position |
873 | - response->data_start; | 885 | - response->data_start; |
874 | if (data_write_offset > (uint64_t)SIZE_MAX) | 886 | if (data_write_offset > (uint64_t) SIZE_MAX) |
875 | MHD_PANIC (_("Data offset exceeds limit")); | 887 | MHD_PANIC (_ ("Data offset exceeds limit")); |
876 | ret = connection->send_cls (connection, | 888 | ret = connection->send_cls (connection, |
877 | &response->data | 889 | &response->data |
878 | [(size_t)data_write_offset], | 890 | [(size_t) data_write_offset], |
879 | response->data_size - | 891 | response->data_size |
880 | (size_t)data_write_offset); | 892 | - (size_t) data_write_offset); |
881 | #if DEBUG_SEND_DATA | 893 | #if DEBUG_SEND_DATA |
882 | if (ret > 0) | 894 | if (ret > 0) |
883 | fprintf (stderr, | 895 | fprintf (stderr, |
884 | _("Sent %d-byte DATA response: `%.*s'\n"), | 896 | _ ("Sent %d-byte DATA response: `%.*s'\n"), |
885 | (int) ret, | 897 | (int) ret, |
886 | (int) ret, | 898 | (int) ret, |
887 | &response->data[request->response_write_position - | 899 | &response->data[request->response_write_position |
888 | response->data_start]); | 900 | - response->data_start]); |
889 | #endif | 901 | #endif |
890 | } | 902 | } |
891 | if (NULL != response->crc) | 903 | if (NULL != response->crc) |
892 | MHD_mutex_unlock_chk_ (&response->mutex); | 904 | MHD_mutex_unlock_chk_ (&response->mutex); |
893 | if (ret < 0) | ||
894 | { | ||
895 | if (MHD_ERR_AGAIN_ == ret) | ||
896 | return; | ||
897 | #ifdef HAVE_MESSAGES | ||
898 | MHD_DLOG (daemon, | ||
899 | MHD_SC_CONNECTION_WRITE_FAIL_CLOSED, | ||
900 | _("Failed to send data in request for `%s'.\n"), | ||
901 | request->url); | ||
902 | #endif | ||
903 | CONNECTION_CLOSE_ERROR (connection, | ||
904 | MHD_SC_CONNECTION_WRITE_FAIL_CLOSED, | ||
905 | NULL); | ||
906 | return; | ||
907 | } | ||
908 | request->response_write_position += ret; | ||
909 | MHD_connection_update_last_activity_ (connection); | ||
910 | } | ||
911 | if (request->response_write_position == | ||
912 | request->response->total_size) | ||
913 | request->state = MHD_REQUEST_FOOTERS_SENT; /* have no footers */ | ||
914 | return; | ||
915 | case MHD_REQUEST_NORMAL_BODY_UNREADY: | ||
916 | mhd_assert (0); | ||
917 | return; | ||
918 | case MHD_REQUEST_CHUNKED_BODY_READY: | ||
919 | ret = connection->send_cls (connection, | ||
920 | &request->write_buffer | ||
921 | [request->write_buffer_send_offset], | ||
922 | request->write_buffer_append_offset - | ||
923 | request->write_buffer_send_offset); | ||
924 | if (ret < 0) | 905 | if (ret < 0) |
925 | { | 906 | { |
926 | if (MHD_ERR_AGAIN_ == ret) | 907 | if (MHD_ERR_AGAIN_ == ret) |
927 | return; | ||
928 | CONNECTION_CLOSE_ERROR (connection, | ||
929 | MHD_SC_CONNECTION_WRITE_FAIL_CLOSED, | ||
930 | _("Connection was closed while sending response body.\n")); | ||
931 | return; | 908 | return; |
932 | } | 909 | #ifdef HAVE_MESSAGES |
933 | request->write_buffer_send_offset += ret; | 910 | MHD_DLOG (daemon, |
911 | MHD_SC_CONNECTION_WRITE_FAIL_CLOSED, | ||
912 | _ ("Failed to send data in request for `%s'.\n"), | ||
913 | request->url); | ||
914 | #endif | ||
915 | CONNECTION_CLOSE_ERROR (connection, | ||
916 | MHD_SC_CONNECTION_WRITE_FAIL_CLOSED, | ||
917 | NULL); | ||
918 | return; | ||
919 | } | ||
920 | request->response_write_position += ret; | ||
934 | MHD_connection_update_last_activity_ (connection); | 921 | MHD_connection_update_last_activity_ (connection); |
935 | if (MHD_REQUEST_CHUNKED_BODY_READY != request->state) | 922 | } |
923 | if (request->response_write_position == | ||
924 | request->response->total_size) | ||
925 | request->state = MHD_REQUEST_FOOTERS_SENT; /* have no footers */ | ||
926 | return; | ||
927 | case MHD_REQUEST_NORMAL_BODY_UNREADY: | ||
928 | mhd_assert (0); | ||
929 | return; | ||
930 | case MHD_REQUEST_CHUNKED_BODY_READY: | ||
931 | ret = connection->send_cls (connection, | ||
932 | &request->write_buffer | ||
933 | [request->write_buffer_send_offset], | ||
934 | request->write_buffer_append_offset | ||
935 | - request->write_buffer_send_offset); | ||
936 | if (ret < 0) | ||
937 | { | ||
938 | if (MHD_ERR_AGAIN_ == ret) | ||
936 | return; | 939 | return; |
937 | check_write_done (request, | 940 | CONNECTION_CLOSE_ERROR (connection, |
938 | (request->response->total_size == | 941 | MHD_SC_CONNECTION_WRITE_FAIL_CLOSED, |
939 | request->response_write_position) ? | 942 | _ ( |
940 | MHD_REQUEST_BODY_SENT : | 943 | "Connection was closed while sending response body.\n")); |
941 | MHD_REQUEST_CHUNKED_BODY_UNREADY); | ||
942 | return; | 944 | return; |
943 | case MHD_REQUEST_CHUNKED_BODY_UNREADY: | 945 | } |
944 | case MHD_REQUEST_BODY_SENT: | 946 | request->write_buffer_send_offset += ret; |
945 | mhd_assert (0); | 947 | MHD_connection_update_last_activity_ (connection); |
948 | if (MHD_REQUEST_CHUNKED_BODY_READY != request->state) | ||
946 | return; | 949 | return; |
947 | case MHD_REQUEST_FOOTERS_SENDING: | 950 | check_write_done (request, |
948 | ret = connection->send_cls (connection, | 951 | (request->response->total_size == |
949 | &request->write_buffer | 952 | request->response_write_position) ? |
950 | [request->write_buffer_send_offset], | 953 | MHD_REQUEST_BODY_SENT : |
951 | request->write_buffer_append_offset - | 954 | MHD_REQUEST_CHUNKED_BODY_UNREADY); |
952 | request->write_buffer_send_offset); | 955 | return; |
953 | if (ret < 0) | 956 | case MHD_REQUEST_CHUNKED_BODY_UNREADY: |
954 | { | 957 | case MHD_REQUEST_BODY_SENT: |
955 | if (MHD_ERR_AGAIN_ == ret) | 958 | mhd_assert (0); |
956 | return; | 959 | return; |
957 | CONNECTION_CLOSE_ERROR (connection, | 960 | case MHD_REQUEST_FOOTERS_SENDING: |
958 | MHD_SC_CONNECTION_WRITE_FAIL_CLOSED, | 961 | ret = connection->send_cls (connection, |
959 | _("Connection was closed while sending response body.\n")); | 962 | &request->write_buffer |
960 | return; | 963 | [request->write_buffer_send_offset], |
961 | } | 964 | request->write_buffer_append_offset |
962 | request->write_buffer_send_offset += ret; | 965 | - request->write_buffer_send_offset); |
963 | MHD_connection_update_last_activity_ (connection); | 966 | if (ret < 0) |
964 | if (MHD_REQUEST_FOOTERS_SENDING != request->state) | 967 | { |
968 | if (MHD_ERR_AGAIN_ == ret) | ||
965 | return; | 969 | return; |
966 | check_write_done (request, | 970 | CONNECTION_CLOSE_ERROR (connection, |
967 | MHD_REQUEST_FOOTERS_SENT); | 971 | MHD_SC_CONNECTION_WRITE_FAIL_CLOSED, |
968 | return; | 972 | _ ( |
969 | case MHD_REQUEST_FOOTERS_SENT: | 973 | "Connection was closed while sending response body.\n")); |
970 | mhd_assert (0); | ||
971 | return; | 974 | return; |
972 | case MHD_REQUEST_CLOSED: | 975 | } |
976 | request->write_buffer_send_offset += ret; | ||
977 | MHD_connection_update_last_activity_ (connection); | ||
978 | if (MHD_REQUEST_FOOTERS_SENDING != request->state) | ||
973 | return; | 979 | return; |
980 | check_write_done (request, | ||
981 | MHD_REQUEST_FOOTERS_SENT); | ||
982 | return; | ||
983 | case MHD_REQUEST_FOOTERS_SENT: | ||
984 | mhd_assert (0); | ||
985 | return; | ||
986 | case MHD_REQUEST_CLOSED: | ||
987 | return; | ||
974 | #ifdef UPGRADE_SUPPORT | 988 | #ifdef UPGRADE_SUPPORT |
975 | case MHD_REQUEST_UPGRADE: | 989 | case MHD_REQUEST_UPGRADE: |
976 | mhd_assert (0); | 990 | mhd_assert (0); |
977 | return; | 991 | return; |
978 | #endif /* UPGRADE_SUPPORT */ | 992 | #endif /* UPGRADE_SUPPORT */ |
979 | default: | 993 | default: |
980 | mhd_assert (0); | 994 | mhd_assert (0); |
981 | CONNECTION_CLOSE_ERROR (connection, | 995 | CONNECTION_CLOSE_ERROR (connection, |
982 | MHD_SC_STATEMACHINE_FAILURE_CONNECTION_CLOSED, | 996 | MHD_SC_STATEMACHINE_FAILURE_CONNECTION_CLOSED, |
983 | _("Internal error\n")); | 997 | _ ("Internal error\n")); |
984 | break; | 998 | break; |
985 | } | 999 | } |
986 | } | 1000 | } |
987 | 1001 | ||
988 | 1002 | ||
@@ -1001,9 +1015,9 @@ MHD_request_handle_write_ (struct MHD_Request *request) | |||
1001 | */ | 1015 | */ |
1002 | static bool | 1016 | static bool |
1003 | MHD_lookup_header_token_ci (const struct MHD_Request *request, | 1017 | MHD_lookup_header_token_ci (const struct MHD_Request *request, |
1004 | const char *header, | 1018 | const char *header, |
1005 | const char *token, | 1019 | const char *token, |
1006 | size_t token_len) | 1020 | size_t token_len) |
1007 | { | 1021 | { |
1008 | struct MHD_HTTP_Header *pos; | 1022 | struct MHD_HTTP_Header *pos; |
1009 | 1023 | ||
@@ -1014,16 +1028,16 @@ MHD_lookup_header_token_ci (const struct MHD_Request *request, | |||
1014 | (0 == token[0]) ) | 1028 | (0 == token[0]) ) |
1015 | return false; | 1029 | return false; |
1016 | for (pos = request->headers_received; NULL != pos; pos = pos->next) | 1030 | for (pos = request->headers_received; NULL != pos; pos = pos->next) |
1017 | { | 1031 | { |
1018 | if ( (0 != (pos->kind & MHD_HEADER_KIND)) && | 1032 | if ( (0 != (pos->kind & MHD_HEADER_KIND)) && |
1019 | ( (header == pos->header) || | 1033 | ( (header == pos->header) || |
1020 | (MHD_str_equal_caseless_(header, | 1034 | (MHD_str_equal_caseless_ (header, |
1021 | pos->header)) ) && | 1035 | pos->header)) ) && |
1022 | (MHD_str_has_token_caseless_ (pos->value, | 1036 | (MHD_str_has_token_caseless_ (pos->value, |
1023 | token, | 1037 | token, |
1024 | token_len)) ) | 1038 | token_len)) ) |
1025 | return true; | 1039 | return true; |
1026 | } | 1040 | } |
1027 | return false; | 1041 | return false; |
1028 | } | 1042 | } |
1029 | 1043 | ||
@@ -1040,7 +1054,7 @@ MHD_lookup_header_token_ci (const struct MHD_Request *request, | |||
1040 | * false otherwise | 1054 | * false otherwise |
1041 | */ | 1055 | */ |
1042 | #define MHD_lookup_header_s_token_ci(r,h,tkn) \ | 1056 | #define MHD_lookup_header_s_token_ci(r,h,tkn) \ |
1043 | MHD_lookup_header_token_ci((r),(h),(tkn),MHD_STATICSTR_LEN_(tkn)) | 1057 | MHD_lookup_header_token_ci ((r),(h),(tkn),MHD_STATICSTR_LEN_ (tkn)) |
1044 | 1058 | ||
1045 | 1059 | ||
1046 | /** | 1060 | /** |
@@ -1071,27 +1085,27 @@ keepalive_possible (struct MHD_Request *request) | |||
1071 | return false; | 1085 | return false; |
1072 | 1086 | ||
1073 | if (MHD_str_equal_caseless_ (request->version_s, | 1087 | if (MHD_str_equal_caseless_ (request->version_s, |
1074 | MHD_HTTP_VERSION_1_1)) | 1088 | MHD_HTTP_VERSION_1_1)) |
1075 | { | 1089 | { |
1076 | if (MHD_lookup_header_s_token_ci (request, | 1090 | if (MHD_lookup_header_s_token_ci (request, |
1077 | MHD_HTTP_HEADER_CONNECTION, | 1091 | MHD_HTTP_HEADER_CONNECTION, |
1078 | "upgrade")) | 1092 | "upgrade")) |
1079 | return false; | ||
1080 | if (MHD_lookup_header_s_token_ci (request, | ||
1081 | MHD_HTTP_HEADER_CONNECTION, | ||
1082 | "close")) | ||
1083 | return false; | ||
1084 | return true; | ||
1085 | } | ||
1086 | if (MHD_str_equal_caseless_ (request->version_s, | ||
1087 | MHD_HTTP_VERSION_1_0)) | ||
1088 | { | ||
1089 | if (MHD_lookup_header_s_token_ci (request, | ||
1090 | MHD_HTTP_HEADER_CONNECTION, | ||
1091 | "Keep-Alive")) | ||
1092 | return true; | ||
1093 | return false; | 1093 | return false; |
1094 | } | 1094 | if (MHD_lookup_header_s_token_ci (request, |
1095 | MHD_HTTP_HEADER_CONNECTION, | ||
1096 | "close")) | ||
1097 | return false; | ||
1098 | return true; | ||
1099 | } | ||
1100 | if (MHD_str_equal_caseless_ (request->version_s, | ||
1101 | MHD_HTTP_VERSION_1_0)) | ||
1102 | { | ||
1103 | if (MHD_lookup_header_s_token_ci (request, | ||
1104 | MHD_HTTP_HEADER_CONNECTION, | ||
1105 | "Keep-Alive")) | ||
1106 | return true; | ||
1107 | return false; | ||
1108 | } | ||
1095 | return false; | 1109 | return false; |
1096 | } | 1110 | } |
1097 | 1111 | ||
@@ -1105,7 +1119,7 @@ keepalive_possible (struct MHD_Request *request) | |||
1105 | */ | 1119 | */ |
1106 | static void | 1120 | static void |
1107 | get_date_string (char *date, | 1121 | get_date_string (char *date, |
1108 | size_t date_len) | 1122 | size_t date_len) |
1109 | { | 1123 | { |
1110 | static const char *const days[] = { | 1124 | static const char *const days[] = { |
1111 | "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" | 1125 | "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" |
@@ -1116,8 +1130,9 @@ get_date_string (char *date, | |||
1116 | }; | 1130 | }; |
1117 | struct tm now; | 1131 | struct tm now; |
1118 | time_t t; | 1132 | time_t t; |
1119 | #if !defined(HAVE_C11_GMTIME_S) && !defined(HAVE_W32_GMTIME_S) && !defined(HAVE_GMTIME_R) | 1133 | #if ! defined(HAVE_C11_GMTIME_S) && ! defined(HAVE_W32_GMTIME_S) && \ |
1120 | struct tm* pNow; | 1134 | ! defined(HAVE_GMTIME_R) |
1135 | struct tm*pNow; | ||
1121 | #endif | 1136 | #endif |
1122 | 1137 | ||
1123 | date[0] = 0; | 1138 | date[0] = 0; |
@@ -1131,25 +1146,25 @@ get_date_string (char *date, | |||
1131 | &t)) | 1146 | &t)) |
1132 | return; | 1147 | return; |
1133 | #elif defined(HAVE_GMTIME_R) | 1148 | #elif defined(HAVE_GMTIME_R) |
1134 | if (NULL == gmtime_r(&t, | 1149 | if (NULL == gmtime_r (&t, |
1135 | &now)) | 1150 | &now)) |
1136 | return; | 1151 | return; |
1137 | #else | 1152 | #else |
1138 | pNow = gmtime(&t); | 1153 | pNow = gmtime (&t); |
1139 | if (NULL == pNow) | 1154 | if (NULL == pNow) |
1140 | return; | 1155 | return; |
1141 | now = *pNow; | 1156 | now = *pNow; |
1142 | #endif | 1157 | #endif |
1143 | MHD_snprintf_ (date, | 1158 | MHD_snprintf_ (date, |
1144 | date_len, | 1159 | date_len, |
1145 | "Date: %3s, %02u %3s %04u %02u:%02u:%02u GMT\r\n", | 1160 | "Date: %3s, %02u %3s %04u %02u:%02u:%02u GMT\r\n", |
1146 | days[now.tm_wday % 7], | 1161 | days[now.tm_wday % 7], |
1147 | (unsigned int) now.tm_mday, | 1162 | (unsigned int) now.tm_mday, |
1148 | mons[now.tm_mon % 12], | 1163 | mons[now.tm_mon % 12], |
1149 | (unsigned int) (1900 + now.tm_year), | 1164 | (unsigned int) (1900 + now.tm_year), |
1150 | (unsigned int) now.tm_hour, | 1165 | (unsigned int) now.tm_hour, |
1151 | (unsigned int) now.tm_min, | 1166 | (unsigned int) now.tm_min, |
1152 | (unsigned int) now.tm_sec); | 1167 | (unsigned int) now.tm_sec); |
1153 | } | 1168 | } |
1154 | 1169 | ||
1155 | 1170 | ||
@@ -1168,9 +1183,9 @@ get_date_string (char *date, | |||
1168 | */ | 1183 | */ |
1169 | static bool | 1184 | static bool |
1170 | check_response_header_token_ci (const struct MHD_Response *response, | 1185 | check_response_header_token_ci (const struct MHD_Response *response, |
1171 | const char *key, | 1186 | const char *key, |
1172 | const char *token, | 1187 | const char *token, |
1173 | size_t token_len) | 1188 | size_t token_len) |
1174 | { | 1189 | { |
1175 | struct MHD_HTTP_Header *pos; | 1190 | struct MHD_HTTP_Header *pos; |
1176 | 1191 | ||
@@ -1183,15 +1198,15 @@ check_response_header_token_ci (const struct MHD_Response *response, | |||
1183 | for (pos = response->first_header; | 1198 | for (pos = response->first_header; |
1184 | NULL != pos; | 1199 | NULL != pos; |
1185 | pos = pos->next) | 1200 | pos = pos->next) |
1186 | { | 1201 | { |
1187 | if ( (pos->kind == MHD_HEADER_KIND) && | 1202 | if ( (pos->kind == MHD_HEADER_KIND) && |
1188 | MHD_str_equal_caseless_ (pos->header, | 1203 | MHD_str_equal_caseless_ (pos->header, |
1189 | key) && | 1204 | key) && |
1190 | MHD_str_has_token_caseless_ (pos->value, | 1205 | MHD_str_has_token_caseless_ (pos->value, |
1191 | token, | 1206 | token, |
1192 | token_len) ) | 1207 | token_len) ) |
1193 | return true; | 1208 | return true; |
1194 | } | 1209 | } |
1195 | return false; | 1210 | return false; |
1196 | } | 1211 | } |
1197 | 1212 | ||
@@ -1208,7 +1223,7 @@ check_response_header_token_ci (const struct MHD_Response *response, | |||
1208 | * false otherwise | 1223 | * false otherwise |
1209 | */ | 1224 | */ |
1210 | #define check_response_header_s_token_ci(r,k,tkn) \ | 1225 | #define check_response_header_s_token_ci(r,k,tkn) \ |
1211 | check_response_header_token_ci((r),(k),(tkn),MHD_STATICSTR_LEN_(tkn)) | 1226 | check_response_header_token_ci ((r),(k),(tkn),MHD_STATICSTR_LEN_ (tkn)) |
1212 | 1227 | ||
1213 | 1228 | ||
1214 | /** | 1229 | /** |
@@ -1248,58 +1263,58 @@ build_header_response (struct MHD_Request *request) | |||
1248 | 1263 | ||
1249 | mhd_assert (NULL != request->version_s); | 1264 | mhd_assert (NULL != request->version_s); |
1250 | if (0 == request->version_s[0]) | 1265 | if (0 == request->version_s[0]) |
1251 | { | 1266 | { |
1252 | data = MHD_pool_allocate (connection->pool, | 1267 | data = MHD_pool_allocate (connection->pool, |
1253 | 0, | 1268 | 0, |
1254 | MHD_YES); | 1269 | MHD_YES); |
1255 | request->write_buffer = data; | 1270 | request->write_buffer = data; |
1256 | request->write_buffer_append_offset = 0; | 1271 | request->write_buffer_append_offset = 0; |
1257 | request->write_buffer_send_offset = 0; | 1272 | request->write_buffer_send_offset = 0; |
1258 | request->write_buffer_size = 0; | 1273 | request->write_buffer_size = 0; |
1259 | return true; | 1274 | return true; |
1260 | } | 1275 | } |
1261 | if (MHD_REQUEST_FOOTERS_RECEIVED == request->state) | 1276 | if (MHD_REQUEST_FOOTERS_RECEIVED == request->state) |
1262 | { | 1277 | { |
1263 | const char *reason_phrase; | 1278 | const char *reason_phrase; |
1264 | const char *version; | 1279 | const char *version; |
1265 | 1280 | ||
1266 | reason_phrase | 1281 | reason_phrase |
1267 | = MHD_get_reason_phrase_for (response->status_code); | 1282 | = MHD_get_reason_phrase_for (response->status_code); |
1268 | version | 1283 | version |
1269 | = (response->icy) | 1284 | = (response->icy) |
1270 | ? "ICY" | 1285 | ? "ICY" |
1271 | : ( (MHD_str_equal_caseless_ (MHD_HTTP_VERSION_1_0, | 1286 | : ( (MHD_str_equal_caseless_ (MHD_HTTP_VERSION_1_0, |
1272 | request->version_s)) | 1287 | request->version_s)) |
1273 | ? MHD_HTTP_VERSION_1_0 | 1288 | ? MHD_HTTP_VERSION_1_0 |
1274 | : MHD_HTTP_VERSION_1_1); | 1289 | : MHD_HTTP_VERSION_1_1); |
1275 | MHD_snprintf_ (code, | 1290 | MHD_snprintf_ (code, |
1276 | sizeof (code), | 1291 | sizeof (code), |
1277 | "%s %u %s\r\n", | 1292 | "%s %u %s\r\n", |
1278 | version, | 1293 | version, |
1279 | response->status_code, | 1294 | response->status_code, |
1280 | reason_phrase); | 1295 | reason_phrase); |
1281 | off = strlen (code); | 1296 | off = strlen (code); |
1282 | /* estimate size */ | 1297 | /* estimate size */ |
1283 | size = off + 2; /* +2 for extra "\r\n" at the end */ | 1298 | size = off + 2; /* +2 for extra "\r\n" at the end */ |
1284 | kind = MHD_HEADER_KIND; | 1299 | kind = MHD_HEADER_KIND; |
1285 | if ( (! daemon->suppress_date) && | 1300 | if ( (! daemon->suppress_date) && |
1286 | (NULL == MHD_response_get_header (response, | 1301 | (NULL == MHD_response_get_header (response, |
1287 | MHD_HTTP_HEADER_DATE)) ) | 1302 | MHD_HTTP_HEADER_DATE)) ) |
1288 | get_date_string (date, | 1303 | get_date_string (date, |
1289 | sizeof (date)); | 1304 | sizeof (date)); |
1290 | else | 1305 | else |
1291 | date[0] = '\0'; | 1306 | date[0] = '\0'; |
1292 | datelen = strlen (date); | 1307 | datelen = strlen (date); |
1293 | size += datelen; | 1308 | size += datelen; |
1294 | } | 1309 | } |
1295 | else | 1310 | else |
1296 | { | 1311 | { |
1297 | /* 2 bytes for final CRLF of a Chunked-Body */ | 1312 | /* 2 bytes for final CRLF of a Chunked-Body */ |
1298 | size = 2; | 1313 | size = 2; |
1299 | kind = MHD_FOOTER_KIND; | 1314 | kind = MHD_FOOTER_KIND; |
1300 | off = 0; | 1315 | off = 0; |
1301 | datelen = 0; | 1316 | datelen = 0; |
1302 | } | 1317 | } |
1303 | 1318 | ||
1304 | /* calculate extra headers we need to add, such as 'Connection: close', | 1319 | /* calculate extra headers we need to add, such as 'Connection: close', |
1305 | first see what was explicitly requested by the application */ | 1320 | first see what was explicitly requested by the application */ |
@@ -1309,153 +1324,154 @@ build_header_response (struct MHD_Request *request) | |||
1309 | must_add_content_length = false; | 1324 | must_add_content_length = false; |
1310 | response_has_close = false; | 1325 | response_has_close = false; |
1311 | switch (request->state) | 1326 | switch (request->state) |
1312 | { | 1327 | { |
1313 | case MHD_REQUEST_FOOTERS_RECEIVED: | 1328 | case MHD_REQUEST_FOOTERS_RECEIVED: |
1314 | response_has_close | 1329 | response_has_close |
1315 | = check_response_header_s_token_ci (response, | 1330 | = check_response_header_s_token_ci (response, |
1316 | MHD_HTTP_HEADER_CONNECTION, | 1331 | MHD_HTTP_HEADER_CONNECTION, |
1317 | "close"); | 1332 | "close"); |
1318 | response_has_keepalive | 1333 | response_has_keepalive |
1319 | = check_response_header_s_token_ci (response, | 1334 | = check_response_header_s_token_ci (response, |
1320 | MHD_HTTP_HEADER_CONNECTION, | 1335 | MHD_HTTP_HEADER_CONNECTION, |
1321 | "Keep-Alive"); | 1336 | "Keep-Alive"); |
1322 | client_requested_close | 1337 | client_requested_close |
1323 | = MHD_lookup_header_s_token_ci (request, | 1338 | = MHD_lookup_header_s_token_ci (request, |
1324 | MHD_HTTP_HEADER_CONNECTION, | 1339 | MHD_HTTP_HEADER_CONNECTION, |
1325 | "close"); | 1340 | "close"); |
1326 | 1341 | ||
1327 | if (response->v10_only) | 1342 | if (response->v10_only) |
1328 | request->keepalive = MHD_CONN_MUST_CLOSE; | 1343 | request->keepalive = MHD_CONN_MUST_CLOSE; |
1329 | #ifdef UPGRADE_SUPPORT | 1344 | #ifdef UPGRADE_SUPPORT |
1330 | else if (NULL != response->upgrade_handler) | 1345 | else if (NULL != response->upgrade_handler) |
1331 | /* If this connection will not be "upgraded", it must be closed. */ | 1346 | /* If this connection will not be "upgraded", it must be closed. */ |
1332 | request->keepalive = MHD_CONN_MUST_CLOSE; | 1347 | request->keepalive = MHD_CONN_MUST_CLOSE; |
1333 | #endif /* UPGRADE_SUPPORT */ | 1348 | #endif /* UPGRADE_SUPPORT */ |
1334 | 1349 | ||
1335 | /* now analyze chunked encoding situation */ | 1350 | /* now analyze chunked encoding situation */ |
1336 | request->have_chunked_upload = false; | 1351 | request->have_chunked_upload = false; |
1337 | 1352 | ||
1338 | if ( (MHD_SIZE_UNKNOWN == response->total_size) && | 1353 | if ( (MHD_SIZE_UNKNOWN == response->total_size) && |
1339 | #ifdef UPGRADE_SUPPORT | 1354 | #ifdef UPGRADE_SUPPORT |
1340 | (NULL == response->upgrade_handler) && | 1355 | (NULL == response->upgrade_handler) && |
1341 | #endif /* UPGRADE_SUPPORT */ | 1356 | #endif /* UPGRADE_SUPPORT */ |
1342 | (! response_has_close) && | 1357 | (! response_has_close) && |
1343 | (! client_requested_close) ) | 1358 | (! client_requested_close) ) |
1359 | { | ||
1360 | /* size is unknown, and close was not explicitly requested; | ||
1361 | need to either to HTTP 1.1 chunked encoding or | ||
1362 | close the connection */ | ||
1363 | /* 'close' header doesn't exist yet, see if we need to add one; | ||
1364 | if the client asked for a close, no need to start chunk'ing */ | ||
1365 | if ( (keepalive_possible (request)) && | ||
1366 | (MHD_str_equal_caseless_ (MHD_HTTP_VERSION_1_1, | ||
1367 | request->version_s)) ) | ||
1368 | { | ||
1369 | have_encoding | ||
1370 | = MHD_response_get_header (response, | ||
1371 | MHD_HTTP_HEADER_TRANSFER_ENCODING); | ||
1372 | if (NULL == have_encoding) | ||
1344 | { | 1373 | { |
1345 | /* size is unknown, and close was not explicitly requested; | 1374 | must_add_chunked_encoding = true; |
1346 | need to either to HTTP 1.1 chunked encoding or | 1375 | request->have_chunked_upload = true; |
1347 | close the connection */ | ||
1348 | /* 'close' header doesn't exist yet, see if we need to add one; | ||
1349 | if the client asked for a close, no need to start chunk'ing */ | ||
1350 | if ( (keepalive_possible (request)) && | ||
1351 | (MHD_str_equal_caseless_ (MHD_HTTP_VERSION_1_1, | ||
1352 | request->version_s)) ) | ||
1353 | { | ||
1354 | have_encoding | ||
1355 | = MHD_response_get_header (response, | ||
1356 | MHD_HTTP_HEADER_TRANSFER_ENCODING); | ||
1357 | if (NULL == have_encoding) | ||
1358 | { | ||
1359 | must_add_chunked_encoding = true; | ||
1360 | request->have_chunked_upload = true; | ||
1361 | } | ||
1362 | else if (MHD_str_equal_caseless_ (have_encoding, | ||
1363 | "identity")) | ||
1364 | { | ||
1365 | /* application forced identity encoding, can't do 'chunked' */ | ||
1366 | must_add_close = true; | ||
1367 | } | ||
1368 | else | ||
1369 | { | ||
1370 | request->have_chunked_upload = true; | ||
1371 | } | ||
1372 | } | ||
1373 | else | ||
1374 | { | ||
1375 | /* Keep alive or chunking not possible | ||
1376 | => set close header if not present */ | ||
1377 | if (! response_has_close) | ||
1378 | must_add_close = true; | ||
1379 | } | ||
1380 | } | 1376 | } |
1381 | 1377 | else if (MHD_str_equal_caseless_ (have_encoding, | |
1382 | /* check for other reasons to add 'close' header */ | 1378 | "identity")) |
1383 | if ( ( (client_requested_close) || | ||
1384 | (connection->read_closed) || | ||
1385 | (MHD_CONN_MUST_CLOSE == request->keepalive)) && | ||
1386 | (! response_has_close) && | ||
1387 | #ifdef UPGRADE_SUPPORT | ||
1388 | (NULL == response->upgrade_handler) && | ||
1389 | #endif /* UPGRADE_SUPPORT */ | ||
1390 | (! response->v10_only) ) | ||
1391 | must_add_close = true; | ||
1392 | |||
1393 | /* check if we should add a 'content length' header */ | ||
1394 | have_content_length | ||
1395 | = MHD_response_get_header (response, | ||
1396 | MHD_HTTP_HEADER_CONTENT_LENGTH); | ||
1397 | |||
1398 | /* MHD_HTTP_NO_CONTENT, MHD_HTTP_NOT_MODIFIED and 1xx-status | ||
1399 | codes SHOULD NOT have a Content-Length according to spec; | ||
1400 | also chunked encoding / unknown length or CONNECT... */ | ||
1401 | if ( (MHD_SIZE_UNKNOWN != response->total_size) && | ||
1402 | (MHD_HTTP_NO_CONTENT != response->status_code) && | ||
1403 | (MHD_HTTP_NOT_MODIFIED != response->status_code) && | ||
1404 | (MHD_HTTP_OK <= response->status_code) && | ||
1405 | (NULL == have_content_length) && | ||
1406 | (request->method != MHD_METHOD_CONNECT) ) | ||
1407 | { | 1379 | { |
1408 | /* | 1380 | /* application forced identity encoding, can't do 'chunked' */ |
1409 | Here we add a content-length if one is missing; however, | 1381 | must_add_close = true; |
1410 | for 'connect' methods, the responses MUST NOT include a | ||
1411 | content-length header *if* the response code is 2xx (in | ||
1412 | which case we expect there to be no body). Still, | ||
1413 | as we don't know the response code here in some cases, we | ||
1414 | simply only force adding a content-length header if this | ||
1415 | is not a 'connect' or if the response is not empty | ||
1416 | (which is kind of more sane, because if some crazy | ||
1417 | application did return content with a 2xx status code, | ||
1418 | then having a content-length might again be a good idea). | ||
1419 | |||
1420 | Note that the change from 'SHOULD NOT' to 'MUST NOT' is | ||
1421 | a recent development of the HTTP 1.1 specification. | ||
1422 | */ | ||
1423 | content_length_len | ||
1424 | = MHD_snprintf_ (content_length_buf, | ||
1425 | sizeof (content_length_buf), | ||
1426 | MHD_HTTP_HEADER_CONTENT_LENGTH ": " MHD_UNSIGNED_LONG_LONG_PRINTF "\r\n", | ||
1427 | (MHD_UNSIGNED_LONG_LONG) response->total_size); | ||
1428 | must_add_content_length = true; | ||
1429 | } | 1382 | } |
1430 | 1383 | else | |
1431 | /* check for adding keep alive */ | 1384 | { |
1432 | if ( (! response_has_keepalive) && | 1385 | request->have_chunked_upload = true; |
1433 | (! response_has_close) && | 1386 | } |
1434 | (! must_add_close) && | 1387 | } |
1435 | (MHD_CONN_MUST_CLOSE != request->keepalive) && | 1388 | else |
1389 | { | ||
1390 | /* Keep alive or chunking not possible | ||
1391 | => set close header if not present */ | ||
1392 | if (! response_has_close) | ||
1393 | must_add_close = true; | ||
1394 | } | ||
1395 | } | ||
1396 | |||
1397 | /* check for other reasons to add 'close' header */ | ||
1398 | if ( ( (client_requested_close) || | ||
1399 | (connection->read_closed) || | ||
1400 | (MHD_CONN_MUST_CLOSE == request->keepalive)) && | ||
1401 | (! response_has_close) && | ||
1436 | #ifdef UPGRADE_SUPPORT | 1402 | #ifdef UPGRADE_SUPPORT |
1437 | (NULL == response->upgrade_handler) && | 1403 | (NULL == response->upgrade_handler) && |
1438 | #endif /* UPGRADE_SUPPORT */ | 1404 | #endif /* UPGRADE_SUPPORT */ |
1439 | (keepalive_possible (request)) ) | 1405 | (! response->v10_only) ) |
1440 | must_add_keep_alive = true; | 1406 | must_add_close = true; |
1441 | break; | 1407 | |
1442 | case MHD_REQUEST_BODY_SENT: | 1408 | /* check if we should add a 'content length' header */ |
1443 | response_has_keepalive = false; | 1409 | have_content_length |
1444 | break; | 1410 | = MHD_response_get_header (response, |
1445 | default: | 1411 | MHD_HTTP_HEADER_CONTENT_LENGTH); |
1446 | mhd_assert (0); | 1412 | |
1447 | return MHD_NO; | 1413 | /* MHD_HTTP_NO_CONTENT, MHD_HTTP_NOT_MODIFIED and 1xx-status |
1448 | } | 1414 | codes SHOULD NOT have a Content-Length according to spec; |
1415 | also chunked encoding / unknown length or CONNECT... */ | ||
1416 | if ( (MHD_SIZE_UNKNOWN != response->total_size) && | ||
1417 | (MHD_HTTP_NO_CONTENT != response->status_code) && | ||
1418 | (MHD_HTTP_NOT_MODIFIED != response->status_code) && | ||
1419 | (MHD_HTTP_OK <= response->status_code) && | ||
1420 | (NULL == have_content_length) && | ||
1421 | (request->method != MHD_METHOD_CONNECT) ) | ||
1422 | { | ||
1423 | /* | ||
1424 | Here we add a content-length if one is missing; however, | ||
1425 | for 'connect' methods, the responses MUST NOT include a | ||
1426 | content-length header *if* the response code is 2xx (in | ||
1427 | which case we expect there to be no body). Still, | ||
1428 | as we don't know the response code here in some cases, we | ||
1429 | simply only force adding a content-length header if this | ||
1430 | is not a 'connect' or if the response is not empty | ||
1431 | (which is kind of more sane, because if some crazy | ||
1432 | application did return content with a 2xx status code, | ||
1433 | then having a content-length might again be a good idea). | ||
1434 | |||
1435 | Note that the change from 'SHOULD NOT' to 'MUST NOT' is | ||
1436 | a recent development of the HTTP 1.1 specification. | ||
1437 | */ | ||
1438 | content_length_len | ||
1439 | = MHD_snprintf_ (content_length_buf, | ||
1440 | sizeof (content_length_buf), | ||
1441 | MHD_HTTP_HEADER_CONTENT_LENGTH ": " | ||
1442 | MHD_UNSIGNED_LONG_LONG_PRINTF "\r\n", | ||
1443 | (MHD_UNSIGNED_LONG_LONG) response->total_size); | ||
1444 | must_add_content_length = true; | ||
1445 | } | ||
1446 | |||
1447 | /* check for adding keep alive */ | ||
1448 | if ( (! response_has_keepalive) && | ||
1449 | (! response_has_close) && | ||
1450 | (! must_add_close) && | ||
1451 | (MHD_CONN_MUST_CLOSE != request->keepalive) && | ||
1452 | #ifdef UPGRADE_SUPPORT | ||
1453 | (NULL == response->upgrade_handler) && | ||
1454 | #endif /* UPGRADE_SUPPORT */ | ||
1455 | (keepalive_possible (request)) ) | ||
1456 | must_add_keep_alive = true; | ||
1457 | break; | ||
1458 | case MHD_REQUEST_BODY_SENT: | ||
1459 | response_has_keepalive = false; | ||
1460 | break; | ||
1461 | default: | ||
1462 | mhd_assert (0); | ||
1463 | return MHD_NO; | ||
1464 | } | ||
1449 | 1465 | ||
1450 | if (MHD_CONN_MUST_CLOSE != request->keepalive) | 1466 | if (MHD_CONN_MUST_CLOSE != request->keepalive) |
1451 | { | 1467 | { |
1452 | if ( (must_add_close) || | 1468 | if ( (must_add_close) || |
1453 | (response_has_close) ) | 1469 | (response_has_close) ) |
1454 | request->keepalive = MHD_CONN_MUST_CLOSE; | 1470 | request->keepalive = MHD_CONN_MUST_CLOSE; |
1455 | else if ( (must_add_keep_alive) || | 1471 | else if ( (must_add_keep_alive) || |
1456 | (response_has_keepalive) ) | 1472 | (response_has_keepalive) ) |
1457 | request->keepalive = MHD_CONN_USE_KEEPALIVE; | 1473 | request->keepalive = MHD_CONN_USE_KEEPALIVE; |
1458 | } | 1474 | } |
1459 | 1475 | ||
1460 | if (must_add_close) | 1476 | if (must_add_close) |
1461 | size += MHD_STATICSTR_LEN_ ("Connection: close\r\n"); | 1477 | size += MHD_STATICSTR_LEN_ ("Connection: close\r\n"); |
@@ -1469,91 +1485,91 @@ build_header_response (struct MHD_Request *request) | |||
1469 | mhd_assert (! (must_add_chunked_encoding && must_add_content_length) ); | 1485 | mhd_assert (! (must_add_chunked_encoding && must_add_content_length) ); |
1470 | 1486 | ||
1471 | for (pos = response->first_header; NULL != pos; pos = pos->next) | 1487 | for (pos = response->first_header; NULL != pos; pos = pos->next) |
1472 | { | 1488 | { |
1473 | /* TODO: add proper support for excluding "Keep-Alive" token. */ | 1489 | /* TODO: add proper support for excluding "Keep-Alive" token. */ |
1474 | if ( (pos->kind == kind) && | 1490 | if ( (pos->kind == kind) && |
1475 | (! ( (must_add_close) && | 1491 | (! ( (must_add_close) && |
1476 | (response_has_keepalive) && | 1492 | (response_has_keepalive) && |
1477 | (MHD_str_equal_caseless_(pos->header, | 1493 | (MHD_str_equal_caseless_ (pos->header, |
1478 | MHD_HTTP_HEADER_CONNECTION)) && | 1494 | MHD_HTTP_HEADER_CONNECTION)) && |
1479 | (MHD_str_equal_caseless_(pos->value, | 1495 | (MHD_str_equal_caseless_ (pos->value, |
1480 | "Keep-Alive")) ) ) ) | 1496 | "Keep-Alive")) ) ) ) |
1481 | size += strlen (pos->header) + strlen (pos->value) + 4; /* colon, space, linefeeds */ | 1497 | size += strlen (pos->header) + strlen (pos->value) + 4; /* colon, space, linefeeds */ |
1482 | } | 1498 | } |
1483 | /* produce data */ | 1499 | /* produce data */ |
1484 | data = MHD_pool_allocate (connection->pool, | 1500 | data = MHD_pool_allocate (connection->pool, |
1485 | size + 1, | 1501 | size + 1, |
1486 | MHD_NO); | 1502 | MHD_NO); |
1487 | if (NULL == data) | 1503 | if (NULL == data) |
1488 | { | 1504 | { |
1489 | #ifdef HAVE_MESSAGES | 1505 | #ifdef HAVE_MESSAGES |
1490 | MHD_DLOG (daemon, | 1506 | MHD_DLOG (daemon, |
1491 | MHD_SC_CONNECTION_POOL_MALLOC_FAILURE, | 1507 | MHD_SC_CONNECTION_POOL_MALLOC_FAILURE, |
1492 | "Not enough memory for write!\n"); | 1508 | "Not enough memory for write!\n"); |
1493 | #endif | 1509 | #endif |
1494 | return false; | 1510 | return false; |
1495 | } | 1511 | } |
1496 | if (MHD_REQUEST_FOOTERS_RECEIVED == request->state) | 1512 | if (MHD_REQUEST_FOOTERS_RECEIVED == request->state) |
1497 | { | 1513 | { |
1498 | memcpy (data, | 1514 | memcpy (data, |
1499 | code, | 1515 | code, |
1500 | off); | 1516 | off); |
1501 | } | 1517 | } |
1502 | if (must_add_close) | 1518 | if (must_add_close) |
1503 | { | 1519 | { |
1504 | /* we must add the 'Connection: close' header */ | 1520 | /* we must add the 'Connection: close' header */ |
1505 | memcpy (&data[off], | 1521 | memcpy (&data[off], |
1506 | "Connection: close\r\n", | 1522 | "Connection: close\r\n", |
1507 | MHD_STATICSTR_LEN_ ("Connection: close\r\n")); | 1523 | MHD_STATICSTR_LEN_ ("Connection: close\r\n")); |
1508 | off += MHD_STATICSTR_LEN_ ("Connection: close\r\n"); | 1524 | off += MHD_STATICSTR_LEN_ ("Connection: close\r\n"); |
1509 | } | 1525 | } |
1510 | if (must_add_keep_alive) | 1526 | if (must_add_keep_alive) |
1511 | { | 1527 | { |
1512 | /* we must add the 'Connection: Keep-Alive' header */ | 1528 | /* we must add the 'Connection: Keep-Alive' header */ |
1513 | memcpy (&data[off], | 1529 | memcpy (&data[off], |
1514 | "Connection: Keep-Alive\r\n", | 1530 | "Connection: Keep-Alive\r\n", |
1515 | MHD_STATICSTR_LEN_ ("Connection: Keep-Alive\r\n")); | 1531 | MHD_STATICSTR_LEN_ ("Connection: Keep-Alive\r\n")); |
1516 | off += MHD_STATICSTR_LEN_ ("Connection: Keep-Alive\r\n"); | 1532 | off += MHD_STATICSTR_LEN_ ("Connection: Keep-Alive\r\n"); |
1517 | } | 1533 | } |
1518 | if (must_add_chunked_encoding) | 1534 | if (must_add_chunked_encoding) |
1519 | { | 1535 | { |
1520 | /* we must add the 'Transfer-Encoding: chunked' header */ | 1536 | /* we must add the 'Transfer-Encoding: chunked' header */ |
1521 | memcpy (&data[off], | 1537 | memcpy (&data[off], |
1522 | "Transfer-Encoding: chunked\r\n", | 1538 | "Transfer-Encoding: chunked\r\n", |
1523 | MHD_STATICSTR_LEN_ ("Transfer-Encoding: chunked\r\n")); | 1539 | MHD_STATICSTR_LEN_ ("Transfer-Encoding: chunked\r\n")); |
1524 | off += MHD_STATICSTR_LEN_ ("Transfer-Encoding: chunked\r\n"); | 1540 | off += MHD_STATICSTR_LEN_ ("Transfer-Encoding: chunked\r\n"); |
1525 | } | 1541 | } |
1526 | if (must_add_content_length) | 1542 | if (must_add_content_length) |
1527 | { | 1543 | { |
1528 | /* we must add the 'Content-Length' header */ | 1544 | /* we must add the 'Content-Length' header */ |
1529 | memcpy (&data[off], | 1545 | memcpy (&data[off], |
1530 | content_length_buf, | 1546 | content_length_buf, |
1531 | content_length_len); | 1547 | content_length_len); |
1532 | off += content_length_len; | 1548 | off += content_length_len; |
1533 | } | 1549 | } |
1534 | for (pos = response->first_header; NULL != pos; pos = pos->next) | 1550 | for (pos = response->first_header; NULL != pos; pos = pos->next) |
1535 | { | 1551 | { |
1536 | /* TODO: add proper support for excluding "Keep-Alive" token. */ | 1552 | /* TODO: add proper support for excluding "Keep-Alive" token. */ |
1537 | if ( (pos->kind == kind) && | 1553 | if ( (pos->kind == kind) && |
1538 | (! ( (must_add_close) && | 1554 | (! ( (must_add_close) && |
1539 | (response_has_keepalive) && | 1555 | (response_has_keepalive) && |
1540 | (MHD_str_equal_caseless_(pos->header, | 1556 | (MHD_str_equal_caseless_ (pos->header, |
1541 | MHD_HTTP_HEADER_CONNECTION)) && | 1557 | MHD_HTTP_HEADER_CONNECTION)) && |
1542 | (MHD_str_equal_caseless_(pos->value, | 1558 | (MHD_str_equal_caseless_ (pos->value, |
1543 | "Keep-Alive")) ) ) ) | 1559 | "Keep-Alive")) ) ) ) |
1544 | off += MHD_snprintf_ (&data[off], | 1560 | off += MHD_snprintf_ (&data[off], |
1545 | size - off, | 1561 | size - off, |
1546 | "%s: %s\r\n", | 1562 | "%s: %s\r\n", |
1547 | pos->header, | 1563 | pos->header, |
1548 | pos->value); | 1564 | pos->value); |
1549 | } | 1565 | } |
1550 | if (MHD_REQUEST_FOOTERS_RECEIVED == request->state) | 1566 | if (MHD_REQUEST_FOOTERS_RECEIVED == request->state) |
1551 | { | 1567 | { |
1552 | memcpy (&data[off], | 1568 | memcpy (&data[off], |
1553 | date, | 1569 | date, |
1554 | datelen); | 1570 | datelen); |
1555 | off += datelen; | 1571 | off += datelen; |
1556 | } | 1572 | } |
1557 | memcpy (&data[off], | 1573 | memcpy (&data[off], |
1558 | "\r\n", | 1574 | "\r\n", |
1559 | 2); | 1575 | 2); |
@@ -1584,50 +1600,52 @@ build_header_response (struct MHD_Request *request) | |||
1584 | */ | 1600 | */ |
1585 | static void | 1601 | static void |
1586 | transmit_error_response (struct MHD_Request *request, | 1602 | transmit_error_response (struct MHD_Request *request, |
1587 | enum MHD_StatusCode ec, | 1603 | enum MHD_StatusCode ec, |
1588 | enum MHD_HTTP_StatusCode status_code, | 1604 | enum MHD_HTTP_StatusCode status_code, |
1589 | const char *message) | 1605 | const char *message) |
1590 | { | 1606 | { |
1591 | struct MHD_Response *response; | 1607 | struct MHD_Response *response; |
1592 | 1608 | ||
1593 | if (NULL == request->version_s) | 1609 | if (NULL == request->version_s) |
1594 | { | 1610 | { |
1595 | /* we were unable to process the full header line, so we don't | 1611 | /* we were unable to process the full header line, so we don't |
1596 | really know what version the client speaks; assume 1.0 */ | 1612 | really know what version the client speaks; assume 1.0 */ |
1597 | request->version_s = MHD_HTTP_VERSION_1_0; | 1613 | request->version_s = MHD_HTTP_VERSION_1_0; |
1598 | } | 1614 | } |
1599 | request->state = MHD_REQUEST_FOOTERS_RECEIVED; | 1615 | request->state = MHD_REQUEST_FOOTERS_RECEIVED; |
1600 | request->connection->read_closed = true; | 1616 | request->connection->read_closed = true; |
1601 | #ifdef HAVE_MESSAGES | 1617 | #ifdef HAVE_MESSAGES |
1602 | MHD_DLOG (request->daemon, | 1618 | MHD_DLOG (request->daemon, |
1603 | ec, | 1619 | ec, |
1604 | _("Error processing request (HTTP response code is %u (`%s')). Closing connection.\n"), | 1620 | _ ( |
1621 | "Error processing request (HTTP response code is %u (`%s')). Closing connection.\n"), | ||
1605 | status_code, | 1622 | status_code, |
1606 | message); | 1623 | message); |
1607 | #endif | 1624 | #endif |
1608 | if (NULL != request->response) | 1625 | if (NULL != request->response) |
1609 | { | 1626 | { |
1610 | MHD_response_queue_for_destroy (request->response); | 1627 | MHD_response_queue_for_destroy (request->response); |
1611 | request->response = NULL; | 1628 | request->response = NULL; |
1612 | } | 1629 | } |
1613 | response = MHD_response_from_buffer (status_code, | 1630 | response = MHD_response_from_buffer (status_code, |
1614 | strlen (message), | 1631 | strlen (message), |
1615 | (void *) message, | 1632 | (void *) message, |
1616 | MHD_RESPMEM_PERSISTENT); | 1633 | MHD_RESPMEM_PERSISTENT); |
1617 | request->response = response; | 1634 | request->response = response; |
1618 | /* Do not reuse this connection. */ | 1635 | /* Do not reuse this connection. */ |
1619 | request->keepalive = MHD_CONN_MUST_CLOSE; | 1636 | request->keepalive = MHD_CONN_MUST_CLOSE; |
1620 | if (! build_header_response (request)) | 1637 | if (! build_header_response (request)) |
1621 | { | 1638 | { |
1622 | /* oops - close! */ | 1639 | /* oops - close! */ |
1623 | CONNECTION_CLOSE_ERROR (request->connection, | 1640 | CONNECTION_CLOSE_ERROR (request->connection, |
1624 | ec, | 1641 | ec, |
1625 | _("Closing connection (failed to create response header)\n")); | 1642 | _ ( |
1626 | } | 1643 | "Closing connection (failed to create response header)\n")); |
1644 | } | ||
1627 | else | 1645 | else |
1628 | { | 1646 | { |
1629 | request->state = MHD_REQUEST_HEADERS_SENDING; | 1647 | request->state = MHD_REQUEST_HEADERS_SENDING; |
1630 | } | 1648 | } |
1631 | } | 1649 | } |
1632 | 1650 | ||
1633 | 1651 | ||
@@ -1640,7 +1658,8 @@ transmit_error_response (struct MHD_Request *request, | |||
1640 | static enum MHD_Method | 1658 | static enum MHD_Method |
1641 | method_string_to_enum (const char *method) | 1659 | method_string_to_enum (const char *method) |
1642 | { | 1660 | { |
1643 | static const struct { | 1661 | static const struct |
1662 | { | ||
1644 | const char *key; | 1663 | const char *key; |
1645 | enum MHD_Method value; | 1664 | enum MHD_Method value; |
1646 | } methods[] = { | 1665 | } methods[] = { |
@@ -1685,10 +1704,10 @@ method_string_to_enum (const char *method) | |||
1685 | }; | 1704 | }; |
1686 | unsigned int i; | 1705 | unsigned int i; |
1687 | 1706 | ||
1688 | for (i=0;NULL != methods[i].key;i++) | 1707 | for (i = 0; NULL != methods[i].key; i++) |
1689 | if (0 == | 1708 | if (0 == |
1690 | MHD_str_equal_caseless_ (method, | 1709 | MHD_str_equal_caseless_ (method, |
1691 | methods[i].key)) | 1710 | methods[i].key)) |
1692 | return methods[i].value; | 1711 | return methods[i].value; |
1693 | return MHD_METHOD_UNKNOWN; | 1712 | return MHD_METHOD_UNKNOWN; |
1694 | } | 1713 | } |
@@ -1706,27 +1725,27 @@ method_string_to_enum (const char *method) | |||
1706 | */ | 1725 | */ |
1707 | static bool | 1726 | static bool |
1708 | request_add_header (struct MHD_Request *request, | 1727 | request_add_header (struct MHD_Request *request, |
1709 | const char *key, | 1728 | const char *key, |
1710 | const char *value, | 1729 | const char *value, |
1711 | enum MHD_ValueKind kind) | 1730 | enum MHD_ValueKind kind) |
1712 | { | 1731 | { |
1713 | if (MHD_NO == | 1732 | if (MHD_NO == |
1714 | MHD_request_set_value (request, | 1733 | MHD_request_set_value (request, |
1715 | kind, | 1734 | kind, |
1716 | key, | 1735 | key, |
1717 | value)) | 1736 | value)) |
1718 | { | 1737 | { |
1719 | #ifdef HAVE_MESSAGES | 1738 | #ifdef HAVE_MESSAGES |
1720 | MHD_DLOG (request->daemon, | 1739 | MHD_DLOG (request->daemon, |
1721 | MHD_SC_CONNECTION_POOL_MALLOC_FAILURE, | 1740 | MHD_SC_CONNECTION_POOL_MALLOC_FAILURE, |
1722 | _("Not enough memory in pool to allocate header record!\n")); | 1741 | _ ("Not enough memory in pool to allocate header record!\n")); |
1723 | #endif | 1742 | #endif |
1724 | transmit_error_response (request, | 1743 | transmit_error_response (request, |
1725 | MHD_SC_CLIENT_HEADER_TOO_BIG, | 1744 | MHD_SC_CLIENT_HEADER_TOO_BIG, |
1726 | MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE, | 1745 | MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE, |
1727 | REQUEST_TOO_BIG); | 1746 | REQUEST_TOO_BIG); |
1728 | return false; | 1747 | return false; |
1729 | } | 1748 | } |
1730 | return true; | 1749 | return true; |
1731 | } | 1750 | } |
1732 | 1751 | ||
@@ -1763,76 +1782,76 @@ parse_initial_message_line (struct MHD_Request *request, | |||
1763 | /* Skip any spaces. Not required by standard but allow | 1782 | /* Skip any spaces. Not required by standard but allow |
1764 | to be more tolerant. */ | 1783 | to be more tolerant. */ |
1765 | while ( (' ' == uri[0]) && | 1784 | while ( (' ' == uri[0]) && |
1766 | ( (size_t)(uri - line) < line_len) ) | 1785 | ( (size_t) (uri - line) < line_len) ) |
1767 | uri++; | 1786 | uri++; |
1768 | if ((size_t)(uri - line) == line_len) | 1787 | if ((size_t) (uri - line) == line_len) |
1769 | { | 1788 | { |
1770 | curi = ""; | 1789 | curi = ""; |
1771 | uri = NULL; | 1790 | uri = NULL; |
1772 | request->version_s = ""; | 1791 | request->version_s = ""; |
1773 | args = NULL; | 1792 | args = NULL; |
1774 | url_end = line_len - (line - uri); // EH, this is garbage. FIXME! | 1793 | url_end = line_len - (line - uri); // EH, this is garbage. FIXME! |
1775 | } | 1794 | } |
1776 | else | 1795 | else |
1796 | { | ||
1797 | curi = uri; | ||
1798 | /* Search from back to accept misformed URI with space */ | ||
1799 | http_version = line + line_len - 1; | ||
1800 | /* Skip any trailing spaces */ | ||
1801 | while ( (' ' == http_version[0]) && | ||
1802 | (http_version > uri) ) | ||
1803 | http_version--; | ||
1804 | /* Find first space in reverse direction */ | ||
1805 | while ( (' ' != http_version[0]) && | ||
1806 | (http_version > uri) ) | ||
1807 | http_version--; | ||
1808 | if (http_version > uri) | ||
1809 | { | ||
1810 | http_version[0] = '\0'; | ||
1811 | request->version_s = http_version + 1; | ||
1812 | args = memchr (uri, | ||
1813 | '?', | ||
1814 | http_version - uri); | ||
1815 | } | ||
1816 | else | ||
1777 | { | 1817 | { |
1778 | curi = uri; | 1818 | request->version_s = ""; |
1779 | /* Search from back to accept misformed URI with space */ | 1819 | args = memchr (uri, |
1780 | http_version = line + line_len - 1; | 1820 | '?', |
1781 | /* Skip any trailing spaces */ | 1821 | line_len - (uri - line)); |
1782 | while ( (' ' == http_version[0]) && | ||
1783 | (http_version > uri) ) | ||
1784 | http_version--; | ||
1785 | /* Find first space in reverse direction */ | ||
1786 | while ( (' ' != http_version[0]) && | ||
1787 | (http_version > uri) ) | ||
1788 | http_version--; | ||
1789 | if (http_version > uri) | ||
1790 | { | ||
1791 | http_version[0] = '\0'; | ||
1792 | request->version_s = http_version + 1; | ||
1793 | args = memchr (uri, | ||
1794 | '?', | ||
1795 | http_version - uri); | ||
1796 | } | ||
1797 | else | ||
1798 | { | ||
1799 | request->version_s = ""; | ||
1800 | args = memchr (uri, | ||
1801 | '?', | ||
1802 | line_len - (uri - line)); | ||
1803 | } | ||
1804 | url_end = http_version - uri; | ||
1805 | } | 1822 | } |
1823 | url_end = http_version - uri; | ||
1824 | } | ||
1806 | if ( (MHD_PSL_STRICT == daemon->protocol_strict_level) && | 1825 | if ( (MHD_PSL_STRICT == daemon->protocol_strict_level) && |
1807 | (NULL != memchr (curi, | 1826 | (NULL != memchr (curi, |
1808 | ' ', | 1827 | ' ', |
1809 | url_end)) ) | 1828 | url_end)) ) |
1810 | { | 1829 | { |
1811 | /* space exists in URI and we are supposed to be strict, reject */ | 1830 | /* space exists in URI and we are supposed to be strict, reject */ |
1812 | return MHD_NO; | 1831 | return MHD_NO; |
1813 | } | 1832 | } |
1814 | if (NULL != daemon->early_uri_logger_cb) | 1833 | if (NULL != daemon->early_uri_logger_cb) |
1815 | { | 1834 | { |
1816 | request->client_context | 1835 | request->client_context |
1817 | = daemon->early_uri_logger_cb (daemon->early_uri_logger_cb_cls, | 1836 | = daemon->early_uri_logger_cb (daemon->early_uri_logger_cb_cls, |
1818 | curi, | 1837 | curi, |
1819 | request); | 1838 | request); |
1820 | } | 1839 | } |
1821 | if (NULL != args) | 1840 | if (NULL != args) |
1822 | { | 1841 | { |
1823 | args[0] = '\0'; | 1842 | args[0] = '\0'; |
1824 | args++; | 1843 | args++; |
1825 | /* note that this call clobbers 'args' */ | 1844 | /* note that this call clobbers 'args' */ |
1826 | MHD_parse_arguments_ (request, | 1845 | MHD_parse_arguments_ (request, |
1827 | MHD_GET_ARGUMENT_KIND, | 1846 | MHD_GET_ARGUMENT_KIND, |
1828 | args, | 1847 | args, |
1829 | &request_add_header, | 1848 | &request_add_header, |
1830 | &unused_num_headers); | 1849 | &unused_num_headers); |
1831 | } | 1850 | } |
1832 | if (NULL != uri) | 1851 | if (NULL != uri) |
1833 | daemon->unescape_cb (daemon->unescape_cb_cls, | 1852 | daemon->unescape_cb (daemon->unescape_cb_cls, |
1834 | request, | 1853 | request, |
1835 | uri); | 1854 | uri); |
1836 | request->url = curi; | 1855 | request->url = curi; |
1837 | return true; | 1856 | return true; |
1838 | } | 1857 | } |
@@ -1856,43 +1875,46 @@ process_header_line (struct MHD_Request *request, | |||
1856 | 1875 | ||
1857 | /* line should be normal header line, find colon */ | 1876 | /* line should be normal header line, find colon */ |
1858 | colon = strchr (line, | 1877 | colon = strchr (line, |
1859 | ':'); | 1878 | ':'); |
1860 | if (NULL == colon) | 1879 | if (NULL == colon) |
1880 | { | ||
1881 | /* error in header line, die hard */ | ||
1882 | CONNECTION_CLOSE_ERROR (connection, | ||
1883 | MHD_SC_CONNECTION_PARSE_FAIL_CLOSED, | ||
1884 | _ ( | ||
1885 | "Received malformed line (no colon). Closing connection.\n")); | ||
1886 | return false; | ||
1887 | } | ||
1888 | if (MHD_PSL_PERMISSIVE != request->daemon->protocol_strict_level) | ||
1889 | { | ||
1890 | /* check for whitespace before colon, which is not allowed | ||
1891 | by RFC 7230 section 3.2.4; we count space ' ' and | ||
1892 | tab '\t', but not '\r\n' as those would have ended the line. */ | ||
1893 | const char *white; | ||
1894 | |||
1895 | white = strchr (line, | ||
1896 | (unsigned char) ' '); | ||
1897 | if ( (NULL != white) && | ||
1898 | (white < colon) ) | ||
1861 | { | 1899 | { |
1862 | /* error in header line, die hard */ | ||
1863 | CONNECTION_CLOSE_ERROR (connection, | 1900 | CONNECTION_CLOSE_ERROR (connection, |
1864 | MHD_SC_CONNECTION_PARSE_FAIL_CLOSED, | 1901 | MHD_SC_CONNECTION_PARSE_FAIL_CLOSED, |
1865 | _("Received malformed line (no colon). Closing connection.\n")); | 1902 | _ ( |
1903 | "Whitespace before colon forbidden by RFC 7230. Closing connection.\n")); | ||
1866 | return false; | 1904 | return false; |
1867 | } | 1905 | } |
1868 | if (MHD_PSL_PERMISSIVE != request->daemon->protocol_strict_level) | 1906 | white = strchr (line, |
1907 | (unsigned char) '\t'); | ||
1908 | if ( (NULL != white) && | ||
1909 | (white < colon) ) | ||
1869 | { | 1910 | { |
1870 | /* check for whitespace before colon, which is not allowed | 1911 | CONNECTION_CLOSE_ERROR (connection, |
1871 | by RFC 7230 section 3.2.4; we count space ' ' and | 1912 | MHD_SC_CONNECTION_PARSE_FAIL_CLOSED, |
1872 | tab '\t', but not '\r\n' as those would have ended the line. */ | 1913 | _ ( |
1873 | const char *white; | 1914 | "Tab before colon forbidden by RFC 7230. Closing connection.\n")); |
1874 | 1915 | return false; | |
1875 | white = strchr (line, | ||
1876 | (unsigned char) ' '); | ||
1877 | if ( (NULL != white) && | ||
1878 | (white < colon) ) | ||
1879 | { | ||
1880 | CONNECTION_CLOSE_ERROR (connection, | ||
1881 | MHD_SC_CONNECTION_PARSE_FAIL_CLOSED, | ||
1882 | _("Whitespace before colon forbidden by RFC 7230. Closing connection.\n")); | ||
1883 | return false; | ||
1884 | } | ||
1885 | white = strchr (line, | ||
1886 | (unsigned char) '\t'); | ||
1887 | if ( (NULL != white) && | ||
1888 | (white < colon) ) | ||
1889 | { | ||
1890 | CONNECTION_CLOSE_ERROR (connection, | ||
1891 | MHD_SC_CONNECTION_PARSE_FAIL_CLOSED, | ||
1892 | _("Tab before colon forbidden by RFC 7230. Closing connection.\n")); | ||
1893 | return false; | ||
1894 | } | ||
1895 | } | 1916 | } |
1917 | } | ||
1896 | /* zero-terminate header */ | 1918 | /* zero-terminate header */ |
1897 | colon[0] = '\0'; | 1919 | colon[0] = '\0'; |
1898 | colon++; /* advance to value */ | 1920 | colon++; /* advance to value */ |
@@ -1935,69 +1957,69 @@ process_broken_line (struct MHD_Request *request, | |||
1935 | last = request->last; | 1957 | last = request->last; |
1936 | if ( (' ' == line[0]) || | 1958 | if ( (' ' == line[0]) || |
1937 | ('\t' == line[0]) ) | 1959 | ('\t' == line[0]) ) |
1938 | { | 1960 | { |
1939 | /* value was continued on the next line, see | 1961 | /* value was continued on the next line, see |
1940 | http://www.jmarshall.com/easy/http/ */ | 1962 | http://www.jmarshall.com/easy/http/ */ |
1941 | last_len = strlen (last); | 1963 | last_len = strlen (last); |
1942 | /* skip whitespace at start of 2nd line */ | 1964 | /* skip whitespace at start of 2nd line */ |
1943 | tmp = line; | 1965 | tmp = line; |
1944 | while ( (' ' == tmp[0]) || | 1966 | while ( (' ' == tmp[0]) || |
1945 | ('\t' == tmp[0]) ) | 1967 | ('\t' == tmp[0]) ) |
1946 | tmp++; | 1968 | tmp++; |
1947 | tmp_len = strlen (tmp); | 1969 | tmp_len = strlen (tmp); |
1948 | /* FIXME: we might be able to do this better (faster!), as most | 1970 | /* FIXME: we might be able to do this better (faster!), as most |
1949 | likely 'last' and 'line' should already be adjacent in | 1971 | likely 'last' and 'line' should already be adjacent in |
1950 | memory; however, doing this right gets tricky if we have a | 1972 | memory; however, doing this right gets tricky if we have a |
1951 | value continued over multiple lines (in which case we need to | 1973 | value continued over multiple lines (in which case we need to |
1952 | record how often we have done this so we can check for | 1974 | record how often we have done this so we can check for |
1953 | adjacency); also, in the case where these are not adjacent | 1975 | adjacency); also, in the case where these are not adjacent |
1954 | (not sure how it can happen!), we would want to allocate from | 1976 | (not sure how it can happen!), we would want to allocate from |
1955 | the end of the pool, so as to not destroy the read-buffer's | 1977 | the end of the pool, so as to not destroy the read-buffer's |
1956 | ability to grow nicely. */ | 1978 | ability to grow nicely. */ |
1957 | last = MHD_pool_reallocate (connection->pool, | 1979 | last = MHD_pool_reallocate (connection->pool, |
1958 | last, | 1980 | last, |
1959 | last_len + 1, | 1981 | last_len + 1, |
1960 | last_len + tmp_len + 1); | 1982 | last_len + tmp_len + 1); |
1961 | if (NULL == last) | 1983 | if (NULL == last) |
1962 | { | ||
1963 | transmit_error_response (request, | ||
1964 | MHD_SC_CLIENT_HEADER_TOO_BIG, | ||
1965 | MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE, | ||
1966 | REQUEST_TOO_BIG); | ||
1967 | return MHD_NO; | ||
1968 | } | ||
1969 | memcpy (&last[last_len], | ||
1970 | tmp, | ||
1971 | tmp_len + 1); | ||
1972 | request->last = last; | ||
1973 | return MHD_YES; /* possibly more than 2 lines... */ | ||
1974 | } | ||
1975 | mhd_assert ( (NULL != last) && | ||
1976 | (NULL != request->colon) ); | ||
1977 | if (! request_add_header (request, | ||
1978 | last, | ||
1979 | request->colon, | ||
1980 | kind)) | ||
1981 | { | 1984 | { |
1982 | transmit_error_response (request, | 1985 | transmit_error_response (request, |
1983 | MHD_SC_CLIENT_HEADER_TOO_BIG, | 1986 | MHD_SC_CLIENT_HEADER_TOO_BIG, |
1984 | MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE, | 1987 | MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE, |
1985 | REQUEST_TOO_BIG); | 1988 | REQUEST_TOO_BIG); |
1986 | return false; | 1989 | return MHD_NO; |
1987 | } | 1990 | } |
1991 | memcpy (&last[last_len], | ||
1992 | tmp, | ||
1993 | tmp_len + 1); | ||
1994 | request->last = last; | ||
1995 | return MHD_YES; /* possibly more than 2 lines... */ | ||
1996 | } | ||
1997 | mhd_assert ( (NULL != last) && | ||
1998 | (NULL != request->colon) ); | ||
1999 | if (! request_add_header (request, | ||
2000 | last, | ||
2001 | request->colon, | ||
2002 | kind)) | ||
2003 | { | ||
2004 | transmit_error_response (request, | ||
2005 | MHD_SC_CLIENT_HEADER_TOO_BIG, | ||
2006 | MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE, | ||
2007 | REQUEST_TOO_BIG); | ||
2008 | return false; | ||
2009 | } | ||
1988 | /* we still have the current line to deal with... */ | 2010 | /* we still have the current line to deal with... */ |
1989 | if ('\0' != line[0]) | 2011 | if ('\0' != line[0]) |
2012 | { | ||
2013 | if (! process_header_line (request, | ||
2014 | line)) | ||
1990 | { | 2015 | { |
1991 | if (! process_header_line (request, | 2016 | transmit_error_response (request, |
1992 | line)) | 2017 | MHD_SC_CONNECTION_PARSE_FAIL_CLOSED, |
1993 | { | 2018 | MHD_HTTP_BAD_REQUEST, |
1994 | transmit_error_response (request, | 2019 | REQUEST_MALFORMED); |
1995 | MHD_SC_CONNECTION_PARSE_FAIL_CLOSED, | 2020 | return false; |
1996 | MHD_HTTP_BAD_REQUEST, | ||
1997 | REQUEST_MALFORMED); | ||
1998 | return false; | ||
1999 | } | ||
2000 | } | 2021 | } |
2022 | } | ||
2001 | return true; | 2023 | return true; |
2002 | } | 2024 | } |
2003 | 2025 | ||
@@ -2032,22 +2054,22 @@ get_next_header_line (struct MHD_Request *request, | |||
2032 | pos++; | 2054 | pos++; |
2033 | if ( (pos == request->read_buffer_offset - 1) && | 2055 | if ( (pos == request->read_buffer_offset - 1) && |
2034 | ('\n' != rbuf[pos]) ) | 2056 | ('\n' != rbuf[pos]) ) |
2057 | { | ||
2058 | /* not found, consider growing... */ | ||
2059 | if ( (request->read_buffer_offset == request->read_buffer_size) && | ||
2060 | (! try_grow_read_buffer (request)) ) | ||
2035 | { | 2061 | { |
2036 | /* not found, consider growing... */ | 2062 | transmit_error_response (request, |
2037 | if ( (request->read_buffer_offset == request->read_buffer_size) && | 2063 | MHD_SC_CLIENT_HEADER_TOO_BIG, |
2038 | (! try_grow_read_buffer (request)) ) | 2064 | (NULL != request->url) |
2039 | { | 2065 | ? MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE |
2040 | transmit_error_response (request, | 2066 | : MHD_HTTP_URI_TOO_LONG, |
2041 | MHD_SC_CLIENT_HEADER_TOO_BIG, | 2067 | REQUEST_TOO_BIG); |
2042 | (NULL != request->url) | ||
2043 | ? MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE | ||
2044 | : MHD_HTTP_URI_TOO_LONG, | ||
2045 | REQUEST_TOO_BIG); | ||
2046 | } | ||
2047 | if (line_len) | ||
2048 | *line_len = 0; | ||
2049 | return NULL; | ||
2050 | } | 2068 | } |
2069 | if (line_len) | ||
2070 | *line_len = 0; | ||
2071 | return NULL; | ||
2072 | } | ||
2051 | 2073 | ||
2052 | if (line_len) | 2074 | if (line_len) |
2053 | *line_len = pos; | 2075 | *line_len = pos; |
@@ -2083,7 +2105,7 @@ get_next_header_line (struct MHD_Request *request, | |||
2083 | * @return true if force push is possible, false otherwise | 2105 | * @return true if force push is possible, false otherwise |
2084 | */ | 2106 | */ |
2085 | static bool | 2107 | static bool |
2086 | socket_flush_possible(struct MHD_Connection *connection) | 2108 | socket_flush_possible (struct MHD_Connection *connection) |
2087 | { | 2109 | { |
2088 | (void) connection; /* Mute compiler warning. */ | 2110 | (void) connection; /* Mute compiler warning. */ |
2089 | #if defined(TCP_CORK) || defined(TCP_PUSH) | 2111 | #if defined(TCP_CORK) || defined(TCP_PUSH) |
@@ -2105,21 +2127,21 @@ static bool | |||
2105 | socket_start_extra_buffering (struct MHD_Connection *connection) | 2127 | socket_start_extra_buffering (struct MHD_Connection *connection) |
2106 | { | 2128 | { |
2107 | bool res = false; | 2129 | bool res = false; |
2108 | (void)connection; /* Mute compiler warning. */ | 2130 | (void) connection; /* Mute compiler warning. */ |
2109 | #if defined(TCP_CORK) || defined(TCP_NOPUSH) | 2131 | #if defined(TCP_CORK) || defined(TCP_NOPUSH) |
2110 | const MHD_SCKT_OPT_BOOL_ on_val = 1; | 2132 | const MHD_SCKT_OPT_BOOL_ on_val = 1; |
2111 | #if defined(TCP_NODELAY) | 2133 | #if defined(TCP_NODELAY) |
2112 | const MHD_SCKT_OPT_BOOL_ off_val = 0; | 2134 | const MHD_SCKT_OPT_BOOL_ off_val = 0; |
2113 | #endif /* TCP_NODELAY */ | 2135 | #endif /* TCP_NODELAY */ |
2114 | mhd_assert(NULL != connection); | 2136 | mhd_assert (NULL != connection); |
2115 | #if defined(TCP_NOPUSH) && !defined(TCP_CORK) | 2137 | #if defined(TCP_NOPUSH) && ! defined(TCP_CORK) |
2116 | /* Buffer data before sending */ | 2138 | /* Buffer data before sending */ |
2117 | res = (0 == setsockopt (connection->socket_fd, | 2139 | res = (0 == setsockopt (connection->socket_fd, |
2118 | IPPROTO_TCP, | 2140 | IPPROTO_TCP, |
2119 | TCP_NOPUSH, | 2141 | TCP_NOPUSH, |
2120 | (const void *) &on_val, | 2142 | (const void *) &on_val, |
2121 | sizeof (on_val))) | 2143 | sizeof (on_val))) |
2122 | ? true : false; | 2144 | ? true : false; |
2123 | #if defined(TCP_NODELAY) | 2145 | #if defined(TCP_NODELAY) |
2124 | /* Enable Nagle's algorithm */ | 2146 | /* Enable Nagle's algorithm */ |
2125 | /* TCP_NODELAY may interfere with TCP_NOPUSH */ | 2147 | /* TCP_NODELAY may interfere with TCP_NOPUSH */ |
@@ -2128,7 +2150,7 @@ socket_start_extra_buffering (struct MHD_Connection *connection) | |||
2128 | TCP_NODELAY, | 2150 | TCP_NODELAY, |
2129 | (const void *) &off_val, | 2151 | (const void *) &off_val, |
2130 | sizeof (off_val))) | 2152 | sizeof (off_val))) |
2131 | ? true : false; | 2153 | ? true : false; |
2132 | #endif /* TCP_NODELAY */ | 2154 | #endif /* TCP_NODELAY */ |
2133 | #else /* TCP_CORK */ | 2155 | #else /* TCP_CORK */ |
2134 | #if defined(TCP_NODELAY) | 2156 | #if defined(TCP_NODELAY) |
@@ -2147,7 +2169,7 @@ socket_start_extra_buffering (struct MHD_Connection *connection) | |||
2147 | TCP_CORK, | 2169 | TCP_CORK, |
2148 | (const void *) &on_val, | 2170 | (const void *) &on_val, |
2149 | sizeof (on_val))) | 2171 | sizeof (on_val))) |
2150 | ? true : false; | 2172 | ? true : false; |
2151 | #endif /* TCP_CORK */ | 2173 | #endif /* TCP_CORK */ |
2152 | #endif /* TCP_CORK || TCP_NOPUSH */ | 2174 | #endif /* TCP_CORK || TCP_NOPUSH */ |
2153 | return res; | 2175 | return res; |
@@ -2170,8 +2192,8 @@ socket_start_no_buffering (struct MHD_Connection *connection) | |||
2170 | const MHD_SCKT_OPT_BOOL_ off_val = 0; | 2192 | const MHD_SCKT_OPT_BOOL_ off_val = 0; |
2171 | #endif /* TCP_CORK || TCP_NOPUSH */ | 2193 | #endif /* TCP_CORK || TCP_NOPUSH */ |
2172 | 2194 | ||
2173 | (void)connection; /* Mute compiler warning. */ | 2195 | (void) connection; /* Mute compiler warning. */ |
2174 | mhd_assert(NULL != connection); | 2196 | mhd_assert (NULL != connection); |
2175 | #if defined(TCP_CORK) | 2197 | #if defined(TCP_CORK) |
2176 | /* Allow partial packets */ | 2198 | /* Allow partial packets */ |
2177 | res &= (0 == setsockopt (connection->socket_fd, | 2199 | res &= (0 == setsockopt (connection->socket_fd, |
@@ -2179,7 +2201,7 @@ socket_start_no_buffering (struct MHD_Connection *connection) | |||
2179 | TCP_CORK, | 2201 | TCP_CORK, |
2180 | (const void *) &off_val, | 2202 | (const void *) &off_val, |
2181 | sizeof (off_val))) | 2203 | sizeof (off_val))) |
2182 | ? true : false; | 2204 | ? true : false; |
2183 | #endif /* TCP_CORK */ | 2205 | #endif /* TCP_CORK */ |
2184 | #if defined(TCP_NODELAY) | 2206 | #if defined(TCP_NODELAY) |
2185 | /* Disable Nagle's algorithm for sending packets without delay */ | 2207 | /* Disable Nagle's algorithm for sending packets without delay */ |
@@ -2188,16 +2210,16 @@ socket_start_no_buffering (struct MHD_Connection *connection) | |||
2188 | TCP_NODELAY, | 2210 | TCP_NODELAY, |
2189 | (const void *) &on_val, | 2211 | (const void *) &on_val, |
2190 | sizeof (on_val))) | 2212 | sizeof (on_val))) |
2191 | ? true : false; | 2213 | ? true : false; |
2192 | #endif /* TCP_NODELAY */ | 2214 | #endif /* TCP_NODELAY */ |
2193 | #if defined(TCP_NOPUSH) && !defined(TCP_CORK) | 2215 | #if defined(TCP_NOPUSH) && ! defined(TCP_CORK) |
2194 | /* Disable extra buffering */ | 2216 | /* Disable extra buffering */ |
2195 | res &= (0 == setsockopt (connection->socket_fd, | 2217 | res &= (0 == setsockopt (connection->socket_fd, |
2196 | IPPROTO_TCP, | 2218 | IPPROTO_TCP, |
2197 | TCP_NOPUSH, | 2219 | TCP_NOPUSH, |
2198 | (const void *) &off_val, | 2220 | (const void *) &off_val, |
2199 | sizeof (off_val))) | 2221 | sizeof (off_val))) |
2200 | ? true : false; | 2222 | ? true : false; |
2201 | #endif /* TCP_NOPUSH && !TCP_CORK */ | 2223 | #endif /* TCP_NOPUSH && !TCP_CORK */ |
2202 | return res; | 2224 | return res; |
2203 | #else /* !TCP_NODELAY */ | 2225 | #else /* !TCP_NODELAY */ |
@@ -2217,21 +2239,21 @@ static bool | |||
2217 | socket_start_no_buffering_flush (struct MHD_Connection *connection) | 2239 | socket_start_no_buffering_flush (struct MHD_Connection *connection) |
2218 | { | 2240 | { |
2219 | bool res = true; | 2241 | bool res = true; |
2220 | #if defined(TCP_NOPUSH) && !defined(TCP_CORK) | 2242 | #if defined(TCP_NOPUSH) && ! defined(TCP_CORK) |
2221 | const int dummy = 0; | 2243 | const int dummy = 0; |
2222 | #endif /* !TCP_CORK */ | 2244 | #endif /* !TCP_CORK */ |
2223 | 2245 | ||
2224 | if (NULL == connection) | 2246 | if (NULL == connection) |
2225 | return false; /* FIXME: use MHD_NONNULL? */ | 2247 | return false; /* FIXME: use MHD_NONNULL? */ |
2226 | res = socket_start_no_buffering (connection); | 2248 | res = socket_start_no_buffering (connection); |
2227 | #if defined(TCP_NOPUSH) && !defined(TCP_CORK) | 2249 | #if defined(TCP_NOPUSH) && ! defined(TCP_CORK) |
2228 | /* Force flush data with zero send otherwise Darwin and some BSD systems | 2250 | /* Force flush data with zero send otherwise Darwin and some BSD systems |
2229 | will add 5 seconds delay. Not required with TCP_CORK as switching off | 2251 | will add 5 seconds delay. Not required with TCP_CORK as switching off |
2230 | TCP_CORK always flushes socket buffer. */ | 2252 | TCP_CORK always flushes socket buffer. */ |
2231 | res &= (0 <= MHD_send_ (connection->socket_fd, | 2253 | res &= (0 <= MHD_send_ (connection->socket_fd, |
2232 | &dummy, | 2254 | &dummy, |
2233 | 0)) | 2255 | 0)) |
2234 | ? true : false; | 2256 | ? true : false; |
2235 | #endif /* TCP_NOPUSH && !TCP_CORK*/ | 2257 | #endif /* TCP_NOPUSH && !TCP_CORK*/ |
2236 | return res; | 2258 | return res; |
2237 | } | 2259 | } |
@@ -2254,7 +2276,7 @@ socket_start_normal_buffering (struct MHD_Connection *connection) | |||
2254 | socklen_t param_size = sizeof (cork_val); | 2276 | socklen_t param_size = sizeof (cork_val); |
2255 | #endif /* TCP_CORK */ | 2277 | #endif /* TCP_CORK */ |
2256 | 2278 | ||
2257 | mhd_assert(NULL != connection); | 2279 | mhd_assert (NULL != connection); |
2258 | #if defined(TCP_CORK) | 2280 | #if defined(TCP_CORK) |
2259 | /* Allow partial packets */ | 2281 | /* Allow partial packets */ |
2260 | /* Disabling TCP_CORK will flush partial packet even if TCP_CORK wasn't enabled before | 2282 | /* Disabling TCP_CORK will flush partial packet even if TCP_CORK wasn't enabled before |
@@ -2262,7 +2284,7 @@ socket_start_normal_buffering (struct MHD_Connection *connection) | |||
2262 | if ( (0 != getsockopt (connection->socket_fd, | 2284 | if ( (0 != getsockopt (connection->socket_fd, |
2263 | IPPROTO_TCP, | 2285 | IPPROTO_TCP, |
2264 | TCP_CORK, | 2286 | TCP_CORK, |
2265 | (void*)&cork_val, | 2287 | (void*) &cork_val, |
2266 | ¶m_size)) || | 2288 | ¶m_size)) || |
2267 | (0 != cork_val)) | 2289 | (0 != cork_val)) |
2268 | res &= (0 == setsockopt (connection->socket_fd, | 2290 | res &= (0 == setsockopt (connection->socket_fd, |
@@ -2270,7 +2292,7 @@ socket_start_normal_buffering (struct MHD_Connection *connection) | |||
2270 | TCP_CORK, | 2292 | TCP_CORK, |
2271 | (const void *) &off_val, | 2293 | (const void *) &off_val, |
2272 | sizeof (off_val))) | 2294 | sizeof (off_val))) |
2273 | ? true : false; | 2295 | ? true : false; |
2274 | #elif defined(TCP_NOPUSH) | 2296 | #elif defined(TCP_NOPUSH) |
2275 | /* Disable extra buffering */ | 2297 | /* Disable extra buffering */ |
2276 | /* No need to check current value as disabling TCP_NOPUSH will not flush partial | 2298 | /* No need to check current value as disabling TCP_NOPUSH will not flush partial |
@@ -2280,7 +2302,7 @@ socket_start_normal_buffering (struct MHD_Connection *connection) | |||
2280 | TCP_NOPUSH, | 2302 | TCP_NOPUSH, |
2281 | (const void *) &off_val, | 2303 | (const void *) &off_val, |
2282 | sizeof (off_val))) | 2304 | sizeof (off_val))) |
2283 | ? true : false; | 2305 | ? true : false; |
2284 | #endif /* TCP_NOPUSH && !TCP_CORK */ | 2306 | #endif /* TCP_NOPUSH && !TCP_CORK */ |
2285 | /* Enable Nagle's algorithm for normal buffering */ | 2307 | /* Enable Nagle's algorithm for normal buffering */ |
2286 | res &= (0 == setsockopt (connection->socket_fd, | 2308 | res &= (0 == setsockopt (connection->socket_fd, |
@@ -2288,7 +2310,7 @@ socket_start_normal_buffering (struct MHD_Connection *connection) | |||
2288 | TCP_NODELAY, | 2310 | TCP_NODELAY, |
2289 | (const void *) &off_val, | 2311 | (const void *) &off_val, |
2290 | sizeof (off_val))) | 2312 | sizeof (off_val))) |
2291 | ? true : false; | 2313 | ? true : false; |
2292 | return res; | 2314 | return res; |
2293 | #else /* !TCP_NODELAY */ | 2315 | #else /* !TCP_NODELAY */ |
2294 | return false; | 2316 | return false; |
@@ -2309,16 +2331,17 @@ need_100_continue (struct MHD_Request *request) | |||
2309 | const char *expect; | 2331 | const char *expect; |
2310 | 2332 | ||
2311 | return ( (NULL == request->response) && | 2333 | return ( (NULL == request->response) && |
2312 | (NULL != request->version_s) && | 2334 | (NULL != request->version_s) && |
2313 | (MHD_str_equal_caseless_(request->version_s, | 2335 | (MHD_str_equal_caseless_ (request->version_s, |
2314 | MHD_HTTP_VERSION_1_1)) && | 2336 | MHD_HTTP_VERSION_1_1)) && |
2315 | (NULL != (expect = MHD_request_lookup_value (request, | 2337 | (NULL != (expect = MHD_request_lookup_value (request, |
2316 | MHD_HEADER_KIND, | 2338 | MHD_HEADER_KIND, |
2317 | MHD_HTTP_HEADER_EXPECT))) && | 2339 | MHD_HTTP_HEADER_EXPECT))) |
2318 | (MHD_str_equal_caseless_(expect, | 2340 | && |
2319 | "100-continue")) && | 2341 | (MHD_str_equal_caseless_ (expect, |
2320 | (request->continue_message_write_offset < | 2342 | "100-continue")) && |
2321 | MHD_STATICSTR_LEN_ (HTTP_100_CONTINUE)) ); | 2343 | (request->continue_message_write_offset < |
2344 | MHD_STATICSTR_LEN_ (HTTP_100_CONTINUE)) ); | ||
2322 | } | 2345 | } |
2323 | 2346 | ||
2324 | 2347 | ||
@@ -2342,94 +2365,94 @@ parse_cookie_header (struct MHD_Request *request) | |||
2342 | int quotes; | 2365 | int quotes; |
2343 | 2366 | ||
2344 | hdr = MHD_request_lookup_value (request, | 2367 | hdr = MHD_request_lookup_value (request, |
2345 | MHD_HEADER_KIND, | 2368 | MHD_HEADER_KIND, |
2346 | MHD_HTTP_HEADER_COOKIE); | 2369 | MHD_HTTP_HEADER_COOKIE); |
2347 | if (NULL == hdr) | 2370 | if (NULL == hdr) |
2348 | return true; | 2371 | return true; |
2349 | cpy = MHD_pool_allocate (request->connection->pool, | 2372 | cpy = MHD_pool_allocate (request->connection->pool, |
2350 | strlen (hdr) + 1, | 2373 | strlen (hdr) + 1, |
2351 | MHD_YES); | 2374 | MHD_YES); |
2352 | if (NULL == cpy) | 2375 | if (NULL == cpy) |
2353 | { | 2376 | { |
2354 | #ifdef HAVE_MESSAGES | 2377 | #ifdef HAVE_MESSAGES |
2355 | MHD_DLOG (request->daemon, | 2378 | MHD_DLOG (request->daemon, |
2356 | MHD_SC_COOKIE_POOL_ALLOCATION_FAILURE, | 2379 | MHD_SC_COOKIE_POOL_ALLOCATION_FAILURE, |
2357 | _("Not enough memory in pool to parse cookies!\n")); | 2380 | _ ("Not enough memory in pool to parse cookies!\n")); |
2358 | #endif | 2381 | #endif |
2359 | transmit_error_response (request, | 2382 | transmit_error_response (request, |
2360 | MHD_SC_COOKIE_POOL_ALLOCATION_FAILURE, | 2383 | MHD_SC_COOKIE_POOL_ALLOCATION_FAILURE, |
2361 | MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE, | 2384 | MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE, |
2362 | REQUEST_TOO_BIG); | 2385 | REQUEST_TOO_BIG); |
2363 | return false; | 2386 | return false; |
2364 | } | 2387 | } |
2365 | memcpy (cpy, | 2388 | memcpy (cpy, |
2366 | hdr, | 2389 | hdr, |
2367 | strlen (hdr) + 1); | 2390 | strlen (hdr) + 1); |
2368 | pos = cpy; | 2391 | pos = cpy; |
2369 | while (NULL != pos) | 2392 | while (NULL != pos) |
2370 | { | 2393 | { |
2371 | while (' ' == *pos) | 2394 | while (' ' == *pos) |
2372 | pos++; /* skip spaces */ | 2395 | pos++; /* skip spaces */ |
2373 | 2396 | ||
2374 | sce = pos; | 2397 | sce = pos; |
2375 | while ( ((*sce) != '\0') && | 2398 | while ( ((*sce) != '\0') && |
2376 | ((*sce) != ',') && | 2399 | ((*sce) != ',') && |
2377 | ((*sce) != ';') && | 2400 | ((*sce) != ';') && |
2378 | ((*sce) != '=') ) | 2401 | ((*sce) != '=') ) |
2379 | sce++; | 2402 | sce++; |
2380 | /* remove tailing whitespace (if any) from key */ | 2403 | /* remove tailing whitespace (if any) from key */ |
2381 | ekill = sce - 1; | 2404 | ekill = sce - 1; |
2382 | while ( (*ekill == ' ') && | 2405 | while ( (*ekill == ' ') && |
2383 | (ekill >= pos) ) | 2406 | (ekill >= pos) ) |
2384 | *(ekill--) = '\0'; | 2407 | *(ekill--) = '\0'; |
2385 | old = *sce; | 2408 | old = *sce; |
2386 | *sce = '\0'; | 2409 | *sce = '\0'; |
2387 | if (old != '=') | 2410 | if (old != '=') |
2388 | { | 2411 | { |
2389 | /* value part omitted, use empty string... */ | 2412 | /* value part omitted, use empty string... */ |
2390 | if (! request_add_header (request, | ||
2391 | pos, | ||
2392 | "", | ||
2393 | MHD_COOKIE_KIND)) | ||
2394 | return false; | ||
2395 | if (old == '\0') | ||
2396 | break; | ||
2397 | pos = sce + 1; | ||
2398 | continue; | ||
2399 | } | ||
2400 | equals = sce + 1; | ||
2401 | quotes = 0; | ||
2402 | semicolon = equals; | ||
2403 | while ( ('\0' != semicolon[0]) && | ||
2404 | ( (0 != quotes) || | ||
2405 | ( (';' != semicolon[0]) && | ||
2406 | (',' != semicolon[0]) ) ) ) | ||
2407 | { | ||
2408 | if ('"' == semicolon[0]) | ||
2409 | quotes = (quotes + 1) & 1; | ||
2410 | semicolon++; | ||
2411 | } | ||
2412 | if ('\0' == semicolon[0]) | ||
2413 | semicolon = NULL; | ||
2414 | if (NULL != semicolon) | ||
2415 | { | ||
2416 | semicolon[0] = '\0'; | ||
2417 | semicolon++; | ||
2418 | } | ||
2419 | /* remove quotes */ | ||
2420 | if ( ('"' == equals[0]) && | ||
2421 | ('"' == equals[strlen (equals) - 1]) ) | ||
2422 | { | ||
2423 | equals[strlen (equals) - 1] = '\0'; | ||
2424 | equals++; | ||
2425 | } | ||
2426 | if (! request_add_header (request, | 2413 | if (! request_add_header (request, |
2427 | pos, | 2414 | pos, |
2428 | equals, | 2415 | "", |
2429 | MHD_COOKIE_KIND)) | 2416 | MHD_COOKIE_KIND)) |
2430 | return false; | 2417 | return false; |
2431 | pos = semicolon; | 2418 | if (old == '\0') |
2432 | } | 2419 | break; |
2420 | pos = sce + 1; | ||
2421 | continue; | ||
2422 | } | ||
2423 | equals = sce + 1; | ||
2424 | quotes = 0; | ||
2425 | semicolon = equals; | ||
2426 | while ( ('\0' != semicolon[0]) && | ||
2427 | ( (0 != quotes) || | ||
2428 | ( (';' != semicolon[0]) && | ||
2429 | (',' != semicolon[0]) ) ) ) | ||
2430 | { | ||
2431 | if ('"' == semicolon[0]) | ||
2432 | quotes = (quotes + 1) & 1; | ||
2433 | semicolon++; | ||
2434 | } | ||
2435 | if ('\0' == semicolon[0]) | ||
2436 | semicolon = NULL; | ||
2437 | if (NULL != semicolon) | ||
2438 | { | ||
2439 | semicolon[0] = '\0'; | ||
2440 | semicolon++; | ||
2441 | } | ||
2442 | /* remove quotes */ | ||
2443 | if ( ('"' == equals[0]) && | ||
2444 | ('"' == equals[strlen (equals) - 1]) ) | ||
2445 | { | ||
2446 | equals[strlen (equals) - 1] = '\0'; | ||
2447 | equals++; | ||
2448 | } | ||
2449 | if (! request_add_header (request, | ||
2450 | pos, | ||
2451 | equals, | ||
2452 | MHD_COOKIE_KIND)) | ||
2453 | return false; | ||
2454 | pos = semicolon; | ||
2455 | } | ||
2433 | return true; | 2456 | return true; |
2434 | } | 2457 | } |
2435 | 2458 | ||
@@ -2454,64 +2477,64 @@ parse_request_headers (struct MHD_Request *request) | |||
2454 | parse_cookie_header (request); /* FIXME: return value ignored! */ | 2477 | parse_cookie_header (request); /* FIXME: return value ignored! */ |
2455 | if ( (MHD_PSL_STRICT == daemon->protocol_strict_level) && | 2478 | if ( (MHD_PSL_STRICT == daemon->protocol_strict_level) && |
2456 | (NULL != request->version_s) && | 2479 | (NULL != request->version_s) && |
2457 | (MHD_str_equal_caseless_(MHD_HTTP_VERSION_1_1, | 2480 | (MHD_str_equal_caseless_ (MHD_HTTP_VERSION_1_1, |
2458 | request->version_s)) && | 2481 | request->version_s)) && |
2459 | (NULL == | 2482 | (NULL == |
2460 | MHD_request_lookup_value (request, | 2483 | MHD_request_lookup_value (request, |
2461 | MHD_HEADER_KIND, | 2484 | MHD_HEADER_KIND, |
2462 | MHD_HTTP_HEADER_HOST)) ) | 2485 | MHD_HTTP_HEADER_HOST)) ) |
2463 | { | 2486 | { |
2464 | /* die, http 1.1 request without host and we are pedantic */ | 2487 | /* die, http 1.1 request without host and we are pedantic */ |
2465 | request->state = MHD_REQUEST_FOOTERS_RECEIVED; | 2488 | request->state = MHD_REQUEST_FOOTERS_RECEIVED; |
2466 | connection->read_closed = true; | 2489 | connection->read_closed = true; |
2467 | #ifdef HAVE_MESSAGES | 2490 | #ifdef HAVE_MESSAGES |
2468 | MHD_DLOG (daemon, | 2491 | MHD_DLOG (daemon, |
2469 | MHD_SC_HOST_HEADER_MISSING, | 2492 | MHD_SC_HOST_HEADER_MISSING, |
2470 | _("Received HTTP 1.1 request without `Host' header.\n")); | 2493 | _ ("Received HTTP 1.1 request without `Host' header.\n")); |
2471 | #endif | 2494 | #endif |
2472 | mhd_assert (NULL == request->response); | 2495 | mhd_assert (NULL == request->response); |
2473 | response = | 2496 | response = |
2474 | MHD_response_from_buffer (MHD_HTTP_BAD_REQUEST, | 2497 | MHD_response_from_buffer (MHD_HTTP_BAD_REQUEST, |
2475 | MHD_STATICSTR_LEN_ (REQUEST_LACKS_HOST), | 2498 | MHD_STATICSTR_LEN_ (REQUEST_LACKS_HOST), |
2476 | REQUEST_LACKS_HOST, | 2499 | REQUEST_LACKS_HOST, |
2477 | MHD_RESPMEM_PERSISTENT); | 2500 | MHD_RESPMEM_PERSISTENT); |
2478 | request->response = response; | 2501 | request->response = response; |
2479 | // FIXME: state machine advance? | 2502 | // FIXME: state machine advance? |
2480 | return; | 2503 | return; |
2481 | } | 2504 | } |
2482 | 2505 | ||
2483 | request->remaining_upload_size = 0; | 2506 | request->remaining_upload_size = 0; |
2484 | enc = MHD_request_lookup_value (request, | 2507 | enc = MHD_request_lookup_value (request, |
2485 | MHD_HEADER_KIND, | 2508 | MHD_HEADER_KIND, |
2486 | MHD_HTTP_HEADER_TRANSFER_ENCODING); | 2509 | MHD_HTTP_HEADER_TRANSFER_ENCODING); |
2487 | if (NULL != enc) | 2510 | if (NULL != enc) |
2488 | { | 2511 | { |
2489 | request->remaining_upload_size = MHD_SIZE_UNKNOWN; | 2512 | request->remaining_upload_size = MHD_SIZE_UNKNOWN; |
2490 | if (MHD_str_equal_caseless_ (enc, | 2513 | if (MHD_str_equal_caseless_ (enc, |
2491 | "chunked")) | 2514 | "chunked")) |
2492 | request->have_chunked_upload = true; | 2515 | request->have_chunked_upload = true; |
2493 | return; | 2516 | return; |
2494 | } | 2517 | } |
2495 | clen = MHD_request_lookup_value (request, | 2518 | clen = MHD_request_lookup_value (request, |
2496 | MHD_HEADER_KIND, | 2519 | MHD_HEADER_KIND, |
2497 | MHD_HTTP_HEADER_CONTENT_LENGTH); | 2520 | MHD_HTTP_HEADER_CONTENT_LENGTH); |
2498 | if (NULL == clen) | 2521 | if (NULL == clen) |
2499 | return; | 2522 | return; |
2500 | end = clen + MHD_str_to_uint64_ (clen, | 2523 | end = clen + MHD_str_to_uint64_ (clen, |
2501 | &request->remaining_upload_size); | 2524 | &request->remaining_upload_size); |
2502 | if ( (clen == end) || | 2525 | if ( (clen == end) || |
2503 | ('\0' != *end) ) | 2526 | ('\0' != *end) ) |
2504 | { | 2527 | { |
2505 | request->remaining_upload_size = 0; | 2528 | request->remaining_upload_size = 0; |
2506 | #ifdef HAVE_MESSAGES | 2529 | #ifdef HAVE_MESSAGES |
2507 | MHD_DLOG (request->daemon, | 2530 | MHD_DLOG (request->daemon, |
2508 | MHD_SC_CONTENT_LENGTH_MALFORMED, | 2531 | MHD_SC_CONTENT_LENGTH_MALFORMED, |
2509 | "Failed to parse `Content-Length' header. Closing connection.\n"); | 2532 | "Failed to parse `Content-Length' header. Closing connection.\n"); |
2510 | #endif | 2533 | #endif |
2511 | CONNECTION_CLOSE_ERROR (connection, | 2534 | CONNECTION_CLOSE_ERROR (connection, |
2512 | MHD_SC_CONTENT_LENGTH_MALFORMED, | 2535 | MHD_SC_CONTENT_LENGTH_MALFORMED, |
2513 | NULL); | 2536 | NULL); |
2514 | } | 2537 | } |
2515 | } | 2538 | } |
2516 | 2539 | ||
2517 | 2540 | ||
@@ -2531,19 +2554,20 @@ call_request_handler (struct MHD_Request *request) | |||
2531 | if (NULL != request->response) | 2554 | if (NULL != request->response) |
2532 | return; /* already queued a response */ | 2555 | return; /* already queued a response */ |
2533 | if (NULL == (action = | 2556 | if (NULL == (action = |
2534 | daemon->rc (daemon->rc_cls, | 2557 | daemon->rc (daemon->rc_cls, |
2535 | request, | 2558 | request, |
2536 | request->url, | 2559 | request->url, |
2537 | request->method))) | 2560 | request->method))) |
2538 | { | 2561 | { |
2539 | /* serious internal error, close connection */ | 2562 | /* serious internal error, close connection */ |
2540 | CONNECTION_CLOSE_ERROR (connection, | 2563 | CONNECTION_CLOSE_ERROR (connection, |
2541 | MHD_SC_APPLICATION_CALLBACK_FAILURE_CLOSED, | 2564 | MHD_SC_APPLICATION_CALLBACK_FAILURE_CLOSED, |
2542 | _("Application reported internal error, closing connection.\n")); | 2565 | _ ( |
2543 | return; | 2566 | "Application reported internal error, closing connection.\n")); |
2544 | } | 2567 | return; |
2568 | } | ||
2545 | action->action (action->action_cls, | 2569 | action->action (action->action_cls, |
2546 | request); | 2570 | request); |
2547 | } | 2571 | } |
2548 | 2572 | ||
2549 | 2573 | ||
@@ -2568,208 +2592,212 @@ process_request_body (struct MHD_Request *request) | |||
2568 | buffer_head = request->read_buffer; | 2592 | buffer_head = request->read_buffer; |
2569 | available = request->read_buffer_offset; | 2593 | available = request->read_buffer_offset; |
2570 | do | 2594 | do |
2571 | { | 2595 | { |
2572 | size_t to_be_processed; | 2596 | size_t to_be_processed; |
2573 | size_t left_unprocessed; | 2597 | size_t left_unprocessed; |
2574 | size_t processed_size; | 2598 | size_t processed_size; |
2575 | 2599 | ||
2576 | instant_retry = false; | 2600 | instant_retry = false; |
2577 | if ( (request->have_chunked_upload) && | 2601 | if ( (request->have_chunked_upload) && |
2578 | (MHD_SIZE_UNKNOWN == request->remaining_upload_size) ) | 2602 | (MHD_SIZE_UNKNOWN == request->remaining_upload_size) ) |
2603 | { | ||
2604 | if ( (request->current_chunk_offset == request->current_chunk_size) && | ||
2605 | (0LLU != request->current_chunk_offset) && | ||
2606 | (available >= 2) ) | ||
2607 | { | ||
2608 | size_t i; | ||
2609 | |||
2610 | /* skip new line at the *end* of a chunk */ | ||
2611 | i = 0; | ||
2612 | if ( ('\r' == buffer_head[i]) || | ||
2613 | ('\n' == buffer_head[i]) ) | ||
2614 | i++; /* skip 1st part of line feed */ | ||
2615 | if ( ('\r' == buffer_head[i]) || | ||
2616 | ('\n' == buffer_head[i]) ) | ||
2617 | i++; /* skip 2nd part of line feed */ | ||
2618 | if (0 == i) | ||
2579 | { | 2619 | { |
2580 | if ( (request->current_chunk_offset == request->current_chunk_size) && | 2620 | /* malformed encoding */ |
2581 | (0LLU != request->current_chunk_offset) && | 2621 | CONNECTION_CLOSE_ERROR (connection, |
2582 | (available >= 2) ) | 2622 | MHD_SC_CHUNKED_ENCODING_MALFORMED, |
2583 | { | 2623 | _ ( |
2584 | size_t i; | 2624 | "Received malformed HTTP request (bad chunked encoding). Closing connection.\n")); |
2585 | 2625 | return; | |
2586 | /* skip new line at the *end* of a chunk */ | ||
2587 | i = 0; | ||
2588 | if ( ('\r' == buffer_head[i]) || | ||
2589 | ('\n' == buffer_head[i]) ) | ||
2590 | i++; /* skip 1st part of line feed */ | ||
2591 | if ( ('\r' == buffer_head[i]) || | ||
2592 | ('\n' == buffer_head[i]) ) | ||
2593 | i++; /* skip 2nd part of line feed */ | ||
2594 | if (0 == i) | ||
2595 | { | ||
2596 | /* malformed encoding */ | ||
2597 | CONNECTION_CLOSE_ERROR (connection, | ||
2598 | MHD_SC_CHUNKED_ENCODING_MALFORMED, | ||
2599 | _("Received malformed HTTP request (bad chunked encoding). Closing connection.\n")); | ||
2600 | return; | ||
2601 | } | ||
2602 | available -= i; | ||
2603 | buffer_head += i; | ||
2604 | request->current_chunk_offset = 0; | ||
2605 | request->current_chunk_size = 0; | ||
2606 | } | ||
2607 | if (request->current_chunk_offset < | ||
2608 | request->current_chunk_size) | ||
2609 | { | ||
2610 | uint64_t cur_chunk_left; | ||
2611 | |||
2612 | /* we are in the middle of a chunk, give | ||
2613 | as much as possible to the client (without | ||
2614 | crossing chunk boundaries) */ | ||
2615 | cur_chunk_left | ||
2616 | = request->current_chunk_size - request->current_chunk_offset; | ||
2617 | if (cur_chunk_left > available) | ||
2618 | { | ||
2619 | to_be_processed = available; | ||
2620 | } | ||
2621 | else | ||
2622 | { /* cur_chunk_left <= (size_t)available */ | ||
2623 | to_be_processed = (size_t)cur_chunk_left; | ||
2624 | if (available > to_be_processed) | ||
2625 | instant_retry = true; | ||
2626 | } | ||
2627 | } | ||
2628 | else | ||
2629 | { | ||
2630 | size_t i; | ||
2631 | size_t end_size; | ||
2632 | bool malformed; | ||
2633 | |||
2634 | /* we need to read chunk boundaries */ | ||
2635 | i = 0; | ||
2636 | while (i < available) | ||
2637 | { | ||
2638 | if ( ('\r' == buffer_head[i]) || | ||
2639 | ('\n' == buffer_head[i]) || | ||
2640 | (';' == buffer_head[i]) ) | ||
2641 | break; | ||
2642 | i++; | ||
2643 | if (i >= 16) | ||
2644 | break; | ||
2645 | } | ||
2646 | end_size = i; | ||
2647 | /* find beginning of CRLF (skip over chunk extensions) */ | ||
2648 | if (';' == buffer_head[i]) | ||
2649 | { | ||
2650 | while (i < available) | ||
2651 | { | ||
2652 | if ( ('\r' == buffer_head[i]) || | ||
2653 | ('\n' == buffer_head[i]) ) | ||
2654 | break; | ||
2655 | i++; | ||
2656 | } | ||
2657 | } | ||
2658 | /* take '\n' into account; if '\n' is the unavailable | ||
2659 | character, we will need to wait until we have it | ||
2660 | before going further */ | ||
2661 | if ( (i + 1 >= available) && | ||
2662 | ! ( (1 == i) && | ||
2663 | (2 == available) && | ||
2664 | ('0' == buffer_head[0]) ) ) | ||
2665 | break; /* need more data... */ | ||
2666 | i++; | ||
2667 | malformed = (end_size >= 16); | ||
2668 | if (! malformed) | ||
2669 | { | ||
2670 | size_t num_dig = MHD_strx_to_uint64_n_ (buffer_head, | ||
2671 | end_size, | ||
2672 | &request->current_chunk_size); | ||
2673 | malformed = (end_size != num_dig); | ||
2674 | } | ||
2675 | if (malformed) | ||
2676 | { | ||
2677 | /* malformed encoding */ | ||
2678 | CONNECTION_CLOSE_ERROR (connection, | ||
2679 | MHD_SC_CHUNKED_ENCODING_MALFORMED, | ||
2680 | _("Received malformed HTTP request (bad chunked encoding). Closing connection.\n")); | ||
2681 | return; | ||
2682 | } | ||
2683 | /* skip 2nd part of line feed */ | ||
2684 | if ( (i < available) && | ||
2685 | ( ('\r' == buffer_head[i]) || | ||
2686 | ('\n' == buffer_head[i]) ) ) | ||
2687 | i++; | ||
2688 | |||
2689 | buffer_head += i; | ||
2690 | available -= i; | ||
2691 | request->current_chunk_offset = 0; | ||
2692 | |||
2693 | if (available > 0) | ||
2694 | instant_retry = true; | ||
2695 | if (0LLU == request->current_chunk_size) | ||
2696 | { | ||
2697 | request->remaining_upload_size = 0; | ||
2698 | break; | ||
2699 | } | ||
2700 | continue; | ||
2701 | } | ||
2702 | } | 2626 | } |
2627 | available -= i; | ||
2628 | buffer_head += i; | ||
2629 | request->current_chunk_offset = 0; | ||
2630 | request->current_chunk_size = 0; | ||
2631 | } | ||
2632 | if (request->current_chunk_offset < | ||
2633 | request->current_chunk_size) | ||
2634 | { | ||
2635 | uint64_t cur_chunk_left; | ||
2636 | |||
2637 | /* we are in the middle of a chunk, give | ||
2638 | as much as possible to the client (without | ||
2639 | crossing chunk boundaries) */ | ||
2640 | cur_chunk_left | ||
2641 | = request->current_chunk_size - request->current_chunk_offset; | ||
2642 | if (cur_chunk_left > available) | ||
2643 | { | ||
2644 | to_be_processed = available; | ||
2645 | } | ||
2646 | else | ||
2647 | { /* cur_chunk_left <= (size_t)available */ | ||
2648 | to_be_processed = (size_t) cur_chunk_left; | ||
2649 | if (available > to_be_processed) | ||
2650 | instant_retry = true; | ||
2651 | } | ||
2652 | } | ||
2703 | else | 2653 | else |
2654 | { | ||
2655 | size_t i; | ||
2656 | size_t end_size; | ||
2657 | bool malformed; | ||
2658 | |||
2659 | /* we need to read chunk boundaries */ | ||
2660 | i = 0; | ||
2661 | while (i < available) | ||
2704 | { | 2662 | { |
2705 | /* no chunked encoding, give all to the client */ | 2663 | if ( ('\r' == buffer_head[i]) || |
2706 | if ( (0 != request->remaining_upload_size) && | 2664 | ('\n' == buffer_head[i]) || |
2707 | (MHD_SIZE_UNKNOWN != request->remaining_upload_size) && | 2665 | (';' == buffer_head[i]) ) |
2708 | (request->remaining_upload_size < available) ) | 2666 | break; |
2709 | { | 2667 | i++; |
2710 | to_be_processed = (size_t)request->remaining_upload_size; | 2668 | if (i >= 16) |
2711 | } | 2669 | break; |
2712 | else | ||
2713 | { | ||
2714 | /** | ||
2715 | * 1. no chunked encoding, give all to the client | ||
2716 | * 2. client may send large chunked data, but only a smaller part is available at one time. | ||
2717 | */ | ||
2718 | to_be_processed = available; | ||
2719 | } | ||
2720 | } | 2670 | } |
2721 | left_unprocessed = to_be_processed; | 2671 | end_size = i; |
2722 | #if FIXME_OLD_STYLE | 2672 | /* find beginning of CRLF (skip over chunk extensions) */ |
2723 | if (MHD_NO == | 2673 | if (';' == buffer_head[i]) |
2724 | daemon->rc (daemon->rc_cls, | 2674 | { |
2725 | request, | 2675 | while (i < available) |
2726 | request->url, | 2676 | { |
2727 | request->method, | 2677 | if ( ('\r' == buffer_head[i]) || |
2728 | request->version, | 2678 | ('\n' == buffer_head[i]) ) |
2729 | buffer_head, | 2679 | break; |
2730 | &left_unprocessed, | 2680 | i++; |
2731 | &request->client_context)) | 2681 | } |
2682 | } | ||
2683 | /* take '\n' into account; if '\n' is the unavailable | ||
2684 | character, we will need to wait until we have it | ||
2685 | before going further */ | ||
2686 | if ( (i + 1 >= available) && | ||
2687 | ! ( (1 == i) && | ||
2688 | (2 == available) && | ||
2689 | ('0' == buffer_head[0]) ) ) | ||
2690 | break; /* need more data... */ | ||
2691 | i++; | ||
2692 | malformed = (end_size >= 16); | ||
2693 | if (! malformed) | ||
2694 | { | ||
2695 | size_t num_dig = MHD_strx_to_uint64_n_ (buffer_head, | ||
2696 | end_size, | ||
2697 | &request->current_chunk_size); | ||
2698 | malformed = (end_size != num_dig); | ||
2699 | } | ||
2700 | if (malformed) | ||
2732 | { | 2701 | { |
2733 | /* serious internal error, close connection */ | 2702 | /* malformed encoding */ |
2734 | CONNECTION_CLOSE_ERROR (connection, | 2703 | CONNECTION_CLOSE_ERROR (connection, |
2735 | MHD_SC_APPLICATION_CALLBACK_FAILURE_CLOSED, | 2704 | MHD_SC_CHUNKED_ENCODING_MALFORMED, |
2736 | _("Application reported internal error, closing connection.\n")); | 2705 | _ ( |
2706 | "Received malformed HTTP request (bad chunked encoding). Closing connection.\n")); | ||
2737 | return; | 2707 | return; |
2738 | } | 2708 | } |
2709 | /* skip 2nd part of line feed */ | ||
2710 | if ( (i < available) && | ||
2711 | ( ('\r' == buffer_head[i]) || | ||
2712 | ('\n' == buffer_head[i]) ) ) | ||
2713 | i++; | ||
2714 | |||
2715 | buffer_head += i; | ||
2716 | available -= i; | ||
2717 | request->current_chunk_offset = 0; | ||
2718 | |||
2719 | if (available > 0) | ||
2720 | instant_retry = true; | ||
2721 | if (0LLU == request->current_chunk_size) | ||
2722 | { | ||
2723 | request->remaining_upload_size = 0; | ||
2724 | break; | ||
2725 | } | ||
2726 | continue; | ||
2727 | } | ||
2728 | } | ||
2729 | else | ||
2730 | { | ||
2731 | /* no chunked encoding, give all to the client */ | ||
2732 | if ( (0 != request->remaining_upload_size) && | ||
2733 | (MHD_SIZE_UNKNOWN != request->remaining_upload_size) && | ||
2734 | (request->remaining_upload_size < available) ) | ||
2735 | { | ||
2736 | to_be_processed = (size_t) request->remaining_upload_size; | ||
2737 | } | ||
2738 | else | ||
2739 | { | ||
2740 | /** | ||
2741 | * 1. no chunked encoding, give all to the client | ||
2742 | * 2. client may send large chunked data, but only a smaller part is available at one time. | ||
2743 | */ | ||
2744 | to_be_processed = available; | ||
2745 | } | ||
2746 | } | ||
2747 | left_unprocessed = to_be_processed; | ||
2748 | #if FIXME_OLD_STYLE | ||
2749 | if (MHD_NO == | ||
2750 | daemon->rc (daemon->rc_cls, | ||
2751 | request, | ||
2752 | request->url, | ||
2753 | request->method, | ||
2754 | request->version, | ||
2755 | buffer_head, | ||
2756 | &left_unprocessed, | ||
2757 | &request->client_context)) | ||
2758 | { | ||
2759 | /* serious internal error, close connection */ | ||
2760 | CONNECTION_CLOSE_ERROR (connection, | ||
2761 | MHD_SC_APPLICATION_CALLBACK_FAILURE_CLOSED, | ||
2762 | _ ( | ||
2763 | "Application reported internal error, closing connection.\n")); | ||
2764 | return; | ||
2765 | } | ||
2739 | #endif | 2766 | #endif |
2740 | if (left_unprocessed > to_be_processed) | 2767 | if (left_unprocessed > to_be_processed) |
2741 | mhd_panic (mhd_panic_cls, | 2768 | mhd_panic (mhd_panic_cls, |
2742 | __FILE__, | 2769 | __FILE__, |
2743 | __LINE__ | 2770 | __LINE__ |
2744 | #ifdef HAVE_MESSAGES | 2771 | #ifdef HAVE_MESSAGES |
2745 | , _("libmicrohttpd API violation") | 2772 | , _ ("libmicrohttpd API violation") |
2746 | #else | 2773 | #else |
2747 | , NULL | 2774 | , NULL |
2748 | #endif | 2775 | #endif |
2749 | ); | 2776 | ); |
2750 | if (0 != left_unprocessed) | 2777 | if (0 != left_unprocessed) |
2751 | { | 2778 | { |
2752 | instant_retry = false; /* client did not process everything */ | 2779 | instant_retry = false; /* client did not process everything */ |
2753 | #ifdef HAVE_MESSAGES | 2780 | #ifdef HAVE_MESSAGES |
2754 | /* client did not process all upload data, complain if | 2781 | /* client did not process all upload data, complain if |
2755 | the setup was incorrect, which may prevent us from | 2782 | the setup was incorrect, which may prevent us from |
2756 | handling the rest of the request */ | 2783 | handling the rest of the request */ |
2757 | if ( (MHD_TM_EXTERNAL_EVENT_LOOP == daemon->threading_mode) && | 2784 | if ( (MHD_TM_EXTERNAL_EVENT_LOOP == daemon->threading_mode) && |
2758 | (! connection->suspended) ) | 2785 | (! connection->suspended) ) |
2759 | MHD_DLOG (daemon, | 2786 | MHD_DLOG (daemon, |
2760 | MHD_SC_APPLICATION_HUNG_CONNECTION, | 2787 | MHD_SC_APPLICATION_HUNG_CONNECTION, |
2761 | _("WARNING: incomplete upload processing and connection not suspended may result in hung connection.\n")); | 2788 | _ ( |
2789 | "WARNING: incomplete upload processing and connection not suspended may result in hung connection.\n")); | ||
2762 | #endif | 2790 | #endif |
2763 | } | ||
2764 | processed_size = to_be_processed - left_unprocessed; | ||
2765 | if (request->have_chunked_upload) | ||
2766 | request->current_chunk_offset += processed_size; | ||
2767 | /* dh left "processed" bytes in buffer for next time... */ | ||
2768 | buffer_head += processed_size; | ||
2769 | available -= processed_size; | ||
2770 | if (MHD_SIZE_UNKNOWN != request->remaining_upload_size) | ||
2771 | request->remaining_upload_size -= processed_size; | ||
2772 | } | 2791 | } |
2792 | processed_size = to_be_processed - left_unprocessed; | ||
2793 | if (request->have_chunked_upload) | ||
2794 | request->current_chunk_offset += processed_size; | ||
2795 | /* dh left "processed" bytes in buffer for next time... */ | ||
2796 | buffer_head += processed_size; | ||
2797 | available -= processed_size; | ||
2798 | if (MHD_SIZE_UNKNOWN != request->remaining_upload_size) | ||
2799 | request->remaining_upload_size -= processed_size; | ||
2800 | } | ||
2773 | while (instant_retry); | 2801 | while (instant_retry); |
2774 | if (available > 0) | 2802 | if (available > 0) |
2775 | memmove (request->read_buffer, | 2803 | memmove (request->read_buffer, |
@@ -2796,58 +2824,59 @@ cleanup_connection (struct MHD_Connection *connection) | |||
2796 | return; /* Prevent double cleanup. */ | 2824 | return; /* Prevent double cleanup. */ |
2797 | connection->request.in_cleanup = true; | 2825 | connection->request.in_cleanup = true; |
2798 | if (NULL != connection->request.response) | 2826 | if (NULL != connection->request.response) |
2799 | { | 2827 | { |
2800 | MHD_response_queue_for_destroy (connection->request.response); | 2828 | MHD_response_queue_for_destroy (connection->request.response); |
2801 | connection->request.response = NULL; | 2829 | connection->request.response = NULL; |
2802 | } | 2830 | } |
2803 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); | 2831 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); |
2804 | if (connection->suspended) | 2832 | if (connection->suspended) |
2805 | { | 2833 | { |
2806 | DLL_remove (daemon->suspended_connections_head, | 2834 | DLL_remove (daemon->suspended_connections_head, |
2807 | daemon->suspended_connections_tail, | 2835 | daemon->suspended_connections_tail, |
2808 | connection); | 2836 | connection); |
2809 | connection->suspended = false; | 2837 | connection->suspended = false; |
2810 | } | 2838 | } |
2811 | else | 2839 | else |
2840 | { | ||
2841 | if (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) | ||
2812 | { | 2842 | { |
2813 | if (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) | 2843 | if (connection->connection_timeout == |
2814 | { | 2844 | daemon->connection_default_timeout) |
2815 | if (connection->connection_timeout == | 2845 | XDLL_remove (daemon->normal_timeout_head, |
2816 | daemon->connection_default_timeout) | 2846 | daemon->normal_timeout_tail, |
2817 | XDLL_remove (daemon->normal_timeout_head, | 2847 | connection); |
2818 | daemon->normal_timeout_tail, | 2848 | else |
2819 | connection); | 2849 | XDLL_remove (daemon->manual_timeout_head, |
2820 | else | 2850 | daemon->manual_timeout_tail, |
2821 | XDLL_remove (daemon->manual_timeout_head, | 2851 | connection); |
2822 | daemon->manual_timeout_tail, | ||
2823 | connection); | ||
2824 | } | ||
2825 | DLL_remove (daemon->connections_head, | ||
2826 | daemon->connections_tail, | ||
2827 | connection); | ||
2828 | } | 2852 | } |
2853 | DLL_remove (daemon->connections_head, | ||
2854 | daemon->connections_tail, | ||
2855 | connection); | ||
2856 | } | ||
2829 | DLL_insert (daemon->cleanup_head, | 2857 | DLL_insert (daemon->cleanup_head, |
2830 | daemon->cleanup_tail, | 2858 | daemon->cleanup_tail, |
2831 | connection); | 2859 | connection); |
2832 | connection->resuming = false; | 2860 | connection->resuming = false; |
2833 | connection->request.in_idle = false; | 2861 | connection->request.in_idle = false; |
2834 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); | 2862 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); |
2835 | if (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode) | 2863 | if (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode) |
2864 | { | ||
2865 | /* if we were at the connection limit before and are in | ||
2866 | thread-per-connection mode, signal the main thread | ||
2867 | to resume accepting connections */ | ||
2868 | if ( (MHD_ITC_IS_VALID_ (daemon->itc)) && | ||
2869 | (! MHD_itc_activate_ (daemon->itc, | ||
2870 | "c")) ) | ||
2836 | { | 2871 | { |
2837 | /* if we were at the connection limit before and are in | ||
2838 | thread-per-connection mode, signal the main thread | ||
2839 | to resume accepting connections */ | ||
2840 | if ( (MHD_ITC_IS_VALID_ (daemon->itc)) && | ||
2841 | (! MHD_itc_activate_ (daemon->itc, | ||
2842 | "c")) ) | ||
2843 | { | ||
2844 | #ifdef HAVE_MESSAGES | 2872 | #ifdef HAVE_MESSAGES |
2845 | MHD_DLOG (daemon, | 2873 | MHD_DLOG (daemon, |
2846 | MHD_SC_ITC_USE_FAILED, | 2874 | MHD_SC_ITC_USE_FAILED, |
2847 | _("Failed to signal end of connection via inter-thread communication channel")); | 2875 | _ ( |
2876 | "Failed to signal end of connection via inter-thread communication channel")); | ||
2848 | #endif | 2877 | #endif |
2849 | } | ||
2850 | } | 2878 | } |
2879 | } | ||
2851 | } | 2880 | } |
2852 | 2881 | ||
2853 | 2882 | ||
@@ -2870,31 +2899,31 @@ connection_epoll_update_ (struct MHD_Connection *connection) | |||
2870 | (0 == (connection->epoll_state & MHD_EPOLL_STATE_SUSPENDED)) && | 2899 | (0 == (connection->epoll_state & MHD_EPOLL_STATE_SUSPENDED)) && |
2871 | ( ( (MHD_EVENT_LOOP_INFO_WRITE == connection->request.event_loop_info) && | 2900 | ( ( (MHD_EVENT_LOOP_INFO_WRITE == connection->request.event_loop_info) && |
2872 | (0 == (connection->epoll_state & MHD_EPOLL_STATE_WRITE_READY))) || | 2901 | (0 == (connection->epoll_state & MHD_EPOLL_STATE_WRITE_READY))) || |
2873 | ( (MHD_EVENT_LOOP_INFO_READ == connection->request.event_loop_info) && | 2902 | ( (MHD_EVENT_LOOP_INFO_READ == connection->request.event_loop_info) && |
2874 | (0 == (connection->epoll_state & MHD_EPOLL_STATE_READ_READY)) ) ) ) | 2903 | (0 == (connection->epoll_state & MHD_EPOLL_STATE_READ_READY)) ) ) ) |
2904 | { | ||
2905 | /* add to epoll set */ | ||
2906 | struct epoll_event event; | ||
2907 | |||
2908 | event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET; | ||
2909 | event.data.ptr = connection; | ||
2910 | if (0 != epoll_ctl (daemon->epoll_fd, | ||
2911 | EPOLL_CTL_ADD, | ||
2912 | connection->socket_fd, | ||
2913 | &event)) | ||
2875 | { | 2914 | { |
2876 | /* add to epoll set */ | ||
2877 | struct epoll_event event; | ||
2878 | |||
2879 | event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET; | ||
2880 | event.data.ptr = connection; | ||
2881 | if (0 != epoll_ctl (daemon->epoll_fd, | ||
2882 | EPOLL_CTL_ADD, | ||
2883 | connection->socket_fd, | ||
2884 | &event)) | ||
2885 | { | ||
2886 | #ifdef HAVE_MESSAGES | 2915 | #ifdef HAVE_MESSAGES |
2887 | MHD_DLOG (daemon, | 2916 | MHD_DLOG (daemon, |
2888 | MHD_SC_EPOLL_CTL_ADD_FAILED, | 2917 | MHD_SC_EPOLL_CTL_ADD_FAILED, |
2889 | _("Call to epoll_ctl failed: %s\n"), | 2918 | _ ("Call to epoll_ctl failed: %s\n"), |
2890 | MHD_socket_last_strerr_ ()); | 2919 | MHD_socket_last_strerr_ ()); |
2891 | #endif | 2920 | #endif |
2892 | connection->request.state = MHD_REQUEST_CLOSED; | 2921 | connection->request.state = MHD_REQUEST_CLOSED; |
2893 | cleanup_connection (connection); | 2922 | cleanup_connection (connection); |
2894 | return false; | 2923 | return false; |
2895 | } | ||
2896 | connection->epoll_state |= MHD_EPOLL_STATE_IN_EPOLL_SET; | ||
2897 | } | 2924 | } |
2925 | connection->epoll_state |= MHD_EPOLL_STATE_IN_EPOLL_SET; | ||
2926 | } | ||
2898 | return true; | 2927 | return true; |
2899 | } | 2928 | } |
2900 | #endif | 2929 | #endif |
@@ -2922,142 +2951,142 @@ connection_update_event_loop_info (struct MHD_Connection *connection) | |||
2922 | struct MHD_TLS_Plugin *tls; | 2951 | struct MHD_TLS_Plugin *tls; |
2923 | 2952 | ||
2924 | if ( (NULL != (tls = daemon->tls_api)) && | 2953 | if ( (NULL != (tls = daemon->tls_api)) && |
2925 | (tls->update_event_loop_info (tls->cls, | 2954 | (tls->update_event_loop_info (tls->cls, |
2926 | connection->tls_cs, | 2955 | connection->tls_cs, |
2927 | &request->event_loop_info)) ) | 2956 | &request->event_loop_info)) ) |
2928 | return; /* TLS has decided what to do */ | 2957 | return; /* TLS has decided what to do */ |
2929 | } | 2958 | } |
2930 | #endif /* HTTPS_SUPPORT */ | 2959 | #endif /* HTTPS_SUPPORT */ |
2931 | while (1) | 2960 | while (1) |
2932 | { | 2961 | { |
2933 | #if DEBUG_STATES | 2962 | #if DEBUG_STATES |
2934 | MHD_DLOG (daemon, | 2963 | MHD_DLOG (daemon, |
2935 | MHD_SC_STATE_MACHINE_STATUS_REPORT, | 2964 | MHD_SC_STATE_MACHINE_STATUS_REPORT, |
2936 | _("In function %s handling connection at state: %s\n"), | 2965 | _ ("In function %s handling connection at state: %s\n"), |
2937 | __FUNCTION__, | 2966 | __FUNCTION__, |
2938 | MHD_state_to_string (request->state)); | 2967 | MHD_state_to_string (request->state)); |
2939 | #endif | 2968 | #endif |
2940 | switch (request->state) | 2969 | switch (request->state) |
2970 | { | ||
2971 | case MHD_REQUEST_INIT: | ||
2972 | case MHD_REQUEST_URL_RECEIVED: | ||
2973 | case MHD_REQUEST_HEADER_PART_RECEIVED: | ||
2974 | /* while reading headers, we always grow the | ||
2975 | read buffer if needed, no size-check required */ | ||
2976 | if ( (request->read_buffer_offset == request->read_buffer_size) && | ||
2977 | (! try_grow_read_buffer (request)) ) | ||
2978 | { | ||
2979 | transmit_error_response (request, | ||
2980 | MHD_SC_CLIENT_HEADER_TOO_BIG, | ||
2981 | (NULL != request->url) | ||
2982 | ? MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE | ||
2983 | : MHD_HTTP_URI_TOO_LONG, | ||
2984 | REQUEST_TOO_BIG); | ||
2985 | continue; | ||
2986 | } | ||
2987 | if (! connection->read_closed) | ||
2988 | request->event_loop_info = MHD_EVENT_LOOP_INFO_READ; | ||
2989 | else | ||
2990 | request->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK; | ||
2991 | break; | ||
2992 | case MHD_REQUEST_HEADERS_RECEIVED: | ||
2993 | mhd_assert (0); | ||
2994 | break; | ||
2995 | case MHD_REQUEST_HEADERS_PROCESSED: | ||
2996 | mhd_assert (0); | ||
2997 | break; | ||
2998 | case MHD_REQUEST_CONTINUE_SENDING: | ||
2999 | request->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE; | ||
3000 | break; | ||
3001 | case MHD_REQUEST_CONTINUE_SENT: | ||
3002 | if (request->read_buffer_offset == request->read_buffer_size) | ||
3003 | { | ||
3004 | if ( (! try_grow_read_buffer (request)) && | ||
3005 | (MHD_TM_EXTERNAL_EVENT_LOOP != daemon->threading_mode) ) | ||
2941 | { | 3006 | { |
2942 | case MHD_REQUEST_INIT: | 3007 | /* failed to grow the read buffer, and the client |
2943 | case MHD_REQUEST_URL_RECEIVED: | 3008 | which is supposed to handle the received data in |
2944 | case MHD_REQUEST_HEADER_PART_RECEIVED: | 3009 | a *blocking* fashion (in this mode) did not |
2945 | /* while reading headers, we always grow the | 3010 | handle the data as it was supposed to! |
2946 | read buffer if needed, no size-check required */ | 3011 | |
2947 | if ( (request->read_buffer_offset == request->read_buffer_size) && | 3012 | => we would either have to do busy-waiting |
2948 | (! try_grow_read_buffer (request)) ) | 3013 | (on the client, which would likely fail), |
2949 | { | 3014 | or if we do nothing, we would just timeout |
2950 | transmit_error_response (request, | 3015 | on the connection (if a timeout is even set!). |
2951 | MHD_SC_CLIENT_HEADER_TOO_BIG, | 3016 | |
2952 | (NULL != request->url) | 3017 | Solution: we kill the connection with an error */ |
2953 | ? MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE | 3018 | transmit_error_response (request, |
2954 | : MHD_HTTP_URI_TOO_LONG, | 3019 | MHD_SC_APPLICATION_HUNG_CONNECTION_CLOSED, |
2955 | REQUEST_TOO_BIG); | 3020 | MHD_HTTP_INTERNAL_SERVER_ERROR, |
2956 | continue; | 3021 | INTERNAL_ERROR); |
2957 | } | 3022 | continue; |
2958 | if (! connection->read_closed) | ||
2959 | request->event_loop_info = MHD_EVENT_LOOP_INFO_READ; | ||
2960 | else | ||
2961 | request->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK; | ||
2962 | break; | ||
2963 | case MHD_REQUEST_HEADERS_RECEIVED: | ||
2964 | mhd_assert (0); | ||
2965 | break; | ||
2966 | case MHD_REQUEST_HEADERS_PROCESSED: | ||
2967 | mhd_assert (0); | ||
2968 | break; | ||
2969 | case MHD_REQUEST_CONTINUE_SENDING: | ||
2970 | request->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE; | ||
2971 | break; | ||
2972 | case MHD_REQUEST_CONTINUE_SENT: | ||
2973 | if (request->read_buffer_offset == request->read_buffer_size) | ||
2974 | { | ||
2975 | if ( (! try_grow_read_buffer (request)) && | ||
2976 | (MHD_TM_EXTERNAL_EVENT_LOOP != daemon->threading_mode) ) | ||
2977 | { | ||
2978 | /* failed to grow the read buffer, and the client | ||
2979 | which is supposed to handle the received data in | ||
2980 | a *blocking* fashion (in this mode) did not | ||
2981 | handle the data as it was supposed to! | ||
2982 | |||
2983 | => we would either have to do busy-waiting | ||
2984 | (on the client, which would likely fail), | ||
2985 | or if we do nothing, we would just timeout | ||
2986 | on the connection (if a timeout is even set!). | ||
2987 | |||
2988 | Solution: we kill the connection with an error */ | ||
2989 | transmit_error_response (request, | ||
2990 | MHD_SC_APPLICATION_HUNG_CONNECTION_CLOSED, | ||
2991 | MHD_HTTP_INTERNAL_SERVER_ERROR, | ||
2992 | INTERNAL_ERROR); | ||
2993 | continue; | ||
2994 | } | ||
2995 | } | ||
2996 | if ( (request->read_buffer_offset < request->read_buffer_size) && | ||
2997 | (! connection->read_closed) ) | ||
2998 | request->event_loop_info = MHD_EVENT_LOOP_INFO_READ; | ||
2999 | else | ||
3000 | request->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK; | ||
3001 | break; | ||
3002 | case MHD_REQUEST_BODY_RECEIVED: | ||
3003 | case MHD_REQUEST_FOOTER_PART_RECEIVED: | ||
3004 | /* while reading footers, we always grow the | ||
3005 | read buffer if needed, no size-check required */ | ||
3006 | if (connection->read_closed) | ||
3007 | { | ||
3008 | CONNECTION_CLOSE_ERROR (connection, | ||
3009 | MHD_SC_CONNECTION_READ_FAIL_CLOSED, | ||
3010 | NULL); | ||
3011 | continue; | ||
3012 | } | ||
3013 | request->event_loop_info = MHD_EVENT_LOOP_INFO_READ; | ||
3014 | /* transition to FOOTERS_RECEIVED | ||
3015 | happens in read handler */ | ||
3016 | break; | ||
3017 | case MHD_REQUEST_FOOTERS_RECEIVED: | ||
3018 | request->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK; | ||
3019 | break; | ||
3020 | case MHD_REQUEST_HEADERS_SENDING: | ||
3021 | /* headers in buffer, keep writing */ | ||
3022 | request->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE; | ||
3023 | break; | ||
3024 | case MHD_REQUEST_HEADERS_SENT: | ||
3025 | mhd_assert (0); | ||
3026 | break; | ||
3027 | case MHD_REQUEST_NORMAL_BODY_READY: | ||
3028 | request->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE; | ||
3029 | break; | ||
3030 | case MHD_REQUEST_NORMAL_BODY_UNREADY: | ||
3031 | request->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK; | ||
3032 | break; | ||
3033 | case MHD_REQUEST_CHUNKED_BODY_READY: | ||
3034 | request->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE; | ||
3035 | break; | ||
3036 | case MHD_REQUEST_CHUNKED_BODY_UNREADY: | ||
3037 | request->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK; | ||
3038 | break; | ||
3039 | case MHD_REQUEST_BODY_SENT: | ||
3040 | mhd_assert (0); | ||
3041 | break; | ||
3042 | case MHD_REQUEST_FOOTERS_SENDING: | ||
3043 | request->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE; | ||
3044 | break; | ||
3045 | case MHD_REQUEST_FOOTERS_SENT: | ||
3046 | mhd_assert (0); | ||
3047 | break; | ||
3048 | case MHD_REQUEST_CLOSED: | ||
3049 | request->event_loop_info = MHD_EVENT_LOOP_INFO_CLEANUP; | ||
3050 | return; /* do nothing, not even reading */ | ||
3051 | #ifdef UPGRADE_SUPPORT | ||
3052 | case MHD_REQUEST_UPGRADE: | ||
3053 | mhd_assert (0); | ||
3054 | break; | ||
3055 | #endif /* UPGRADE_SUPPORT */ | ||
3056 | default: | ||
3057 | mhd_assert (0); | ||
3058 | } | 3023 | } |
3024 | } | ||
3025 | if ( (request->read_buffer_offset < request->read_buffer_size) && | ||
3026 | (! connection->read_closed) ) | ||
3027 | request->event_loop_info = MHD_EVENT_LOOP_INFO_READ; | ||
3028 | else | ||
3029 | request->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK; | ||
3030 | break; | ||
3031 | case MHD_REQUEST_BODY_RECEIVED: | ||
3032 | case MHD_REQUEST_FOOTER_PART_RECEIVED: | ||
3033 | /* while reading footers, we always grow the | ||
3034 | read buffer if needed, no size-check required */ | ||
3035 | if (connection->read_closed) | ||
3036 | { | ||
3037 | CONNECTION_CLOSE_ERROR (connection, | ||
3038 | MHD_SC_CONNECTION_READ_FAIL_CLOSED, | ||
3039 | NULL); | ||
3040 | continue; | ||
3041 | } | ||
3042 | request->event_loop_info = MHD_EVENT_LOOP_INFO_READ; | ||
3043 | /* transition to FOOTERS_RECEIVED | ||
3044 | happens in read handler */ | ||
3045 | break; | ||
3046 | case MHD_REQUEST_FOOTERS_RECEIVED: | ||
3047 | request->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK; | ||
3048 | break; | ||
3049 | case MHD_REQUEST_HEADERS_SENDING: | ||
3050 | /* headers in buffer, keep writing */ | ||
3051 | request->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE; | ||
3052 | break; | ||
3053 | case MHD_REQUEST_HEADERS_SENT: | ||
3054 | mhd_assert (0); | ||
3055 | break; | ||
3056 | case MHD_REQUEST_NORMAL_BODY_READY: | ||
3057 | request->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE; | ||
3058 | break; | ||
3059 | case MHD_REQUEST_NORMAL_BODY_UNREADY: | ||
3060 | request->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK; | ||
3061 | break; | ||
3062 | case MHD_REQUEST_CHUNKED_BODY_READY: | ||
3063 | request->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE; | ||
3064 | break; | ||
3065 | case MHD_REQUEST_CHUNKED_BODY_UNREADY: | ||
3066 | request->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK; | ||
3067 | break; | ||
3068 | case MHD_REQUEST_BODY_SENT: | ||
3069 | mhd_assert (0); | ||
3070 | break; | ||
3071 | case MHD_REQUEST_FOOTERS_SENDING: | ||
3072 | request->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE; | ||
3059 | break; | 3073 | break; |
3074 | case MHD_REQUEST_FOOTERS_SENT: | ||
3075 | mhd_assert (0); | ||
3076 | break; | ||
3077 | case MHD_REQUEST_CLOSED: | ||
3078 | request->event_loop_info = MHD_EVENT_LOOP_INFO_CLEANUP; | ||
3079 | return; /* do nothing, not even reading */ | ||
3080 | #ifdef UPGRADE_SUPPORT | ||
3081 | case MHD_REQUEST_UPGRADE: | ||
3082 | mhd_assert (0); | ||
3083 | break; | ||
3084 | #endif /* UPGRADE_SUPPORT */ | ||
3085 | default: | ||
3086 | mhd_assert (0); | ||
3060 | } | 3087 | } |
3088 | break; | ||
3089 | } | ||
3061 | } | 3090 | } |
3062 | 3091 | ||
3063 | 3092 | ||
@@ -3082,491 +3111,494 @@ MHD_request_handle_idle_ (struct MHD_Request *request) | |||
3082 | 3111 | ||
3083 | request->in_idle = true; | 3112 | request->in_idle = true; |
3084 | while (! connection->suspended) | 3113 | while (! connection->suspended) |
3085 | { | 3114 | { |
3086 | #ifdef HTTPS_SUPPORT | 3115 | #ifdef HTTPS_SUPPORT |
3087 | struct MHD_TLS_Plugin *tls; | 3116 | struct MHD_TLS_Plugin *tls; |
3088 | 3117 | ||
3089 | if ( (NULL != (tls = daemon->tls_api)) && | 3118 | if ( (NULL != (tls = daemon->tls_api)) && |
3090 | (! tls->idle_ready (tls->cls, | 3119 | (! tls->idle_ready (tls->cls, |
3091 | connection->tls_cs)) ) | 3120 | connection->tls_cs)) ) |
3092 | break; | 3121 | break; |
3093 | #endif /* HTTPS_SUPPORT */ | 3122 | #endif /* HTTPS_SUPPORT */ |
3094 | #if DEBUG_STATES | 3123 | #if DEBUG_STATES |
3095 | MHD_DLOG (daemon, | 3124 | MHD_DLOG (daemon, |
3096 | MHD_SC_STATE_MACHINE_STATUS_REPORT, | 3125 | MHD_SC_STATE_MACHINE_STATUS_REPORT, |
3097 | _("In function %s handling connection at state: %s\n"), | 3126 | _ ("In function %s handling connection at state: %s\n"), |
3098 | __FUNCTION__, | 3127 | __FUNCTION__, |
3099 | MHD_state_to_string (request->state)); | 3128 | MHD_state_to_string (request->state)); |
3100 | #endif | 3129 | #endif |
3101 | switch (request->state) | 3130 | switch (request->state) |
3131 | { | ||
3132 | case MHD_REQUEST_INIT: | ||
3133 | line = get_next_header_line (request, | ||
3134 | &line_len); | ||
3135 | /* Check for empty string, as we might want | ||
3136 | to tolerate 'spurious' empty lines; also | ||
3137 | NULL means we didn't get a full line yet; | ||
3138 | line is not 0-terminated here. */ | ||
3139 | if ( (NULL == line) || | ||
3140 | (0 == line[0]) ) | ||
3141 | { | ||
3142 | if (MHD_REQUEST_INIT != request->state) | ||
3143 | continue; | ||
3144 | if (connection->read_closed) | ||
3102 | { | 3145 | { |
3103 | case MHD_REQUEST_INIT: | 3146 | CONNECTION_CLOSE_ERROR (connection, |
3104 | line = get_next_header_line (request, | 3147 | MHD_SC_CONNECTION_READ_FAIL_CLOSED, |
3105 | &line_len); | 3148 | NULL); |
3106 | /* Check for empty string, as we might want | ||
3107 | to tolerate 'spurious' empty lines; also | ||
3108 | NULL means we didn't get a full line yet; | ||
3109 | line is not 0-terminated here. */ | ||
3110 | if ( (NULL == line) || | ||
3111 | (0 == line[0]) ) | ||
3112 | { | ||
3113 | if (MHD_REQUEST_INIT != request->state) | ||
3114 | continue; | ||
3115 | if (connection->read_closed) | ||
3116 | { | ||
3117 | CONNECTION_CLOSE_ERROR (connection, | ||
3118 | MHD_SC_CONNECTION_READ_FAIL_CLOSED, | ||
3119 | NULL); | ||
3120 | continue; | ||
3121 | } | ||
3122 | break; | ||
3123 | } | ||
3124 | if (MHD_NO == | ||
3125 | parse_initial_message_line (request, | ||
3126 | line, | ||
3127 | line_len)) | ||
3128 | CONNECTION_CLOSE_ERROR (connection, | ||
3129 | MHD_SC_CONNECTION_CLOSED, | ||
3130 | NULL); | ||
3131 | else | ||
3132 | request->state = MHD_REQUEST_URL_RECEIVED; | ||
3133 | continue; | 3149 | continue; |
3134 | case MHD_REQUEST_URL_RECEIVED: | 3150 | } |
3135 | line = get_next_header_line (request, | 3151 | break; |
3136 | NULL); | 3152 | } |
3137 | if (NULL == line) | 3153 | if (MHD_NO == |
3138 | { | 3154 | parse_initial_message_line (request, |
3139 | if (MHD_REQUEST_URL_RECEIVED != request->state) | 3155 | line, |
3140 | continue; | 3156 | line_len)) |
3141 | if (connection->read_closed) | 3157 | CONNECTION_CLOSE_ERROR (connection, |
3142 | { | 3158 | MHD_SC_CONNECTION_CLOSED, |
3143 | CONNECTION_CLOSE_ERROR (connection, | 3159 | NULL); |
3144 | MHD_SC_CONNECTION_READ_FAIL_CLOSED, | 3160 | else |
3145 | NULL); | 3161 | request->state = MHD_REQUEST_URL_RECEIVED; |
3146 | continue; | 3162 | continue; |
3147 | } | 3163 | case MHD_REQUEST_URL_RECEIVED: |
3148 | break; | 3164 | line = get_next_header_line (request, |
3149 | } | 3165 | NULL); |
3150 | if (0 == line[0]) | 3166 | if (NULL == line) |
3151 | { | 3167 | { |
3152 | request->state = MHD_REQUEST_HEADERS_RECEIVED; | 3168 | if (MHD_REQUEST_URL_RECEIVED != request->state) |
3153 | request->header_size = (size_t) (line - request->read_buffer); | ||
3154 | continue; | ||
3155 | } | ||
3156 | if (! process_header_line (request, | ||
3157 | line)) | ||
3158 | { | ||
3159 | transmit_error_response (request, | ||
3160 | MHD_SC_CONNECTION_PARSE_FAIL_CLOSED, | ||
3161 | MHD_HTTP_BAD_REQUEST, | ||
3162 | REQUEST_MALFORMED); | ||
3163 | break; | ||
3164 | } | ||
3165 | request->state = MHD_REQUEST_HEADER_PART_RECEIVED; | ||
3166 | continue; | 3169 | continue; |
3167 | case MHD_REQUEST_HEADER_PART_RECEIVED: | 3170 | if (connection->read_closed) |
3168 | line = get_next_header_line (request, | 3171 | { |
3169 | NULL); | 3172 | CONNECTION_CLOSE_ERROR (connection, |
3170 | if (NULL == line) | 3173 | MHD_SC_CONNECTION_READ_FAIL_CLOSED, |
3171 | { | 3174 | NULL); |
3172 | if (request->state != MHD_REQUEST_HEADER_PART_RECEIVED) | ||
3173 | continue; | ||
3174 | if (connection->read_closed) | ||
3175 | { | ||
3176 | CONNECTION_CLOSE_ERROR (connection, | ||
3177 | MHD_SC_CONNECTION_READ_FAIL_CLOSED, | ||
3178 | NULL); | ||
3179 | continue; | ||
3180 | } | ||
3181 | break; | ||
3182 | } | ||
3183 | if (MHD_NO == | ||
3184 | process_broken_line (request, | ||
3185 | line, | ||
3186 | MHD_HEADER_KIND)) | ||
3187 | continue; | ||
3188 | if (0 == line[0]) | ||
3189 | { | ||
3190 | request->state = MHD_REQUEST_HEADERS_RECEIVED; | ||
3191 | request->header_size = (size_t) (line - request->read_buffer); | ||
3192 | continue; | ||
3193 | } | ||
3194 | continue; | 3175 | continue; |
3195 | case MHD_REQUEST_HEADERS_RECEIVED: | 3176 | } |
3196 | parse_request_headers (request); | 3177 | break; |
3197 | if (MHD_REQUEST_CLOSED == request->state) | 3178 | } |
3198 | continue; | 3179 | if (0 == line[0]) |
3199 | request->state = MHD_REQUEST_HEADERS_PROCESSED; | 3180 | { |
3200 | if (connection->suspended) | 3181 | request->state = MHD_REQUEST_HEADERS_RECEIVED; |
3201 | break; | 3182 | request->header_size = (size_t) (line - request->read_buffer); |
3183 | continue; | ||
3184 | } | ||
3185 | if (! process_header_line (request, | ||
3186 | line)) | ||
3187 | { | ||
3188 | transmit_error_response (request, | ||
3189 | MHD_SC_CONNECTION_PARSE_FAIL_CLOSED, | ||
3190 | MHD_HTTP_BAD_REQUEST, | ||
3191 | REQUEST_MALFORMED); | ||
3192 | break; | ||
3193 | } | ||
3194 | request->state = MHD_REQUEST_HEADER_PART_RECEIVED; | ||
3195 | continue; | ||
3196 | case MHD_REQUEST_HEADER_PART_RECEIVED: | ||
3197 | line = get_next_header_line (request, | ||
3198 | NULL); | ||
3199 | if (NULL == line) | ||
3200 | { | ||
3201 | if (request->state != MHD_REQUEST_HEADER_PART_RECEIVED) | ||
3202 | continue; | 3202 | continue; |
3203 | case MHD_REQUEST_HEADERS_PROCESSED: | 3203 | if (connection->read_closed) |
3204 | call_request_handler (request); /* first call */ | 3204 | { |
3205 | if (MHD_REQUEST_CLOSED == request->state) | 3205 | CONNECTION_CLOSE_ERROR (connection, |
3206 | continue; | 3206 | MHD_SC_CONNECTION_READ_FAIL_CLOSED, |
3207 | if (need_100_continue (request)) | 3207 | NULL); |
3208 | { | ||
3209 | request->state = MHD_REQUEST_CONTINUE_SENDING; | ||
3210 | if (socket_flush_possible (connection)) | ||
3211 | socket_start_extra_buffering (connection); | ||
3212 | else | ||
3213 | socket_start_no_buffering (connection); | ||
3214 | break; | ||
3215 | } | ||
3216 | if ( (NULL != request->response) && | ||
3217 | ( (MHD_METHOD_POST == request->method) || | ||
3218 | (MHD_METHOD_PUT == request->method) ) ) | ||
3219 | { | ||
3220 | /* we refused (no upload allowed!) */ | ||
3221 | request->remaining_upload_size = 0; | ||
3222 | /* force close, in case client still tries to upload... */ | ||
3223 | connection->read_closed = true; | ||
3224 | } | ||
3225 | request->state = (0 == request->remaining_upload_size) | ||
3226 | ? MHD_REQUEST_FOOTERS_RECEIVED | ||
3227 | : MHD_REQUEST_CONTINUE_SENT; | ||
3228 | if (connection->suspended) | ||
3229 | break; | ||
3230 | continue; | 3208 | continue; |
3231 | case MHD_REQUEST_CONTINUE_SENDING: | 3209 | } |
3232 | if (request->continue_message_write_offset == | 3210 | break; |
3233 | MHD_STATICSTR_LEN_ (HTTP_100_CONTINUE)) | 3211 | } |
3234 | { | 3212 | if (MHD_NO == |
3235 | request->state = MHD_REQUEST_CONTINUE_SENT; | 3213 | process_broken_line (request, |
3236 | if (! socket_flush_possible (connection)) | 3214 | line, |
3237 | socket_start_no_buffering_flush (connection); | 3215 | MHD_HEADER_KIND)) |
3238 | else | 3216 | continue; |
3239 | socket_start_normal_buffering (connection); | 3217 | if (0 == line[0]) |
3240 | continue; | 3218 | { |
3241 | } | 3219 | request->state = MHD_REQUEST_HEADERS_RECEIVED; |
3242 | break; | 3220 | request->header_size = (size_t) (line - request->read_buffer); |
3243 | case MHD_REQUEST_CONTINUE_SENT: | 3221 | continue; |
3244 | if (0 != request->read_buffer_offset) | 3222 | } |
3245 | { | 3223 | continue; |
3246 | process_request_body (request); /* loop call */ | 3224 | case MHD_REQUEST_HEADERS_RECEIVED: |
3247 | if (MHD_REQUEST_CLOSED == request->state) | 3225 | parse_request_headers (request); |
3248 | continue; | 3226 | if (MHD_REQUEST_CLOSED == request->state) |
3249 | } | 3227 | continue; |
3250 | if ( (0 == request->remaining_upload_size) || | 3228 | request->state = MHD_REQUEST_HEADERS_PROCESSED; |
3251 | ( (MHD_SIZE_UNKNOWN == request->remaining_upload_size) && | 3229 | if (connection->suspended) |
3252 | (0 == request->read_buffer_offset) && | 3230 | break; |
3253 | (connection->read_closed) ) ) | 3231 | continue; |
3254 | { | 3232 | case MHD_REQUEST_HEADERS_PROCESSED: |
3255 | if ( (request->have_chunked_upload) && | 3233 | call_request_handler (request); /* first call */ |
3256 | (! connection->read_closed) ) | 3234 | if (MHD_REQUEST_CLOSED == request->state) |
3257 | request->state = MHD_REQUEST_BODY_RECEIVED; | 3235 | continue; |
3258 | else | 3236 | if (need_100_continue (request)) |
3259 | request->state = MHD_REQUEST_FOOTERS_RECEIVED; | 3237 | { |
3260 | if (connection->suspended) | 3238 | request->state = MHD_REQUEST_CONTINUE_SENDING; |
3261 | break; | 3239 | if (socket_flush_possible (connection)) |
3262 | continue; | 3240 | socket_start_extra_buffering (connection); |
3263 | } | 3241 | else |
3242 | socket_start_no_buffering (connection); | ||
3243 | break; | ||
3244 | } | ||
3245 | if ( (NULL != request->response) && | ||
3246 | ( (MHD_METHOD_POST == request->method) || | ||
3247 | (MHD_METHOD_PUT == request->method) ) ) | ||
3248 | { | ||
3249 | /* we refused (no upload allowed!) */ | ||
3250 | request->remaining_upload_size = 0; | ||
3251 | /* force close, in case client still tries to upload... */ | ||
3252 | connection->read_closed = true; | ||
3253 | } | ||
3254 | request->state = (0 == request->remaining_upload_size) | ||
3255 | ? MHD_REQUEST_FOOTERS_RECEIVED | ||
3256 | : MHD_REQUEST_CONTINUE_SENT; | ||
3257 | if (connection->suspended) | ||
3258 | break; | ||
3259 | continue; | ||
3260 | case MHD_REQUEST_CONTINUE_SENDING: | ||
3261 | if (request->continue_message_write_offset == | ||
3262 | MHD_STATICSTR_LEN_ (HTTP_100_CONTINUE)) | ||
3263 | { | ||
3264 | request->state = MHD_REQUEST_CONTINUE_SENT; | ||
3265 | if (! socket_flush_possible (connection)) | ||
3266 | socket_start_no_buffering_flush (connection); | ||
3267 | else | ||
3268 | socket_start_normal_buffering (connection); | ||
3269 | continue; | ||
3270 | } | ||
3271 | break; | ||
3272 | case MHD_REQUEST_CONTINUE_SENT: | ||
3273 | if (0 != request->read_buffer_offset) | ||
3274 | { | ||
3275 | process_request_body (request); /* loop call */ | ||
3276 | if (MHD_REQUEST_CLOSED == request->state) | ||
3277 | continue; | ||
3278 | } | ||
3279 | if ( (0 == request->remaining_upload_size) || | ||
3280 | ( (MHD_SIZE_UNKNOWN == request->remaining_upload_size) && | ||
3281 | (0 == request->read_buffer_offset) && | ||
3282 | (connection->read_closed) ) ) | ||
3283 | { | ||
3284 | if ( (request->have_chunked_upload) && | ||
3285 | (! connection->read_closed) ) | ||
3286 | request->state = MHD_REQUEST_BODY_RECEIVED; | ||
3287 | else | ||
3288 | request->state = MHD_REQUEST_FOOTERS_RECEIVED; | ||
3289 | if (connection->suspended) | ||
3264 | break; | 3290 | break; |
3265 | case MHD_REQUEST_BODY_RECEIVED: | 3291 | continue; |
3266 | line = get_next_header_line (request, | 3292 | } |
3267 | NULL); | 3293 | break; |
3268 | if (NULL == line) | 3294 | case MHD_REQUEST_BODY_RECEIVED: |
3269 | { | 3295 | line = get_next_header_line (request, |
3270 | if (request->state != MHD_REQUEST_BODY_RECEIVED) | 3296 | NULL); |
3271 | continue; | 3297 | if (NULL == line) |
3272 | if (connection->read_closed) | 3298 | { |
3273 | { | 3299 | if (request->state != MHD_REQUEST_BODY_RECEIVED) |
3274 | CONNECTION_CLOSE_ERROR (connection, | ||
3275 | MHD_SC_CONNECTION_CLOSED, | ||
3276 | NULL); | ||
3277 | continue; | ||
3278 | } | ||
3279 | break; | ||
3280 | } | ||
3281 | if (0 == line[0]) | ||
3282 | { | ||
3283 | request->state = MHD_REQUEST_FOOTERS_RECEIVED; | ||
3284 | if (connection->suspended) | ||
3285 | break; | ||
3286 | continue; | ||
3287 | } | ||
3288 | if (MHD_NO == process_header_line (request, | ||
3289 | line)) | ||
3290 | { | ||
3291 | transmit_error_response (request, | ||
3292 | MHD_SC_CONNECTION_PARSE_FAIL_CLOSED, | ||
3293 | MHD_HTTP_BAD_REQUEST, | ||
3294 | REQUEST_MALFORMED); | ||
3295 | break; | ||
3296 | } | ||
3297 | request->state = MHD_REQUEST_FOOTER_PART_RECEIVED; | ||
3298 | continue; | 3300 | continue; |
3299 | case MHD_REQUEST_FOOTER_PART_RECEIVED: | 3301 | if (connection->read_closed) |
3300 | line = get_next_header_line (request, | 3302 | { |
3301 | NULL); | 3303 | CONNECTION_CLOSE_ERROR (connection, |
3302 | if (NULL == line) | 3304 | MHD_SC_CONNECTION_CLOSED, |
3303 | { | 3305 | NULL); |
3304 | if (request->state != MHD_REQUEST_FOOTER_PART_RECEIVED) | ||
3305 | continue; | ||
3306 | if (connection->read_closed) | ||
3307 | { | ||
3308 | CONNECTION_CLOSE_ERROR (connection, | ||
3309 | MHD_SC_CONNECTION_CLOSED, | ||
3310 | NULL); | ||
3311 | continue; | ||
3312 | } | ||
3313 | break; | ||
3314 | } | ||
3315 | if (MHD_NO == | ||
3316 | process_broken_line (request, | ||
3317 | line, | ||
3318 | MHD_FOOTER_KIND)) | ||
3319 | continue; | ||
3320 | if (0 == line[0]) | ||
3321 | { | ||
3322 | request->state = MHD_REQUEST_FOOTERS_RECEIVED; | ||
3323 | if (connection->suspended) | ||
3324 | break; | ||
3325 | continue; | ||
3326 | } | ||
3327 | continue; | 3306 | continue; |
3328 | case MHD_REQUEST_FOOTERS_RECEIVED: | 3307 | } |
3329 | call_request_handler (request); /* "final" call */ | 3308 | break; |
3330 | if (request->state == MHD_REQUEST_CLOSED) | 3309 | } |
3331 | continue; | 3310 | if (0 == line[0]) |
3332 | if (NULL == request->response) | 3311 | { |
3333 | break; /* try again next time */ | 3312 | request->state = MHD_REQUEST_FOOTERS_RECEIVED; |
3334 | if (! build_header_response (request)) | 3313 | if (connection->suspended) |
3335 | { | ||
3336 | /* oops - close! */ | ||
3337 | CONNECTION_CLOSE_ERROR (connection, | ||
3338 | MHD_SC_FAILED_RESPONSE_HEADER_GENERATION, | ||
3339 | _("Closing connection (failed to create response header)\n")); | ||
3340 | continue; | ||
3341 | } | ||
3342 | request->state = MHD_REQUEST_HEADERS_SENDING; | ||
3343 | if (MHD_NO != socket_flush_possible (connection)) | ||
3344 | socket_start_extra_buffering (connection); | ||
3345 | else | ||
3346 | socket_start_no_buffering (connection); | ||
3347 | |||
3348 | break; | 3314 | break; |
3349 | case MHD_REQUEST_HEADERS_SENDING: | 3315 | continue; |
3350 | /* no default action */ | 3316 | } |
3317 | if (MHD_NO == process_header_line (request, | ||
3318 | line)) | ||
3319 | { | ||
3320 | transmit_error_response (request, | ||
3321 | MHD_SC_CONNECTION_PARSE_FAIL_CLOSED, | ||
3322 | MHD_HTTP_BAD_REQUEST, | ||
3323 | REQUEST_MALFORMED); | ||
3324 | break; | ||
3325 | } | ||
3326 | request->state = MHD_REQUEST_FOOTER_PART_RECEIVED; | ||
3327 | continue; | ||
3328 | case MHD_REQUEST_FOOTER_PART_RECEIVED: | ||
3329 | line = get_next_header_line (request, | ||
3330 | NULL); | ||
3331 | if (NULL == line) | ||
3332 | { | ||
3333 | if (request->state != MHD_REQUEST_FOOTER_PART_RECEIVED) | ||
3334 | continue; | ||
3335 | if (connection->read_closed) | ||
3336 | { | ||
3337 | CONNECTION_CLOSE_ERROR (connection, | ||
3338 | MHD_SC_CONNECTION_CLOSED, | ||
3339 | NULL); | ||
3340 | continue; | ||
3341 | } | ||
3342 | break; | ||
3343 | } | ||
3344 | if (MHD_NO == | ||
3345 | process_broken_line (request, | ||
3346 | line, | ||
3347 | MHD_FOOTER_KIND)) | ||
3348 | continue; | ||
3349 | if (0 == line[0]) | ||
3350 | { | ||
3351 | request->state = MHD_REQUEST_FOOTERS_RECEIVED; | ||
3352 | if (connection->suspended) | ||
3351 | break; | 3353 | break; |
3352 | case MHD_REQUEST_HEADERS_SENT: | 3354 | continue; |
3353 | /* Some clients may take some actions right after header receive */ | 3355 | } |
3354 | if (MHD_NO != socket_flush_possible (connection)) | 3356 | continue; |
3355 | socket_start_no_buffering_flush (connection); | 3357 | case MHD_REQUEST_FOOTERS_RECEIVED: |
3358 | call_request_handler (request); /* "final" call */ | ||
3359 | if (request->state == MHD_REQUEST_CLOSED) | ||
3360 | continue; | ||
3361 | if (NULL == request->response) | ||
3362 | break; /* try again next time */ | ||
3363 | if (! build_header_response (request)) | ||
3364 | { | ||
3365 | /* oops - close! */ | ||
3366 | CONNECTION_CLOSE_ERROR (connection, | ||
3367 | MHD_SC_FAILED_RESPONSE_HEADER_GENERATION, | ||
3368 | _ ( | ||
3369 | "Closing connection (failed to create response header)\n")); | ||
3370 | continue; | ||
3371 | } | ||
3372 | request->state = MHD_REQUEST_HEADERS_SENDING; | ||
3373 | if (MHD_NO != socket_flush_possible (connection)) | ||
3374 | socket_start_extra_buffering (connection); | ||
3375 | else | ||
3376 | socket_start_no_buffering (connection); | ||
3377 | |||
3378 | break; | ||
3379 | case MHD_REQUEST_HEADERS_SENDING: | ||
3380 | /* no default action */ | ||
3381 | break; | ||
3382 | case MHD_REQUEST_HEADERS_SENT: | ||
3383 | /* Some clients may take some actions right after header receive */ | ||
3384 | if (MHD_NO != socket_flush_possible (connection)) | ||
3385 | socket_start_no_buffering_flush (connection); | ||
3356 | 3386 | ||
3357 | #ifdef UPGRADE_SUPPORT | 3387 | #ifdef UPGRADE_SUPPORT |
3358 | if (NULL != request->response->upgrade_handler) | 3388 | if (NULL != request->response->upgrade_handler) |
3359 | { | 3389 | { |
3360 | socket_start_normal_buffering (connection); | 3390 | socket_start_normal_buffering (connection); |
3361 | request->state = MHD_REQUEST_UPGRADE; | 3391 | request->state = MHD_REQUEST_UPGRADE; |
3362 | #if FIXME_LEGACY_STYLE | 3392 | #if FIXME_LEGACY_STYLE |
3363 | /* This request is "upgraded". Pass socket to application. */ | 3393 | /* This request is "upgraded". Pass socket to application. */ |
3364 | if (! MHD_response_execute_upgrade_ (request->response, | 3394 | if (! MHD_response_execute_upgrade_ (request->response, |
3365 | request)) | 3395 | request)) |
3366 | { | 3396 | { |
3367 | /* upgrade failed, fail hard */ | 3397 | /* upgrade failed, fail hard */ |
3368 | CONNECTION_CLOSE_ERROR (connection, | 3398 | CONNECTION_CLOSE_ERROR (connection, |
3369 | MHD_SC_CONNECTION_CLOSED, | 3399 | MHD_SC_CONNECTION_CLOSED, |
3370 | NULL); | 3400 | NULL); |
3371 | continue; | 3401 | continue; |
3372 | } | 3402 | } |
3373 | #endif | 3403 | #endif |
3374 | /* Response is not required anymore for this request. */ | 3404 | /* Response is not required anymore for this request. */ |
3375 | { | 3405 | { |
3376 | struct MHD_Response * const resp = request->response; | 3406 | struct MHD_Response *const resp = request->response; |
3377 | 3407 | ||
3378 | request->response = NULL; | 3408 | request->response = NULL; |
3379 | MHD_response_queue_for_destroy (resp); | 3409 | MHD_response_queue_for_destroy (resp); |
3380 | } | 3410 | } |
3381 | continue; | 3411 | continue; |
3382 | } | 3412 | } |
3383 | #endif /* UPGRADE_SUPPORT */ | 3413 | #endif /* UPGRADE_SUPPORT */ |
3384 | if (MHD_NO != socket_flush_possible (connection)) | 3414 | if (MHD_NO != socket_flush_possible (connection)) |
3385 | socket_start_extra_buffering (connection); | 3415 | socket_start_extra_buffering (connection); |
3386 | else | 3416 | else |
3387 | socket_start_normal_buffering (connection); | 3417 | socket_start_normal_buffering (connection); |
3388 | 3418 | ||
3389 | if (request->have_chunked_upload) | 3419 | if (request->have_chunked_upload) |
3390 | request->state = MHD_REQUEST_CHUNKED_BODY_UNREADY; | 3420 | request->state = MHD_REQUEST_CHUNKED_BODY_UNREADY; |
3391 | else | 3421 | else |
3392 | request->state = MHD_REQUEST_NORMAL_BODY_UNREADY; | 3422 | request->state = MHD_REQUEST_NORMAL_BODY_UNREADY; |
3393 | continue; | 3423 | continue; |
3394 | case MHD_REQUEST_NORMAL_BODY_READY: | 3424 | case MHD_REQUEST_NORMAL_BODY_READY: |
3395 | /* nothing to do here */ | 3425 | /* nothing to do here */ |
3396 | break; | 3426 | break; |
3397 | case MHD_REQUEST_NORMAL_BODY_UNREADY: | 3427 | case MHD_REQUEST_NORMAL_BODY_UNREADY: |
3398 | if (NULL != request->response->crc) | 3428 | if (NULL != request->response->crc) |
3399 | MHD_mutex_lock_chk_ (&request->response->mutex); | 3429 | MHD_mutex_lock_chk_ (&request->response->mutex); |
3400 | if (0 == request->response->total_size) | 3430 | if (0 == request->response->total_size) |
3401 | { | 3431 | { |
3402 | if (NULL != request->response->crc) | 3432 | if (NULL != request->response->crc) |
3403 | MHD_mutex_unlock_chk_ (&request->response->mutex); | 3433 | MHD_mutex_unlock_chk_ (&request->response->mutex); |
3404 | request->state = MHD_REQUEST_BODY_SENT; | 3434 | request->state = MHD_REQUEST_BODY_SENT; |
3405 | continue; | 3435 | continue; |
3406 | } | 3436 | } |
3407 | if (try_ready_normal_body (request)) | 3437 | if (try_ready_normal_body (request)) |
3408 | { | 3438 | { |
3409 | if (NULL != request->response->crc) | 3439 | if (NULL != request->response->crc) |
3410 | MHD_mutex_unlock_chk_ (&request->response->mutex); | 3440 | MHD_mutex_unlock_chk_ (&request->response->mutex); |
3411 | request->state = MHD_REQUEST_NORMAL_BODY_READY; | 3441 | request->state = MHD_REQUEST_NORMAL_BODY_READY; |
3412 | /* Buffering for flushable socket was already enabled*/ | 3442 | /* Buffering for flushable socket was already enabled*/ |
3413 | if (MHD_NO == socket_flush_possible (connection)) | 3443 | if (MHD_NO == socket_flush_possible (connection)) |
3414 | socket_start_no_buffering (connection); | 3444 | socket_start_no_buffering (connection); |
3415 | break; | 3445 | break; |
3416 | } | 3446 | } |
3417 | /* mutex was already unlocked by "try_ready_normal_body */ | 3447 | /* mutex was already unlocked by "try_ready_normal_body */ |
3418 | /* not ready, no socket action */ | 3448 | /* not ready, no socket action */ |
3419 | break; | 3449 | break; |
3420 | case MHD_REQUEST_CHUNKED_BODY_READY: | 3450 | case MHD_REQUEST_CHUNKED_BODY_READY: |
3421 | /* nothing to do here */ | 3451 | /* nothing to do here */ |
3422 | break; | 3452 | break; |
3423 | case MHD_REQUEST_CHUNKED_BODY_UNREADY: | 3453 | case MHD_REQUEST_CHUNKED_BODY_UNREADY: |
3424 | if (NULL != request->response->crc) | 3454 | if (NULL != request->response->crc) |
3425 | MHD_mutex_lock_chk_ (&request->response->mutex); | 3455 | MHD_mutex_lock_chk_ (&request->response->mutex); |
3426 | if ( (0 == request->response->total_size) || | 3456 | if ( (0 == request->response->total_size) || |
3427 | (request->response_write_position == | 3457 | (request->response_write_position == |
3428 | request->response->total_size) ) | 3458 | request->response->total_size) ) |
3429 | { | 3459 | { |
3430 | if (NULL != request->response->crc) | 3460 | if (NULL != request->response->crc) |
3431 | MHD_mutex_unlock_chk_ (&request->response->mutex); | 3461 | MHD_mutex_unlock_chk_ (&request->response->mutex); |
3432 | request->state = MHD_REQUEST_BODY_SENT; | 3462 | request->state = MHD_REQUEST_BODY_SENT; |
3433 | continue; | 3463 | continue; |
3434 | } | 3464 | } |
3435 | if (try_ready_chunked_body (request)) | 3465 | if (try_ready_chunked_body (request)) |
3436 | { | 3466 | { |
3437 | if (NULL != request->response->crc) | 3467 | if (NULL != request->response->crc) |
3438 | MHD_mutex_unlock_chk_ (&request->response->mutex); | 3468 | MHD_mutex_unlock_chk_ (&request->response->mutex); |
3439 | request->state = MHD_REQUEST_CHUNKED_BODY_READY; | 3469 | request->state = MHD_REQUEST_CHUNKED_BODY_READY; |
3440 | /* Buffering for flushable socket was already enabled */ | 3470 | /* Buffering for flushable socket was already enabled */ |
3441 | if (MHD_NO == socket_flush_possible (connection)) | 3471 | if (MHD_NO == socket_flush_possible (connection)) |
3442 | socket_start_no_buffering (connection); | 3472 | socket_start_no_buffering (connection); |
3443 | continue; | 3473 | continue; |
3444 | } | 3474 | } |
3445 | /* mutex was already unlocked by try_ready_chunked_body */ | 3475 | /* mutex was already unlocked by try_ready_chunked_body */ |
3446 | break; | 3476 | break; |
3447 | case MHD_REQUEST_BODY_SENT: | 3477 | case MHD_REQUEST_BODY_SENT: |
3448 | if (! build_header_response (request)) | 3478 | if (! build_header_response (request)) |
3449 | { | 3479 | { |
3450 | /* oops - close! */ | 3480 | /* oops - close! */ |
3451 | CONNECTION_CLOSE_ERROR (connection, | 3481 | CONNECTION_CLOSE_ERROR (connection, |
3452 | MHD_SC_FAILED_RESPONSE_HEADER_GENERATION, | 3482 | MHD_SC_FAILED_RESPONSE_HEADER_GENERATION, |
3453 | _("Closing connection (failed to create response header)\n")); | 3483 | _ ( |
3454 | continue; | 3484 | "Closing connection (failed to create response header)\n")); |
3455 | } | 3485 | continue; |
3456 | if ( (! request->have_chunked_upload) || | 3486 | } |
3457 | (request->write_buffer_send_offset == | 3487 | if ( (! request->have_chunked_upload) || |
3458 | request->write_buffer_append_offset) ) | 3488 | (request->write_buffer_send_offset == |
3459 | request->state = MHD_REQUEST_FOOTERS_SENT; | 3489 | request->write_buffer_append_offset) ) |
3460 | else | 3490 | request->state = MHD_REQUEST_FOOTERS_SENT; |
3461 | request->state = MHD_REQUEST_FOOTERS_SENDING; | 3491 | else |
3462 | continue; | 3492 | request->state = MHD_REQUEST_FOOTERS_SENDING; |
3463 | case MHD_REQUEST_FOOTERS_SENDING: | 3493 | continue; |
3464 | /* no default action */ | 3494 | case MHD_REQUEST_FOOTERS_SENDING: |
3465 | break; | 3495 | /* no default action */ |
3466 | case MHD_REQUEST_FOOTERS_SENT: | 3496 | break; |
3467 | { | 3497 | case MHD_REQUEST_FOOTERS_SENT: |
3468 | struct MHD_Response *response = request->response; | 3498 | { |
3469 | 3499 | struct MHD_Response *response = request->response; | |
3470 | if (MHD_HTTP_PROCESSING == response->status_code) | 3500 | |
3471 | { | 3501 | if (MHD_HTTP_PROCESSING == response->status_code) |
3472 | /* After this type of response, we allow sending another! */ | 3502 | { |
3473 | request->state = MHD_REQUEST_HEADERS_PROCESSED; | 3503 | /* After this type of response, we allow sending another! */ |
3474 | MHD_response_queue_for_destroy (response); | 3504 | request->state = MHD_REQUEST_HEADERS_PROCESSED; |
3475 | request->response = NULL; | 3505 | MHD_response_queue_for_destroy (response); |
3476 | /* FIXME: maybe partially reset memory pool? */ | 3506 | request->response = NULL; |
3477 | continue; | 3507 | /* FIXME: maybe partially reset memory pool? */ |
3478 | } | ||
3479 | if (socket_flush_possible (connection)) | ||
3480 | socket_start_no_buffering_flush (connection); | ||
3481 | else | ||
3482 | socket_start_normal_buffering (connection); | ||
3483 | |||
3484 | if (NULL != response->termination_cb) | ||
3485 | { | ||
3486 | response->termination_cb (response->termination_cb_cls, | ||
3487 | MHD_REQUEST_TERMINATED_COMPLETED_OK, | ||
3488 | request->client_context); | ||
3489 | } | ||
3490 | MHD_response_queue_for_destroy (response); | ||
3491 | request->response = NULL; | ||
3492 | } | ||
3493 | if ( (MHD_CONN_USE_KEEPALIVE != request->keepalive) || | ||
3494 | (connection->read_closed) ) | ||
3495 | { | ||
3496 | /* have to close for some reason */ | ||
3497 | MHD_connection_close_ (connection, | ||
3498 | MHD_REQUEST_TERMINATED_COMPLETED_OK); | ||
3499 | MHD_pool_destroy (connection->pool); | ||
3500 | connection->pool = NULL; | ||
3501 | request->read_buffer = NULL; | ||
3502 | request->read_buffer_size = 0; | ||
3503 | request->read_buffer_offset = 0; | ||
3504 | } | ||
3505 | else | ||
3506 | { | ||
3507 | /* can try to keep-alive */ | ||
3508 | if (socket_flush_possible (connection)) | ||
3509 | socket_start_normal_buffering (connection); | ||
3510 | request->version_s = NULL; | ||
3511 | request->state = MHD_REQUEST_INIT; | ||
3512 | request->last = NULL; | ||
3513 | request->colon = NULL; | ||
3514 | request->header_size = 0; | ||
3515 | request->keepalive = MHD_CONN_KEEPALIVE_UNKOWN; | ||
3516 | /* Reset the read buffer to the starting size, | ||
3517 | preserving the bytes we have already read. */ | ||
3518 | request->read_buffer | ||
3519 | = MHD_pool_reset (connection->pool, | ||
3520 | request->read_buffer, | ||
3521 | request->read_buffer_offset, | ||
3522 | daemon->connection_memory_limit_b / 2); | ||
3523 | request->read_buffer_size | ||
3524 | = daemon->connection_memory_limit_b / 2; | ||
3525 | } | ||
3526 | // FIXME: this is too much, NULLs out some of the things | ||
3527 | // initialized above... | ||
3528 | memset (request, | ||
3529 | 0, | ||
3530 | sizeof (struct MHD_Request)); | ||
3531 | request->daemon = daemon; | ||
3532 | request->connection = connection; | ||
3533 | continue; | 3508 | continue; |
3534 | case MHD_REQUEST_CLOSED: | 3509 | } |
3535 | cleanup_connection (connection); | 3510 | if (socket_flush_possible (connection)) |
3536 | request->in_idle = false; | 3511 | socket_start_no_buffering_flush (connection); |
3537 | return false; | 3512 | else |
3513 | socket_start_normal_buffering (connection); | ||
3514 | |||
3515 | if (NULL != response->termination_cb) | ||
3516 | { | ||
3517 | response->termination_cb (response->termination_cb_cls, | ||
3518 | MHD_REQUEST_TERMINATED_COMPLETED_OK, | ||
3519 | request->client_context); | ||
3520 | } | ||
3521 | MHD_response_queue_for_destroy (response); | ||
3522 | request->response = NULL; | ||
3523 | } | ||
3524 | if ( (MHD_CONN_USE_KEEPALIVE != request->keepalive) || | ||
3525 | (connection->read_closed) ) | ||
3526 | { | ||
3527 | /* have to close for some reason */ | ||
3528 | MHD_connection_close_ (connection, | ||
3529 | MHD_REQUEST_TERMINATED_COMPLETED_OK); | ||
3530 | MHD_pool_destroy (connection->pool); | ||
3531 | connection->pool = NULL; | ||
3532 | request->read_buffer = NULL; | ||
3533 | request->read_buffer_size = 0; | ||
3534 | request->read_buffer_offset = 0; | ||
3535 | } | ||
3536 | else | ||
3537 | { | ||
3538 | /* can try to keep-alive */ | ||
3539 | if (socket_flush_possible (connection)) | ||
3540 | socket_start_normal_buffering (connection); | ||
3541 | request->version_s = NULL; | ||
3542 | request->state = MHD_REQUEST_INIT; | ||
3543 | request->last = NULL; | ||
3544 | request->colon = NULL; | ||
3545 | request->header_size = 0; | ||
3546 | request->keepalive = MHD_CONN_KEEPALIVE_UNKOWN; | ||
3547 | /* Reset the read buffer to the starting size, | ||
3548 | preserving the bytes we have already read. */ | ||
3549 | request->read_buffer | ||
3550 | = MHD_pool_reset (connection->pool, | ||
3551 | request->read_buffer, | ||
3552 | request->read_buffer_offset, | ||
3553 | daemon->connection_memory_limit_b / 2); | ||
3554 | request->read_buffer_size | ||
3555 | = daemon->connection_memory_limit_b / 2; | ||
3556 | } | ||
3557 | // FIXME: this is too much, NULLs out some of the things | ||
3558 | // initialized above... | ||
3559 | memset (request, | ||
3560 | 0, | ||
3561 | sizeof (struct MHD_Request)); | ||
3562 | request->daemon = daemon; | ||
3563 | request->connection = connection; | ||
3564 | continue; | ||
3565 | case MHD_REQUEST_CLOSED: | ||
3566 | cleanup_connection (connection); | ||
3567 | request->in_idle = false; | ||
3568 | return false; | ||
3538 | #ifdef UPGRADE_SUPPORT | 3569 | #ifdef UPGRADE_SUPPORT |
3539 | case MHD_REQUEST_UPGRADE: | 3570 | case MHD_REQUEST_UPGRADE: |
3540 | request->in_idle = false; | 3571 | request->in_idle = false; |
3541 | return true; /* keep open */ | 3572 | return true; /* keep open */ |
3542 | #endif /* UPGRADE_SUPPORT */ | 3573 | #endif /* UPGRADE_SUPPORT */ |
3543 | default: | 3574 | default: |
3544 | mhd_assert (0); | 3575 | mhd_assert (0); |
3545 | break; | ||
3546 | } | ||
3547 | break; | 3576 | break; |
3548 | } | 3577 | } |
3578 | break; | ||
3579 | } | ||
3549 | if (! connection->suspended) | 3580 | if (! connection->suspended) |
3581 | { | ||
3582 | time_t timeout; | ||
3583 | timeout = connection->connection_timeout; | ||
3584 | if ( (0 != timeout) && | ||
3585 | (timeout < (MHD_monotonic_sec_counter () | ||
3586 | - connection->last_activity)) ) | ||
3550 | { | 3587 | { |
3551 | time_t timeout; | 3588 | MHD_connection_close_ (connection, |
3552 | timeout = connection->connection_timeout; | 3589 | MHD_REQUEST_TERMINATED_TIMEOUT_REACHED); |
3553 | if ( (0 != timeout) && | 3590 | request->in_idle = false; |
3554 | (timeout < (MHD_monotonic_sec_counter() - connection->last_activity)) ) | 3591 | return true; |
3555 | { | ||
3556 | MHD_connection_close_ (connection, | ||
3557 | MHD_REQUEST_TERMINATED_TIMEOUT_REACHED); | ||
3558 | request->in_idle = false; | ||
3559 | return true; | ||
3560 | } | ||
3561 | } | 3592 | } |
3593 | } | ||
3562 | connection_update_event_loop_info (connection); | 3594 | connection_update_event_loop_info (connection); |
3563 | ret = true; | 3595 | ret = true; |
3564 | #ifdef EPOLL_SUPPORT | 3596 | #ifdef EPOLL_SUPPORT |
3565 | if ( (! connection->suspended) && | 3597 | if ( (! connection->suspended) && |
3566 | (MHD_ELS_EPOLL == daemon->event_loop_syscall) ) | 3598 | (MHD_ELS_EPOLL == daemon->event_loop_syscall) ) |
3567 | { | 3599 | { |
3568 | ret = connection_epoll_update_ (connection); | 3600 | ret = connection_epoll_update_ (connection); |
3569 | } | 3601 | } |
3570 | #endif /* EPOLL_SUPPORT */ | 3602 | #endif /* EPOLL_SUPPORT */ |
3571 | request->in_idle = false; | 3603 | request->in_idle = false; |
3572 | return ret; | 3604 | return ret; |
@@ -3589,9 +3621,9 @@ MHD_request_handle_idle_ (struct MHD_Request *request) | |||
3589 | // FIXME: rename connection->request? | 3621 | // FIXME: rename connection->request? |
3590 | int | 3622 | int |
3591 | MHD_connection_call_handlers_ (struct MHD_Connection *con, | 3623 | MHD_connection_call_handlers_ (struct MHD_Connection *con, |
3592 | bool read_ready, | 3624 | bool read_ready, |
3593 | bool write_ready, | 3625 | bool write_ready, |
3594 | bool force_close) | 3626 | bool force_close) |
3595 | { | 3627 | { |
3596 | struct MHD_Daemon *daemon = con->daemon; | 3628 | struct MHD_Daemon *daemon = con->daemon; |
3597 | int ret; | 3629 | int ret; |
@@ -3604,38 +3636,38 @@ MHD_connection_call_handlers_ (struct MHD_Connection *con, | |||
3604 | read_ready = true; | 3636 | read_ready = true; |
3605 | #endif /* HTTPS_SUPPORT */ | 3637 | #endif /* HTTPS_SUPPORT */ |
3606 | if (! force_close) | 3638 | if (! force_close) |
3639 | { | ||
3640 | if ( (MHD_EVENT_LOOP_INFO_READ == | ||
3641 | con->request.event_loop_info) && | ||
3642 | read_ready) | ||
3607 | { | 3643 | { |
3608 | if ( (MHD_EVENT_LOOP_INFO_READ == | 3644 | MHD_request_handle_read_ (&con->request); |
3609 | con->request.event_loop_info) && | 3645 | ret = MHD_request_handle_idle_ (&con->request); |
3610 | read_ready) | 3646 | states_info_processed = true; |
3611 | { | ||
3612 | MHD_request_handle_read_ (&con->request); | ||
3613 | ret = MHD_request_handle_idle_ (&con->request); | ||
3614 | states_info_processed = true; | ||
3615 | } | ||
3616 | /* No need to check value of 'ret' here as closed connection | ||
3617 | * cannot be in MHD_EVENT_LOOP_INFO_WRITE state. */ | ||
3618 | if ( (MHD_EVENT_LOOP_INFO_WRITE == | ||
3619 | con->request.event_loop_info) && | ||
3620 | write_ready) | ||
3621 | { | ||
3622 | MHD_request_handle_write_ (&con->request); | ||
3623 | ret = MHD_request_handle_idle_ (&con->request); | ||
3624 | states_info_processed = true; | ||
3625 | } | ||
3626 | } | 3647 | } |
3627 | else | 3648 | /* No need to check value of 'ret' here as closed connection |
3649 | * cannot be in MHD_EVENT_LOOP_INFO_WRITE state. */ | ||
3650 | if ( (MHD_EVENT_LOOP_INFO_WRITE == | ||
3651 | con->request.event_loop_info) && | ||
3652 | write_ready) | ||
3628 | { | 3653 | { |
3629 | MHD_connection_close_ (con, | 3654 | MHD_request_handle_write_ (&con->request); |
3630 | MHD_REQUEST_TERMINATED_WITH_ERROR); | 3655 | ret = MHD_request_handle_idle_ (&con->request); |
3631 | return MHD_request_handle_idle_ (&con->request); | 3656 | states_info_processed = true; |
3632 | } | 3657 | } |
3658 | } | ||
3659 | else | ||
3660 | { | ||
3661 | MHD_connection_close_ (con, | ||
3662 | MHD_REQUEST_TERMINATED_WITH_ERROR); | ||
3663 | return MHD_request_handle_idle_ (&con->request); | ||
3664 | } | ||
3633 | 3665 | ||
3634 | if (! states_info_processed) | 3666 | if (! states_info_processed) |
3635 | { /* Connection is not read or write ready, but external conditions | 3667 | { /* Connection is not read or write ready, but external conditions |
3636 | * may be changed and need to be processed. */ | 3668 | * may be changed and need to be processed. */ |
3637 | ret = MHD_request_handle_idle_ (&con->request); | 3669 | ret = MHD_request_handle_idle_ (&con->request); |
3638 | } | 3670 | } |
3639 | /* Fast track for fast connections. */ | 3671 | /* Fast track for fast connections. */ |
3640 | /* If full request was read by single read_handler() invocation | 3672 | /* If full request was read by single read_handler() invocation |
3641 | and headers were completely prepared by single MHD_request_handle_idle_() | 3673 | and headers were completely prepared by single MHD_request_handle_idle_() |
@@ -3647,24 +3679,24 @@ MHD_connection_call_handlers_ (struct MHD_Connection *con, | |||
3647 | /* No need to check 'ret' as connection is always in | 3679 | /* No need to check 'ret' as connection is always in |
3648 | * MHD_CONNECTION_CLOSED state if 'ret' is equal 'MHD_NO'. */ | 3680 | * MHD_CONNECTION_CLOSED state if 'ret' is equal 'MHD_NO'. */ |
3649 | else if (on_fasttrack && | 3681 | else if (on_fasttrack && |
3650 | con->sk_nonblck) | 3682 | con->sk_nonblck) |
3683 | { | ||
3684 | if (MHD_REQUEST_HEADERS_SENDING == con->request.state) | ||
3651 | { | 3685 | { |
3652 | if (MHD_REQUEST_HEADERS_SENDING == con->request.state) | 3686 | MHD_request_handle_write_ (&con->request); |
3653 | { | 3687 | /* Always call 'MHD_request_handle_idle_()' after each read/write. */ |
3654 | MHD_request_handle_write_ (&con->request); | 3688 | ret = MHD_request_handle_idle_ (&con->request); |
3655 | /* Always call 'MHD_request_handle_idle_()' after each read/write. */ | 3689 | } |
3656 | ret = MHD_request_handle_idle_ (&con->request); | 3690 | /* If all headers were sent by single write_handler() and |
3657 | } | 3691 | * response body is prepared by single MHD_request_handle_idle_() |
3658 | /* If all headers were sent by single write_handler() and | 3692 | * call - continue. */ |
3659 | * response body is prepared by single MHD_request_handle_idle_() | 3693 | if ((MHD_REQUEST_NORMAL_BODY_READY == con->request.state) || |
3660 | * call - continue. */ | 3694 | (MHD_REQUEST_CHUNKED_BODY_READY == con->request.state)) |
3661 | if ((MHD_REQUEST_NORMAL_BODY_READY == con->request.state) || | 3695 | { |
3662 | (MHD_REQUEST_CHUNKED_BODY_READY == con->request.state)) | 3696 | MHD_request_handle_write_ (&con->request); |
3663 | { | 3697 | ret = MHD_request_handle_idle_ (&con->request); |
3664 | MHD_request_handle_write_ (&con->request); | ||
3665 | ret = MHD_request_handle_idle_ (&con->request); | ||
3666 | } | ||
3667 | } | 3698 | } |
3699 | } | ||
3668 | 3700 | ||
3669 | /* All connection's data and states are processed for this turn. | 3701 | /* All connection's data and states are processed for this turn. |
3670 | * If connection already has more data to be processed - use | 3702 | * If connection already has more data to be processed - use |
@@ -3676,17 +3708,17 @@ MHD_connection_call_handlers_ (struct MHD_Connection *con, | |||
3676 | * without space in read buffer will be market as 'info block'. */ | 3708 | * without space in read buffer will be market as 'info block'. */ |
3677 | if ( (! daemon->data_already_pending) && | 3709 | if ( (! daemon->data_already_pending) && |
3678 | (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) ) | 3710 | (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) ) |
3679 | { | 3711 | { |
3680 | if (MHD_EVENT_LOOP_INFO_BLOCK == | 3712 | if (MHD_EVENT_LOOP_INFO_BLOCK == |
3681 | con->request.event_loop_info) | 3713 | con->request.event_loop_info) |
3682 | daemon->data_already_pending = true; | 3714 | daemon->data_already_pending = true; |
3683 | #ifdef HTTPS_SUPPORT | 3715 | #ifdef HTTPS_SUPPORT |
3684 | else if ( (con->tls_read_ready) && | 3716 | else if ( (con->tls_read_ready) && |
3685 | (MHD_EVENT_LOOP_INFO_READ == | 3717 | (MHD_EVENT_LOOP_INFO_READ == |
3686 | con->request.event_loop_info) ) | 3718 | con->request.event_loop_info) ) |
3687 | daemon->data_already_pending = true; | 3719 | daemon->data_already_pending = true; |
3688 | #endif /* HTTPS_SUPPORT */ | 3720 | #endif /* HTTPS_SUPPORT */ |
3689 | } | 3721 | } |
3690 | return ret; | 3722 | return ret; |
3691 | } | 3723 | } |
3692 | 3724 | ||
diff --git a/src/lib/connection_call_handlers.h b/src/lib/connection_call_handlers.h index 980e8064..6297bb9e 100644 --- a/src/lib/connection_call_handlers.h +++ b/src/lib/connection_call_handlers.h | |||
@@ -40,10 +40,10 @@ | |||
40 | */ | 40 | */ |
41 | int | 41 | int |
42 | MHD_connection_call_handlers_ (struct MHD_Connection *con, | 42 | MHD_connection_call_handlers_ (struct MHD_Connection *con, |
43 | bool read_ready, | 43 | bool read_ready, |
44 | bool write_ready, | 44 | bool write_ready, |
45 | bool force_close) | 45 | bool force_close) |
46 | MHD_NONNULL (1); | 46 | MHD_NONNULL (1); |
47 | 47 | ||
48 | 48 | ||
49 | /** | 49 | /** |
@@ -58,7 +58,7 @@ MHD_connection_call_handlers_ (struct MHD_Connection *con, | |||
58 | */ | 58 | */ |
59 | bool | 59 | bool |
60 | MHD_request_handle_idle_ (struct MHD_Request *request) | 60 | MHD_request_handle_idle_ (struct MHD_Request *request) |
61 | MHD_NONNULL (1); | 61 | MHD_NONNULL (1); |
62 | |||
62 | 63 | ||
63 | |||
64 | #endif | 64 | #endif |
diff --git a/src/lib/connection_cleanup.c b/src/lib/connection_cleanup.c index 8883213b..4f2cfb0f 100644 --- a/src/lib/connection_cleanup.c +++ b/src/lib/connection_cleanup.c | |||
@@ -49,7 +49,7 @@ connection_cleanup_upgraded (struct MHD_Connection *connection) | |||
49 | 49 | ||
50 | if (NULL != (tls = connection->daemon->tls_api)) | 50 | if (NULL != (tls = connection->daemon->tls_api)) |
51 | (void) tls->shutdown_connection (tls->cls, | 51 | (void) tls->shutdown_connection (tls->cls, |
52 | connection->tls_cs); | 52 | connection->tls_cs); |
53 | } | 53 | } |
54 | if (MHD_INVALID_SOCKET != urh->mhd.socket) | 54 | if (MHD_INVALID_SOCKET != urh->mhd.socket) |
55 | MHD_socket_close_chk_ (urh->mhd.socket); | 55 | MHD_socket_close_chk_ (urh->mhd.socket); |
@@ -65,7 +65,7 @@ connection_cleanup_upgraded (struct MHD_Connection *connection) | |||
65 | /** | 65 | /** |
66 | * Free resources associated with all closed connections. (destroy | 66 | * Free resources associated with all closed connections. (destroy |
67 | * responses, free buffers, etc.). All closed connections are kept in | 67 | * responses, free buffers, etc.). All closed connections are kept in |
68 | * the "cleanup" doubly-linked list. | 68 | * the "cleanup" doubly-linked list. |
69 | * | 69 | * |
70 | * @remark To be called only from thread that process daemon's | 70 | * @remark To be called only from thread that process daemon's |
71 | * select()/poll()/etc. | 71 | * select()/poll()/etc. |
@@ -79,79 +79,79 @@ MHD_connection_cleanup_ (struct MHD_Daemon *daemon) | |||
79 | 79 | ||
80 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); | 80 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); |
81 | while (NULL != (pos = daemon->cleanup_tail)) | 81 | while (NULL != (pos = daemon->cleanup_tail)) |
82 | { | 82 | { |
83 | DLL_remove (daemon->cleanup_head, | 83 | DLL_remove (daemon->cleanup_head, |
84 | daemon->cleanup_tail, | 84 | daemon->cleanup_tail, |
85 | pos); | 85 | pos); |
86 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); | 86 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); |
87 | 87 | ||
88 | if ( (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode) && | 88 | if ( (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode) && |
89 | (! pos->thread_joined) && | 89 | (! pos->thread_joined) && |
90 | (! MHD_join_thread_ (pos->pid.handle)) ) | 90 | (! MHD_join_thread_ (pos->pid.handle)) ) |
91 | MHD_PANIC (_("Failed to join a thread\n")); | 91 | MHD_PANIC (_ ("Failed to join a thread\n")); |
92 | #ifdef UPGRADE_SUPPORT | 92 | #ifdef UPGRADE_SUPPORT |
93 | connection_cleanup_upgraded (pos); | 93 | connection_cleanup_upgraded (pos); |
94 | #endif /* UPGRADE_SUPPORT */ | 94 | #endif /* UPGRADE_SUPPORT */ |
95 | MHD_pool_destroy (pos->pool); | 95 | MHD_pool_destroy (pos->pool); |
96 | #ifdef HTTPS_SUPPORT | 96 | #ifdef HTTPS_SUPPORT |
97 | { | 97 | { |
98 | struct MHD_TLS_Plugin *tls; | 98 | struct MHD_TLS_Plugin *tls; |
99 | 99 | ||
100 | if (NULL != (tls = daemon->tls_api)) | 100 | if (NULL != (tls = daemon->tls_api)) |
101 | tls->teardown_connection (tls->cls, | 101 | tls->teardown_connection (tls->cls, |
102 | pos->tls_cs); | 102 | pos->tls_cs); |
103 | } | 103 | } |
104 | #endif /* HTTPS_SUPPORT */ | 104 | #endif /* HTTPS_SUPPORT */ |
105 | 105 | ||
106 | /* clean up the connection */ | 106 | /* clean up the connection */ |
107 | if (NULL != daemon->notify_connection_cb) | 107 | if (NULL != daemon->notify_connection_cb) |
108 | daemon->notify_connection_cb (daemon->notify_connection_cb_cls, | 108 | daemon->notify_connection_cb (daemon->notify_connection_cb_cls, |
109 | pos, | 109 | pos, |
110 | MHD_CONNECTION_NOTIFY_CLOSED); | 110 | MHD_CONNECTION_NOTIFY_CLOSED); |
111 | MHD_ip_limit_del (daemon, | 111 | MHD_ip_limit_del (daemon, |
112 | (const struct sockaddr *) &pos->addr, | 112 | (const struct sockaddr *) &pos->addr, |
113 | pos->addr_len); | 113 | pos->addr_len); |
114 | #ifdef EPOLL_SUPPORT | 114 | #ifdef EPOLL_SUPPORT |
115 | if (MHD_ELS_EPOLL == daemon->event_loop_syscall) | 115 | if (MHD_ELS_EPOLL == daemon->event_loop_syscall) |
116 | { | 116 | { |
117 | if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) | 117 | if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) |
118 | { | 118 | { |
119 | EDLL_remove (daemon->eready_head, | 119 | EDLL_remove (daemon->eready_head, |
120 | daemon->eready_tail, | 120 | daemon->eready_tail, |
121 | pos); | 121 | pos); |
122 | pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL; | 122 | pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL; |
123 | } | 123 | } |
124 | if ( (-1 != daemon->epoll_fd) && | 124 | if ( (-1 != daemon->epoll_fd) && |
125 | (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) ) | 125 | (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) ) |
126 | { | 126 | { |
127 | /* epoll documentation suggests that closing a FD | 127 | /* epoll documentation suggests that closing a FD |
128 | automatically removes it from the epoll set; however, | 128 | automatically removes it from the epoll set; however, |
129 | this is not true as if we fail to do manually remove it, | 129 | this is not true as if we fail to do manually remove it, |
130 | we are still seeing an event for this fd in epoll, | 130 | we are still seeing an event for this fd in epoll, |
131 | causing grief (use-after-free...) --- at least on my | 131 | causing grief (use-after-free...) --- at least on my |
132 | system. */ | 132 | system. */ |
133 | if (0 != epoll_ctl (daemon->epoll_fd, | 133 | if (0 != epoll_ctl (daemon->epoll_fd, |
134 | EPOLL_CTL_DEL, | 134 | EPOLL_CTL_DEL, |
135 | pos->socket_fd, | 135 | pos->socket_fd, |
136 | NULL)) | 136 | NULL)) |
137 | MHD_PANIC (_("Failed to remove FD from epoll set\n")); | 137 | MHD_PANIC (_ ("Failed to remove FD from epoll set\n")); |
138 | pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET; | 138 | pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET; |
139 | } | 139 | } |
140 | } | 140 | } |
141 | #endif | 141 | #endif |
142 | if (NULL != pos->request.response) | 142 | if (NULL != pos->request.response) |
143 | { | 143 | { |
144 | MHD_response_queue_for_destroy (pos->request.response); | 144 | MHD_response_queue_for_destroy (pos->request.response); |
145 | pos->request.response = NULL; | 145 | pos->request.response = NULL; |
146 | } | ||
147 | if (MHD_INVALID_SOCKET != pos->socket_fd) | ||
148 | MHD_socket_close_chk_ (pos->socket_fd); | ||
149 | free (pos); | ||
150 | |||
151 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); | ||
152 | daemon->connections--; | ||
153 | daemon->at_limit = false; | ||
154 | } | 146 | } |
147 | if (MHD_INVALID_SOCKET != pos->socket_fd) | ||
148 | MHD_socket_close_chk_ (pos->socket_fd); | ||
149 | free (pos); | ||
150 | |||
151 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); | ||
152 | daemon->connections--; | ||
153 | daemon->at_limit = false; | ||
154 | } | ||
155 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); | 155 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); |
156 | } | 156 | } |
157 | 157 | ||
diff --git a/src/lib/connection_cleanup.h b/src/lib/connection_cleanup.h index 26fbebaf..c6beeeee 100644 --- a/src/lib/connection_cleanup.h +++ b/src/lib/connection_cleanup.h | |||
@@ -18,7 +18,7 @@ | |||
18 | */ | 18 | */ |
19 | /** | 19 | /** |
20 | * @file lib/connection_cleanup.h | 20 | * @file lib/connection_cleanup.h |
21 | * @brief functions to cleanup completed connection | 21 | * @brief functions to cleanup completed connection |
22 | * @author Christian Grothoff | 22 | * @author Christian Grothoff |
23 | */ | 23 | */ |
24 | #ifndef CONNECTION_CLEANUP_H | 24 | #ifndef CONNECTION_CLEANUP_H |
@@ -28,7 +28,7 @@ | |||
28 | /** | 28 | /** |
29 | * Free resources associated with all closed connections. (destroy | 29 | * Free resources associated with all closed connections. (destroy |
30 | * responses, free buffers, etc.). All closed connections are kept in | 30 | * responses, free buffers, etc.). All closed connections are kept in |
31 | * the "cleanup" doubly-linked list. | 31 | * the "cleanup" doubly-linked list. |
32 | * | 32 | * |
33 | * @remark To be called only from thread that process daemon's | 33 | * @remark To be called only from thread that process daemon's |
34 | * select()/poll()/etc. | 34 | * select()/poll()/etc. |
@@ -37,6 +37,6 @@ | |||
37 | */ | 37 | */ |
38 | void | 38 | void |
39 | MHD_connection_cleanup_ (struct MHD_Daemon *daemon) | 39 | MHD_connection_cleanup_ (struct MHD_Daemon *daemon) |
40 | MHD_NONNULL (1); | 40 | MHD_NONNULL (1); |
41 | 41 | ||
42 | #endif | 42 | #endif |
diff --git a/src/lib/connection_close.c b/src/lib/connection_close.c index 945997db..3c872b0b 100644 --- a/src/lib/connection_close.c +++ b/src/lib/connection_close.c | |||
@@ -40,33 +40,33 @@ MHD_connection_mark_closed_ (struct MHD_Connection *connection) | |||
40 | connection->request.state = MHD_REQUEST_CLOSED; | 40 | connection->request.state = MHD_REQUEST_CLOSED; |
41 | connection->request.event_loop_info = MHD_EVENT_LOOP_INFO_CLEANUP; | 41 | connection->request.event_loop_info = MHD_EVENT_LOOP_INFO_CLEANUP; |
42 | if (! daemon->enable_turbo) | 42 | if (! daemon->enable_turbo) |
43 | { | 43 | { |
44 | #ifdef HTTPS_SUPPORT | 44 | #ifdef HTTPS_SUPPORT |
45 | struct MHD_TLS_Plugin *tls; | 45 | struct MHD_TLS_Plugin *tls; |
46 | 46 | ||
47 | /* For TLS connection use shutdown of TLS layer | 47 | /* For TLS connection use shutdown of TLS layer |
48 | * and do not shutdown TCP socket. This give more | 48 | * and do not shutdown TCP socket. This give more |
49 | * chances to send TLS closure data to remote side. | 49 | * chances to send TLS closure data to remote side. |
50 | * Closure of TLS layer will be interpreted by | 50 | * Closure of TLS layer will be interpreted by |
51 | * remote side as end of transmission. */ | 51 | * remote side as end of transmission. */ |
52 | if (NULL != (tls = daemon->tls_api)) | 52 | if (NULL != (tls = daemon->tls_api)) |
53 | { | 53 | { |
54 | if (MHD_YES != | 54 | if (MHD_YES != |
55 | tls->shutdown_connection (tls->cls, | 55 | tls->shutdown_connection (tls->cls, |
56 | connection->tls_cs)) | 56 | connection->tls_cs)) |
57 | { | 57 | { |
58 | (void) shutdown (connection->socket_fd, | 58 | (void) shutdown (connection->socket_fd, |
59 | SHUT_WR); | 59 | SHUT_WR); |
60 | /* FIXME: log errors */ | 60 | /* FIXME: log errors */ |
61 | } | 61 | } |
62 | } | 62 | } |
63 | else /* Combined with next 'shutdown()'. */ | 63 | else /* Combined with next 'shutdown()'. */ |
64 | #endif /* HTTPS_SUPPORT */ | 64 | #endif /* HTTPS_SUPPORT */ |
65 | { | 65 | { |
66 | (void) shutdown (connection->socket_fd, | 66 | (void) shutdown (connection->socket_fd, |
67 | SHUT_WR); /* FIXME: log errors */ | 67 | SHUT_WR); /* FIXME: log errors */ |
68 | } | ||
69 | } | 68 | } |
69 | } | ||
70 | } | 70 | } |
71 | 71 | ||
72 | 72 | ||
@@ -90,14 +90,14 @@ MHD_connection_close_ (struct MHD_Connection *connection, | |||
90 | (void) rtc; // FIXME | 90 | (void) rtc; // FIXME |
91 | MHD_connection_mark_closed_ (connection); | 91 | MHD_connection_mark_closed_ (connection); |
92 | if (NULL != resp) | 92 | if (NULL != resp) |
93 | { | 93 | { |
94 | connection->request.response = NULL; | 94 | connection->request.response = NULL; |
95 | MHD_response_queue_for_destroy (resp); | 95 | MHD_response_queue_for_destroy (resp); |
96 | } | 96 | } |
97 | if (NULL != daemon->notify_connection_cb) | 97 | if (NULL != daemon->notify_connection_cb) |
98 | daemon->notify_connection_cb (daemon->notify_connection_cb_cls, | 98 | daemon->notify_connection_cb (daemon->notify_connection_cb_cls, |
99 | connection, | 99 | connection, |
100 | MHD_CONNECTION_NOTIFY_CLOSED); | 100 | MHD_CONNECTION_NOTIFY_CLOSED); |
101 | } | 101 | } |
102 | 102 | ||
103 | /* end of connection_close.c */ | 103 | /* end of connection_close.c */ |
diff --git a/src/lib/connection_close.h b/src/lib/connection_close.h index 41f141d2..c8e159ee 100644 --- a/src/lib/connection_close.h +++ b/src/lib/connection_close.h | |||
@@ -35,7 +35,7 @@ | |||
35 | */ | 35 | */ |
36 | void | 36 | void |
37 | MHD_connection_mark_closed_ (struct MHD_Connection *connection) | 37 | MHD_connection_mark_closed_ (struct MHD_Connection *connection) |
38 | MHD_NONNULL (1); | 38 | MHD_NONNULL (1); |
39 | 39 | ||
40 | 40 | ||
41 | /** | 41 | /** |
@@ -51,6 +51,6 @@ MHD_connection_mark_closed_ (struct MHD_Connection *connection) | |||
51 | void | 51 | void |
52 | MHD_connection_close_ (struct MHD_Connection *connection, | 52 | MHD_connection_close_ (struct MHD_Connection *connection, |
53 | enum MHD_RequestTerminationCode rtc) | 53 | enum MHD_RequestTerminationCode rtc) |
54 | MHD_NONNULL (1); | 54 | MHD_NONNULL (1); |
55 | 55 | ||
56 | #endif | 56 | #endif |
diff --git a/src/lib/connection_finish_forward.c b/src/lib/connection_finish_forward.c index 335a03bf..1ea9aa31 100644 --- a/src/lib/connection_finish_forward.c +++ b/src/lib/connection_finish_forward.c | |||
@@ -55,34 +55,34 @@ MHD_connection_finish_forward_ (struct MHD_Connection *connection) | |||
55 | EPOLL_CTL_DEL, | 55 | EPOLL_CTL_DEL, |
56 | connection->socket_fd, | 56 | connection->socket_fd, |
57 | NULL)) ) | 57 | NULL)) ) |
58 | { | 58 | { |
59 | MHD_PANIC (_("Failed to remove FD from epoll set\n")); | 59 | MHD_PANIC (_ ("Failed to remove FD from epoll set\n")); |
60 | } | 60 | } |
61 | if (urh->in_eready_list) | 61 | if (urh->in_eready_list) |
62 | { | 62 | { |
63 | EDLL_remove (daemon->eready_urh_head, | 63 | EDLL_remove (daemon->eready_urh_head, |
64 | daemon->eready_urh_tail, | 64 | daemon->eready_urh_tail, |
65 | urh); | 65 | urh); |
66 | urh->in_eready_list = false; | 66 | urh->in_eready_list = false; |
67 | } | 67 | } |
68 | #endif /* EPOLL_SUPPORT */ | 68 | #endif /* EPOLL_SUPPORT */ |
69 | if (MHD_INVALID_SOCKET != urh->mhd.socket) | 69 | if (MHD_INVALID_SOCKET != urh->mhd.socket) |
70 | { | 70 | { |
71 | #if EPOLL_SUPPORT | 71 | #if EPOLL_SUPPORT |
72 | if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) && | 72 | if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) && |
73 | (0 != epoll_ctl (daemon->epoll_upgrade_fd, | 73 | (0 != epoll_ctl (daemon->epoll_upgrade_fd, |
74 | EPOLL_CTL_DEL, | 74 | EPOLL_CTL_DEL, |
75 | urh->mhd.socket, | 75 | urh->mhd.socket, |
76 | NULL)) ) | 76 | NULL)) ) |
77 | { | 77 | { |
78 | MHD_PANIC (_("Failed to remove FD from epoll set\n")); | 78 | MHD_PANIC (_ ("Failed to remove FD from epoll set\n")); |
79 | } | ||
80 | #endif /* EPOLL_SUPPORT */ | ||
81 | /* Reflect remote disconnect to application by breaking | ||
82 | * socketpair connection. */ | ||
83 | shutdown (urh->mhd.socket, | ||
84 | SHUT_RDWR); | ||
85 | } | 79 | } |
80 | #endif /* EPOLL_SUPPORT */ | ||
81 | /* Reflect remote disconnect to application by breaking | ||
82 | * socketpair connection. */ | ||
83 | shutdown (urh->mhd.socket, | ||
84 | SHUT_RDWR); | ||
85 | } | ||
86 | /* Socketpair sockets will remain open as they will be | 86 | /* Socketpair sockets will remain open as they will be |
87 | * used with MHD_UPGRADE_ACTION_CLOSE. They will be | 87 | * used with MHD_UPGRADE_ACTION_CLOSE. They will be |
88 | * closed by MHD_cleanup_upgraded_connection_() during | 88 | * closed by MHD_cleanup_upgraded_connection_() during |
diff --git a/src/lib/connection_finish_forward.h b/src/lib/connection_finish_forward.h index c6c04f42..ebb77d12 100644 --- a/src/lib/connection_finish_forward.h +++ b/src/lib/connection_finish_forward.h | |||
@@ -39,6 +39,6 @@ | |||
39 | */ | 39 | */ |
40 | void | 40 | void |
41 | MHD_connection_finish_forward_ (struct MHD_Connection *connection) | 41 | MHD_connection_finish_forward_ (struct MHD_Connection *connection) |
42 | MHD_NONNULL (1); | 42 | MHD_NONNULL (1); |
43 | 43 | ||
44 | #endif | 44 | #endif |
diff --git a/src/lib/connection_info.c b/src/lib/connection_info.c index 88055fa4..d83b34c5 100644 --- a/src/lib/connection_info.c +++ b/src/lib/connection_info.c | |||
@@ -42,13 +42,13 @@ | |||
42 | */ | 42 | */ |
43 | enum MHD_Bool | 43 | enum MHD_Bool |
44 | MHD_connection_get_information_sz (struct MHD_Connection *connection, | 44 | MHD_connection_get_information_sz (struct MHD_Connection *connection, |
45 | enum MHD_ConnectionInformationType info_type, | 45 | enum MHD_ConnectionInformationType info_type, |
46 | union MHD_ConnectionInformation *return_value, | 46 | union MHD_ConnectionInformation *return_value, |
47 | size_t return_value_size) | 47 | size_t return_value_size) |
48 | { | 48 | { |
49 | #define CHECK_SIZE(type) if (sizeof(type) < return_value_size) \ | 49 | #define CHECK_SIZE(type) if (sizeof(type) < return_value_size) \ |
50 | return MHD_NO | 50 | return MHD_NO |
51 | 51 | ||
52 | switch (info_type) | 52 | switch (info_type) |
53 | { | 53 | { |
54 | #ifdef HTTPS_SUPPORT | 54 | #ifdef HTTPS_SUPPORT |
@@ -63,7 +63,7 @@ MHD_connection_get_information_sz (struct MHD_Connection *connection, | |||
63 | CHECK_SIZE (int); | 63 | CHECK_SIZE (int); |
64 | if (NULL == connection->tls_cs) | 64 | if (NULL == connection->tls_cs) |
65 | return MHD_NO; | 65 | return MHD_NO; |
66 | //return_value->protocol | 66 | // return_value->protocol |
67 | // = gnutls_protocol_get_version (connection->tls_session); | 67 | // = gnutls_protocol_get_version (connection->tls_session); |
68 | return MHD_NO; // FIXME: to be implemented | 68 | return MHD_NO; // FIXME: to be implemented |
69 | case MHD_CONNECTION_INFORMATION_GNUTLS_SESSION: | 69 | case MHD_CONNECTION_INFORMATION_GNUTLS_SESSION: |
@@ -103,7 +103,7 @@ MHD_connection_get_information_sz (struct MHD_Connection *connection, | |||
103 | default: | 103 | default: |
104 | return MHD_NO; | 104 | return MHD_NO; |
105 | } | 105 | } |
106 | 106 | ||
107 | #undef CHECK_SIZE | 107 | #undef CHECK_SIZE |
108 | } | 108 | } |
109 | 109 | ||
diff --git a/src/lib/connection_options.c b/src/lib/connection_options.c index 00652161..ce31b315 100644 --- a/src/lib/connection_options.c +++ b/src/lib/connection_options.c | |||
@@ -35,44 +35,44 @@ | |||
35 | */ | 35 | */ |
36 | void | 36 | void |
37 | MHD_connection_set_timeout (struct MHD_Connection *connection, | 37 | MHD_connection_set_timeout (struct MHD_Connection *connection, |
38 | unsigned int timeout_s) | 38 | unsigned int timeout_s) |
39 | { | 39 | { |
40 | struct MHD_Daemon *daemon = connection->daemon; | 40 | struct MHD_Daemon *daemon = connection->daemon; |
41 | 41 | ||
42 | connection->last_activity = MHD_monotonic_sec_counter(); | 42 | connection->last_activity = MHD_monotonic_sec_counter (); |
43 | if (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode) | 43 | if (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode) |
44 | { | 44 | { |
45 | /* Simple case, no need to lock to update DLLs */ | 45 | /* Simple case, no need to lock to update DLLs */ |
46 | connection->connection_timeout = (time_t) timeout_s; | 46 | connection->connection_timeout = (time_t) timeout_s; |
47 | return; | 47 | return; |
48 | } | 48 | } |
49 | 49 | ||
50 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); | 50 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); |
51 | if (! connection->suspended) | 51 | if (! connection->suspended) |
52 | { | 52 | { |
53 | if (connection->connection_timeout == | 53 | if (connection->connection_timeout == |
54 | daemon->connection_default_timeout) | 54 | daemon->connection_default_timeout) |
55 | XDLL_remove (daemon->normal_timeout_head, | 55 | XDLL_remove (daemon->normal_timeout_head, |
56 | daemon->normal_timeout_tail, | 56 | daemon->normal_timeout_tail, |
57 | connection); | 57 | connection); |
58 | else | 58 | else |
59 | XDLL_remove (daemon->manual_timeout_head, | 59 | XDLL_remove (daemon->manual_timeout_head, |
60 | daemon->manual_timeout_tail, | 60 | daemon->manual_timeout_tail, |
61 | connection); | 61 | connection); |
62 | } | 62 | } |
63 | connection->connection_timeout = (time_t) timeout_s; | 63 | connection->connection_timeout = (time_t) timeout_s; |
64 | if (! connection->suspended) | 64 | if (! connection->suspended) |
65 | { | 65 | { |
66 | if (connection->connection_timeout == | 66 | if (connection->connection_timeout == |
67 | daemon->connection_default_timeout) | 67 | daemon->connection_default_timeout) |
68 | XDLL_insert (daemon->normal_timeout_head, | 68 | XDLL_insert (daemon->normal_timeout_head, |
69 | daemon->normal_timeout_tail, | 69 | daemon->normal_timeout_tail, |
70 | connection); | 70 | connection); |
71 | else | 71 | else |
72 | XDLL_insert (daemon->manual_timeout_head, | 72 | XDLL_insert (daemon->manual_timeout_head, |
73 | daemon->manual_timeout_tail, | 73 | daemon->manual_timeout_tail, |
74 | connection); | 74 | connection); |
75 | } | 75 | } |
76 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); | 76 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); |
77 | } | 77 | } |
78 | 78 | ||
@@ -95,7 +95,7 @@ MHD_update_last_activity_ (struct MHD_Connection *connection) | |||
95 | if (connection->suspended) | 95 | if (connection->suspended) |
96 | return; /* no activity on suspended connections */ | 96 | return; /* no activity on suspended connections */ |
97 | 97 | ||
98 | connection->last_activity = MHD_monotonic_sec_counter(); | 98 | connection->last_activity = MHD_monotonic_sec_counter (); |
99 | if (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode) | 99 | if (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode) |
100 | return; /* each connection has personal timeout */ | 100 | return; /* each connection has personal timeout */ |
101 | 101 | ||
@@ -106,11 +106,11 @@ MHD_update_last_activity_ (struct MHD_Connection *connection) | |||
106 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); | 106 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); |
107 | /* move connection to head of timeout list (by remove + add operation) */ | 107 | /* move connection to head of timeout list (by remove + add operation) */ |
108 | XDLL_remove (daemon->normal_timeout_head, | 108 | XDLL_remove (daemon->normal_timeout_head, |
109 | daemon->normal_timeout_tail, | 109 | daemon->normal_timeout_tail, |
110 | connection); | 110 | connection); |
111 | XDLL_insert (daemon->normal_timeout_head, | 111 | XDLL_insert (daemon->normal_timeout_head, |
112 | daemon->normal_timeout_tail, | 112 | daemon->normal_timeout_tail, |
113 | connection); | 113 | connection); |
114 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); | 114 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); |
115 | } | 115 | } |
116 | 116 | ||
diff --git a/src/lib/connection_update_last_activity.c b/src/lib/connection_update_last_activity.c index 7253dc83..741da681 100644 --- a/src/lib/connection_update_last_activity.c +++ b/src/lib/connection_update_last_activity.c | |||
@@ -43,7 +43,7 @@ MHD_connection_update_last_activity_ (struct MHD_Connection *connection) | |||
43 | if (connection->suspended) | 43 | if (connection->suspended) |
44 | return; /* no activity on suspended connections */ | 44 | return; /* no activity on suspended connections */ |
45 | 45 | ||
46 | connection->last_activity = MHD_monotonic_sec_counter(); | 46 | connection->last_activity = MHD_monotonic_sec_counter (); |
47 | if (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode) | 47 | if (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode) |
48 | return; /* each connection has personal timeout */ | 48 | return; /* each connection has personal timeout */ |
49 | 49 | ||
@@ -53,13 +53,12 @@ MHD_connection_update_last_activity_ (struct MHD_Connection *connection) | |||
53 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); | 53 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); |
54 | /* move connection to head of timeout list (by remove + add operation) */ | 54 | /* move connection to head of timeout list (by remove + add operation) */ |
55 | XDLL_remove (daemon->normal_timeout_head, | 55 | XDLL_remove (daemon->normal_timeout_head, |
56 | daemon->normal_timeout_tail, | 56 | daemon->normal_timeout_tail, |
57 | connection); | 57 | connection); |
58 | XDLL_insert (daemon->normal_timeout_head, | 58 | XDLL_insert (daemon->normal_timeout_head, |
59 | daemon->normal_timeout_tail, | 59 | daemon->normal_timeout_tail, |
60 | connection); | 60 | connection); |
61 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); | 61 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); |
62 | } | 62 | } |
63 | 63 | ||
64 | /* end of connection_update_last_activity.c */ | 64 | /* end of connection_update_last_activity.c */ |
65 | |||
diff --git a/src/lib/connection_update_last_activity.h b/src/lib/connection_update_last_activity.h index 8383b6be..ee9f9975 100644 --- a/src/lib/connection_update_last_activity.h +++ b/src/lib/connection_update_last_activity.h | |||
@@ -35,6 +35,6 @@ | |||
35 | */ | 35 | */ |
36 | void | 36 | void |
37 | MHD_connection_update_last_activity_ (struct MHD_Connection *connection) | 37 | MHD_connection_update_last_activity_ (struct MHD_Connection *connection) |
38 | MHD_NONNULL (1); | 38 | MHD_NONNULL (1); |
39 | 39 | ||
40 | #endif | 40 | #endif |
diff --git a/src/lib/daemon_close_all_connections.c b/src/lib/daemon_close_all_connections.c index d4b825da..1a777494 100644 --- a/src/lib/daemon_close_all_connections.c +++ b/src/lib/daemon_close_all_connections.c | |||
@@ -45,10 +45,10 @@ close_connection (struct MHD_Connection *pos) | |||
45 | struct MHD_Daemon *daemon = pos->daemon; | 45 | struct MHD_Daemon *daemon = pos->daemon; |
46 | 46 | ||
47 | if (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode) | 47 | if (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode) |
48 | { | 48 | { |
49 | MHD_connection_mark_closed_ (pos); | 49 | MHD_connection_mark_closed_ (pos); |
50 | return; /* must let thread to do the rest */ | 50 | return; /* must let thread to do the rest */ |
51 | } | 51 | } |
52 | MHD_connection_close_ (pos, | 52 | MHD_connection_close_ (pos, |
53 | MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN); | 53 | MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN); |
54 | 54 | ||
@@ -59,18 +59,18 @@ close_connection (struct MHD_Connection *pos) | |||
59 | if (pos->connection_timeout == | 59 | if (pos->connection_timeout == |
60 | pos->daemon->connection_default_timeout) | 60 | pos->daemon->connection_default_timeout) |
61 | XDLL_remove (daemon->normal_timeout_head, | 61 | XDLL_remove (daemon->normal_timeout_head, |
62 | daemon->normal_timeout_tail, | 62 | daemon->normal_timeout_tail, |
63 | pos); | 63 | pos); |
64 | else | 64 | else |
65 | XDLL_remove (daemon->manual_timeout_head, | 65 | XDLL_remove (daemon->manual_timeout_head, |
66 | daemon->manual_timeout_tail, | 66 | daemon->manual_timeout_tail, |
67 | pos); | 67 | pos); |
68 | DLL_remove (daemon->connections_head, | 68 | DLL_remove (daemon->connections_head, |
69 | daemon->connections_tail, | 69 | daemon->connections_tail, |
70 | pos); | 70 | pos); |
71 | DLL_insert (daemon->cleanup_head, | 71 | DLL_insert (daemon->cleanup_head, |
72 | daemon->cleanup_tail, | 72 | daemon->cleanup_tail, |
73 | pos); | 73 | pos); |
74 | 74 | ||
75 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); | 75 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); |
76 | } | 76 | } |
@@ -89,7 +89,8 @@ void | |||
89 | MHD_daemon_close_all_connections_ (struct MHD_Daemon *daemon) | 89 | MHD_daemon_close_all_connections_ (struct MHD_Daemon *daemon) |
90 | { | 90 | { |
91 | struct MHD_Connection *pos; | 91 | struct MHD_Connection *pos; |
92 | const bool used_thr_p_c = (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode); | 92 | const bool used_thr_p_c = (MHD_TM_THREAD_PER_CONNECTION == |
93 | daemon->threading_mode); | ||
93 | #ifdef UPGRADE_SUPPORT | 94 | #ifdef UPGRADE_SUPPORT |
94 | const bool upg_allowed = (! daemon->disallow_upgrade); | 95 | const bool upg_allowed = (! daemon->disallow_upgrade); |
95 | #endif /* UPGRADE_SUPPORT */ | 96 | #endif /* UPGRADE_SUPPORT */ |
@@ -103,16 +104,16 @@ MHD_daemon_close_all_connections_ (struct MHD_Daemon *daemon) | |||
103 | /* give upgraded HTTPS connections a chance to finish */ | 104 | /* give upgraded HTTPS connections a chance to finish */ |
104 | /* 'daemon->urh_head' is not used in thread-per-connection mode. */ | 105 | /* 'daemon->urh_head' is not used in thread-per-connection mode. */ |
105 | for (urh = daemon->urh_tail; NULL != urh; urh = urhn) | 106 | for (urh = daemon->urh_tail; NULL != urh; urh = urhn) |
106 | { | 107 | { |
107 | urhn = urh->prev; | 108 | urhn = urh->prev; |
108 | /* call generic forwarding function for passing data | 109 | /* call generic forwarding function for passing data |
109 | with chance to detect that application is done. */ | 110 | with chance to detect that application is done. */ |
110 | MHD_upgrade_response_handle_process_ (urh); | 111 | MHD_upgrade_response_handle_process_ (urh); |
111 | MHD_connection_finish_forward_ (urh->connection); | 112 | MHD_connection_finish_forward_ (urh->connection); |
112 | urh->clean_ready = true; | 113 | urh->clean_ready = true; |
113 | /* Resuming will move connection to cleanup list. */ | 114 | /* Resuming will move connection to cleanup list. */ |
114 | MHD_request_resume (&urh->connection->request); | 115 | MHD_request_resume (&urh->connection->request); |
115 | } | 116 | } |
116 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ | 117 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ |
117 | 118 | ||
118 | /* Give suspended connections a chance to resume to avoid | 119 | /* Give suspended connections a chance to resume to avoid |
@@ -120,89 +121,93 @@ MHD_daemon_close_all_connections_ (struct MHD_Daemon *daemon) | |||
120 | connections left in case of a tight race with a recently | 121 | connections left in case of a tight race with a recently |
121 | resumed connection. */ | 122 | resumed connection. */ |
122 | if (! daemon->disallow_suspend_resume) | 123 | if (! daemon->disallow_suspend_resume) |
123 | { | 124 | { |
124 | daemon->resuming = true; /* Force check for pending resume. */ | 125 | daemon->resuming = true; /* Force check for pending resume. */ |
125 | MHD_resume_suspended_connections_ (daemon); | 126 | MHD_resume_suspended_connections_ (daemon); |
126 | } | 127 | } |
127 | /* first, make sure all threads are aware of shutdown; need to | 128 | /* first, make sure all threads are aware of shutdown; need to |
128 | traverse DLLs in peace... */ | 129 | traverse DLLs in peace... */ |
129 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); | 130 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); |
130 | #ifdef UPGRADE_SUPPORT | 131 | #ifdef UPGRADE_SUPPORT |
131 | if (upg_allowed) | 132 | if (upg_allowed) |
132 | { | 133 | { |
133 | struct MHD_Connection * susp; | 134 | struct MHD_Connection *susp; |
134 | 135 | ||
135 | susp = daemon->suspended_connections_tail; | 136 | susp = daemon->suspended_connections_tail; |
136 | while (NULL != susp) | 137 | while (NULL != susp) |
137 | { | 138 | { |
138 | if (NULL == susp->request.urh) /* "Upgraded" connection? */ | 139 | if (NULL == susp->request.urh) /* "Upgraded" connection? */ |
139 | MHD_PANIC (_("MHD_stop_daemon() called while we have suspended connections.\n")); | 140 | MHD_PANIC (_ ( |
141 | "MHD_stop_daemon() called while we have suspended connections.\n")); | ||
140 | #ifdef HTTPS_SUPPORT | 142 | #ifdef HTTPS_SUPPORT |
141 | else if (used_tls && | 143 | else if (used_tls && |
142 | used_thr_p_c && | 144 | used_thr_p_c && |
143 | (! susp->request.urh->clean_ready) ) | 145 | (! susp->request.urh->clean_ready) ) |
144 | shutdown (susp->request.urh->app.socket, | 146 | shutdown (susp->request.urh->app.socket, |
145 | SHUT_RDWR); /* Wake thread by shutdown of app socket. */ | 147 | SHUT_RDWR); /* Wake thread by shutdown of app socket. */ |
146 | #endif /* HTTPS_SUPPORT */ | 148 | #endif /* HTTPS_SUPPORT */ |
147 | else | 149 | else |
148 | { | 150 | { |
149 | #ifdef HAVE_MESSAGES | 151 | #ifdef HAVE_MESSAGES |
150 | if (! susp->request.urh->was_closed) | 152 | if (! susp->request.urh->was_closed) |
151 | MHD_DLOG (daemon, | 153 | MHD_DLOG (daemon, |
152 | MHD_SC_SHUTDOWN_WITH_OPEN_UPGRADED_CONNECTION, | 154 | MHD_SC_SHUTDOWN_WITH_OPEN_UPGRADED_CONNECTION, |
153 | _("Initiated daemon shutdown while \"upgraded\" connection was not closed.\n")); | 155 | _ ( |
156 | "Initiated daemon shutdown while \"upgraded\" connection was not closed.\n")); | ||
154 | #endif | 157 | #endif |
155 | susp->request.urh->was_closed = true; | 158 | susp->request.urh->was_closed = true; |
156 | /* If thread-per-connection is used, connection's thread | 159 | /* If thread-per-connection is used, connection's thread |
157 | * may still processing "upgrade" (exiting). */ | 160 | * may still processing "upgrade" (exiting). */ |
158 | if (! used_thr_p_c) | 161 | if (! used_thr_p_c) |
159 | MHD_connection_finish_forward_ (susp); | 162 | MHD_connection_finish_forward_ (susp); |
160 | /* Do not use MHD_resume_connection() as mutex is | 163 | /* Do not use MHD_resume_connection() as mutex is |
161 | * already locked. */ | 164 | * already locked. */ |
162 | susp->resuming = true; | 165 | susp->resuming = true; |
163 | daemon->resuming = true; | 166 | daemon->resuming = true; |
164 | } | 167 | } |
165 | susp = susp->prev; | 168 | susp = susp->prev; |
166 | } | ||
167 | } | 169 | } |
170 | } | ||
168 | else /* This 'else' is combined with next 'if' */ | 171 | else /* This 'else' is combined with next 'if' */ |
169 | #endif /* UPGRADE_SUPPORT */ | 172 | #endif /* UPGRADE_SUPPORT */ |
170 | if (NULL != daemon->suspended_connections_head) | 173 | if (NULL != daemon->suspended_connections_head) |
171 | MHD_PANIC (_("MHD_stop_daemon() called while we have suspended connections.\n")); | 174 | MHD_PANIC (_ ( |
175 | "MHD_stop_daemon() called while we have suspended connections.\n")); | ||
172 | for (pos = daemon->connections_tail; NULL != pos; pos = pos->prev) | 176 | for (pos = daemon->connections_tail; NULL != pos; pos = pos->prev) |
173 | { | 177 | { |
174 | shutdown (pos->socket_fd, | 178 | shutdown (pos->socket_fd, |
175 | SHUT_RDWR); | 179 | SHUT_RDWR); |
176 | #if MHD_WINSOCK_SOCKETS | 180 | #if MHD_WINSOCK_SOCKETS |
177 | if ( (used_thr_p_c) && | 181 | if ( (used_thr_p_c) && |
178 | (MHD_ITC_IS_VALID_(daemon->itc)) && | 182 | (MHD_ITC_IS_VALID_ (daemon->itc)) && |
179 | (! MHD_itc_activate_ (daemon->itc, | 183 | (! MHD_itc_activate_ (daemon->itc, |
180 | "e")) ) | 184 | "e")) ) |
181 | MHD_PANIC (_("Failed to signal shutdown via inter-thread communication channel")); | 185 | MHD_PANIC (_ ( |
186 | "Failed to signal shutdown via inter-thread communication channel")); | ||
182 | #endif | 187 | #endif |
183 | } | 188 | } |
184 | 189 | ||
185 | /* now, collect per-connection threads */ | 190 | /* now, collect per-connection threads */ |
186 | if (used_thr_p_c) | 191 | if (used_thr_p_c) |
192 | { | ||
193 | pos = daemon->connections_tail; | ||
194 | while (NULL != pos) | ||
187 | { | 195 | { |
188 | pos = daemon->connections_tail; | 196 | if (! pos->thread_joined) |
189 | while (NULL != pos) | ||
190 | { | 197 | { |
191 | if (! pos->thread_joined) | 198 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); |
192 | { | 199 | if (! MHD_join_thread_ (pos->pid.handle)) |
193 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); | 200 | MHD_PANIC (_ ("Failed to join a thread\n")); |
194 | if (! MHD_join_thread_ (pos->pid.handle)) | 201 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); |
195 | MHD_PANIC (_("Failed to join a thread\n")); | 202 | pos->thread_joined = true; |
196 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); | 203 | /* The thread may have concurrently modified the DLL, |
197 | pos->thread_joined = true; | 204 | need to restart from the beginning */ |
198 | /* The thread may have concurrently modified the DLL, | 205 | pos = daemon->connections_tail; |
199 | need to restart from the beginning */ | 206 | continue; |
200 | pos = daemon->connections_tail; | ||
201 | continue; | ||
202 | } | ||
203 | pos = pos->prev; | ||
204 | } | 207 | } |
208 | pos = pos->prev; | ||
205 | } | 209 | } |
210 | } | ||
206 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); | 211 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); |
207 | 212 | ||
208 | #ifdef UPGRADE_SUPPORT | 213 | #ifdef UPGRADE_SUPPORT |
@@ -211,10 +216,10 @@ MHD_daemon_close_all_connections_ (struct MHD_Daemon *daemon) | |||
211 | /* "Upgraded" connections that were not closed explicitly by | 216 | /* "Upgraded" connections that were not closed explicitly by |
212 | * application should be moved to cleanup list too. */ | 217 | * application should be moved to cleanup list too. */ |
213 | if (upg_allowed) | 218 | if (upg_allowed) |
214 | { | 219 | { |
215 | daemon->resuming = true; /* Force check for pending resume. */ | 220 | daemon->resuming = true; /* Force check for pending resume. */ |
216 | MHD_resume_suspended_connections_ (daemon); | 221 | MHD_resume_suspended_connections_ (daemon); |
217 | } | 222 | } |
218 | #endif /* UPGRADE_SUPPORT */ | 223 | #endif /* UPGRADE_SUPPORT */ |
219 | 224 | ||
220 | /* now that we're alone, move everyone to cleanup */ | 225 | /* now that we're alone, move everyone to cleanup */ |
@@ -222,7 +227,7 @@ MHD_daemon_close_all_connections_ (struct MHD_Daemon *daemon) | |||
222 | { | 227 | { |
223 | if ( (used_thr_p_c) && | 228 | if ( (used_thr_p_c) && |
224 | (! pos->thread_joined) ) | 229 | (! pos->thread_joined) ) |
225 | MHD_PANIC (_("Failed to join a thread\n")); | 230 | MHD_PANIC (_ ("Failed to join a thread\n")); |
226 | close_connection (pos); | 231 | close_connection (pos); |
227 | } | 232 | } |
228 | MHD_connection_cleanup_ (daemon); | 233 | MHD_connection_cleanup_ (daemon); |
diff --git a/src/lib/daemon_close_all_connections.h b/src/lib/daemon_close_all_connections.h index 340b0d47..2716f9ba 100644 --- a/src/lib/daemon_close_all_connections.h +++ b/src/lib/daemon_close_all_connections.h | |||
@@ -37,6 +37,6 @@ | |||
37 | */ | 37 | */ |
38 | void | 38 | void |
39 | MHD_daemon_close_all_connections_ (struct MHD_Daemon *daemon) | 39 | MHD_daemon_close_all_connections_ (struct MHD_Daemon *daemon) |
40 | MHD_NONNULL (1); | 40 | MHD_NONNULL (1); |
41 | 41 | ||
42 | #endif | 42 | #endif |
diff --git a/src/lib/daemon_create.c b/src/lib/daemon_create.c index a2173d88..cd3d0ec4 100644 --- a/src/lib/daemon_create.c +++ b/src/lib/daemon_create.c | |||
@@ -38,16 +38,16 @@ | |||
38 | */ | 38 | */ |
39 | static void | 39 | static void |
40 | file_logger (void *cls, | 40 | file_logger (void *cls, |
41 | enum MHD_StatusCode sc, | 41 | enum MHD_StatusCode sc, |
42 | const char *fm, | 42 | const char *fm, |
43 | va_list ap) | 43 | va_list ap) |
44 | { | 44 | { |
45 | FILE *f = cls; | 45 | FILE *f = cls; |
46 | 46 | ||
47 | (void) sc; | 47 | (void) sc; |
48 | (void) vfprintf (f, | 48 | (void) vfprintf (f, |
49 | fm, | 49 | fm, |
50 | ap); | 50 | ap); |
51 | } | 51 | } |
52 | 52 | ||
53 | 53 | ||
@@ -84,16 +84,16 @@ unescape_wrapper (void *cls, | |||
84 | */ | 84 | */ |
85 | struct MHD_Daemon * | 85 | struct MHD_Daemon * |
86 | MHD_daemon_create (MHD_RequestCallback cb, | 86 | MHD_daemon_create (MHD_RequestCallback cb, |
87 | void *cb_cls) | 87 | void *cb_cls) |
88 | { | 88 | { |
89 | struct MHD_Daemon *daemon; | 89 | struct MHD_Daemon *daemon; |
90 | 90 | ||
91 | MHD_check_global_init_(); | 91 | MHD_check_global_init_ (); |
92 | if (NULL == (daemon = malloc (sizeof (struct MHD_Daemon)))) | 92 | if (NULL == (daemon = malloc (sizeof (struct MHD_Daemon)))) |
93 | return NULL; | 93 | return NULL; |
94 | memset (daemon, | 94 | memset (daemon, |
95 | 0, | 95 | 0, |
96 | sizeof (struct MHD_Daemon)); | 96 | sizeof (struct MHD_Daemon)); |
97 | #ifdef EPOLL_SUPPORT | 97 | #ifdef EPOLL_SUPPORT |
98 | daemon->epoll_itc_marker = "itc_marker"; | 98 | daemon->epoll_itc_marker = "itc_marker"; |
99 | #endif | 99 | #endif |
@@ -107,29 +107,29 @@ MHD_daemon_create (MHD_RequestCallback cb, | |||
107 | #if ENABLE_DAUTH | 107 | #if ENABLE_DAUTH |
108 | daemon->digest_nc_length = DIGEST_NC_LENGTH_DEFAULT; | 108 | daemon->digest_nc_length = DIGEST_NC_LENGTH_DEFAULT; |
109 | #endif | 109 | #endif |
110 | daemon->listen_backlog = LISTEN_BACKLOG_DEFAULT; | 110 | daemon->listen_backlog = LISTEN_BACKLOG_DEFAULT; |
111 | daemon->fo_queue_length = FO_QUEUE_LENGTH_DEFAULT; | 111 | daemon->fo_queue_length = FO_QUEUE_LENGTH_DEFAULT; |
112 | daemon->listen_socket = MHD_INVALID_SOCKET; | 112 | daemon->listen_socket = MHD_INVALID_SOCKET; |
113 | 113 | ||
114 | if (! MHD_mutex_init_ (&daemon->cleanup_connection_mutex)) | 114 | if (! MHD_mutex_init_ (&daemon->cleanup_connection_mutex)) |
115 | { | 115 | { |
116 | free (daemon); | 116 | free (daemon); |
117 | return NULL; | 117 | return NULL; |
118 | } | 118 | } |
119 | if (! MHD_mutex_init_ (&daemon->per_ip_connection_mutex)) | 119 | if (! MHD_mutex_init_ (&daemon->per_ip_connection_mutex)) |
120 | { | 120 | { |
121 | (void) MHD_mutex_destroy_ (&daemon->cleanup_connection_mutex); | 121 | (void) MHD_mutex_destroy_ (&daemon->cleanup_connection_mutex); |
122 | free (daemon); | 122 | free (daemon); |
123 | return NULL; | 123 | return NULL; |
124 | } | 124 | } |
125 | #ifdef DAUTH_SUPPORT | 125 | #ifdef DAUTH_SUPPORT |
126 | if (! MHD_mutex_init_ (&daemon->nnc_lock)) | 126 | if (! MHD_mutex_init_ (&daemon->nnc_lock)) |
127 | { | 127 | { |
128 | (void) MHD_mutex_destroy_ (&daemon->cleanup_connection_mutex); | 128 | (void) MHD_mutex_destroy_ (&daemon->cleanup_connection_mutex); |
129 | (void) MHD_mutex_destroy_ (&daemon->per_ip_connection_mutex); | 129 | (void) MHD_mutex_destroy_ (&daemon->per_ip_connection_mutex); |
130 | free (daemon); | 130 | free (daemon); |
131 | return NULL; | 131 | return NULL; |
132 | } | 132 | } |
133 | #endif | 133 | #endif |
134 | return daemon; | 134 | return daemon; |
135 | } | 135 | } |
diff --git a/src/lib/daemon_destroy.c b/src/lib/daemon_destroy.c index b4f34d16..a76c2d6b 100644 --- a/src/lib/daemon_destroy.c +++ b/src/lib/daemon_destroy.c | |||
@@ -46,35 +46,36 @@ stop_workers (struct MHD_Daemon *daemon) | |||
46 | fd = daemon->listen_socket; | 46 | fd = daemon->listen_socket; |
47 | /* Let workers shutdown in parallel. */ | 47 | /* Let workers shutdown in parallel. */ |
48 | for (i = 0; i < daemon->worker_pool_size; i++) | 48 | for (i = 0; i < daemon->worker_pool_size; i++) |
49 | { | ||
50 | daemon->worker_pool[i].shutdown = true; | ||
51 | if (MHD_ITC_IS_VALID_ (daemon->worker_pool[i].itc)) | ||
49 | { | 52 | { |
50 | daemon->worker_pool[i].shutdown = true; | 53 | if (! MHD_itc_activate_ (daemon->worker_pool[i].itc, |
51 | if (MHD_ITC_IS_VALID_(daemon->worker_pool[i].itc)) | 54 | "e")) |
52 | { | 55 | MHD_PANIC (_ ( |
53 | if (! MHD_itc_activate_ (daemon->worker_pool[i].itc, | 56 | "Failed to signal shutdown via inter-thread communication channel.")); |
54 | "e")) | ||
55 | MHD_PANIC (_("Failed to signal shutdown via inter-thread communication channel.")); | ||
56 | } | ||
57 | else | ||
58 | { | ||
59 | /* Better hope shutdown() works... */ | ||
60 | mhd_assert (MHD_INVALID_SOCKET != fd); | ||
61 | } | ||
62 | } | 57 | } |
63 | #ifdef HAVE_LISTEN_SHUTDOWN | 58 | else |
64 | if (MHD_INVALID_SOCKET != fd) | ||
65 | { | 59 | { |
66 | (void) shutdown (fd, | 60 | /* Better hope shutdown() works... */ |
67 | SHUT_RDWR); | 61 | mhd_assert (MHD_INVALID_SOCKET != fd); |
68 | } | 62 | } |
63 | } | ||
64 | #ifdef HAVE_LISTEN_SHUTDOWN | ||
65 | if (MHD_INVALID_SOCKET != fd) | ||
66 | { | ||
67 | (void) shutdown (fd, | ||
68 | SHUT_RDWR); | ||
69 | } | ||
69 | #endif /* HAVE_LISTEN_SHUTDOWN */ | 70 | #endif /* HAVE_LISTEN_SHUTDOWN */ |
70 | for (i = 0; i < daemon->worker_pool_size; ++i) | 71 | for (i = 0; i < daemon->worker_pool_size; ++i) |
71 | { | 72 | { |
72 | MHD_daemon_destroy (&daemon->worker_pool[i]); | 73 | MHD_daemon_destroy (&daemon->worker_pool[i]); |
73 | } | 74 | } |
74 | free (daemon->worker_pool); | 75 | free (daemon->worker_pool); |
75 | daemon->worker_pool = NULL; | 76 | daemon->worker_pool = NULL; |
76 | /* FIXME: does this still hold? */ | 77 | /* FIXME: does this still hold? */ |
77 | mhd_assert (MHD_ITC_IS_INVALID_(daemon->itc)); | 78 | mhd_assert (MHD_ITC_IS_INVALID_ (daemon->itc)); |
78 | #ifdef EPOLL_SUPPORT | 79 | #ifdef EPOLL_SUPPORT |
79 | mhd_assert (-1 == daemon->epoll_fd); | 80 | mhd_assert (-1 == daemon->epoll_fd); |
80 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) | 81 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) |
@@ -104,65 +105,66 @@ MHD_daemon_destroy (struct MHD_Daemon *daemon) | |||
104 | /* FIXME: convert from here to microhttpd2-style API! */ | 105 | /* FIXME: convert from here to microhttpd2-style API! */ |
105 | 106 | ||
106 | if (NULL != daemon->worker_pool) | 107 | if (NULL != daemon->worker_pool) |
107 | { /* Master daemon with worker pool. */ | 108 | { /* Master daemon with worker pool. */ |
108 | stop_workers (daemon); | 109 | stop_workers (daemon); |
109 | } | 110 | } |
110 | else | 111 | else |
112 | { | ||
113 | mhd_assert (0 == daemon->worker_pool_size); | ||
114 | /* Worker daemon or single-thread daemon. */ | ||
115 | if (MHD_TM_EXTERNAL_EVENT_LOOP != daemon->threading_mode) | ||
111 | { | 116 | { |
112 | mhd_assert (0 == daemon->worker_pool_size); | 117 | /* Worker daemon or single daemon with internal thread(s). */ |
113 | /* Worker daemon or single-thread daemon. */ | 118 | /* Separate thread(s) is used for polling sockets. */ |
114 | if (MHD_TM_EXTERNAL_EVENT_LOOP != daemon->threading_mode) | 119 | if (MHD_ITC_IS_VALID_ (daemon->itc)) |
115 | { | 120 | { |
116 | /* Worker daemon or single daemon with internal thread(s). */ | 121 | if (! MHD_itc_activate_ (daemon->itc, |
117 | /* Separate thread(s) is used for polling sockets. */ | 122 | "e")) |
118 | if (MHD_ITC_IS_VALID_(daemon->itc)) | 123 | MHD_PANIC (_ ( |
119 | { | 124 | "Failed to signal shutdown via inter-thread communication channel")); |
120 | if (! MHD_itc_activate_ (daemon->itc, | 125 | } |
121 | "e")) | ||
122 | MHD_PANIC (_("Failed to signal shutdown via inter-thread communication channel")); | ||
123 | } | ||
124 | else | ||
125 | { | ||
126 | #ifdef HAVE_LISTEN_SHUTDOWN | ||
127 | if (MHD_INVALID_SOCKET != fd) | ||
128 | { | ||
129 | if (NULL == daemon->master) | ||
130 | (void) shutdown (fd, | ||
131 | SHUT_RDWR); | ||
132 | } | ||
133 | else | ||
134 | #endif /* HAVE_LISTEN_SHUTDOWN */ | ||
135 | mhd_assert (false); /* Should never happen */ | ||
136 | } | ||
137 | |||
138 | if (! MHD_join_thread_ (daemon->pid.handle)) | ||
139 | { | ||
140 | MHD_PANIC (_("Failed to join a thread\n")); | ||
141 | } | ||
142 | /* close_all_connections() was called in daemon thread. */ | ||
143 | } | ||
144 | else | 126 | else |
127 | { | ||
128 | #ifdef HAVE_LISTEN_SHUTDOWN | ||
129 | if (MHD_INVALID_SOCKET != fd) | ||
145 | { | 130 | { |
146 | /* No internal threads are used for polling sockets | 131 | if (NULL == daemon->master) |
147 | (external event loop) */ | 132 | (void) shutdown (fd, |
148 | MHD_daemon_close_all_connections_ (daemon); | 133 | SHUT_RDWR); |
149 | } | 134 | } |
150 | if (MHD_ITC_IS_VALID_ (daemon->itc)) | 135 | else |
151 | MHD_itc_destroy_chk_ (daemon->itc); | 136 | #endif /* HAVE_LISTEN_SHUTDOWN */ |
137 | mhd_assert (false); /* Should never happen */ | ||
138 | } | ||
139 | |||
140 | if (! MHD_join_thread_ (daemon->pid.handle)) | ||
141 | { | ||
142 | MHD_PANIC (_ ("Failed to join a thread\n")); | ||
143 | } | ||
144 | /* close_all_connections() was called in daemon thread. */ | ||
145 | } | ||
146 | else | ||
147 | { | ||
148 | /* No internal threads are used for polling sockets | ||
149 | (external event loop) */ | ||
150 | MHD_daemon_close_all_connections_ (daemon); | ||
151 | } | ||
152 | if (MHD_ITC_IS_VALID_ (daemon->itc)) | ||
153 | MHD_itc_destroy_chk_ (daemon->itc); | ||
152 | 154 | ||
153 | #ifdef EPOLL_SUPPORT | 155 | #ifdef EPOLL_SUPPORT |
154 | if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) && | 156 | if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) && |
155 | (-1 != daemon->epoll_fd) ) | 157 | (-1 != daemon->epoll_fd) ) |
156 | MHD_socket_close_chk_ (daemon->epoll_fd); | 158 | MHD_socket_close_chk_ (daemon->epoll_fd); |
157 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) | 159 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) |
158 | if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) && | 160 | if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) && |
159 | (-1 != daemon->epoll_upgrade_fd) ) | 161 | (-1 != daemon->epoll_upgrade_fd) ) |
160 | MHD_socket_close_chk_ (daemon->epoll_upgrade_fd); | 162 | MHD_socket_close_chk_ (daemon->epoll_upgrade_fd); |
161 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ | 163 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ |
162 | #endif /* EPOLL_SUPPORT */ | 164 | #endif /* EPOLL_SUPPORT */ |
163 | 165 | ||
164 | MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex); | 166 | MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex); |
165 | } | 167 | } |
166 | 168 | ||
167 | if (NULL != daemon->master) | 169 | if (NULL != daemon->master) |
168 | return; | 170 | return; |
@@ -175,18 +177,18 @@ MHD_daemon_destroy (struct MHD_Daemon *daemon) | |||
175 | /* TLS clean up */ | 177 | /* TLS clean up */ |
176 | #ifdef HTTPS_SUPPORT | 178 | #ifdef HTTPS_SUPPORT |
177 | if (NULL != daemon->tls_api) | 179 | if (NULL != daemon->tls_api) |
178 | { | 180 | { |
179 | #if FIXME_TLS_API | 181 | #if FIXME_TLS_API |
180 | if (daemon->have_dhparams) | 182 | if (daemon->have_dhparams) |
181 | { | 183 | { |
182 | gnutls_dh_params_deinit (daemon->https_mem_dhparams); | 184 | gnutls_dh_params_deinit (daemon->https_mem_dhparams); |
183 | daemon->have_dhparams = false; | 185 | daemon->have_dhparams = false; |
184 | } | ||
185 | gnutls_priority_deinit (daemon->priority_cache); | ||
186 | if (daemon->x509_cred) | ||
187 | gnutls_certificate_free_credentials (daemon->x509_cred); | ||
188 | #endif | ||
189 | } | 186 | } |
187 | gnutls_priority_deinit (daemon->priority_cache); | ||
188 | if (daemon->x509_cred) | ||
189 | gnutls_certificate_free_credentials (daemon->x509_cred); | ||
190 | #endif | ||
191 | } | ||
190 | #endif /* HTTPS_SUPPORT */ | 192 | #endif /* HTTPS_SUPPORT */ |
191 | 193 | ||
192 | #ifdef DAUTH_SUPPORT | 194 | #ifdef DAUTH_SUPPORT |
diff --git a/src/lib/daemon_epoll.c b/src/lib/daemon_epoll.c index 4bed148f..b25ba9a7 100644 --- a/src/lib/daemon_epoll.c +++ b/src/lib/daemon_epoll.c | |||
@@ -53,9 +53,9 @@ | |||
53 | * 'false' otherwise | 53 | * 'false' otherwise |
54 | */ | 54 | */ |
55 | static bool | 55 | static bool |
56 | is_urh_ready (struct MHD_UpgradeResponseHandle * const urh) | 56 | is_urh_ready (struct MHD_UpgradeResponseHandle *const urh) |
57 | { | 57 | { |
58 | const struct MHD_Connection * const connection = urh->connection; | 58 | const struct MHD_Connection *const connection = urh->connection; |
59 | 59 | ||
60 | if ( (0 == urh->in_buffer_size) && | 60 | if ( (0 == urh->in_buffer_size) && |
61 | (0 == urh->out_buffer_size) && | 61 | (0 == urh->out_buffer_size) && |
@@ -80,7 +80,7 @@ is_urh_ready (struct MHD_UpgradeResponseHandle * const urh) | |||
80 | return true; | 80 | return true; |
81 | 81 | ||
82 | if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->mhd.celi)) && | 82 | if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->mhd.celi)) && |
83 | (urh->in_buffer_used > 0) ) | 83 | (urh->in_buffer_used > 0) ) |
84 | return true; | 84 | return true; |
85 | 85 | ||
86 | return false; | 86 | return false; |
@@ -103,99 +103,99 @@ run_epoll_for_upgrade (struct MHD_Daemon *daemon) | |||
103 | { | 103 | { |
104 | struct epoll_event events[MAX_EVENTS]; | 104 | struct epoll_event events[MAX_EVENTS]; |
105 | int num_events; | 105 | int num_events; |
106 | struct MHD_UpgradeResponseHandle * pos; | 106 | struct MHD_UpgradeResponseHandle *pos; |
107 | struct MHD_UpgradeResponseHandle * prev; | 107 | struct MHD_UpgradeResponseHandle *prev; |
108 | 108 | ||
109 | num_events = MAX_EVENTS; | 109 | num_events = MAX_EVENTS; |
110 | while (MAX_EVENTS == num_events) | 110 | while (MAX_EVENTS == num_events) |
111 | { | ||
112 | unsigned int i; | ||
113 | |||
114 | /* update event masks */ | ||
115 | num_events = epoll_wait (daemon->epoll_upgrade_fd, | ||
116 | events, | ||
117 | MAX_EVENTS, | ||
118 | 0); | ||
119 | if (-1 == num_events) | ||
111 | { | 120 | { |
112 | unsigned int i; | 121 | const int err = MHD_socket_get_error_ (); |
113 | 122 | if (MHD_SCKT_ERR_IS_EINTR_ (err)) | |
114 | /* update event masks */ | 123 | return MHD_SC_OK; |
115 | num_events = epoll_wait (daemon->epoll_upgrade_fd, | ||
116 | events, | ||
117 | MAX_EVENTS, | ||
118 | 0); | ||
119 | if (-1 == num_events) | ||
120 | { | ||
121 | const int err = MHD_socket_get_error_ (); | ||
122 | if (MHD_SCKT_ERR_IS_EINTR_ (err)) | ||
123 | return MHD_SC_OK; | ||
124 | #ifdef HAVE_MESSAGES | 124 | #ifdef HAVE_MESSAGES |
125 | MHD_DLOG (daemon, | 125 | MHD_DLOG (daemon, |
126 | MHD_SC_UNEXPECTED_EPOLL_WAIT_ERROR, | 126 | MHD_SC_UNEXPECTED_EPOLL_WAIT_ERROR, |
127 | _("Call to epoll_wait failed: %s\n"), | 127 | _ ("Call to epoll_wait failed: %s\n"), |
128 | MHD_socket_strerr_ (err)); | 128 | MHD_socket_strerr_ (err)); |
129 | #endif | 129 | #endif |
130 | return MHD_SC_UNEXPECTED_EPOLL_WAIT_ERROR; | 130 | return MHD_SC_UNEXPECTED_EPOLL_WAIT_ERROR; |
131 | } | 131 | } |
132 | for (i = 0; i < (unsigned int) num_events; i++) | 132 | for (i = 0; i < (unsigned int) num_events; i++) |
133 | { | 133 | { |
134 | struct UpgradeEpollHandle * const ueh = events[i].data.ptr; | 134 | struct UpgradeEpollHandle *const ueh = events[i].data.ptr; |
135 | struct MHD_UpgradeResponseHandle * const urh = ueh->urh; | 135 | struct MHD_UpgradeResponseHandle *const urh = ueh->urh; |
136 | bool new_err_state = false; | 136 | bool new_err_state = false; |
137 | 137 | ||
138 | if (urh->clean_ready) | 138 | if (urh->clean_ready) |
139 | continue; | 139 | continue; |
140 | 140 | ||
141 | /* Update ueh state based on what is ready according to epoll() */ | 141 | /* Update ueh state based on what is ready according to epoll() */ |
142 | if (0 != (events[i].events & EPOLLIN)) | 142 | if (0 != (events[i].events & EPOLLIN)) |
143 | ueh->celi |= MHD_EPOLL_STATE_READ_READY; | 143 | ueh->celi |= MHD_EPOLL_STATE_READ_READY; |
144 | if (0 != (events[i].events & EPOLLOUT)) | 144 | if (0 != (events[i].events & EPOLLOUT)) |
145 | ueh->celi |= MHD_EPOLL_STATE_WRITE_READY; | 145 | ueh->celi |= MHD_EPOLL_STATE_WRITE_READY; |
146 | if (0 != (events[i].events & EPOLLHUP)) | 146 | if (0 != (events[i].events & EPOLLHUP)) |
147 | ueh->celi |= MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_WRITE_READY; | 147 | ueh->celi |= MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_WRITE_READY; |
148 | 148 | ||
149 | if ( (0 == (ueh->celi & MHD_EPOLL_STATE_ERROR)) && | 149 | if ( (0 == (ueh->celi & MHD_EPOLL_STATE_ERROR)) && |
150 | (0 != (events[i].events & (EPOLLERR | EPOLLPRI))) ) | 150 | (0 != (events[i].events & (EPOLLERR | EPOLLPRI))) ) |
151 | { | 151 | { |
152 | /* Process new error state only one time | 152 | /* Process new error state only one time |
153 | * and avoid continuously marking this connection | 153 | * and avoid continuously marking this connection |
154 | * as 'ready'. */ | 154 | * as 'ready'. */ |
155 | ueh->celi |= MHD_EPOLL_STATE_ERROR; | 155 | ueh->celi |= MHD_EPOLL_STATE_ERROR; |
156 | new_err_state = true; | 156 | new_err_state = true; |
157 | } | 157 | } |
158 | 158 | ||
159 | if (! urh->in_eready_list) | 159 | if (! urh->in_eready_list) |
160 | { | 160 | { |
161 | if (new_err_state || | 161 | if (new_err_state || |
162 | is_urh_ready(urh)) | 162 | is_urh_ready (urh)) |
163 | { | 163 | { |
164 | EDLL_insert (daemon->eready_urh_head, | 164 | EDLL_insert (daemon->eready_urh_head, |
165 | daemon->eready_urh_tail, | 165 | daemon->eready_urh_tail, |
166 | urh); | 166 | urh); |
167 | urh->in_eready_list = true; | 167 | urh->in_eready_list = true; |
168 | } | ||
169 | } | ||
170 | } | 168 | } |
169 | } | ||
171 | } | 170 | } |
171 | } | ||
172 | prev = daemon->eready_urh_tail; | 172 | prev = daemon->eready_urh_tail; |
173 | while (NULL != (pos = prev)) | 173 | while (NULL != (pos = prev)) |
174 | { | ||
175 | prev = pos->prevE; | ||
176 | MHD_upgrade_response_handle_process_ (pos); | ||
177 | if (! is_urh_ready (pos)) | ||
174 | { | 178 | { |
175 | prev = pos->prevE; | 179 | EDLL_remove (daemon->eready_urh_head, |
176 | MHD_upgrade_response_handle_process_ (pos); | 180 | daemon->eready_urh_tail, |
177 | if (! is_urh_ready(pos)) | 181 | pos); |
178 | { | 182 | pos->in_eready_list = false; |
179 | EDLL_remove (daemon->eready_urh_head, | 183 | } |
180 | daemon->eready_urh_tail, | 184 | /* Finished forwarding? */ |
181 | pos); | 185 | if ( (0 == pos->in_buffer_size) && |
182 | pos->in_eready_list = false; | 186 | (0 == pos->out_buffer_size) && |
183 | } | 187 | (0 == pos->in_buffer_used) && |
184 | /* Finished forwarding? */ | 188 | (0 == pos->out_buffer_used) ) |
185 | if ( (0 == pos->in_buffer_size) && | 189 | { |
186 | (0 == pos->out_buffer_size) && | 190 | MHD_connection_finish_forward_ (pos->connection); |
187 | (0 == pos->in_buffer_used) && | 191 | pos->clean_ready = true; |
188 | (0 == pos->out_buffer_used) ) | 192 | /* If 'pos->was_closed' already was set to true, connection |
189 | { | 193 | * will be moved immediately to cleanup list. Otherwise |
190 | MHD_connection_finish_forward_ (pos->connection); | 194 | * connection will stay in suspended list until 'pos' will |
191 | pos->clean_ready = true; | 195 | * be marked with 'was_closed' by application. */ |
192 | /* If 'pos->was_closed' already was set to true, connection | 196 | MHD_request_resume (&pos->connection->request); |
193 | * will be moved immediately to cleanup list. Otherwise | ||
194 | * connection will stay in suspended list until 'pos' will | ||
195 | * be marked with 'was_closed' by application. */ | ||
196 | MHD_request_resume (&pos->connection->request); | ||
197 | } | ||
198 | } | 197 | } |
198 | } | ||
199 | 199 | ||
200 | return MHD_SC_OK; | 200 | return MHD_SC_OK; |
201 | } | 201 | } |
@@ -212,10 +212,10 @@ run_epoll_for_upgrade (struct MHD_Daemon *daemon) | |||
212 | */ | 212 | */ |
213 | enum MHD_StatusCode | 213 | enum MHD_StatusCode |
214 | MHD_daemon_epoll_ (struct MHD_Daemon *daemon, | 214 | MHD_daemon_epoll_ (struct MHD_Daemon *daemon, |
215 | bool may_block) | 215 | bool may_block) |
216 | { | 216 | { |
217 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) | 217 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) |
218 | static const char * const upgrade_marker = "upgrade_ptr"; | 218 | static const char *const upgrade_marker = "upgrade_ptr"; |
219 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ | 219 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ |
220 | struct MHD_Connection *pos; | 220 | struct MHD_Connection *pos; |
221 | struct MHD_Connection *prev; | 221 | struct MHD_Connection *prev; |
@@ -239,24 +239,24 @@ MHD_daemon_epoll_ (struct MHD_Daemon *daemon, | |||
239 | (daemon->connections < daemon->global_connection_limit) && | 239 | (daemon->connections < daemon->global_connection_limit) && |
240 | (! daemon->listen_socket_in_epoll) && | 240 | (! daemon->listen_socket_in_epoll) && |
241 | (! daemon->at_limit) ) | 241 | (! daemon->at_limit) ) |
242 | { | ||
243 | event.events = EPOLLIN; | ||
244 | event.data.ptr = daemon; | ||
245 | if (0 != epoll_ctl (daemon->epoll_fd, | ||
246 | EPOLL_CTL_ADD, | ||
247 | ls, | ||
248 | &event)) | ||
242 | { | 249 | { |
243 | event.events = EPOLLIN; | ||
244 | event.data.ptr = daemon; | ||
245 | if (0 != epoll_ctl (daemon->epoll_fd, | ||
246 | EPOLL_CTL_ADD, | ||
247 | ls, | ||
248 | &event)) | ||
249 | { | ||
250 | #ifdef HAVE_MESSAGES | 250 | #ifdef HAVE_MESSAGES |
251 | MHD_DLOG (daemon, | 251 | MHD_DLOG (daemon, |
252 | MHD_SC_EPOLL_CTL_ADD_FAILED, | 252 | MHD_SC_EPOLL_CTL_ADD_FAILED, |
253 | _("Call to epoll_ctl failed: %s\n"), | 253 | _ ("Call to epoll_ctl failed: %s\n"), |
254 | MHD_socket_last_strerr_ ()); | 254 | MHD_socket_last_strerr_ ()); |
255 | #endif | 255 | #endif |
256 | return MHD_SC_EPOLL_CTL_ADD_FAILED; | 256 | return MHD_SC_EPOLL_CTL_ADD_FAILED; |
257 | } | ||
258 | daemon->listen_socket_in_epoll = true; | ||
259 | } | 257 | } |
258 | daemon->listen_socket_in_epoll = true; | ||
259 | } | ||
260 | if ( (daemon->was_quiesced) && | 260 | if ( (daemon->was_quiesced) && |
261 | (daemon->listen_socket_in_epoll) ) | 261 | (daemon->listen_socket_in_epoll) ) |
262 | { | 262 | { |
@@ -271,58 +271,58 @@ MHD_daemon_epoll_ (struct MHD_Daemon *daemon, | |||
271 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) | 271 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) |
272 | if ( (! daemon->upgrade_fd_in_epoll) && | 272 | if ( (! daemon->upgrade_fd_in_epoll) && |
273 | (-1 != daemon->epoll_upgrade_fd) ) | 273 | (-1 != daemon->epoll_upgrade_fd) ) |
274 | { | ||
275 | event.events = EPOLLIN | EPOLLOUT; | ||
276 | event.data.ptr = (void *) upgrade_marker; | ||
277 | if (0 != epoll_ctl (daemon->epoll_fd, | ||
278 | EPOLL_CTL_ADD, | ||
279 | daemon->epoll_upgrade_fd, | ||
280 | &event)) | ||
274 | { | 281 | { |
275 | event.events = EPOLLIN | EPOLLOUT; | ||
276 | event.data.ptr = (void *) upgrade_marker; | ||
277 | if (0 != epoll_ctl (daemon->epoll_fd, | ||
278 | EPOLL_CTL_ADD, | ||
279 | daemon->epoll_upgrade_fd, | ||
280 | &event)) | ||
281 | { | ||
282 | #ifdef HAVE_MESSAGES | 282 | #ifdef HAVE_MESSAGES |
283 | MHD_DLOG (daemon, | 283 | MHD_DLOG (daemon, |
284 | MHD_SC_EPOLL_CTL_ADD_FAILED, | 284 | MHD_SC_EPOLL_CTL_ADD_FAILED, |
285 | _("Call to epoll_ctl failed: %s\n"), | 285 | _ ("Call to epoll_ctl failed: %s\n"), |
286 | MHD_socket_last_strerr_ ()); | 286 | MHD_socket_last_strerr_ ()); |
287 | #endif | 287 | #endif |
288 | return MHD_SC_EPOLL_CTL_ADD_FAILED; | 288 | return MHD_SC_EPOLL_CTL_ADD_FAILED; |
289 | } | ||
290 | daemon->upgrade_fd_in_epoll = true; | ||
291 | } | 289 | } |
290 | daemon->upgrade_fd_in_epoll = true; | ||
291 | } | ||
292 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ | 292 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ |
293 | if ( (daemon->listen_socket_in_epoll) && | 293 | if ( (daemon->listen_socket_in_epoll) && |
294 | ( (daemon->connections == daemon->global_connection_limit) || | 294 | ( (daemon->connections == daemon->global_connection_limit) || |
295 | (daemon->at_limit) || | 295 | (daemon->at_limit) || |
296 | (daemon->was_quiesced) ) ) | 296 | (daemon->was_quiesced) ) ) |
297 | { | 297 | { |
298 | /* we're at the connection limit, disable listen socket | 298 | /* we're at the connection limit, disable listen socket |
299 | for event loop for now */ | 299 | for event loop for now */ |
300 | if (0 != epoll_ctl (daemon->epoll_fd, | 300 | if (0 != epoll_ctl (daemon->epoll_fd, |
301 | EPOLL_CTL_DEL, | 301 | EPOLL_CTL_DEL, |
302 | ls, | 302 | ls, |
303 | NULL)) | 303 | NULL)) |
304 | MHD_PANIC (_("Failed to remove listen FD from epoll set\n")); | 304 | MHD_PANIC (_ ("Failed to remove listen FD from epoll set\n")); |
305 | daemon->listen_socket_in_epoll = false; | 305 | daemon->listen_socket_in_epoll = false; |
306 | } | 306 | } |
307 | 307 | ||
308 | if ( (! daemon->disallow_suspend_resume) && | 308 | if ( (! daemon->disallow_suspend_resume) && |
309 | (MHD_resume_suspended_connections_ (daemon)) ) | 309 | (MHD_resume_suspended_connections_ (daemon)) ) |
310 | may_block = false; | 310 | may_block = false; |
311 | 311 | ||
312 | if (may_block) | 312 | if (may_block) |
313 | { | ||
314 | if (MHD_SC_OK == /* FIXME: distinguish between NO_TIMEOUT and errors */ | ||
315 | MHD_daemon_get_timeout (daemon, | ||
316 | &timeout_ll)) | ||
313 | { | 317 | { |
314 | if (MHD_SC_OK == /* FIXME: distinguish between NO_TIMEOUT and errors */ | 318 | if (timeout_ll >= (MHD_UNSIGNED_LONG_LONG) INT_MAX) |
315 | MHD_daemon_get_timeout (daemon, | 319 | timeout_ms = INT_MAX; |
316 | &timeout_ll)) | ||
317 | { | ||
318 | if (timeout_ll >= (MHD_UNSIGNED_LONG_LONG) INT_MAX) | ||
319 | timeout_ms = INT_MAX; | ||
320 | else | ||
321 | timeout_ms = (int) timeout_ll; | ||
322 | } | ||
323 | else | 320 | else |
324 | timeout_ms = -1; | 321 | timeout_ms = (int) timeout_ll; |
325 | } | 322 | } |
323 | else | ||
324 | timeout_ms = -1; | ||
325 | } | ||
326 | else | 326 | else |
327 | timeout_ms = 0; | 327 | timeout_ms = 0; |
328 | 328 | ||
@@ -337,113 +337,114 @@ MHD_daemon_epoll_ (struct MHD_Daemon *daemon, | |||
337 | than unfair behavior... */ | 337 | than unfair behavior... */ |
338 | num_events = MAX_EVENTS; | 338 | num_events = MAX_EVENTS; |
339 | while (MAX_EVENTS == num_events) | 339 | while (MAX_EVENTS == num_events) |
340 | { | ||
341 | /* update event masks */ | ||
342 | num_events = epoll_wait (daemon->epoll_fd, | ||
343 | events, | ||
344 | MAX_EVENTS, | ||
345 | timeout_ms); | ||
346 | if (-1 == num_events) | ||
340 | { | 347 | { |
341 | /* update event masks */ | 348 | const int err = MHD_socket_get_error_ (); |
342 | num_events = epoll_wait (daemon->epoll_fd, | 349 | if (MHD_SCKT_ERR_IS_EINTR_ (err)) |
343 | events, | 350 | return MHD_SC_OK; |
344 | MAX_EVENTS, | ||
345 | timeout_ms); | ||
346 | if (-1 == num_events) | ||
347 | { | ||
348 | const int err = MHD_socket_get_error_ (); | ||
349 | if (MHD_SCKT_ERR_IS_EINTR_ (err)) | ||
350 | return MHD_SC_OK; | ||
351 | #ifdef HAVE_MESSAGES | 351 | #ifdef HAVE_MESSAGES |
352 | MHD_DLOG (daemon, | 352 | MHD_DLOG (daemon, |
353 | MHD_SC_UNEXPECTED_EPOLL_WAIT_ERROR, | 353 | MHD_SC_UNEXPECTED_EPOLL_WAIT_ERROR, |
354 | _("Call to epoll_wait failed: %s\n"), | 354 | _ ("Call to epoll_wait failed: %s\n"), |
355 | MHD_socket_strerr_ (err)); | 355 | MHD_socket_strerr_ (err)); |
356 | #endif | 356 | #endif |
357 | return MHD_SC_UNEXPECTED_EPOLL_WAIT_ERROR; | 357 | return MHD_SC_UNEXPECTED_EPOLL_WAIT_ERROR; |
358 | } | 358 | } |
359 | for (i=0;i<(unsigned int) num_events;i++) | 359 | for (i = 0; i<(unsigned int) num_events; i++) |
360 | { | 360 | { |
361 | /* First, check for the values of `ptr` that would indicate | 361 | /* First, check for the values of `ptr` that would indicate |
362 | that this event is not about a normal connection. */ | 362 | that this event is not about a normal connection. */ |
363 | if (NULL == events[i].data.ptr) | 363 | if (NULL == events[i].data.ptr) |
364 | continue; /* shutdown signal! */ | 364 | continue; /* shutdown signal! */ |
365 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) | 365 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) |
366 | if (upgrade_marker == events[i].data.ptr) | 366 | if (upgrade_marker == events[i].data.ptr) |
367 | { | 367 | { |
368 | /* activity on an upgraded connection, we process | 368 | /* activity on an upgraded connection, we process |
369 | those in a separate epoll() */ | 369 | those in a separate epoll() */ |
370 | run_upgraded = true; | 370 | run_upgraded = true; |
371 | continue; | 371 | continue; |
372 | } | 372 | } |
373 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ | 373 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ |
374 | if (daemon->epoll_itc_marker == events[i].data.ptr) | 374 | if (daemon->epoll_itc_marker == events[i].data.ptr) |
375 | { | 375 | { |
376 | /* It's OK to clear ITC here as all external | 376 | /* It's OK to clear ITC here as all external |
377 | conditions will be processed later. */ | 377 | conditions will be processed later. */ |
378 | MHD_itc_clear_ (daemon->itc); | 378 | MHD_itc_clear_ (daemon->itc); |
379 | continue; | 379 | continue; |
380 | } | 380 | } |
381 | if (daemon == events[i].data.ptr) | 381 | if (daemon == events[i].data.ptr) |
382 | { | 382 | { |
383 | /* Check for error conditions on listen socket. */ | 383 | /* Check for error conditions on listen socket. */ |
384 | /* FIXME: Initiate MHD_quiesce_daemon() to prevent busy waiting? */ | 384 | /* FIXME: Initiate MHD_quiesce_daemon() to prevent busy waiting? */ |
385 | if (0 == (events[i].events & (EPOLLERR | EPOLLHUP))) | 385 | if (0 == (events[i].events & (EPOLLERR | EPOLLHUP))) |
386 | { | 386 | { |
387 | unsigned int series_length = 0; | 387 | unsigned int series_length = 0; |
388 | /* Run 'accept' until it fails or daemon at limit of connections. | 388 | /* Run 'accept' until it fails or daemon at limit of connections. |
389 | * Do not accept more then 10 connections at once. The rest will | 389 | * Do not accept more then 10 connections at once. The rest will |
390 | * be accepted on next turn (level trigger is used for listen | 390 | * be accepted on next turn (level trigger is used for listen |
391 | * socket). */ | 391 | * socket). */ |
392 | while ( (MHD_SC_OK == | 392 | while ( (MHD_SC_OK == |
393 | MHD_accept_connection_ (daemon)) && | 393 | MHD_accept_connection_ (daemon)) && |
394 | (series_length < 10) && | 394 | (series_length < 10) && |
395 | (daemon->connections < daemon->global_connection_limit) && | 395 | (daemon->connections < daemon->global_connection_limit) && |
396 | (! daemon->at_limit) ) | 396 | (! daemon->at_limit) ) |
397 | series_length++; | 397 | series_length++; |
398 | } | 398 | } |
399 | continue; | 399 | continue; |
400 | } | 400 | } |
401 | /* this is an event relating to a 'normal' connection, | 401 | /* this is an event relating to a 'normal' connection, |
402 | remember the event and if appropriate mark the | 402 | remember the event and if appropriate mark the |
403 | connection as 'eready'. */ | 403 | connection as 'eready'. */ |
404 | pos = events[i].data.ptr; | 404 | pos = events[i].data.ptr; |
405 | /* normal processing: update read/write data */ | 405 | /* normal processing: update read/write data */ |
406 | if (0 != (events[i].events & (EPOLLPRI | EPOLLERR | EPOLLHUP))) | 406 | if (0 != (events[i].events & (EPOLLPRI | EPOLLERR | EPOLLHUP))) |
407 | { | 407 | { |
408 | pos->epoll_state |= MHD_EPOLL_STATE_ERROR; | 408 | pos->epoll_state |= MHD_EPOLL_STATE_ERROR; |
409 | if (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) | 409 | if (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) |
410 | { | 410 | { |
411 | EDLL_insert (daemon->eready_head, | 411 | EDLL_insert (daemon->eready_head, |
412 | daemon->eready_tail, | 412 | daemon->eready_tail, |
413 | pos); | 413 | pos); |
414 | pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL; | 414 | pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL; |
415 | } | 415 | } |
416 | } | 416 | } |
417 | else | 417 | else |
418 | { | 418 | { |
419 | if (0 != (events[i].events & EPOLLIN)) | 419 | if (0 != (events[i].events & EPOLLIN)) |
420 | { | 420 | { |
421 | pos->epoll_state |= MHD_EPOLL_STATE_READ_READY; | 421 | pos->epoll_state |= MHD_EPOLL_STATE_READ_READY; |
422 | if ( ( (MHD_EVENT_LOOP_INFO_READ == pos->request.event_loop_info) || | 422 | if ( ( (MHD_EVENT_LOOP_INFO_READ == pos->request.event_loop_info) || |
423 | (pos->request.read_buffer_size > pos->request.read_buffer_offset) ) && | 423 | (pos->request.read_buffer_size > |
424 | (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) ) | 424 | pos->request.read_buffer_offset) ) && |
425 | { | 425 | (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) ) |
426 | EDLL_insert (daemon->eready_head, | 426 | { |
427 | daemon->eready_tail, | 427 | EDLL_insert (daemon->eready_head, |
428 | pos); | 428 | daemon->eready_tail, |
429 | pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL; | 429 | pos); |
430 | } | 430 | pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL; |
431 | } | 431 | } |
432 | if (0 != (events[i].events & EPOLLOUT)) | 432 | } |
433 | { | 433 | if (0 != (events[i].events & EPOLLOUT)) |
434 | pos->epoll_state |= MHD_EPOLL_STATE_WRITE_READY; | 434 | { |
435 | if ( (MHD_EVENT_LOOP_INFO_WRITE == pos->request.event_loop_info) && | 435 | pos->epoll_state |= MHD_EPOLL_STATE_WRITE_READY; |
436 | (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) ) | 436 | if ( (MHD_EVENT_LOOP_INFO_WRITE == pos->request.event_loop_info) && |
437 | { | 437 | (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) ) |
438 | EDLL_insert (daemon->eready_head, | 438 | { |
439 | daemon->eready_tail, | 439 | EDLL_insert (daemon->eready_head, |
440 | pos); | 440 | daemon->eready_tail, |
441 | pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL; | 441 | pos); |
442 | } | 442 | pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL; |
443 | } | 443 | } |
444 | } | ||
445 | } | 444 | } |
445 | } | ||
446 | } | 446 | } |
447 | } | ||
447 | 448 | ||
448 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) | 449 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) |
449 | if (run_upgraded) | 450 | if (run_upgraded) |
@@ -453,28 +454,32 @@ MHD_daemon_epoll_ (struct MHD_Daemon *daemon, | |||
453 | /* process events for connections */ | 454 | /* process events for connections */ |
454 | prev = daemon->eready_tail; | 455 | prev = daemon->eready_tail; |
455 | while (NULL != (pos = prev)) | 456 | while (NULL != (pos = prev)) |
457 | { | ||
458 | prev = pos->prevE; | ||
459 | MHD_connection_call_handlers_ (pos, | ||
460 | 0 != (pos->epoll_state | ||
461 | & MHD_EPOLL_STATE_READ_READY), | ||
462 | 0 != (pos->epoll_state | ||
463 | & MHD_EPOLL_STATE_WRITE_READY), | ||
464 | 0 != (pos->epoll_state | ||
465 | & MHD_EPOLL_STATE_ERROR)); | ||
466 | if (MHD_EPOLL_STATE_IN_EREADY_EDLL == | ||
467 | (pos->epoll_state & (MHD_EPOLL_STATE_SUSPENDED | ||
468 | | MHD_EPOLL_STATE_IN_EREADY_EDLL))) | ||
456 | { | 469 | { |
457 | prev = pos->prevE; | 470 | if ( ((MHD_EVENT_LOOP_INFO_READ == pos->request.event_loop_info) && |
458 | MHD_connection_call_handlers_ (pos, | 471 | (0 == (pos->epoll_state & MHD_EPOLL_STATE_READ_READY)) ) || |
459 | 0 != (pos->epoll_state & MHD_EPOLL_STATE_READ_READY), | 472 | ((MHD_EVENT_LOOP_INFO_WRITE == pos->request.event_loop_info) && |
460 | 0 != (pos->epoll_state & MHD_EPOLL_STATE_WRITE_READY), | 473 | (0 == (pos->epoll_state & MHD_EPOLL_STATE_WRITE_READY)) ) || |
461 | 0 != (pos->epoll_state & MHD_EPOLL_STATE_ERROR)); | 474 | (MHD_EVENT_LOOP_INFO_CLEANUP == pos->request.event_loop_info) ) |
462 | if (MHD_EPOLL_STATE_IN_EREADY_EDLL == | 475 | { |
463 | (pos->epoll_state & (MHD_EPOLL_STATE_SUSPENDED | MHD_EPOLL_STATE_IN_EREADY_EDLL))) | 476 | EDLL_remove (daemon->eready_head, |
464 | { | 477 | daemon->eready_tail, |
465 | if ( (MHD_EVENT_LOOP_INFO_READ == pos->request.event_loop_info && | 478 | pos); |
466 | 0 == (pos->epoll_state & MHD_EPOLL_STATE_READ_READY) ) || | 479 | pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL; |
467 | (MHD_EVENT_LOOP_INFO_WRITE == pos->request.event_loop_info && | 480 | } |
468 | 0 == (pos->epoll_state & MHD_EPOLL_STATE_WRITE_READY) ) || | ||
469 | MHD_EVENT_LOOP_INFO_CLEANUP == pos->request.event_loop_info) | ||
470 | { | ||
471 | EDLL_remove (daemon->eready_head, | ||
472 | daemon->eready_tail, | ||
473 | pos); | ||
474 | pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL; | ||
475 | } | ||
476 | } | ||
477 | } | 481 | } |
482 | } | ||
478 | 483 | ||
479 | /* Finally, handle timed-out connections; we need to do this here | 484 | /* Finally, handle timed-out connections; we need to do this here |
480 | as the epoll mechanism won't call the 'MHD_request_handle_idle_()' on everything, | 485 | as the epoll mechanism won't call the 'MHD_request_handle_idle_()' on everything, |
@@ -486,22 +491,22 @@ MHD_daemon_epoll_ (struct MHD_Daemon *daemon, | |||
486 | do not bother to sort that (presumably very short) list. */ | 491 | do not bother to sort that (presumably very short) list. */ |
487 | prev = daemon->manual_timeout_tail; | 492 | prev = daemon->manual_timeout_tail; |
488 | while (NULL != (pos = prev)) | 493 | while (NULL != (pos = prev)) |
489 | { | 494 | { |
490 | prev = pos->prevX; | 495 | prev = pos->prevX; |
491 | MHD_request_handle_idle_ (&pos->request); | 496 | MHD_request_handle_idle_ (&pos->request); |
492 | } | 497 | } |
493 | /* Connections with the default timeout are sorted by prepending | 498 | /* Connections with the default timeout are sorted by prepending |
494 | them to the head of the list whenever we touch the connection; | 499 | them to the head of the list whenever we touch the connection; |
495 | thus it suffices to iterate from the tail until the first | 500 | thus it suffices to iterate from the tail until the first |
496 | connection is NOT timed out */ | 501 | connection is NOT timed out */ |
497 | prev = daemon->normal_timeout_tail; | 502 | prev = daemon->normal_timeout_tail; |
498 | while (NULL != (pos = prev)) | 503 | while (NULL != (pos = prev)) |
499 | { | 504 | { |
500 | prev = pos->prevX; | 505 | prev = pos->prevX; |
501 | MHD_request_handle_idle_ (&pos->request); | 506 | MHD_request_handle_idle_ (&pos->request); |
502 | if (MHD_REQUEST_CLOSED != pos->request.state) | 507 | if (MHD_REQUEST_CLOSED != pos->request.state) |
503 | break; /* sorted by timeout, no need to visit the rest! */ | 508 | break; /* sorted by timeout, no need to visit the rest! */ |
504 | } | 509 | } |
505 | return MHD_SC_OK; | 510 | return MHD_SC_OK; |
506 | } | 511 | } |
507 | #endif | 512 | #endif |
diff --git a/src/lib/daemon_epoll.h b/src/lib/daemon_epoll.h index 50452d8d..37d0e423 100644 --- a/src/lib/daemon_epoll.h +++ b/src/lib/daemon_epoll.h | |||
@@ -38,8 +38,8 @@ | |||
38 | */ | 38 | */ |
39 | enum MHD_StatusCode | 39 | enum MHD_StatusCode |
40 | MHD_daemon_epoll_ (struct MHD_Daemon *daemon, | 40 | MHD_daemon_epoll_ (struct MHD_Daemon *daemon, |
41 | bool may_block) | 41 | bool may_block) |
42 | MHD_NONNULL (1); | 42 | MHD_NONNULL (1); |
43 | 43 | ||
44 | #endif | 44 | #endif |
45 | 45 | ||
diff --git a/src/lib/daemon_get_timeout.c b/src/lib/daemon_get_timeout.c index fcf3ecbc..604c52e2 100644 --- a/src/lib/daemon_get_timeout.c +++ b/src/lib/daemon_get_timeout.c | |||
@@ -46,7 +46,7 @@ | |||
46 | */ | 46 | */ |
47 | enum MHD_StatusCode | 47 | enum MHD_StatusCode |
48 | MHD_daemon_get_timeout (struct MHD_Daemon *daemon, | 48 | MHD_daemon_get_timeout (struct MHD_Daemon *daemon, |
49 | MHD_UNSIGNED_LONG_LONG *timeout) | 49 | MHD_UNSIGNED_LONG_LONG *timeout) |
50 | { | 50 | { |
51 | time_t earliest_deadline; | 51 | time_t earliest_deadline; |
52 | time_t now; | 52 | time_t now; |
@@ -54,71 +54,71 @@ MHD_daemon_get_timeout (struct MHD_Daemon *daemon, | |||
54 | bool have_timeout; | 54 | bool have_timeout; |
55 | 55 | ||
56 | if (MHD_TM_EXTERNAL_EVENT_LOOP != daemon->threading_mode) | 56 | if (MHD_TM_EXTERNAL_EVENT_LOOP != daemon->threading_mode) |
57 | { | 57 | { |
58 | #ifdef HAVE_MESSAGES | 58 | #ifdef HAVE_MESSAGES |
59 | MHD_DLOG (daemon, | 59 | MHD_DLOG (daemon, |
60 | MHD_SC_CONFIGURATION_MISMATCH_FOR_GET_TIMEOUT, | 60 | MHD_SC_CONFIGURATION_MISMATCH_FOR_GET_TIMEOUT, |
61 | _("Illegal call to MHD_get_timeout\n")); | 61 | _ ("Illegal call to MHD_get_timeout\n")); |
62 | #endif | 62 | #endif |
63 | return MHD_SC_CONFIGURATION_MISSMATCH_FOR_GET_TIMEOUT; | 63 | return MHD_SC_CONFIGURATION_MISSMATCH_FOR_GET_TIMEOUT; |
64 | } | 64 | } |
65 | 65 | ||
66 | if (daemon->data_already_pending) | 66 | if (daemon->data_already_pending) |
67 | { | 67 | { |
68 | /* Some data already waiting to be processed. */ | 68 | /* Some data already waiting to be processed. */ |
69 | *timeout = 0; | 69 | *timeout = 0; |
70 | return MHD_SC_OK; | 70 | return MHD_SC_OK; |
71 | } | 71 | } |
72 | 72 | ||
73 | #ifdef EPOLL_SUPPORT | 73 | #ifdef EPOLL_SUPPORT |
74 | if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) && | 74 | if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) && |
75 | ((NULL != daemon->eready_head) | 75 | ((NULL != daemon->eready_head) |
76 | #if defined(UPGRADE_SUPPORT) && defined(HTTPS_SUPPORT) | 76 | #if defined(UPGRADE_SUPPORT) && defined(HTTPS_SUPPORT) |
77 | || (NULL != daemon->eready_urh_head) | 77 | || (NULL != daemon->eready_urh_head) |
78 | #endif /* UPGRADE_SUPPORT && HTTPS_SUPPORT */ | 78 | #endif /* UPGRADE_SUPPORT && HTTPS_SUPPORT */ |
79 | ) ) | 79 | ) ) |
80 | { | 80 | { |
81 | /* Some connection(s) already have some data pending. */ | 81 | /* Some connection(s) already have some data pending. */ |
82 | *timeout = 0; | 82 | *timeout = 0; |
83 | return MHD_SC_OK; | 83 | return MHD_SC_OK; |
84 | } | 84 | } |
85 | #endif /* EPOLL_SUPPORT */ | 85 | #endif /* EPOLL_SUPPORT */ |
86 | 86 | ||
87 | have_timeout = false; | 87 | have_timeout = false; |
88 | earliest_deadline = 0; /* avoid compiler warnings */ | 88 | earliest_deadline = 0; /* avoid compiler warnings */ |
89 | for (pos = daemon->manual_timeout_tail; NULL != pos; pos = pos->prevX) | 89 | for (pos = daemon->manual_timeout_tail; NULL != pos; pos = pos->prevX) |
90 | { | ||
91 | if (0 != pos->connection_timeout) | ||
90 | { | 92 | { |
91 | if (0 != pos->connection_timeout) | 93 | if ( (! have_timeout) || |
92 | { | 94 | (earliest_deadline - pos->last_activity > pos->connection_timeout) ) |
93 | if ( (! have_timeout) || | 95 | earliest_deadline = pos->last_activity + pos->connection_timeout; |
94 | (earliest_deadline - pos->last_activity > pos->connection_timeout) ) | 96 | have_timeout = true; |
95 | earliest_deadline = pos->last_activity + pos->connection_timeout; | ||
96 | have_timeout = true; | ||
97 | } | ||
98 | } | 97 | } |
98 | } | ||
99 | /* normal timeouts are sorted, so we only need to look at the 'tail' (oldest) */ | 99 | /* normal timeouts are sorted, so we only need to look at the 'tail' (oldest) */ |
100 | pos = daemon->normal_timeout_tail; | 100 | pos = daemon->normal_timeout_tail; |
101 | if ( (NULL != pos) && | 101 | if ( (NULL != pos) && |
102 | (0 != pos->connection_timeout) ) | 102 | (0 != pos->connection_timeout) ) |
103 | { | 103 | { |
104 | if ( (! have_timeout) || | 104 | if ( (! have_timeout) || |
105 | (earliest_deadline - pos->connection_timeout > pos->last_activity) ) | 105 | (earliest_deadline - pos->connection_timeout > pos->last_activity) ) |
106 | earliest_deadline = pos->last_activity + pos->connection_timeout; | 106 | earliest_deadline = pos->last_activity + pos->connection_timeout; |
107 | have_timeout = true; | 107 | have_timeout = true; |
108 | } | 108 | } |
109 | 109 | ||
110 | if (! have_timeout) | 110 | if (! have_timeout) |
111 | return MHD_SC_NO_TIMEOUT; | 111 | return MHD_SC_NO_TIMEOUT; |
112 | now = MHD_monotonic_sec_counter(); | 112 | now = MHD_monotonic_sec_counter (); |
113 | if (earliest_deadline < now) | 113 | if (earliest_deadline < now) |
114 | *timeout = 0; | 114 | *timeout = 0; |
115 | else | 115 | else |
116 | { | 116 | { |
117 | const time_t second_left = earliest_deadline - now; | 117 | const time_t second_left = earliest_deadline - now; |
118 | if (second_left > ULLONG_MAX / 1000) /* Ignore compiler warning: 'second_left' is always positive. */ | 118 | if (second_left > ULLONG_MAX / 1000) /* Ignore compiler warning: 'second_left' is always positive. */ |
119 | *timeout = ULLONG_MAX; | 119 | *timeout = ULLONG_MAX; |
120 | else | 120 | else |
121 | *timeout = 1000LL * second_left; | 121 | *timeout = 1000LL * second_left; |
122 | } | 122 | } |
123 | return MHD_SC_OK; | 123 | return MHD_SC_OK; |
124 | } | 124 | } |
diff --git a/src/lib/daemon_info.c b/src/lib/daemon_info.c index b0c5ec14..d32f244b 100644 --- a/src/lib/daemon_info.c +++ b/src/lib/daemon_info.c | |||
@@ -43,62 +43,62 @@ | |||
43 | */ | 43 | */ |
44 | enum MHD_Bool | 44 | enum MHD_Bool |
45 | MHD_daemon_get_information_sz (struct MHD_Daemon *daemon, | 45 | MHD_daemon_get_information_sz (struct MHD_Daemon *daemon, |
46 | enum MHD_DaemonInformationType info_type, | 46 | enum MHD_DaemonInformationType info_type, |
47 | union MHD_DaemonInformation *return_value, | 47 | union MHD_DaemonInformation *return_value, |
48 | size_t return_value_size) | 48 | size_t return_value_size) |
49 | { | 49 | { |
50 | #define CHECK_SIZE(type) if (sizeof(type) < return_value_size) \ | 50 | #define CHECK_SIZE(type) if (sizeof(type) < return_value_size) \ |
51 | return MHD_NO | 51 | return MHD_NO |
52 | 52 | ||
53 | switch (info_type) | 53 | switch (info_type) |
54 | { | 54 | { |
55 | case MHD_DAEMON_INFORMATION_LISTEN_SOCKET: | 55 | case MHD_DAEMON_INFORMATION_LISTEN_SOCKET: |
56 | CHECK_SIZE (MHD_socket); | 56 | CHECK_SIZE (MHD_socket); |
57 | return_value->listen_socket | 57 | return_value->listen_socket |
58 | = daemon->listen_socket; | 58 | = daemon->listen_socket; |
59 | return MHD_YES; | 59 | return MHD_YES; |
60 | #ifdef EPOLL_SUPPORT | 60 | #ifdef EPOLL_SUPPORT |
61 | case MHD_DAEMON_INFORMATION_EPOLL_FD: | 61 | case MHD_DAEMON_INFORMATION_EPOLL_FD: |
62 | CHECK_SIZE (int); | 62 | CHECK_SIZE (int); |
63 | // FIXME: maybe return MHD_NO if we are not using EPOLL? | 63 | // FIXME: maybe return MHD_NO if we are not using EPOLL? |
64 | return_value->epoll_fd = daemon->epoll_fd; | 64 | return_value->epoll_fd = daemon->epoll_fd; |
65 | return MHD_YES; | 65 | return MHD_YES; |
66 | #endif | 66 | #endif |
67 | case MHD_DAEMON_INFORMATION_CURRENT_CONNECTIONS: | 67 | case MHD_DAEMON_INFORMATION_CURRENT_CONNECTIONS: |
68 | CHECK_SIZE (unsigned int); | 68 | CHECK_SIZE (unsigned int); |
69 | if (MHD_TM_EXTERNAL_EVENT_LOOP == daemon->threading_mode) | 69 | if (MHD_TM_EXTERNAL_EVENT_LOOP == daemon->threading_mode) |
70 | { | 70 | { |
71 | /* Assumes that MHD_run() in not called in other thread | 71 | /* Assumes that MHD_run() in not called in other thread |
72 | (of the application) at the same time. */ | 72 | (of the application) at the same time. */ |
73 | MHD_connection_cleanup_ (daemon); | 73 | MHD_connection_cleanup_ (daemon); |
74 | return_value->num_connections | 74 | return_value->num_connections |
75 | = daemon->connections; | 75 | = daemon->connections; |
76 | } | ||
77 | else if (daemon->worker_pool) | ||
78 | { | ||
79 | unsigned int i; | ||
80 | /* Collect the connection information stored in the workers. */ | ||
81 | return_value->num_connections = 0; | ||
82 | for (i = 0; i < daemon->worker_pool_size; i++) | ||
83 | { | ||
84 | /* FIXME: next line is thread-safe only if read is atomic. */ | ||
85 | return_value->num_connections | ||
86 | += daemon->worker_pool[i].connections; | ||
87 | } | ||
88 | } | ||
89 | else | ||
90 | return_value->num_connections | ||
91 | = daemon->connections; | ||
92 | return MHD_YES; | ||
93 | case MHD_DAEMON_INFORMATION_BIND_PORT: | ||
94 | CHECK_SIZE (uint16_t); | ||
95 | // FIXME: return MHD_NO if port is not known/UNIX? | ||
96 | return_value->port = daemon->listen_port; | ||
97 | return MHD_YES; | ||
98 | default: | ||
99 | return MHD_NO; | ||
100 | } | 76 | } |
101 | 77 | else if (daemon->worker_pool) | |
78 | { | ||
79 | unsigned int i; | ||
80 | /* Collect the connection information stored in the workers. */ | ||
81 | return_value->num_connections = 0; | ||
82 | for (i = 0; i < daemon->worker_pool_size; i++) | ||
83 | { | ||
84 | /* FIXME: next line is thread-safe only if read is atomic. */ | ||
85 | return_value->num_connections | ||
86 | += daemon->worker_pool[i].connections; | ||
87 | } | ||
88 | } | ||
89 | else | ||
90 | return_value->num_connections | ||
91 | = daemon->connections; | ||
92 | return MHD_YES; | ||
93 | case MHD_DAEMON_INFORMATION_BIND_PORT: | ||
94 | CHECK_SIZE (uint16_t); | ||
95 | // FIXME: return MHD_NO if port is not known/UNIX? | ||
96 | return_value->port = daemon->listen_port; | ||
97 | return MHD_YES; | ||
98 | default: | ||
99 | return MHD_NO; | ||
100 | } | ||
101 | |||
102 | #undef CHECK_SIZE | 102 | #undef CHECK_SIZE |
103 | } | 103 | } |
104 | 104 | ||
diff --git a/src/lib/daemon_ip_limit.c b/src/lib/daemon_ip_limit.c index 4a131c92..21550265 100644 --- a/src/lib/daemon_ip_limit.c +++ b/src/lib/daemon_ip_limit.c | |||
@@ -89,7 +89,7 @@ get_master (struct MHD_Daemon *daemon) | |||
89 | static void | 89 | static void |
90 | MHD_ip_count_lock (struct MHD_Daemon *daemon) | 90 | MHD_ip_count_lock (struct MHD_Daemon *daemon) |
91 | { | 91 | { |
92 | MHD_mutex_lock_chk_(&daemon->per_ip_connection_mutex); | 92 | MHD_mutex_lock_chk_ (&daemon->per_ip_connection_mutex); |
93 | } | 93 | } |
94 | 94 | ||
95 | 95 | ||
@@ -101,7 +101,7 @@ MHD_ip_count_lock (struct MHD_Daemon *daemon) | |||
101 | static void | 101 | static void |
102 | MHD_ip_count_unlock (struct MHD_Daemon *daemon) | 102 | MHD_ip_count_unlock (struct MHD_Daemon *daemon) |
103 | { | 103 | { |
104 | MHD_mutex_unlock_chk_(&daemon->per_ip_connection_mutex); | 104 | MHD_mutex_unlock_chk_ (&daemon->per_ip_connection_mutex); |
105 | } | 105 | } |
106 | 106 | ||
107 | 107 | ||
@@ -135,37 +135,37 @@ MHD_ip_addr_compare (const void *a1, | |||
135 | */ | 135 | */ |
136 | static int | 136 | static int |
137 | MHD_ip_addr_to_key (const struct sockaddr *addr, | 137 | MHD_ip_addr_to_key (const struct sockaddr *addr, |
138 | socklen_t addrlen, | 138 | socklen_t addrlen, |
139 | struct MHD_IPCount *key) | 139 | struct MHD_IPCount *key) |
140 | { | 140 | { |
141 | memset(key, | 141 | memset (key, |
142 | 0, | 142 | 0, |
143 | sizeof(*key)); | 143 | sizeof(*key)); |
144 | 144 | ||
145 | /* IPv4 addresses */ | 145 | /* IPv4 addresses */ |
146 | if (sizeof (struct sockaddr_in) == addrlen) | 146 | if (sizeof (struct sockaddr_in) == addrlen) |
147 | { | 147 | { |
148 | const struct sockaddr_in *addr4 = (const struct sockaddr_in*) addr; | 148 | const struct sockaddr_in *addr4 = (const struct sockaddr_in*) addr; |
149 | 149 | ||
150 | key->family = AF_INET; | 150 | key->family = AF_INET; |
151 | memcpy (&key->addr.ipv4, | 151 | memcpy (&key->addr.ipv4, |
152 | &addr4->sin_addr, | 152 | &addr4->sin_addr, |
153 | sizeof(addr4->sin_addr)); | 153 | sizeof(addr4->sin_addr)); |
154 | return MHD_YES; | 154 | return MHD_YES; |
155 | } | 155 | } |
156 | 156 | ||
157 | #if HAVE_INET6 | 157 | #if HAVE_INET6 |
158 | /* IPv6 addresses */ | 158 | /* IPv6 addresses */ |
159 | if (sizeof (struct sockaddr_in6) == addrlen) | 159 | if (sizeof (struct sockaddr_in6) == addrlen) |
160 | { | 160 | { |
161 | const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6*) addr; | 161 | const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6*) addr; |
162 | 162 | ||
163 | key->family = AF_INET6; | 163 | key->family = AF_INET6; |
164 | memcpy (&key->addr.ipv6, | 164 | memcpy (&key->addr.ipv6, |
165 | &addr6->sin6_addr, | 165 | &addr6->sin6_addr, |
166 | sizeof(addr6->sin6_addr)); | 166 | sizeof(addr6->sin6_addr)); |
167 | return MHD_YES; | 167 | return MHD_YES; |
168 | } | 168 | } |
169 | #endif | 169 | #endif |
170 | 170 | ||
171 | /* Some other address */ | 171 | /* Some other address */ |
@@ -186,8 +186,8 @@ MHD_ip_addr_to_key (const struct sockaddr *addr, | |||
186 | */ | 186 | */ |
187 | int | 187 | int |
188 | MHD_ip_limit_add (struct MHD_Daemon *daemon, | 188 | MHD_ip_limit_add (struct MHD_Daemon *daemon, |
189 | const struct sockaddr *addr, | 189 | const struct sockaddr *addr, |
190 | socklen_t addrlen) | 190 | socklen_t addrlen) |
191 | { | 191 | { |
192 | struct MHD_IPCount *key; | 192 | struct MHD_IPCount *key; |
193 | void **nodep; | 193 | void **nodep; |
@@ -206,31 +206,31 @@ MHD_ip_limit_add (struct MHD_Daemon *daemon, | |||
206 | if (MHD_NO == MHD_ip_addr_to_key (addr, | 206 | if (MHD_NO == MHD_ip_addr_to_key (addr, |
207 | addrlen, | 207 | addrlen, |
208 | key)) | 208 | key)) |
209 | { | 209 | { |
210 | /* Allow unhandled address types through */ | 210 | /* Allow unhandled address types through */ |
211 | free (key); | 211 | free (key); |
212 | return MHD_YES; | 212 | return MHD_YES; |
213 | } | 213 | } |
214 | MHD_ip_count_lock (daemon); | 214 | MHD_ip_count_lock (daemon); |
215 | 215 | ||
216 | /* Search for the IP address */ | 216 | /* Search for the IP address */ |
217 | if (NULL == (nodep = tsearch (key, | 217 | if (NULL == (nodep = tsearch (key, |
218 | &daemon->per_ip_connection_count, | 218 | &daemon->per_ip_connection_count, |
219 | &MHD_ip_addr_compare))) | 219 | &MHD_ip_addr_compare))) |
220 | { | 220 | { |
221 | #ifdef HAVE_MESSAGES | 221 | #ifdef HAVE_MESSAGES |
222 | MHD_DLOG (daemon, | 222 | MHD_DLOG (daemon, |
223 | MHD_SC_IP_COUNTER_FAILURE, | 223 | MHD_SC_IP_COUNTER_FAILURE, |
224 | _("Failed to add IP connection count node\n")); | 224 | _ ("Failed to add IP connection count node\n")); |
225 | #endif | 225 | #endif |
226 | MHD_ip_count_unlock (daemon); | 226 | MHD_ip_count_unlock (daemon); |
227 | free (key); | 227 | free (key); |
228 | return MHD_NO; | 228 | return MHD_NO; |
229 | } | 229 | } |
230 | node = *nodep; | 230 | node = *nodep; |
231 | /* If we got an existing node back, free the one we created */ | 231 | /* If we got an existing node back, free the one we created */ |
232 | if (node != key) | 232 | if (node != key) |
233 | free(key); | 233 | free (key); |
234 | key = (struct MHD_IPCount *) node; | 234 | key = (struct MHD_IPCount *) node; |
235 | /* Test if there is room for another connection; if so, | 235 | /* Test if there is room for another connection; if so, |
236 | * increment count */ | 236 | * increment count */ |
@@ -253,8 +253,8 @@ MHD_ip_limit_add (struct MHD_Daemon *daemon, | |||
253 | */ | 253 | */ |
254 | void | 254 | void |
255 | MHD_ip_limit_del (struct MHD_Daemon *daemon, | 255 | MHD_ip_limit_del (struct MHD_Daemon *daemon, |
256 | const struct sockaddr *addr, | 256 | const struct sockaddr *addr, |
257 | socklen_t addrlen) | 257 | socklen_t addrlen) |
258 | { | 258 | { |
259 | struct MHD_IPCount search_key; | 259 | struct MHD_IPCount search_key; |
260 | struct MHD_IPCount *found_key; | 260 | struct MHD_IPCount *found_key; |
@@ -274,27 +274,27 @@ MHD_ip_limit_del (struct MHD_Daemon *daemon, | |||
274 | 274 | ||
275 | /* Search for the IP address */ | 275 | /* Search for the IP address */ |
276 | if (NULL == (nodep = tfind (&search_key, | 276 | if (NULL == (nodep = tfind (&search_key, |
277 | &daemon->per_ip_connection_count, | 277 | &daemon->per_ip_connection_count, |
278 | &MHD_ip_addr_compare))) | 278 | &MHD_ip_addr_compare))) |
279 | { | 279 | { |
280 | /* Something's wrong if we couldn't find an IP address | 280 | /* Something's wrong if we couldn't find an IP address |
281 | * that was previously added */ | 281 | * that was previously added */ |
282 | MHD_PANIC (_("Failed to find previously-added IP address\n")); | 282 | MHD_PANIC (_ ("Failed to find previously-added IP address\n")); |
283 | } | 283 | } |
284 | found_key = (struct MHD_IPCount *) *nodep; | 284 | found_key = (struct MHD_IPCount *) *nodep; |
285 | /* Validate existing count for IP address */ | 285 | /* Validate existing count for IP address */ |
286 | if (0 == found_key->count) | 286 | if (0 == found_key->count) |
287 | { | 287 | { |
288 | MHD_PANIC (_("Previously-added IP address had counter of zero\n")); | 288 | MHD_PANIC (_ ("Previously-added IP address had counter of zero\n")); |
289 | } | 289 | } |
290 | /* Remove the node entirely if count reduces to 0 */ | 290 | /* Remove the node entirely if count reduces to 0 */ |
291 | if (0 == --found_key->count) | 291 | if (0 == --found_key->count) |
292 | { | 292 | { |
293 | tdelete (found_key, | 293 | tdelete (found_key, |
294 | &daemon->per_ip_connection_count, | 294 | &daemon->per_ip_connection_count, |
295 | &MHD_ip_addr_compare); | 295 | &MHD_ip_addr_compare); |
296 | free (found_key); | 296 | free (found_key); |
297 | } | 297 | } |
298 | 298 | ||
299 | MHD_ip_count_unlock (daemon); | 299 | MHD_ip_count_unlock (daemon); |
300 | } | 300 | } |
diff --git a/src/lib/daemon_ip_limit.h b/src/lib/daemon_ip_limit.h index 5f22db05..9c587825 100644 --- a/src/lib/daemon_ip_limit.h +++ b/src/lib/daemon_ip_limit.h | |||
@@ -38,9 +38,9 @@ | |||
38 | */ | 38 | */ |
39 | int | 39 | int |
40 | MHD_ip_limit_add (struct MHD_Daemon *daemon, | 40 | MHD_ip_limit_add (struct MHD_Daemon *daemon, |
41 | const struct sockaddr *addr, | 41 | const struct sockaddr *addr, |
42 | socklen_t addrlen) | 42 | socklen_t addrlen) |
43 | MHD_NONNULL (1,2); | 43 | MHD_NONNULL (1,2); |
44 | 44 | ||
45 | 45 | ||
46 | /** | 46 | /** |
@@ -53,8 +53,8 @@ MHD_ip_limit_add (struct MHD_Daemon *daemon, | |||
53 | */ | 53 | */ |
54 | void | 54 | void |
55 | MHD_ip_limit_del (struct MHD_Daemon *daemon, | 55 | MHD_ip_limit_del (struct MHD_Daemon *daemon, |
56 | const struct sockaddr *addr, | 56 | const struct sockaddr *addr, |
57 | socklen_t addrlen) | 57 | socklen_t addrlen) |
58 | MHD_NONNULL (1,2); | 58 | MHD_NONNULL (1,2); |
59 | 59 | ||
60 | #endif | 60 | #endif |
diff --git a/src/lib/daemon_options.c b/src/lib/daemon_options.c index 4d7bbdf1..04c9cb2f 100644 --- a/src/lib/daemon_options.c +++ b/src/lib/daemon_options.c | |||
@@ -38,8 +38,8 @@ | |||
38 | */ | 38 | */ |
39 | void | 39 | void |
40 | MHD_daemon_set_logger (struct MHD_Daemon *daemon, | 40 | MHD_daemon_set_logger (struct MHD_Daemon *daemon, |
41 | MHD_LoggingCallback logger, | 41 | MHD_LoggingCallback logger, |
42 | void *logger_cls) | 42 | void *logger_cls) |
43 | { | 43 | { |
44 | daemon->logger = logger; | 44 | daemon->logger = logger; |
45 | daemon->logger_cls = logger_cls; | 45 | daemon->logger_cls = logger_cls; |
@@ -148,8 +148,8 @@ MHD_daemon_disallow_upgrade (struct MHD_Daemon *daemon) | |||
148 | */ | 148 | */ |
149 | enum MHD_Bool | 149 | enum MHD_Bool |
150 | MHD_daemon_tcp_fastopen (struct MHD_Daemon *daemon, | 150 | MHD_daemon_tcp_fastopen (struct MHD_Daemon *daemon, |
151 | enum MHD_FastOpenMethod fom, | 151 | enum MHD_FastOpenMethod fom, |
152 | unsigned int queue_length) | 152 | unsigned int queue_length) |
153 | { | 153 | { |
154 | daemon->fast_open_method = fom; | 154 | daemon->fast_open_method = fom; |
155 | daemon->fo_queue_length = queue_length; | 155 | daemon->fo_queue_length = queue_length; |
@@ -185,8 +185,8 @@ MHD_daemon_tcp_fastopen (struct MHD_Daemon *daemon, | |||
185 | */ | 185 | */ |
186 | void | 186 | void |
187 | MHD_daemon_bind_port (struct MHD_Daemon *daemon, | 187 | MHD_daemon_bind_port (struct MHD_Daemon *daemon, |
188 | enum MHD_AddressFamily af, | 188 | enum MHD_AddressFamily af, |
189 | uint16_t port) | 189 | uint16_t port) |
190 | { | 190 | { |
191 | daemon->listen_af = af; | 191 | daemon->listen_af = af; |
192 | daemon->listen_port = port; | 192 | daemon->listen_port = port; |
@@ -204,12 +204,12 @@ MHD_daemon_bind_port (struct MHD_Daemon *daemon, | |||
204 | */ | 204 | */ |
205 | void | 205 | void |
206 | MHD_daemon_bind_socket_address (struct MHD_Daemon *daemon, | 206 | MHD_daemon_bind_socket_address (struct MHD_Daemon *daemon, |
207 | const struct sockaddr *sa, | 207 | const struct sockaddr *sa, |
208 | size_t sa_len) | 208 | size_t sa_len) |
209 | { | 209 | { |
210 | memcpy (&daemon->listen_sa, | 210 | memcpy (&daemon->listen_sa, |
211 | sa, | 211 | sa, |
212 | sa_len); | 212 | sa_len); |
213 | daemon->listen_sa_len = sa_len; | 213 | daemon->listen_sa_len = sa_len; |
214 | } | 214 | } |
215 | 215 | ||
@@ -223,7 +223,7 @@ MHD_daemon_bind_socket_address (struct MHD_Daemon *daemon, | |||
223 | */ | 223 | */ |
224 | void | 224 | void |
225 | MHD_daemon_listen_backlog (struct MHD_Daemon *daemon, | 225 | MHD_daemon_listen_backlog (struct MHD_Daemon *daemon, |
226 | int listen_backlog) | 226 | int listen_backlog) |
227 | { | 227 | { |
228 | daemon->listen_backlog = listen_backlog; | 228 | daemon->listen_backlog = listen_backlog; |
229 | } | 229 | } |
@@ -275,7 +275,7 @@ MHD_daemon_enable_shoutcast (struct MHD_Daemon *daemon) | |||
275 | */ | 275 | */ |
276 | void | 276 | void |
277 | MHD_daemon_listen_socket (struct MHD_Daemon *daemon, | 277 | MHD_daemon_listen_socket (struct MHD_Daemon *daemon, |
278 | MHD_socket listen_socket) | 278 | MHD_socket listen_socket) |
279 | { | 279 | { |
280 | daemon->listen_socket = listen_socket; | 280 | daemon->listen_socket = listen_socket; |
281 | } | 281 | } |
@@ -290,7 +290,7 @@ MHD_daemon_listen_socket (struct MHD_Daemon *daemon, | |||
290 | */ | 290 | */ |
291 | enum MHD_Bool | 291 | enum MHD_Bool |
292 | MHD_daemon_event_loop (struct MHD_Daemon *daemon, | 292 | MHD_daemon_event_loop (struct MHD_Daemon *daemon, |
293 | enum MHD_EventLoopSyscall els) | 293 | enum MHD_EventLoopSyscall els) |
294 | { | 294 | { |
295 | switch (els) | 295 | switch (els) |
296 | { | 296 | { |
@@ -326,7 +326,7 @@ MHD_daemon_event_loop (struct MHD_Daemon *daemon, | |||
326 | */ | 326 | */ |
327 | void | 327 | void |
328 | MHD_daemon_protocol_strict_level (struct MHD_Daemon *daemon, | 328 | MHD_daemon_protocol_strict_level (struct MHD_Daemon *daemon, |
329 | enum MHD_ProtocolStrictLevel sl) | 329 | enum MHD_ProtocolStrictLevel sl) |
330 | { | 330 | { |
331 | daemon->protocol_strict_level = sl; | 331 | daemon->protocol_strict_level = sl; |
332 | } | 332 | } |
@@ -349,8 +349,8 @@ MHD_daemon_protocol_strict_level (struct MHD_Daemon *daemon, | |||
349 | */ | 349 | */ |
350 | enum MHD_StatusCode | 350 | enum MHD_StatusCode |
351 | MHD_daemon_set_tls_backend (struct MHD_Daemon *daemon, | 351 | MHD_daemon_set_tls_backend (struct MHD_Daemon *daemon, |
352 | const char *tls_backend, | 352 | const char *tls_backend, |
353 | const char *ciphers) | 353 | const char *ciphers) |
354 | { | 354 | { |
355 | #if ! (defined(HTTPS_SUPPORT) && defined (HAVE_DLFCN_H)) | 355 | #if ! (defined(HTTPS_SUPPORT) && defined (HAVE_DLFCN_H)) |
356 | return MHD_SC_TLS_DISABLED; | 356 | return MHD_SC_TLS_DISABLED; |
@@ -361,18 +361,18 @@ MHD_daemon_set_tls_backend (struct MHD_Daemon *daemon, | |||
361 | 361 | ||
362 | /* todo: .dll on W32? */ | 362 | /* todo: .dll on W32? */ |
363 | res = MHD_snprintf_ (filename, | 363 | res = MHD_snprintf_ (filename, |
364 | sizeof (filename), | 364 | sizeof (filename), |
365 | "%s/libmicrohttpd_tls_%s.so", | 365 | "%s/libmicrohttpd_tls_%s.so", |
366 | MHD_PLUGIN_INSTALL_PREFIX, | 366 | MHD_PLUGIN_INSTALL_PREFIX, |
367 | tls_backend); | 367 | tls_backend); |
368 | if (0 >= res) | 368 | if (0 >= res) |
369 | return MHD_SC_TLS_BACKEND_UNSUPPORTED; /* string too long? */ | 369 | return MHD_SC_TLS_BACKEND_UNSUPPORTED; /* string too long? */ |
370 | if (NULL == | 370 | if (NULL == |
371 | (daemon->tls_backend_lib = dlopen (filename, | 371 | (daemon->tls_backend_lib = dlopen (filename, |
372 | RTLD_NOW | RTLD_LOCAL))) | 372 | RTLD_NOW | RTLD_LOCAL))) |
373 | return MHD_SC_TLS_BACKEND_UNSUPPORTED; /* plugin not found */ | 373 | return MHD_SC_TLS_BACKEND_UNSUPPORTED; /* plugin not found */ |
374 | if (NULL == (init = dlsym (daemon->tls_backend_lib, | 374 | if (NULL == (init = dlsym (daemon->tls_backend_lib, |
375 | "MHD_TLS_init_" MHD_TLS_ABI_VERSION_STR))) | 375 | "MHD_TLS_init_" MHD_TLS_ABI_VERSION_STR))) |
376 | 376 | ||
377 | { | 377 | { |
378 | dlclose (daemon->tls_backend_lib); | 378 | dlclose (daemon->tls_backend_lib); |
@@ -405,9 +405,9 @@ MHD_daemon_set_tls_backend (struct MHD_Daemon *daemon, | |||
405 | */ | 405 | */ |
406 | enum MHD_StatusCode | 406 | enum MHD_StatusCode |
407 | MHD_daemon_tls_key_and_cert_from_memory (struct MHD_Daemon *daemon, | 407 | MHD_daemon_tls_key_and_cert_from_memory (struct MHD_Daemon *daemon, |
408 | const char *mem_key, | 408 | const char *mem_key, |
409 | const char *mem_cert, | 409 | const char *mem_cert, |
410 | const char *pass) | 410 | const char *pass) |
411 | { | 411 | { |
412 | #ifndef HTTPS_SUPPORT | 412 | #ifndef HTTPS_SUPPORT |
413 | return MHD_SC_TLS_DISABLED; | 413 | return MHD_SC_TLS_DISABLED; |
@@ -417,9 +417,9 @@ MHD_daemon_tls_key_and_cert_from_memory (struct MHD_Daemon *daemon, | |||
417 | if (NULL == (plugin = daemon->tls_api)) | 417 | if (NULL == (plugin = daemon->tls_api)) |
418 | return MHD_SC_TLS_BACKEND_UNINITIALIZED; | 418 | return MHD_SC_TLS_BACKEND_UNINITIALIZED; |
419 | return plugin->init_kcp (plugin->cls, | 419 | return plugin->init_kcp (plugin->cls, |
420 | mem_key, | 420 | mem_key, |
421 | mem_cert, | 421 | mem_cert, |
422 | pass); | 422 | pass); |
423 | #endif | 423 | #endif |
424 | } | 424 | } |
425 | 425 | ||
@@ -435,7 +435,7 @@ MHD_daemon_tls_key_and_cert_from_memory (struct MHD_Daemon *daemon, | |||
435 | */ | 435 | */ |
436 | enum MHD_StatusCode | 436 | enum MHD_StatusCode |
437 | MHD_daemon_tls_mem_dhparams (struct MHD_Daemon *daemon, | 437 | MHD_daemon_tls_mem_dhparams (struct MHD_Daemon *daemon, |
438 | const char *dh) | 438 | const char *dh) |
439 | { | 439 | { |
440 | #ifndef HTTPS_SUPPORT | 440 | #ifndef HTTPS_SUPPORT |
441 | return MHD_SC_TLS_DISABLED; | 441 | return MHD_SC_TLS_DISABLED; |
@@ -445,7 +445,7 @@ MHD_daemon_tls_mem_dhparams (struct MHD_Daemon *daemon, | |||
445 | if (NULL == (plugin = daemon->tls_api)) | 445 | if (NULL == (plugin = daemon->tls_api)) |
446 | return MHD_SC_TLS_BACKEND_UNINITIALIZED; | 446 | return MHD_SC_TLS_BACKEND_UNINITIALIZED; |
447 | return plugin->init_dhparams (plugin->cls, | 447 | return plugin->init_dhparams (plugin->cls, |
448 | dh); | 448 | dh); |
449 | #endif | 449 | #endif |
450 | } | 450 | } |
451 | 451 | ||
@@ -461,7 +461,7 @@ MHD_daemon_tls_mem_dhparams (struct MHD_Daemon *daemon, | |||
461 | */ | 461 | */ |
462 | enum MHD_StatusCode | 462 | enum MHD_StatusCode |
463 | MHD_daemon_tls_mem_trust (struct MHD_Daemon *daemon, | 463 | MHD_daemon_tls_mem_trust (struct MHD_Daemon *daemon, |
464 | const char *mem_trust) | 464 | const char *mem_trust) |
465 | { | 465 | { |
466 | #ifndef HTTPS_SUPPORT | 466 | #ifndef HTTPS_SUPPORT |
467 | return MHD_SC_TLS_DISABLED; | 467 | return MHD_SC_TLS_DISABLED; |
@@ -471,7 +471,7 @@ MHD_daemon_tls_mem_trust (struct MHD_Daemon *daemon, | |||
471 | if (NULL == (plugin = daemon->tls_api)) | 471 | if (NULL == (plugin = daemon->tls_api)) |
472 | return MHD_SC_TLS_BACKEND_UNINITIALIZED; | 472 | return MHD_SC_TLS_BACKEND_UNINITIALIZED; |
473 | return plugin->init_mem_trust (plugin->cls, | 473 | return plugin->init_mem_trust (plugin->cls, |
474 | mem_trust); | 474 | mem_trust); |
475 | #endif | 475 | #endif |
476 | } | 476 | } |
477 | 477 | ||
@@ -485,7 +485,7 @@ MHD_daemon_tls_mem_trust (struct MHD_Daemon *daemon, | |||
485 | */ | 485 | */ |
486 | enum MHD_StatusCode | 486 | enum MHD_StatusCode |
487 | MHD_daemon_gnutls_credentials (struct MHD_Daemon *daemon, | 487 | MHD_daemon_gnutls_credentials (struct MHD_Daemon *daemon, |
488 | int gnutls_credentials) | 488 | int gnutls_credentials) |
489 | { | 489 | { |
490 | #ifndef HTTPS_SUPPORT | 490 | #ifndef HTTPS_SUPPORT |
491 | return MHD_SC_TLS_DISABLED; | 491 | return MHD_SC_TLS_DISABLED; |
@@ -518,7 +518,7 @@ MHD_daemon_gnutls_credentials (struct MHD_Daemon *daemon, | |||
518 | */ | 518 | */ |
519 | enum MHD_StatusCode | 519 | enum MHD_StatusCode |
520 | MHD_daemon_gnutls_key_and_cert_from_callback (struct MHD_Daemon *daemon, | 520 | MHD_daemon_gnutls_key_and_cert_from_callback (struct MHD_Daemon *daemon, |
521 | void *cb) | 521 | void *cb) |
522 | { | 522 | { |
523 | #ifndef HTTPS_SUPPORT | 523 | #ifndef HTTPS_SUPPORT |
524 | return MHD_SC_TLS_DISABLED; | 524 | return MHD_SC_TLS_DISABLED; |
@@ -541,7 +541,7 @@ MHD_daemon_gnutls_key_and_cert_from_callback (struct MHD_Daemon *daemon, | |||
541 | */ | 541 | */ |
542 | void | 542 | void |
543 | MHD_daemon_threading_mode (struct MHD_Daemon *daemon, | 543 | MHD_daemon_threading_mode (struct MHD_Daemon *daemon, |
544 | enum MHD_ThreadingMode tm) | 544 | enum MHD_ThreadingMode tm) |
545 | { | 545 | { |
546 | daemon->threading_mode = tm; | 546 | daemon->threading_mode = tm; |
547 | } | 547 | } |
@@ -558,8 +558,8 @@ MHD_daemon_threading_mode (struct MHD_Daemon *daemon, | |||
558 | */ | 558 | */ |
559 | void | 559 | void |
560 | MHD_daemon_accept_policy (struct MHD_Daemon *daemon, | 560 | MHD_daemon_accept_policy (struct MHD_Daemon *daemon, |
561 | MHD_AcceptPolicyCallback apc, | 561 | MHD_AcceptPolicyCallback apc, |
562 | void *apc_cls) | 562 | void *apc_cls) |
563 | { | 563 | { |
564 | daemon->accept_policy_cb = apc; | 564 | daemon->accept_policy_cb = apc; |
565 | daemon->accept_policy_cb_cls = apc_cls; | 565 | daemon->accept_policy_cb_cls = apc_cls; |
@@ -577,8 +577,8 @@ MHD_daemon_accept_policy (struct MHD_Daemon *daemon, | |||
577 | */ | 577 | */ |
578 | void | 578 | void |
579 | MHD_daemon_set_early_uri_logger (struct MHD_Daemon *daemon, | 579 | MHD_daemon_set_early_uri_logger (struct MHD_Daemon *daemon, |
580 | MHD_EarlyUriLogCallback cb, | 580 | MHD_EarlyUriLogCallback cb, |
581 | void *cb_cls) | 581 | void *cb_cls) |
582 | { | 582 | { |
583 | daemon->early_uri_logger_cb = cb; | 583 | daemon->early_uri_logger_cb = cb; |
584 | daemon->early_uri_logger_cb_cls = cb_cls; | 584 | daemon->early_uri_logger_cb_cls = cb_cls; |
@@ -595,8 +595,8 @@ MHD_daemon_set_early_uri_logger (struct MHD_Daemon *daemon, | |||
595 | */ | 595 | */ |
596 | void | 596 | void |
597 | MHD_daemon_set_notify_connection (struct MHD_Daemon *daemon, | 597 | MHD_daemon_set_notify_connection (struct MHD_Daemon *daemon, |
598 | MHD_NotifyConnectionCallback ncc, | 598 | MHD_NotifyConnectionCallback ncc, |
599 | void *ncc_cls) | 599 | void *ncc_cls) |
600 | { | 600 | { |
601 | daemon->notify_connection_cb = ncc; | 601 | daemon->notify_connection_cb = ncc; |
602 | daemon->notify_connection_cb_cls = ncc_cls; | 602 | daemon->notify_connection_cb_cls = ncc_cls; |
@@ -616,8 +616,8 @@ MHD_daemon_set_notify_connection (struct MHD_Daemon *daemon, | |||
616 | */ | 616 | */ |
617 | void | 617 | void |
618 | MHD_daemon_connection_memory_limit (struct MHD_Daemon *daemon, | 618 | MHD_daemon_connection_memory_limit (struct MHD_Daemon *daemon, |
619 | size_t memory_limit_b, | 619 | size_t memory_limit_b, |
620 | size_t memory_increment_b) | 620 | size_t memory_increment_b) |
621 | { | 621 | { |
622 | if (memory_increment_b >= memory_limit_b) | 622 | if (memory_increment_b >= memory_limit_b) |
623 | MHD_PANIC ("sane memory increment must be below memory limit"); | 623 | MHD_PANIC ("sane memory increment must be below memory limit"); |
@@ -636,7 +636,7 @@ MHD_daemon_connection_memory_limit (struct MHD_Daemon *daemon, | |||
636 | */ | 636 | */ |
637 | void | 637 | void |
638 | MHD_daemon_thread_stack_size (struct MHD_Daemon *daemon, | 638 | MHD_daemon_thread_stack_size (struct MHD_Daemon *daemon, |
639 | size_t stack_limit_b) | 639 | size_t stack_limit_b) |
640 | { | 640 | { |
641 | daemon->thread_stack_limit_b = stack_limit_b; | 641 | daemon->thread_stack_limit_b = stack_limit_b; |
642 | } | 642 | } |
@@ -659,8 +659,8 @@ MHD_daemon_thread_stack_size (struct MHD_Daemon *daemon, | |||
659 | */ | 659 | */ |
660 | void | 660 | void |
661 | MHD_daemon_connection_limits (struct MHD_Daemon *daemon, | 661 | MHD_daemon_connection_limits (struct MHD_Daemon *daemon, |
662 | unsigned int global_connection_limit, | 662 | unsigned int global_connection_limit, |
663 | unsigned int ip_connection_limit) | 663 | unsigned int ip_connection_limit) |
664 | { | 664 | { |
665 | daemon->global_connection_limit = global_connection_limit; | 665 | daemon->global_connection_limit = global_connection_limit; |
666 | daemon->ip_connection_limit = ip_connection_limit; | 666 | daemon->ip_connection_limit = ip_connection_limit; |
@@ -677,7 +677,7 @@ MHD_daemon_connection_limits (struct MHD_Daemon *daemon, | |||
677 | */ | 677 | */ |
678 | void | 678 | void |
679 | MHD_daemon_connection_default_timeout (struct MHD_Daemon *daemon, | 679 | MHD_daemon_connection_default_timeout (struct MHD_Daemon *daemon, |
680 | unsigned int timeout_s) | 680 | unsigned int timeout_s) |
681 | { | 681 | { |
682 | daemon->connection_default_timeout = (time_t) timeout_s; | 682 | daemon->connection_default_timeout = (time_t) timeout_s; |
683 | } | 683 | } |
@@ -696,8 +696,8 @@ MHD_daemon_connection_default_timeout (struct MHD_Daemon *daemon, | |||
696 | */ | 696 | */ |
697 | void | 697 | void |
698 | MHD_daemon_unescape_cb (struct MHD_Daemon *daemon, | 698 | MHD_daemon_unescape_cb (struct MHD_Daemon *daemon, |
699 | MHD_UnescapeCallback unescape_cb, | 699 | MHD_UnescapeCallback unescape_cb, |
700 | void *unescape_cb_cls) | 700 | void *unescape_cb_cls) |
701 | { | 701 | { |
702 | daemon->unescape_cb = unescape_cb; | 702 | daemon->unescape_cb = unescape_cb; |
703 | daemon->unescape_cb_cls = unescape_cb_cls; | 703 | daemon->unescape_cb_cls = unescape_cb_cls; |
@@ -715,8 +715,8 @@ MHD_daemon_unescape_cb (struct MHD_Daemon *daemon, | |||
715 | */ | 715 | */ |
716 | void | 716 | void |
717 | MHD_daemon_digest_auth_random (struct MHD_Daemon *daemon, | 717 | MHD_daemon_digest_auth_random (struct MHD_Daemon *daemon, |
718 | size_t buf_size, | 718 | size_t buf_size, |
719 | const void *buf) | 719 | const void *buf) |
720 | { | 720 | { |
721 | #if ENABLE_DAUTH | 721 | #if ENABLE_DAUTH |
722 | daemon->digest_auth_random_buf = buf; | 722 | daemon->digest_auth_random_buf = buf; |
@@ -739,34 +739,34 @@ MHD_daemon_digest_auth_random (struct MHD_Daemon *daemon, | |||
739 | */ | 739 | */ |
740 | enum MHD_StatusCode | 740 | enum MHD_StatusCode |
741 | MHD_daemon_digest_auth_nc_length (struct MHD_Daemon *daemon, | 741 | MHD_daemon_digest_auth_nc_length (struct MHD_Daemon *daemon, |
742 | size_t nc_length) | 742 | size_t nc_length) |
743 | { | 743 | { |
744 | #if ENABLE_DAUTH | 744 | #if ENABLE_DAUTH |
745 | if ( ( (size_t) (nc_length * sizeof (struct MHD_NonceNc))) / | 745 | if ( ( (size_t) (nc_length * sizeof (struct MHD_NonceNc))) |
746 | sizeof (struct MHD_NonceNc) != nc_length) | 746 | / sizeof (struct MHD_NonceNc) != nc_length) |
747 | { | 747 | { |
748 | #ifdef HAVE_MESSAGES | 748 | #ifdef HAVE_MESSAGES |
749 | MHD_DLOG (daemon, | 749 | MHD_DLOG (daemon, |
750 | _("Specified value for NC_SIZE too large\n")); | 750 | _ ("Specified value for NC_SIZE too large\n")); |
751 | #endif | 751 | #endif |
752 | return MHD_SC_DIGEST_AUTH_NC_LENGTH_TOO_BIG; | 752 | return MHD_SC_DIGEST_AUTH_NC_LENGTH_TOO_BIG; |
753 | } | 753 | } |
754 | if (0 < nc_length) | 754 | if (0 < nc_length) |
755 | { | ||
756 | if (NULL != daemon->nnc) | ||
757 | free (daemon->nnc); | ||
758 | daemon->nnc = malloc (daemon->nonce_nc_size | ||
759 | * sizeof (struct MHD_NonceNc)); | ||
760 | if (NULL == daemon->nnc) | ||
755 | { | 761 | { |
756 | if (NULL != daemon->nnc) | ||
757 | free (daemon->nnc); | ||
758 | daemon->nnc = malloc (daemon->nonce_nc_size * | ||
759 | sizeof (struct MHD_NonceNc)); | ||
760 | if (NULL == daemon->nnc) | ||
761 | { | ||
762 | #ifdef HAVE_MESSAGES | 762 | #ifdef HAVE_MESSAGES |
763 | MHD_DLOG (daemon, | 763 | MHD_DLOG (daemon, |
764 | _("Failed to allocate memory for nonce-nc map: %s\n"), | 764 | _ ("Failed to allocate memory for nonce-nc map: %s\n"), |
765 | MHD_strerror_ (errno)); | 765 | MHD_strerror_ (errno)); |
766 | #endif | 766 | #endif |
767 | return MHD_SC_DIGEST_AUTH_NC_ALLOCATION_FAILURE; | 767 | return MHD_SC_DIGEST_AUTH_NC_ALLOCATION_FAILURE; |
768 | } | ||
769 | } | 768 | } |
769 | } | ||
770 | daemon->digest_nc_length = nc_length; | 770 | daemon->digest_nc_length = nc_length; |
771 | return MHD_SC_OK; | 771 | return MHD_SC_OK; |
772 | #else | 772 | #else |
diff --git a/src/lib/daemon_poll.c b/src/lib/daemon_poll.c index 80599e93..1fea9fd6 100644 --- a/src/lib/daemon_poll.c +++ b/src/lib/daemon_poll.c | |||
@@ -45,7 +45,7 @@ | |||
45 | */ | 45 | */ |
46 | static void | 46 | static void |
47 | urh_update_pollfd (struct MHD_UpgradeResponseHandle *urh, | 47 | urh_update_pollfd (struct MHD_UpgradeResponseHandle *urh, |
48 | struct pollfd p[2]) | 48 | struct pollfd p[2]) |
49 | { | 49 | { |
50 | p[0].events = 0; | 50 | p[0].events = 0; |
51 | p[1].events = 0; | 51 | p[1].events = 0; |
@@ -86,12 +86,12 @@ urh_update_pollfd (struct MHD_UpgradeResponseHandle *urh, | |||
86 | */ | 86 | */ |
87 | static void | 87 | static void |
88 | urh_to_pollfd (struct MHD_UpgradeResponseHandle *urh, | 88 | urh_to_pollfd (struct MHD_UpgradeResponseHandle *urh, |
89 | struct pollfd p[2]) | 89 | struct pollfd p[2]) |
90 | { | 90 | { |
91 | p[0].fd = urh->connection->socket_fd; | 91 | p[0].fd = urh->connection->socket_fd; |
92 | p[1].fd = urh->mhd.socket; | 92 | p[1].fd = urh->mhd.socket; |
93 | urh_update_pollfd (urh, | 93 | urh_update_pollfd (urh, |
94 | p); | 94 | p); |
95 | } | 95 | } |
96 | 96 | ||
97 | 97 | ||
@@ -102,7 +102,7 @@ urh_to_pollfd (struct MHD_UpgradeResponseHandle *urh, | |||
102 | */ | 102 | */ |
103 | static void | 103 | static void |
104 | urh_from_pollfd (struct MHD_UpgradeResponseHandle *urh, | 104 | urh_from_pollfd (struct MHD_UpgradeResponseHandle *urh, |
105 | struct pollfd p[2]) | 105 | struct pollfd p[2]) |
106 | { | 106 | { |
107 | /* Reset read/write ready, preserve error state. */ | 107 | /* Reset read/write ready, preserve error state. */ |
108 | urh->app.celi &= (~MHD_EPOLL_STATE_READ_READY & ~MHD_EPOLL_STATE_WRITE_READY); | 108 | urh->app.celi &= (~MHD_EPOLL_STATE_READ_READY & ~MHD_EPOLL_STATE_WRITE_READY); |
@@ -138,7 +138,7 @@ urh_from_pollfd (struct MHD_UpgradeResponseHandle *urh, | |||
138 | */ | 138 | */ |
139 | enum MHD_StatusCode | 139 | enum MHD_StatusCode |
140 | MHD_daemon_poll_all_ (struct MHD_Daemon *daemon, | 140 | MHD_daemon_poll_all_ (struct MHD_Daemon *daemon, |
141 | bool may_block) | 141 | bool may_block) |
142 | { | 142 | { |
143 | unsigned int num_connections; | 143 | unsigned int num_connections; |
144 | struct MHD_Connection *pos; | 144 | struct MHD_Connection *pos; |
@@ -171,103 +171,103 @@ MHD_daemon_poll_all_ (struct MHD_Daemon *daemon, | |||
171 | MHD_socket ls; | 171 | MHD_socket ls; |
172 | 172 | ||
173 | p = MHD_calloc_ ((2 + num_connections), | 173 | p = MHD_calloc_ ((2 + num_connections), |
174 | sizeof (struct pollfd)); | 174 | sizeof (struct pollfd)); |
175 | if (NULL == p) | 175 | if (NULL == p) |
176 | { | 176 | { |
177 | #ifdef HAVE_MESSAGES | 177 | #ifdef HAVE_MESSAGES |
178 | MHD_DLOG (daemon, | 178 | MHD_DLOG (daemon, |
179 | MHD_SC_POLL_MALLOC_FAILURE, | 179 | MHD_SC_POLL_MALLOC_FAILURE, |
180 | _("Error allocating memory: %s\n"), | 180 | _ ("Error allocating memory: %s\n"), |
181 | MHD_strerror_(errno)); | 181 | MHD_strerror_ (errno)); |
182 | #endif | 182 | #endif |
183 | return MHD_SC_POLL_MALLOC_FAILURE; | 183 | return MHD_SC_POLL_MALLOC_FAILURE; |
184 | } | 184 | } |
185 | poll_server = 0; | 185 | poll_server = 0; |
186 | poll_listen = -1; | 186 | poll_listen = -1; |
187 | if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_socket)) && | 187 | if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_socket)) && |
188 | (! daemon->was_quiesced) && | 188 | (! daemon->was_quiesced) && |
189 | (daemon->connections < daemon->global_connection_limit) && | 189 | (daemon->connections < daemon->global_connection_limit) && |
190 | (! daemon->at_limit) ) | 190 | (! daemon->at_limit) ) |
191 | { | 191 | { |
192 | /* only listen if we are not at the connection limit */ | 192 | /* only listen if we are not at the connection limit */ |
193 | p[poll_server].fd = ls; | 193 | p[poll_server].fd = ls; |
194 | p[poll_server].events = POLLIN; | 194 | p[poll_server].events = POLLIN; |
195 | p[poll_server].revents = 0; | 195 | p[poll_server].revents = 0; |
196 | poll_listen = (int) poll_server; | 196 | poll_listen = (int) poll_server; |
197 | poll_server++; | 197 | poll_server++; |
198 | } | 198 | } |
199 | poll_itc_idx = -1; | 199 | poll_itc_idx = -1; |
200 | if (MHD_ITC_IS_VALID_(daemon->itc)) | 200 | if (MHD_ITC_IS_VALID_ (daemon->itc)) |
201 | { | 201 | { |
202 | p[poll_server].fd = MHD_itc_r_fd_ (daemon->itc); | 202 | p[poll_server].fd = MHD_itc_r_fd_ (daemon->itc); |
203 | p[poll_server].events = POLLIN; | 203 | p[poll_server].events = POLLIN; |
204 | p[poll_server].revents = 0; | 204 | p[poll_server].revents = 0; |
205 | poll_itc_idx = (int) poll_server; | 205 | poll_itc_idx = (int) poll_server; |
206 | poll_server++; | 206 | poll_server++; |
207 | } | 207 | } |
208 | if (! may_block) | 208 | if (! may_block) |
209 | timeout = 0; | 209 | timeout = 0; |
210 | else if ( (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode) || | 210 | else if ( (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode) || |
211 | (MHD_SC_OK != /* FIXME: distinguish between NO_TIMEOUT and errors! */ | 211 | (MHD_SC_OK != /* FIXME: distinguish between NO_TIMEOUT and errors! */ |
212 | MHD_daemon_get_timeout (daemon, | 212 | MHD_daemon_get_timeout (daemon, |
213 | <imeout)) ) | 213 | <imeout)) ) |
214 | timeout = -1; | 214 | timeout = -1; |
215 | else | 215 | else |
216 | timeout = (ltimeout > INT_MAX) ? INT_MAX : (int) ltimeout; | 216 | timeout = (ltimeout > INT_MAX) ? INT_MAX : (int) ltimeout; |
217 | 217 | ||
218 | i = 0; | 218 | i = 0; |
219 | for (pos = daemon->connections_tail; NULL != pos; pos = pos->prev) | 219 | for (pos = daemon->connections_tail; NULL != pos; pos = pos->prev) |
220 | { | ||
221 | p[poll_server + i].fd = pos->socket_fd; | ||
222 | switch (pos->request.event_loop_info) | ||
220 | { | 223 | { |
221 | p[poll_server+i].fd = pos->socket_fd; | 224 | case MHD_EVENT_LOOP_INFO_READ: |
222 | switch (pos->request.event_loop_info) | 225 | p[poll_server + i].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC; |
223 | { | 226 | break; |
224 | case MHD_EVENT_LOOP_INFO_READ: | 227 | case MHD_EVENT_LOOP_INFO_WRITE: |
225 | p[poll_server+i].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC; | 228 | p[poll_server + i].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC; |
226 | break; | 229 | break; |
227 | case MHD_EVENT_LOOP_INFO_WRITE: | 230 | case MHD_EVENT_LOOP_INFO_BLOCK: |
228 | p[poll_server+i].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC; | 231 | p[poll_server + i].events |= MHD_POLL_EVENTS_ERR_DISC; |
229 | break; | 232 | break; |
230 | case MHD_EVENT_LOOP_INFO_BLOCK: | 233 | case MHD_EVENT_LOOP_INFO_CLEANUP: |
231 | p[poll_server+i].events |= MHD_POLL_EVENTS_ERR_DISC; | 234 | timeout = 0; /* clean up "pos" immediately */ |
232 | break; | 235 | break; |
233 | case MHD_EVENT_LOOP_INFO_CLEANUP: | ||
234 | timeout = 0; /* clean up "pos" immediately */ | ||
235 | break; | ||
236 | } | ||
237 | i++; | ||
238 | } | 236 | } |
237 | i++; | ||
238 | } | ||
239 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) | 239 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) |
240 | for (urh = daemon->urh_tail; NULL != urh; urh = urh->prev) | 240 | for (urh = daemon->urh_tail; NULL != urh; urh = urh->prev) |
241 | { | 241 | { |
242 | urh_to_pollfd (urh, | 242 | urh_to_pollfd (urh, |
243 | &(p[poll_server+i])); | 243 | &(p[poll_server + i])); |
244 | i += 2; | 244 | i += 2; |
245 | } | 245 | } |
246 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ | 246 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ |
247 | if (0 == poll_server + num_connections) | 247 | if (0 == poll_server + num_connections) |
248 | { | ||
249 | free (p); | ||
250 | return MHD_SC_OK; | ||
251 | } | ||
252 | if (MHD_sys_poll_ (p, | ||
253 | poll_server + num_connections, | ||
254 | timeout) < 0) | ||
255 | { | ||
256 | const int err = MHD_socket_get_error_ (); | ||
257 | if (MHD_SCKT_ERR_IS_EINTR_ (err)) | ||
248 | { | 258 | { |
249 | free (p); | 259 | free (p); |
250 | return MHD_SC_OK; | 260 | return MHD_SC_OK; |
251 | } | 261 | } |
252 | if (MHD_sys_poll_(p, | ||
253 | poll_server + num_connections, | ||
254 | timeout) < 0) | ||
255 | { | ||
256 | const int err = MHD_socket_get_error_ (); | ||
257 | if (MHD_SCKT_ERR_IS_EINTR_ (err)) | ||
258 | { | ||
259 | free(p); | ||
260 | return MHD_SC_OK; | ||
261 | } | ||
262 | #ifdef HAVE_MESSAGES | 262 | #ifdef HAVE_MESSAGES |
263 | MHD_DLOG (daemon, | 263 | MHD_DLOG (daemon, |
264 | MHD_SC_UNEXPECTED_POLL_ERROR, | 264 | MHD_SC_UNEXPECTED_POLL_ERROR, |
265 | _("poll failed: %s\n"), | 265 | _ ("poll failed: %s\n"), |
266 | MHD_socket_strerr_ (err)); | 266 | MHD_socket_strerr_ (err)); |
267 | #endif | 267 | #endif |
268 | free(p); | 268 | free (p); |
269 | return MHD_SC_UNEXPECTED_POLL_ERROR; | 269 | return MHD_SC_UNEXPECTED_POLL_ERROR; |
270 | } | 270 | } |
271 | 271 | ||
272 | /* Reset. New value will be set when connections are processed. */ | 272 | /* Reset. New value will be set when connections are processed. */ |
273 | daemon->data_already_pending = false; | 273 | daemon->data_already_pending = false; |
@@ -281,67 +281,69 @@ MHD_daemon_poll_all_ (struct MHD_Daemon *daemon, | |||
281 | 281 | ||
282 | /* handle shutdown */ | 282 | /* handle shutdown */ |
283 | if (daemon->shutdown) | 283 | if (daemon->shutdown) |
284 | { | 284 | { |
285 | free(p); | 285 | free (p); |
286 | return MHD_SC_DAEMON_ALREADY_SHUTDOWN; | 286 | return MHD_SC_DAEMON_ALREADY_SHUTDOWN; |
287 | } | 287 | } |
288 | i = 0; | 288 | i = 0; |
289 | prev = daemon->connections_tail; | 289 | prev = daemon->connections_tail; |
290 | while (NULL != (pos = prev)) | 290 | while (NULL != (pos = prev)) |
291 | { | 291 | { |
292 | prev = pos->prev; | 292 | prev = pos->prev; |
293 | /* first, sanity checks */ | 293 | /* first, sanity checks */ |
294 | if (i >= num_connections) | 294 | if (i >= num_connections) |
295 | break; /* connection list changed somehow, retry later ... */ | 295 | break; /* connection list changed somehow, retry later ... */ |
296 | if (p[poll_server+i].fd != pos->socket_fd) | 296 | if (p[poll_server + i].fd != pos->socket_fd) |
297 | continue; /* fd mismatch, something else happened, retry later ... */ | 297 | continue; /* fd mismatch, something else happened, retry later ... */ |
298 | MHD_connection_call_handlers_ (pos, | 298 | MHD_connection_call_handlers_ (pos, |
299 | 0 != (p[poll_server+i].revents & POLLIN), | 299 | 0 != (p[poll_server + i].revents & POLLIN), |
300 | 0 != (p[poll_server+i].revents & POLLOUT), | 300 | 0 != (p[poll_server + i].revents |
301 | 0 != (p[poll_server+i].revents & MHD_POLL_REVENTS_ERR_DISC)); | 301 | & POLLOUT), |
302 | i++; | 302 | 0 != (p[poll_server + i].revents |
303 | } | 303 | & MHD_POLL_REVENTS_ERR_DISC)); |
304 | i++; | ||
305 | } | ||
304 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) | 306 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) |
305 | for (urh = daemon->urh_tail; NULL != urh; urh = urhn) | 307 | for (urh = daemon->urh_tail; NULL != urh; urh = urhn) |
308 | { | ||
309 | if (i >= num_connections) | ||
310 | break; /* connection list changed somehow, retry later ... */ | ||
311 | |||
312 | /* Get next connection here as connection can be removed | ||
313 | * from 'daemon->urh_head' list. */ | ||
314 | urhn = urh->prev; | ||
315 | /* Check for fd mismatch. FIXME: required for safety? */ | ||
316 | if ((p[poll_server + i].fd != urh->connection->socket_fd) || | ||
317 | (p[poll_server + i + 1].fd != urh->mhd.socket)) | ||
318 | break; | ||
319 | urh_from_pollfd (urh, | ||
320 | &p[poll_server + i]); | ||
321 | i += 2; | ||
322 | MHD_upgrade_response_handle_process_ (urh); | ||
323 | /* Finished forwarding? */ | ||
324 | if ( (0 == urh->in_buffer_size) && | ||
325 | (0 == urh->out_buffer_size) && | ||
326 | (0 == urh->in_buffer_used) && | ||
327 | (0 == urh->out_buffer_used) ) | ||
306 | { | 328 | { |
307 | if (i >= num_connections) | 329 | /* MHD_connection_finish_forward_() will remove connection from |
308 | break; /* connection list changed somehow, retry later ... */ | 330 | * 'daemon->urh_head' list. */ |
309 | 331 | MHD_connection_finish_forward_ (urh->connection); | |
310 | /* Get next connection here as connection can be removed | 332 | urh->clean_ready = true; |
311 | * from 'daemon->urh_head' list. */ | 333 | /* If 'urh->was_closed' already was set to true, connection will be |
312 | urhn = urh->prev; | 334 | * moved immediately to cleanup list. Otherwise connection |
313 | /* Check for fd mismatch. FIXME: required for safety? */ | 335 | * will stay in suspended list until 'urh' will be marked |
314 | if ((p[poll_server+i].fd != urh->connection->socket_fd) || | 336 | * with 'was_closed' by application. */ |
315 | (p[poll_server+i+1].fd != urh->mhd.socket)) | 337 | MHD_request_resume (&urh->connection->request); |
316 | break; | ||
317 | urh_from_pollfd (urh, | ||
318 | &p[poll_server+i]); | ||
319 | i += 2; | ||
320 | MHD_upgrade_response_handle_process_ (urh); | ||
321 | /* Finished forwarding? */ | ||
322 | if ( (0 == urh->in_buffer_size) && | ||
323 | (0 == urh->out_buffer_size) && | ||
324 | (0 == urh->in_buffer_used) && | ||
325 | (0 == urh->out_buffer_used) ) | ||
326 | { | ||
327 | /* MHD_connection_finish_forward_() will remove connection from | ||
328 | * 'daemon->urh_head' list. */ | ||
329 | MHD_connection_finish_forward_ (urh->connection); | ||
330 | urh->clean_ready = true; | ||
331 | /* If 'urh->was_closed' already was set to true, connection will be | ||
332 | * moved immediately to cleanup list. Otherwise connection | ||
333 | * will stay in suspended list until 'urh' will be marked | ||
334 | * with 'was_closed' by application. */ | ||
335 | MHD_request_resume (&urh->connection->request); | ||
336 | } | ||
337 | } | 338 | } |
339 | } | ||
338 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ | 340 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ |
339 | /* handle 'listen' FD */ | 341 | /* handle 'listen' FD */ |
340 | if ( (-1 != poll_listen) && | 342 | if ( (-1 != poll_listen) && |
341 | (0 != (p[poll_listen].revents & POLLIN)) ) | 343 | (0 != (p[poll_listen].revents & POLLIN)) ) |
342 | (void) MHD_accept_connection_ (daemon); | 344 | (void) MHD_accept_connection_ (daemon); |
343 | 345 | ||
344 | free(p); | 346 | free (p); |
345 | } | 347 | } |
346 | return MHD_SC_OK; | 348 | return MHD_SC_OK; |
347 | } | 349 | } |
@@ -356,7 +358,7 @@ MHD_daemon_poll_all_ (struct MHD_Daemon *daemon, | |||
356 | */ | 358 | */ |
357 | enum MHD_StatusCode | 359 | enum MHD_StatusCode |
358 | MHD_daemon_poll_listen_socket_ (struct MHD_Daemon *daemon, | 360 | MHD_daemon_poll_listen_socket_ (struct MHD_Daemon *daemon, |
359 | bool may_block) | 361 | bool may_block) |
360 | { | 362 | { |
361 | struct pollfd p[2]; | 363 | struct pollfd p[2]; |
362 | int timeout; | 364 | int timeout; |
@@ -374,21 +376,21 @@ MHD_daemon_poll_listen_socket_ (struct MHD_Daemon *daemon, | |||
374 | if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_socket)) && | 376 | if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_socket)) && |
375 | (! daemon->was_quiesced) ) | 377 | (! daemon->was_quiesced) ) |
376 | 378 | ||
377 | { | 379 | { |
378 | p[poll_count].fd = ls; | 380 | p[poll_count].fd = ls; |
379 | p[poll_count].events = POLLIN; | 381 | p[poll_count].events = POLLIN; |
380 | p[poll_count].revents = 0; | 382 | p[poll_count].revents = 0; |
381 | poll_listen = poll_count; | 383 | poll_listen = poll_count; |
382 | poll_count++; | 384 | poll_count++; |
383 | } | 385 | } |
384 | if (MHD_ITC_IS_VALID_(daemon->itc)) | 386 | if (MHD_ITC_IS_VALID_ (daemon->itc)) |
385 | { | 387 | { |
386 | p[poll_count].fd = MHD_itc_r_fd_ (daemon->itc); | 388 | p[poll_count].fd = MHD_itc_r_fd_ (daemon->itc); |
387 | p[poll_count].events = POLLIN; | 389 | p[poll_count].events = POLLIN; |
388 | p[poll_count].revents = 0; | 390 | p[poll_count].revents = 0; |
389 | poll_itc_idx = poll_count; | 391 | poll_itc_idx = poll_count; |
390 | poll_count++; | 392 | poll_count++; |
391 | } | 393 | } |
392 | 394 | ||
393 | if (! daemon->disallow_suspend_resume) | 395 | if (! daemon->disallow_suspend_resume) |
394 | (void) MHD_resume_suspended_connections_ (daemon); | 396 | (void) MHD_resume_suspended_connections_ (daemon); |
@@ -399,22 +401,22 @@ MHD_daemon_poll_listen_socket_ (struct MHD_Daemon *daemon, | |||
399 | timeout = -1; | 401 | timeout = -1; |
400 | if (0 == poll_count) | 402 | if (0 == poll_count) |
401 | return MHD_SC_OK; | 403 | return MHD_SC_OK; |
402 | if (MHD_sys_poll_(p, | 404 | if (MHD_sys_poll_ (p, |
403 | poll_count, | 405 | poll_count, |
404 | timeout) < 0) | 406 | timeout) < 0) |
405 | { | 407 | { |
406 | const int err = MHD_socket_get_error_ (); | 408 | const int err = MHD_socket_get_error_ (); |
407 | 409 | ||
408 | if (MHD_SCKT_ERR_IS_EINTR_ (err)) | 410 | if (MHD_SCKT_ERR_IS_EINTR_ (err)) |
409 | return MHD_SC_OK; | 411 | return MHD_SC_OK; |
410 | #ifdef HAVE_MESSAGES | 412 | #ifdef HAVE_MESSAGES |
411 | MHD_DLOG (daemon, | 413 | MHD_DLOG (daemon, |
412 | MHD_SC_UNEXPECTED_POLL_ERROR, | 414 | MHD_SC_UNEXPECTED_POLL_ERROR, |
413 | _("poll failed: %s\n"), | 415 | _ ("poll failed: %s\n"), |
414 | MHD_socket_strerr_ (err)); | 416 | MHD_socket_strerr_ (err)); |
415 | #endif | 417 | #endif |
416 | return MHD_SC_UNEXPECTED_POLL_ERROR; | 418 | return MHD_SC_UNEXPECTED_POLL_ERROR; |
417 | } | 419 | } |
418 | if ( (-1 != poll_itc_idx) && | 420 | if ( (-1 != poll_itc_idx) && |
419 | (0 != (p[poll_itc_idx].revents & POLLIN)) ) | 421 | (0 != (p[poll_itc_idx].revents & POLLIN)) ) |
420 | MHD_itc_clear_ (daemon->itc); | 422 | MHD_itc_clear_ (daemon->itc); |
@@ -439,16 +441,16 @@ MHD_daemon_poll_listen_socket_ (struct MHD_Daemon *daemon, | |||
439 | */ | 441 | */ |
440 | enum MHD_StatusCode | 442 | enum MHD_StatusCode |
441 | MHD_daemon_poll_ (struct MHD_Daemon *daemon, | 443 | MHD_daemon_poll_ (struct MHD_Daemon *daemon, |
442 | bool may_block) | 444 | bool may_block) |
443 | { | 445 | { |
444 | #ifdef HAVE_POLL | 446 | #ifdef HAVE_POLL |
445 | if (daemon->shutdown) | 447 | if (daemon->shutdown) |
446 | return MHD_SC_DAEMON_ALREADY_SHUTDOWN; | 448 | return MHD_SC_DAEMON_ALREADY_SHUTDOWN; |
447 | if (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) | 449 | if (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) |
448 | return MHD_daemon_poll_all_ (daemon, | 450 | return MHD_daemon_poll_all_ (daemon, |
449 | may_block); | 451 | may_block); |
450 | return MHD_daemon_poll_listen_socket_ (daemon, | 452 | return MHD_daemon_poll_listen_socket_ (daemon, |
451 | may_block); | 453 | may_block); |
452 | #else | 454 | #else |
453 | /* This code should be dead, as we should have checked | 455 | /* This code should be dead, as we should have checked |
454 | this earlier... */ | 456 | this earlier... */ |
@@ -472,47 +474,47 @@ MHD_daemon_upgrade_connection_with_poll_ (struct MHD_Connection *con) | |||
472 | struct pollfd p[2]; | 474 | struct pollfd p[2]; |
473 | 475 | ||
474 | memset (p, | 476 | memset (p, |
475 | 0, | 477 | 0, |
476 | sizeof (p)); | 478 | sizeof (p)); |
477 | p[0].fd = urh->connection->socket_fd; | 479 | p[0].fd = urh->connection->socket_fd; |
478 | p[1].fd = urh->mhd.socket; | 480 | p[1].fd = urh->mhd.socket; |
479 | 481 | ||
480 | while ( (0 != urh->in_buffer_size) || | 482 | while ( (0 != urh->in_buffer_size) || |
481 | (0 != urh->out_buffer_size) || | 483 | (0 != urh->out_buffer_size) || |
482 | (0 != urh->in_buffer_used) || | 484 | (0 != urh->in_buffer_used) || |
483 | (0 != urh->out_buffer_used) ) | 485 | (0 != urh->out_buffer_used) ) |
484 | { | 486 | { |
485 | int timeout; | 487 | int timeout; |
486 | 488 | ||
487 | urh_update_pollfd (urh, | 489 | urh_update_pollfd (urh, |
488 | p); | 490 | p); |
489 | 491 | ||
490 | if ( (con->tls_read_ready) && | 492 | if ( (con->tls_read_ready) && |
491 | (urh->in_buffer_used < urh->in_buffer_size)) | 493 | (urh->in_buffer_used < urh->in_buffer_size)) |
492 | timeout = 0; /* No need to wait if incoming data is already pending in TLS buffers. */ | 494 | timeout = 0; /* No need to wait if incoming data is already pending in TLS buffers. */ |
493 | else | 495 | else |
494 | timeout = -1; | 496 | timeout = -1; |
495 | 497 | ||
496 | if (MHD_sys_poll_ (p, | 498 | if (MHD_sys_poll_ (p, |
497 | 2, | 499 | 2, |
498 | timeout) < 0) | 500 | timeout) < 0) |
499 | { | 501 | { |
500 | const int err = MHD_socket_get_error_ (); | 502 | const int err = MHD_socket_get_error_ (); |
501 | 503 | ||
502 | if (MHD_SCKT_ERR_IS_EINTR_ (err)) | 504 | if (MHD_SCKT_ERR_IS_EINTR_ (err)) |
503 | continue; | 505 | continue; |
504 | #ifdef HAVE_MESSAGES | 506 | #ifdef HAVE_MESSAGES |
505 | MHD_DLOG (con->daemon, | 507 | MHD_DLOG (con->daemon, |
506 | MHD_SC_UNEXPECTED_POLL_ERROR, | 508 | MHD_SC_UNEXPECTED_POLL_ERROR, |
507 | _("Error during poll: `%s'\n"), | 509 | _ ("Error during poll: `%s'\n"), |
508 | MHD_socket_strerr_ (err)); | 510 | MHD_socket_strerr_ (err)); |
509 | #endif | 511 | #endif |
510 | break; | 512 | break; |
511 | } | ||
512 | urh_from_pollfd (urh, | ||
513 | p); | ||
514 | MHD_upgrade_response_handle_process_ (urh); | ||
515 | } | 513 | } |
514 | urh_from_pollfd (urh, | ||
515 | p); | ||
516 | MHD_upgrade_response_handle_process_ (urh); | ||
517 | } | ||
516 | } | 518 | } |
517 | #endif | 519 | #endif |
518 | #endif | 520 | #endif |
diff --git a/src/lib/daemon_poll.h b/src/lib/daemon_poll.h index fc5663b0..3c408620 100644 --- a/src/lib/daemon_poll.h +++ b/src/lib/daemon_poll.h | |||
@@ -37,8 +37,8 @@ | |||
37 | */ | 37 | */ |
38 | enum MHD_StatusCode | 38 | enum MHD_StatusCode |
39 | MHD_daemon_poll_all_ (struct MHD_Daemon *daemon, | 39 | MHD_daemon_poll_all_ (struct MHD_Daemon *daemon, |
40 | bool may_block) | 40 | bool may_block) |
41 | MHD_NONNULL(1); | 41 | MHD_NONNULL (1); |
42 | 42 | ||
43 | 43 | ||
44 | /** | 44 | /** |
@@ -50,8 +50,8 @@ MHD_daemon_poll_all_ (struct MHD_Daemon *daemon, | |||
50 | */ | 50 | */ |
51 | enum MHD_StatusCode | 51 | enum MHD_StatusCode |
52 | MHD_daemon_poll_listen_socket_ (struct MHD_Daemon *daemon, | 52 | MHD_daemon_poll_listen_socket_ (struct MHD_Daemon *daemon, |
53 | bool may_block) | 53 | bool may_block) |
54 | MHD_NONNULL (1); | 54 | MHD_NONNULL (1); |
55 | 55 | ||
56 | 56 | ||
57 | /** | 57 | /** |
@@ -63,8 +63,8 @@ MHD_daemon_poll_listen_socket_ (struct MHD_Daemon *daemon, | |||
63 | */ | 63 | */ |
64 | enum MHD_StatusCode | 64 | enum MHD_StatusCode |
65 | MHD_daemon_poll_ (struct MHD_Daemon *daemon, | 65 | MHD_daemon_poll_ (struct MHD_Daemon *daemon, |
66 | bool may_block) | 66 | bool may_block) |
67 | MHD_NONNULL (1); | 67 | MHD_NONNULL (1); |
68 | #endif | 68 | #endif |
69 | 69 | ||
70 | 70 | ||
@@ -78,7 +78,7 @@ MHD_daemon_poll_ (struct MHD_Daemon *daemon, | |||
78 | */ | 78 | */ |
79 | void | 79 | void |
80 | MHD_daemon_upgrade_connection_with_poll_ (struct MHD_Connection *con) | 80 | MHD_daemon_upgrade_connection_with_poll_ (struct MHD_Connection *con) |
81 | MHD_NONNULL(1); | 81 | MHD_NONNULL (1); |
82 | #endif | 82 | #endif |
83 | #endif | 83 | #endif |
84 | 84 | ||
diff --git a/src/lib/daemon_quiesce.c b/src/lib/daemon_quiesce.c index 0d920608..c7275099 100644 --- a/src/lib/daemon_quiesce.c +++ b/src/lib/daemon_quiesce.c | |||
@@ -54,75 +54,76 @@ MHD_daemon_quiesce (struct MHD_Daemon *daemon) | |||
54 | return MHD_INVALID_SOCKET; | 54 | return MHD_INVALID_SOCKET; |
55 | if ( (daemon->disable_itc) && | 55 | if ( (daemon->disable_itc) && |
56 | (MHD_TM_EXTERNAL_EVENT_LOOP != daemon->threading_mode) ) | 56 | (MHD_TM_EXTERNAL_EVENT_LOOP != daemon->threading_mode) ) |
57 | { | 57 | { |
58 | #ifdef HAVE_MESSAGES | 58 | #ifdef HAVE_MESSAGES |
59 | MHD_DLOG (daemon, | 59 | MHD_DLOG (daemon, |
60 | MHD_SC_SYSCALL_QUIESCE_REQUIRES_ITC, | 60 | MHD_SC_SYSCALL_QUIESCE_REQUIRES_ITC, |
61 | "Using MHD_quiesce_daemon in this mode requires ITC\n"); | 61 | "Using MHD_quiesce_daemon in this mode requires ITC\n"); |
62 | #endif | 62 | #endif |
63 | return MHD_INVALID_SOCKET; | 63 | return MHD_INVALID_SOCKET; |
64 | } | 64 | } |
65 | 65 | ||
66 | if (NULL != daemon->worker_pool) | 66 | if (NULL != daemon->worker_pool) |
67 | { | ||
68 | unsigned int i; | ||
69 | |||
70 | for (i = 0; i < daemon->worker_pool_size; i++) | ||
67 | { | 71 | { |
68 | unsigned int i; | 72 | struct MHD_Daemon *worker = &daemon->worker_pool[i]; |
69 | 73 | ||
70 | for (i = 0; i < daemon->worker_pool_size; i++) | 74 | worker->was_quiesced = true; |
71 | { | ||
72 | struct MHD_Daemon *worker = &daemon->worker_pool[i]; | ||
73 | |||
74 | worker->was_quiesced = true; | ||
75 | #ifdef EPOLL_SUPPORT | ||
76 | if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) && | ||
77 | (-1 != worker->epoll_fd) && | ||
78 | (worker->listen_socket_in_epoll) ) | ||
79 | { | ||
80 | if (0 != epoll_ctl (worker->epoll_fd, | ||
81 | EPOLL_CTL_DEL, | ||
82 | listen_socket, | ||
83 | NULL)) | ||
84 | MHD_PANIC (_("Failed to remove listen FD from epoll set\n")); | ||
85 | worker->listen_socket_in_epoll = false; | ||
86 | } | ||
87 | else | ||
88 | #endif | ||
89 | if (MHD_ITC_IS_VALID_(worker->itc)) | ||
90 | { | ||
91 | if (! MHD_itc_activate_ (worker->itc, | ||
92 | "q")) | ||
93 | MHD_PANIC (_("Failed to signal quiesce via inter-thread communication channel")); | ||
94 | } | ||
95 | } | ||
96 | daemon->was_quiesced = true; | ||
97 | #ifdef EPOLL_SUPPORT | 75 | #ifdef EPOLL_SUPPORT |
98 | if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) && | 76 | if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) && |
99 | (-1 != daemon->epoll_fd) && | 77 | (-1 != worker->epoll_fd) && |
100 | (daemon->listen_socket_in_epoll) ) | 78 | (worker->listen_socket_in_epoll) ) |
101 | { | 79 | { |
102 | if (0 != epoll_ctl (daemon->epoll_fd, | 80 | if (0 != epoll_ctl (worker->epoll_fd, |
103 | EPOLL_CTL_DEL, | 81 | EPOLL_CTL_DEL, |
104 | listen_socket, | 82 | listen_socket, |
105 | NULL)) | 83 | NULL)) |
106 | MHD_PANIC ("Failed to remove listen FD from epoll set\n"); | 84 | MHD_PANIC (_ ("Failed to remove listen FD from epoll set\n")); |
107 | daemon->listen_socket_in_epoll = false; | 85 | worker->listen_socket_in_epoll = false; |
108 | } | 86 | } |
87 | else | ||
109 | #endif | 88 | #endif |
89 | if (MHD_ITC_IS_VALID_ (worker->itc)) | ||
90 | { | ||
91 | if (! MHD_itc_activate_ (worker->itc, | ||
92 | "q")) | ||
93 | MHD_PANIC (_ ( | ||
94 | "Failed to signal quiesce via inter-thread communication channel")); | ||
95 | } | ||
110 | } | 96 | } |
111 | 97 | daemon->was_quiesced = true; | |
112 | if ( (MHD_ITC_IS_VALID_(daemon->itc)) && | 98 | #ifdef EPOLL_SUPPORT |
99 | if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) && | ||
100 | (-1 != daemon->epoll_fd) && | ||
101 | (daemon->listen_socket_in_epoll) ) | ||
102 | { | ||
103 | if (0 != epoll_ctl (daemon->epoll_fd, | ||
104 | EPOLL_CTL_DEL, | ||
105 | listen_socket, | ||
106 | NULL)) | ||
107 | MHD_PANIC ("Failed to remove listen FD from epoll set\n"); | ||
108 | daemon->listen_socket_in_epoll = false; | ||
109 | } | ||
110 | #endif | ||
111 | } | ||
112 | |||
113 | if ( (MHD_ITC_IS_VALID_ (daemon->itc)) && | ||
113 | (! MHD_itc_activate_ (daemon->itc, | 114 | (! MHD_itc_activate_ (daemon->itc, |
114 | "q")) ) | 115 | "q")) ) |
115 | MHD_PANIC (_("Failed to signal quiesce via inter-thread communication channel")); | 116 | MHD_PANIC (_ ( |
117 | "Failed to signal quiesce via inter-thread communication channel")); | ||
116 | 118 | ||
117 | /* FIXME: we might want some bi-directional communication here | 119 | /* FIXME: we might want some bi-directional communication here |
118 | (in both the thread-pool and single-thread case!) | 120 | (in both the thread-pool and single-thread case!) |
119 | to be sure that the threads have stopped using the listen | 121 | to be sure that the threads have stopped using the listen |
120 | socket, otherwise there is still the possibility of a race | 122 | socket, otherwise there is still the possibility of a race |
121 | between a thread accept()ing and the caller closing and | 123 | between a thread accept()ing and the caller closing and |
122 | re-binding the socket. */ | 124 | re-binding the socket. */ |
123 | 125 | ||
124 | return listen_socket; | 126 | return listen_socket; |
125 | } | 127 | } |
126 | 128 | ||
127 | /* end of daemon_quiesce.c */ | 129 | /* end of daemon_quiesce.c */ |
128 | |||
diff --git a/src/lib/daemon_run.c b/src/lib/daemon_run.c index 129f7efb..cae500da 100644 --- a/src/lib/daemon_run.c +++ b/src/lib/daemon_run.c | |||
@@ -57,26 +57,26 @@ MHD_daemon_run (struct MHD_Daemon *daemon) | |||
57 | if (MHD_TM_EXTERNAL_EVENT_LOOP != daemon->threading_mode) | 57 | if (MHD_TM_EXTERNAL_EVENT_LOOP != daemon->threading_mode) |
58 | return MHD_SC_CONFIGURATION_MISMATCH_FOR_RUN_EXTERNAL; | 58 | return MHD_SC_CONFIGURATION_MISMATCH_FOR_RUN_EXTERNAL; |
59 | switch (daemon->event_loop_syscall) | 59 | switch (daemon->event_loop_syscall) |
60 | { | 60 | { |
61 | case MHD_ELS_POLL: | 61 | case MHD_ELS_POLL: |
62 | sc = MHD_daemon_poll_ (daemon, | 62 | sc = MHD_daemon_poll_ (daemon, |
63 | MHD_NO); | 63 | MHD_NO); |
64 | MHD_connection_cleanup_ (daemon); | 64 | MHD_connection_cleanup_ (daemon); |
65 | return sc; | 65 | return sc; |
66 | #ifdef EPOLL_SUPPORT | 66 | #ifdef EPOLL_SUPPORT |
67 | case MHD_ELS_EPOLL: | 67 | case MHD_ELS_EPOLL: |
68 | sc = MHD_daemon_epoll_ (daemon, | 68 | sc = MHD_daemon_epoll_ (daemon, |
69 | MHD_NO); | 69 | MHD_NO); |
70 | MHD_connection_cleanup_ (daemon); | 70 | MHD_connection_cleanup_ (daemon); |
71 | return sc; | 71 | return sc; |
72 | #endif | 72 | #endif |
73 | case MHD_ELS_SELECT: | 73 | case MHD_ELS_SELECT: |
74 | return MHD_daemon_select_ (daemon, | 74 | return MHD_daemon_select_ (daemon, |
75 | MHD_NO); | 75 | MHD_NO); |
76 | /* MHD_select does MHD_connection_cleanup_ already */ | 76 | /* MHD_select does MHD_connection_cleanup_ already */ |
77 | default: | 77 | default: |
78 | return MHD_SC_CONFIGURATION_UNEXPECTED_ELS; | 78 | return MHD_SC_CONFIGURATION_UNEXPECTED_ELS; |
79 | } | 79 | } |
80 | } | 80 | } |
81 | 81 | ||
82 | /* end of daemon_run.c */ | 82 | /* end of daemon_run.c */ |
diff --git a/src/lib/daemon_select.c b/src/lib/daemon_select.c index 08281d8c..69913a9a 100644 --- a/src/lib/daemon_select.c +++ b/src/lib/daemon_select.c | |||
@@ -66,17 +66,17 @@ | |||
66 | */ | 66 | */ |
67 | enum MHD_StatusCode | 67 | enum MHD_StatusCode |
68 | MHD_daemon_get_fdset (struct MHD_Daemon *daemon, | 68 | MHD_daemon_get_fdset (struct MHD_Daemon *daemon, |
69 | fd_set *read_fd_set, | 69 | fd_set *read_fd_set, |
70 | fd_set *write_fd_set, | 70 | fd_set *write_fd_set, |
71 | fd_set *except_fd_set, | 71 | fd_set *except_fd_set, |
72 | MHD_socket *max_fd) | 72 | MHD_socket *max_fd) |
73 | { | 73 | { |
74 | return MHD_daemon_get_fdset2 (daemon, | 74 | return MHD_daemon_get_fdset2 (daemon, |
75 | read_fd_set, | 75 | read_fd_set, |
76 | write_fd_set, | 76 | write_fd_set, |
77 | except_fd_set, | 77 | except_fd_set, |
78 | max_fd, | 78 | max_fd, |
79 | _MHD_SYS_DEFAULT_FD_SETSIZE); | 79 | _MHD_SYS_DEFAULT_FD_SETSIZE); |
80 | } | 80 | } |
81 | 81 | ||
82 | 82 | ||
@@ -108,55 +108,55 @@ urh_to_fdset (struct MHD_UpgradeResponseHandle *urh, | |||
108 | /* Do not add to 'es' only if socket is closed | 108 | /* Do not add to 'es' only if socket is closed |
109 | * or not used anymore. */ | 109 | * or not used anymore. */ |
110 | if (MHD_INVALID_SOCKET != conn_sckt) | 110 | if (MHD_INVALID_SOCKET != conn_sckt) |
111 | { | 111 | { |
112 | if ( (urh->in_buffer_used < urh->in_buffer_size) && | 112 | if ( (urh->in_buffer_used < urh->in_buffer_size) && |
113 | (! MHD_add_to_fd_set_ (conn_sckt, | 113 | (! MHD_add_to_fd_set_ (conn_sckt, |
114 | rs, | 114 | rs, |
115 | max_fd, | 115 | max_fd, |
116 | fd_setsize)) ) | 116 | fd_setsize)) ) |
117 | res = false; | 117 | res = false; |
118 | if ( (0 != urh->out_buffer_used) && | 118 | if ( (0 != urh->out_buffer_used) && |
119 | (! MHD_add_to_fd_set_ (conn_sckt, | 119 | (! MHD_add_to_fd_set_ (conn_sckt, |
120 | ws, | 120 | ws, |
121 | max_fd, | 121 | max_fd, |
122 | fd_setsize)) ) | 122 | fd_setsize)) ) |
123 | res = false; | 123 | res = false; |
124 | /* Do not monitor again for errors if error was detected before as | 124 | /* Do not monitor again for errors if error was detected before as |
125 | * error state is remembered. */ | 125 | * error state is remembered. */ |
126 | if ((0 == (urh->app.celi & MHD_EPOLL_STATE_ERROR)) && | 126 | if ((0 == (urh->app.celi & MHD_EPOLL_STATE_ERROR)) && |
127 | ((0 != urh->in_buffer_size) || | 127 | ((0 != urh->in_buffer_size) || |
128 | (0 != urh->out_buffer_size) || | 128 | (0 != urh->out_buffer_size) || |
129 | (0 != urh->out_buffer_used))) | 129 | (0 != urh->out_buffer_used))) |
130 | MHD_add_to_fd_set_ (conn_sckt, | 130 | MHD_add_to_fd_set_ (conn_sckt, |
131 | es, | 131 | es, |
132 | max_fd, | 132 | max_fd, |
133 | fd_setsize); | 133 | fd_setsize); |
134 | } | 134 | } |
135 | if (MHD_INVALID_SOCKET != mhd_sckt) | 135 | if (MHD_INVALID_SOCKET != mhd_sckt) |
136 | { | 136 | { |
137 | if ( (urh->out_buffer_used < urh->out_buffer_size) && | 137 | if ( (urh->out_buffer_used < urh->out_buffer_size) && |
138 | (! MHD_add_to_fd_set_ (mhd_sckt, | 138 | (! MHD_add_to_fd_set_ (mhd_sckt, |
139 | rs, | 139 | rs, |
140 | max_fd, | 140 | max_fd, |
141 | fd_setsize)) ) | 141 | fd_setsize)) ) |
142 | res = false; | 142 | res = false; |
143 | if ( (0 != urh->in_buffer_used) && | 143 | if ( (0 != urh->in_buffer_used) && |
144 | (! MHD_add_to_fd_set_ (mhd_sckt, | 144 | (! MHD_add_to_fd_set_ (mhd_sckt, |
145 | ws, | 145 | ws, |
146 | max_fd, | 146 | max_fd, |
147 | fd_setsize)) ) | 147 | fd_setsize)) ) |
148 | res = false; | 148 | res = false; |
149 | /* Do not monitor again for errors if error was detected before as | 149 | /* Do not monitor again for errors if error was detected before as |
150 | * error state is remembered. */ | 150 | * error state is remembered. */ |
151 | if ((0 == (urh->mhd.celi & MHD_EPOLL_STATE_ERROR)) && | 151 | if ((0 == (urh->mhd.celi & MHD_EPOLL_STATE_ERROR)) && |
152 | ((0 != urh->out_buffer_size) || | 152 | ((0 != urh->out_buffer_size) || |
153 | (0 != urh->in_buffer_size) || | 153 | (0 != urh->in_buffer_size) || |
154 | (0 != urh->in_buffer_used))) | 154 | (0 != urh->in_buffer_used))) |
155 | MHD_add_to_fd_set_ (mhd_sckt, | 155 | MHD_add_to_fd_set_ (mhd_sckt, |
156 | es, | 156 | es, |
157 | max_fd, | 157 | max_fd, |
158 | fd_setsize); | 158 | fd_setsize); |
159 | } | 159 | } |
160 | 160 | ||
161 | return res; | 161 | return res; |
162 | } | 162 | } |
@@ -207,77 +207,77 @@ internal_get_fdset2 (struct MHD_Daemon *daemon, | |||
207 | * or INFO_WRITE sockets will not fit 'except_fd_set'. */ | 207 | * or INFO_WRITE sockets will not fit 'except_fd_set'. */ |
208 | /* Start from oldest connections. Make sense for W32 FDSETs. */ | 208 | /* Start from oldest connections. Make sense for W32 FDSETs. */ |
209 | for (pos = daemon->connections_tail; NULL != pos; pos = posn) | 209 | for (pos = daemon->connections_tail; NULL != pos; pos = posn) |
210 | { | ||
211 | posn = pos->prev; | ||
212 | |||
213 | switch (pos->request.event_loop_info) | ||
210 | { | 214 | { |
211 | posn = pos->prev; | 215 | case MHD_EVENT_LOOP_INFO_READ: |
212 | 216 | if (! MHD_add_to_fd_set_ (pos->socket_fd, | |
213 | switch (pos->request.event_loop_info) | 217 | read_fd_set, |
214 | { | 218 | max_fd, |
215 | case MHD_EVENT_LOOP_INFO_READ: | 219 | fd_setsize)) |
216 | if (! MHD_add_to_fd_set_ (pos->socket_fd, | 220 | result = MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE; |
217 | read_fd_set, | ||
218 | max_fd, | ||
219 | fd_setsize)) | ||
220 | result = MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE; | ||
221 | #ifdef MHD_POSIX_SOCKETS | 221 | #ifdef MHD_POSIX_SOCKETS |
222 | MHD_add_to_fd_set_ (pos->socket_fd, | 222 | MHD_add_to_fd_set_ (pos->socket_fd, |
223 | except_fd_set, | 223 | except_fd_set, |
224 | max_fd, | 224 | max_fd, |
225 | fd_setsize); | 225 | fd_setsize); |
226 | #endif /* MHD_POSIX_SOCKETS */ | 226 | #endif /* MHD_POSIX_SOCKETS */ |
227 | break; | 227 | break; |
228 | case MHD_EVENT_LOOP_INFO_WRITE: | 228 | case MHD_EVENT_LOOP_INFO_WRITE: |
229 | if (! MHD_add_to_fd_set_ (pos->socket_fd, | 229 | if (! MHD_add_to_fd_set_ (pos->socket_fd, |
230 | write_fd_set, | 230 | write_fd_set, |
231 | max_fd, | 231 | max_fd, |
232 | fd_setsize)) | 232 | fd_setsize)) |
233 | result = MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE; | 233 | result = MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE; |
234 | #ifdef MHD_POSIX_SOCKETS | 234 | #ifdef MHD_POSIX_SOCKETS |
235 | MHD_add_to_fd_set_ (pos->socket_fd, | 235 | MHD_add_to_fd_set_ (pos->socket_fd, |
236 | except_fd_set, | 236 | except_fd_set, |
237 | max_fd, | 237 | max_fd, |
238 | fd_setsize); | 238 | fd_setsize); |
239 | #endif /* MHD_POSIX_SOCKETS */ | 239 | #endif /* MHD_POSIX_SOCKETS */ |
240 | break; | 240 | break; |
241 | case MHD_EVENT_LOOP_INFO_BLOCK: | 241 | case MHD_EVENT_LOOP_INFO_BLOCK: |
242 | if ( (NULL == except_fd_set) || | 242 | if ( (NULL == except_fd_set) || |
243 | ! MHD_add_to_fd_set_ (pos->socket_fd, | 243 | ! MHD_add_to_fd_set_ (pos->socket_fd, |
244 | except_fd_set, | 244 | except_fd_set, |
245 | max_fd, | 245 | max_fd, |
246 | fd_setsize)) | 246 | fd_setsize)) |
247 | result = MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE; | 247 | result = MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE; |
248 | break; | 248 | break; |
249 | case MHD_EVENT_LOOP_INFO_CLEANUP: | 249 | case MHD_EVENT_LOOP_INFO_CLEANUP: |
250 | /* this should never happen */ | 250 | /* this should never happen */ |
251 | break; | 251 | break; |
252 | } | ||
253 | } | 252 | } |
253 | } | ||
254 | #ifdef MHD_WINSOCK_SOCKETS | 254 | #ifdef MHD_WINSOCK_SOCKETS |
255 | /* W32 use limited array for fd_set so add INFO_READ/INFO_WRITE sockets | 255 | /* W32 use limited array for fd_set so add INFO_READ/INFO_WRITE sockets |
256 | * only after INFO_BLOCK sockets to ensure that INFO_BLOCK sockets will | 256 | * only after INFO_BLOCK sockets to ensure that INFO_BLOCK sockets will |
257 | * not be pushed out. */ | 257 | * not be pushed out. */ |
258 | for (pos = daemon->connections_tail; NULL != pos; pos = posn) | 258 | for (pos = daemon->connections_tail; NULL != pos; pos = posn) |
259 | { | 259 | { |
260 | posn = pos->prev; | 260 | posn = pos->prev; |
261 | MHD_add_to_fd_set_ (pos->socket_fd, | 261 | MHD_add_to_fd_set_ (pos->socket_fd, |
262 | except_fd_set, | 262 | except_fd_set, |
263 | max_fd, | 263 | max_fd, |
264 | fd_setsize); | 264 | fd_setsize); |
265 | } | 265 | } |
266 | #endif /* MHD_WINSOCK_SOCKETS */ | 266 | #endif /* MHD_WINSOCK_SOCKETS */ |
267 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) | 267 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) |
268 | { | 268 | { |
269 | struct MHD_UpgradeResponseHandle *urh; | 269 | struct MHD_UpgradeResponseHandle *urh; |
270 | 270 | ||
271 | for (urh = daemon->urh_tail; NULL != urh; urh = urh->prev) | 271 | for (urh = daemon->urh_tail; NULL != urh; urh = urh->prev) |
272 | { | 272 | { |
273 | if (! urh_to_fdset (urh, | 273 | if (! urh_to_fdset (urh, |
274 | read_fd_set, | 274 | read_fd_set, |
275 | write_fd_set, | 275 | write_fd_set, |
276 | except_fd_set, | 276 | except_fd_set, |
277 | max_fd, | 277 | max_fd, |
278 | fd_setsize)) | 278 | fd_setsize)) |
279 | result = MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE; | 279 | result = MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE; |
280 | } | 280 | } |
281 | } | 281 | } |
282 | #endif | 282 | #endif |
283 | return result; | 283 | return result; |
@@ -313,11 +313,11 @@ internal_get_fdset2 (struct MHD_Daemon *daemon, | |||
313 | */ | 313 | */ |
314 | enum MHD_StatusCode | 314 | enum MHD_StatusCode |
315 | MHD_daemon_get_fdset2 (struct MHD_Daemon *daemon, | 315 | MHD_daemon_get_fdset2 (struct MHD_Daemon *daemon, |
316 | fd_set *read_fd_set, | 316 | fd_set *read_fd_set, |
317 | fd_set *write_fd_set, | 317 | fd_set *write_fd_set, |
318 | fd_set *except_fd_set, | 318 | fd_set *except_fd_set, |
319 | MHD_socket *max_fd, | 319 | MHD_socket *max_fd, |
320 | unsigned int fd_setsize) | 320 | unsigned int fd_setsize) |
321 | { | 321 | { |
322 | if ( (MHD_TM_EXTERNAL_EVENT_LOOP != daemon->threading_mode) || | 322 | if ( (MHD_TM_EXTERNAL_EVENT_LOOP != daemon->threading_mode) || |
323 | (MHD_ELS_POLL == daemon->event_loop_syscall) ) | 323 | (MHD_ELS_POLL == daemon->event_loop_syscall) ) |
@@ -325,28 +325,28 @@ MHD_daemon_get_fdset2 (struct MHD_Daemon *daemon, | |||
325 | 325 | ||
326 | #ifdef EPOLL_SUPPORT | 326 | #ifdef EPOLL_SUPPORT |
327 | if (MHD_ELS_EPOLL == daemon->event_loop_syscall) | 327 | if (MHD_ELS_EPOLL == daemon->event_loop_syscall) |
328 | { | 328 | { |
329 | if (daemon->shutdown) | 329 | if (daemon->shutdown) |
330 | return MHD_SC_DAEMON_ALREADY_SHUTDOWN; | 330 | return MHD_SC_DAEMON_ALREADY_SHUTDOWN; |
331 | 331 | ||
332 | /* we're in epoll mode, use the epoll FD as a stand-in for | 332 | /* we're in epoll mode, use the epoll FD as a stand-in for |
333 | the entire event set */ | 333 | the entire event set */ |
334 | 334 | ||
335 | return MHD_add_to_fd_set_ (daemon->epoll_fd, | 335 | return MHD_add_to_fd_set_ (daemon->epoll_fd, |
336 | read_fd_set, | 336 | read_fd_set, |
337 | max_fd, | 337 | max_fd, |
338 | fd_setsize) | 338 | fd_setsize) |
339 | ? MHD_SC_OK | 339 | ? MHD_SC_OK |
340 | : MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE; | 340 | : MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE; |
341 | } | 341 | } |
342 | #endif | 342 | #endif |
343 | 343 | ||
344 | return internal_get_fdset2 (daemon, | 344 | return internal_get_fdset2 (daemon, |
345 | read_fd_set, | 345 | read_fd_set, |
346 | write_fd_set, | 346 | write_fd_set, |
347 | except_fd_set, | 347 | except_fd_set, |
348 | max_fd, | 348 | max_fd, |
349 | fd_setsize); | 349 | fd_setsize); |
350 | } | 350 | } |
351 | 351 | ||
352 | 352 | ||
@@ -374,23 +374,23 @@ urh_from_fdset (struct MHD_UpgradeResponseHandle *urh, | |||
374 | urh->mhd.celi &= (~MHD_EPOLL_STATE_READ_READY & ~MHD_EPOLL_STATE_WRITE_READY); | 374 | urh->mhd.celi &= (~MHD_EPOLL_STATE_READ_READY & ~MHD_EPOLL_STATE_WRITE_READY); |
375 | 375 | ||
376 | if (MHD_INVALID_SOCKET != conn_sckt) | 376 | if (MHD_INVALID_SOCKET != conn_sckt) |
377 | { | 377 | { |
378 | if (FD_ISSET (conn_sckt, rs)) | 378 | if (FD_ISSET (conn_sckt, rs)) |
379 | urh->app.celi |= MHD_EPOLL_STATE_READ_READY; | 379 | urh->app.celi |= MHD_EPOLL_STATE_READ_READY; |
380 | if (FD_ISSET (conn_sckt, ws)) | 380 | if (FD_ISSET (conn_sckt, ws)) |
381 | urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY; | 381 | urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY; |
382 | if (FD_ISSET (conn_sckt, es)) | 382 | if (FD_ISSET (conn_sckt, es)) |
383 | urh->app.celi |= MHD_EPOLL_STATE_ERROR; | 383 | urh->app.celi |= MHD_EPOLL_STATE_ERROR; |
384 | } | 384 | } |
385 | if ((MHD_INVALID_SOCKET != mhd_sckt)) | 385 | if ((MHD_INVALID_SOCKET != mhd_sckt)) |
386 | { | 386 | { |
387 | if (FD_ISSET (mhd_sckt, rs)) | 387 | if (FD_ISSET (mhd_sckt, rs)) |
388 | urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY; | 388 | urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY; |
389 | if (FD_ISSET (mhd_sckt, ws)) | 389 | if (FD_ISSET (mhd_sckt, ws)) |
390 | urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY; | 390 | urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY; |
391 | if (FD_ISSET (mhd_sckt, es)) | 391 | if (FD_ISSET (mhd_sckt, es)) |
392 | urh->mhd.celi |= MHD_EPOLL_STATE_ERROR; | 392 | urh->mhd.celi |= MHD_EPOLL_STATE_ERROR; |
393 | } | 393 | } |
394 | } | 394 | } |
395 | #endif | 395 | #endif |
396 | 396 | ||
@@ -425,7 +425,7 @@ internal_run_from_select (struct MHD_Daemon *daemon, | |||
425 | /* Clear ITC to avoid spinning select */ | 425 | /* Clear ITC to avoid spinning select */ |
426 | /* Do it before any other processing so new signals | 426 | /* Do it before any other processing so new signals |
427 | will trigger select again and will be processed */ | 427 | will trigger select again and will be processed */ |
428 | if ( (MHD_ITC_IS_VALID_(daemon->itc)) && | 428 | if ( (MHD_ITC_IS_VALID_ (daemon->itc)) && |
429 | (FD_ISSET (MHD_itc_r_fd_ (daemon->itc), | 429 | (FD_ISSET (MHD_itc_r_fd_ (daemon->itc), |
430 | read_fd_set)) ) | 430 | read_fd_set)) ) |
431 | MHD_itc_clear_ (daemon->itc); | 431 | MHD_itc_clear_ (daemon->itc); |
@@ -438,49 +438,49 @@ internal_run_from_select (struct MHD_Daemon *daemon, | |||
438 | (void) MHD_accept_connection_ (daemon); | 438 | (void) MHD_accept_connection_ (daemon); |
439 | 439 | ||
440 | if (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) | 440 | if (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) |
441 | { | ||
442 | /* do not have a thread per connection, process all connections now */ | ||
443 | prev = daemon->connections_tail; | ||
444 | while (NULL != (pos = prev)) | ||
441 | { | 445 | { |
442 | /* do not have a thread per connection, process all connections now */ | 446 | prev = pos->prev; |
443 | prev = daemon->connections_tail; | 447 | ds = pos->socket_fd; |
444 | while (NULL != (pos = prev)) | 448 | if (MHD_INVALID_SOCKET == ds) |
445 | { | 449 | continue; |
446 | prev = pos->prev; | 450 | MHD_connection_call_handlers_ (pos, |
447 | ds = pos->socket_fd; | 451 | FD_ISSET (ds, |
448 | if (MHD_INVALID_SOCKET == ds) | 452 | read_fd_set), |
449 | continue; | 453 | FD_ISSET (ds, |
450 | MHD_connection_call_handlers_ (pos, | 454 | write_fd_set), |
451 | FD_ISSET (ds, | 455 | FD_ISSET (ds, |
452 | read_fd_set), | 456 | except_fd_set)); |
453 | FD_ISSET (ds, | ||
454 | write_fd_set), | ||
455 | FD_ISSET (ds, | ||
456 | except_fd_set)); | ||
457 | } | ||
458 | } | 457 | } |
458 | } | ||
459 | 459 | ||
460 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) | 460 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) |
461 | /* handle upgraded HTTPS connections */ | 461 | /* handle upgraded HTTPS connections */ |
462 | for (urh = daemon->urh_tail; NULL != urh; urh = urhn) | 462 | for (urh = daemon->urh_tail; NULL != urh; urh = urhn) |
463 | { | ||
464 | urhn = urh->prev; | ||
465 | /* update urh state based on select() output */ | ||
466 | urh_from_fdset (urh, | ||
467 | read_fd_set, | ||
468 | write_fd_set, | ||
469 | except_fd_set); | ||
470 | /* call generic forwarding function for passing data */ | ||
471 | MHD_upgrade_response_handle_process_ (urh); | ||
472 | /* Finished forwarding? */ | ||
473 | if ( (0 == urh->in_buffer_size) && | ||
474 | (0 == urh->out_buffer_size) && | ||
475 | (0 == urh->in_buffer_used) && | ||
476 | (0 == urh->out_buffer_used) ) | ||
463 | { | 477 | { |
464 | urhn = urh->prev; | 478 | MHD_connection_finish_forward_ (urh->connection); |
465 | /* update urh state based on select() output */ | 479 | urh->clean_ready = true; |
466 | urh_from_fdset (urh, | 480 | /* Resuming will move connection to cleanup list. */ |
467 | read_fd_set, | 481 | MHD_request_resume (&urh->connection->request); |
468 | write_fd_set, | ||
469 | except_fd_set); | ||
470 | /* call generic forwarding function for passing data */ | ||
471 | MHD_upgrade_response_handle_process_ (urh); | ||
472 | /* Finished forwarding? */ | ||
473 | if ( (0 == urh->in_buffer_size) && | ||
474 | (0 == urh->out_buffer_size) && | ||
475 | (0 == urh->in_buffer_used) && | ||
476 | (0 == urh->out_buffer_used) ) | ||
477 | { | ||
478 | MHD_connection_finish_forward_ (urh->connection); | ||
479 | urh->clean_ready = true; | ||
480 | /* Resuming will move connection to cleanup list. */ | ||
481 | MHD_request_resume (&urh->connection->request); | ||
482 | } | ||
483 | } | 482 | } |
483 | } | ||
484 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ | 484 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ |
485 | MHD_connection_cleanup_ (daemon); | 485 | MHD_connection_cleanup_ (daemon); |
486 | return MHD_SC_OK; | 486 | return MHD_SC_OK; |
@@ -500,80 +500,80 @@ MHD_daemon_upgrade_connection_with_select_ (struct MHD_Connection *con) | |||
500 | struct MHD_UpgradeResponseHandle *urh = con->request.urh; | 500 | struct MHD_UpgradeResponseHandle *urh = con->request.urh; |
501 | 501 | ||
502 | while ( (0 != urh->in_buffer_size) || | 502 | while ( (0 != urh->in_buffer_size) || |
503 | (0 != urh->out_buffer_size) || | 503 | (0 != urh->out_buffer_size) || |
504 | (0 != urh->in_buffer_used) || | 504 | (0 != urh->in_buffer_used) || |
505 | (0 != urh->out_buffer_used) ) | 505 | (0 != urh->out_buffer_used) ) |
506 | { | ||
507 | /* use select */ | ||
508 | fd_set rs; | ||
509 | fd_set ws; | ||
510 | fd_set es; | ||
511 | MHD_socket max_fd; | ||
512 | int num_ready; | ||
513 | bool result; | ||
514 | |||
515 | FD_ZERO (&rs); | ||
516 | FD_ZERO (&ws); | ||
517 | FD_ZERO (&es); | ||
518 | max_fd = MHD_INVALID_SOCKET; | ||
519 | result = urh_to_fdset (urh, | ||
520 | &rs, | ||
521 | &ws, | ||
522 | &es, | ||
523 | &max_fd, | ||
524 | FD_SETSIZE); | ||
525 | if (! result) | ||
506 | { | 526 | { |
507 | /* use select */ | ||
508 | fd_set rs; | ||
509 | fd_set ws; | ||
510 | fd_set es; | ||
511 | MHD_socket max_fd; | ||
512 | int num_ready; | ||
513 | bool result; | ||
514 | |||
515 | FD_ZERO (&rs); | ||
516 | FD_ZERO (&ws); | ||
517 | FD_ZERO (&es); | ||
518 | max_fd = MHD_INVALID_SOCKET; | ||
519 | result = urh_to_fdset (urh, | ||
520 | &rs, | ||
521 | &ws, | ||
522 | &es, | ||
523 | &max_fd, | ||
524 | FD_SETSIZE); | ||
525 | if (! result) | ||
526 | { | ||
527 | #ifdef HAVE_MESSAGES | 527 | #ifdef HAVE_MESSAGES |
528 | MHD_DLOG (con->daemon, | 528 | MHD_DLOG (con->daemon, |
529 | MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE, | 529 | MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE, |
530 | _("Error preparing select\n")); | 530 | _ ("Error preparing select\n")); |
531 | #endif | 531 | #endif |
532 | break; | 532 | break; |
533 | } | 533 | } |
534 | /* FIXME: does this check really needed? */ | 534 | /* FIXME: does this check really needed? */ |
535 | if (MHD_INVALID_SOCKET != max_fd) | 535 | if (MHD_INVALID_SOCKET != max_fd) |
536 | { | 536 | { |
537 | struct timeval* tvp; | 537 | struct timeval*tvp; |
538 | struct timeval tv; | 538 | struct timeval tv; |
539 | if ( (con->tls_read_ready) && | 539 | if ( (con->tls_read_ready) && |
540 | (urh->in_buffer_used < urh->in_buffer_size)) | 540 | (urh->in_buffer_used < urh->in_buffer_size)) |
541 | { /* No need to wait if incoming data is already pending in TLS buffers. */ | 541 | { /* No need to wait if incoming data is already pending in TLS buffers. */ |
542 | tv.tv_sec = 0; | 542 | tv.tv_sec = 0; |
543 | tv.tv_usec = 0; | 543 | tv.tv_usec = 0; |
544 | tvp = &tv; | 544 | tvp = &tv; |
545 | } | 545 | } |
546 | else | ||
547 | tvp = NULL; | ||
548 | num_ready = MHD_SYS_select_ (max_fd + 1, | ||
549 | &rs, | ||
550 | &ws, | ||
551 | &es, | ||
552 | tvp); | ||
553 | } | ||
554 | else | 546 | else |
555 | num_ready = 0; | 547 | tvp = NULL; |
556 | if (num_ready < 0) | 548 | num_ready = MHD_SYS_select_ (max_fd + 1, |
557 | { | 549 | &rs, |
558 | const int err = MHD_socket_get_error_(); | 550 | &ws, |
551 | &es, | ||
552 | tvp); | ||
553 | } | ||
554 | else | ||
555 | num_ready = 0; | ||
556 | if (num_ready < 0) | ||
557 | { | ||
558 | const int err = MHD_socket_get_error_ (); | ||
559 | 559 | ||
560 | if (MHD_SCKT_ERR_IS_EINTR_(err)) | 560 | if (MHD_SCKT_ERR_IS_EINTR_ (err)) |
561 | continue; | 561 | continue; |
562 | #ifdef HAVE_MESSAGES | 562 | #ifdef HAVE_MESSAGES |
563 | MHD_DLOG (con->daemon, | 563 | MHD_DLOG (con->daemon, |
564 | MHD_SC_UNEXPECTED_SELECT_ERROR, | 564 | MHD_SC_UNEXPECTED_SELECT_ERROR, |
565 | _("Error during select (%d): `%s'\n"), | 565 | _ ("Error during select (%d): `%s'\n"), |
566 | err, | 566 | err, |
567 | MHD_socket_strerr_ (err)); | 567 | MHD_socket_strerr_ (err)); |
568 | #endif | 568 | #endif |
569 | break; | 569 | break; |
570 | } | ||
571 | urh_from_fdset (urh, | ||
572 | &rs, | ||
573 | &ws, | ||
574 | &es); | ||
575 | MHD_upgrade_response_handle_process_ (urh); | ||
576 | } | 570 | } |
571 | urh_from_fdset (urh, | ||
572 | &rs, | ||
573 | &ws, | ||
574 | &es); | ||
575 | MHD_upgrade_response_handle_process_ (urh); | ||
576 | } | ||
577 | } | 577 | } |
578 | #endif | 578 | #endif |
579 | 579 | ||
@@ -602,37 +602,37 @@ MHD_daemon_upgrade_connection_with_select_ (struct MHD_Connection *con) | |||
602 | */ | 602 | */ |
603 | enum MHD_StatusCode | 603 | enum MHD_StatusCode |
604 | MHD_daemon_run_from_select (struct MHD_Daemon *daemon, | 604 | MHD_daemon_run_from_select (struct MHD_Daemon *daemon, |
605 | const fd_set *read_fd_set, | 605 | const fd_set *read_fd_set, |
606 | 606 | ||
607 | 607 | ||
608 | const fd_set *write_fd_set, | 608 | const fd_set *write_fd_set, |
609 | const fd_set *except_fd_set) | 609 | const fd_set *except_fd_set) |
610 | { | 610 | { |
611 | if ( (MHD_TM_EXTERNAL_EVENT_LOOP != daemon->threading_mode) || | 611 | if ( (MHD_TM_EXTERNAL_EVENT_LOOP != daemon->threading_mode) || |
612 | (MHD_ELS_POLL == daemon->event_loop_syscall) ) | 612 | (MHD_ELS_POLL == daemon->event_loop_syscall) ) |
613 | return MHD_SC_CONFIGURATION_MISSMATCH_FOR_RUN_SELECT; | 613 | return MHD_SC_CONFIGURATION_MISSMATCH_FOR_RUN_SELECT; |
614 | if (MHD_ELS_EPOLL == daemon->event_loop_syscall) | 614 | if (MHD_ELS_EPOLL == daemon->event_loop_syscall) |
615 | { | 615 | { |
616 | #ifdef EPOLL_SUPPORT | 616 | #ifdef EPOLL_SUPPORT |
617 | enum MHD_StatusCode sc; | 617 | enum MHD_StatusCode sc; |
618 | 618 | ||
619 | sc = MHD_daemon_epoll_ (daemon, | 619 | sc = MHD_daemon_epoll_ (daemon, |
620 | MHD_NO); | 620 | MHD_NO); |
621 | MHD_connection_cleanup_ (daemon); | 621 | MHD_connection_cleanup_ (daemon); |
622 | return sc; | 622 | return sc; |
623 | #else /* ! EPOLL_SUPPORT */ | 623 | #else /* ! EPOLL_SUPPORT */ |
624 | return MHD_NO; | 624 | return MHD_NO; |
625 | #endif /* ! EPOLL_SUPPORT */ | 625 | #endif /* ! EPOLL_SUPPORT */ |
626 | } | 626 | } |
627 | 627 | ||
628 | /* Resuming external connections when using an extern mainloop */ | 628 | /* Resuming external connections when using an extern mainloop */ |
629 | if (! daemon->disallow_suspend_resume) | 629 | if (! daemon->disallow_suspend_resume) |
630 | (void) MHD_resume_suspended_connections_ (daemon); | 630 | (void) MHD_resume_suspended_connections_ (daemon); |
631 | 631 | ||
632 | return internal_run_from_select (daemon, | 632 | return internal_run_from_select (daemon, |
633 | read_fd_set, | 633 | read_fd_set, |
634 | write_fd_set, | 634 | write_fd_set, |
635 | except_fd_set); | 635 | except_fd_set); |
636 | } | 636 | } |
637 | 637 | ||
638 | 638 | ||
@@ -646,7 +646,7 @@ MHD_daemon_run_from_select (struct MHD_Daemon *daemon, | |||
646 | */ | 646 | */ |
647 | enum MHD_StatusCode | 647 | enum MHD_StatusCode |
648 | MHD_daemon_select_ (struct MHD_Daemon *daemon, | 648 | MHD_daemon_select_ (struct MHD_Daemon *daemon, |
649 | int may_block) | 649 | int may_block) |
650 | { | 650 | { |
651 | int num_ready; | 651 | int num_ready; |
652 | fd_set rs; | 652 | fd_set rs; |
@@ -675,74 +675,75 @@ MHD_daemon_select_ (struct MHD_Daemon *daemon, | |||
675 | may_block = MHD_NO; | 675 | may_block = MHD_NO; |
676 | 676 | ||
677 | if (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) | 677 | if (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) |
678 | { | 678 | { |
679 | 679 | ||
680 | /* single-threaded, go over everything */ | 680 | /* single-threaded, go over everything */ |
681 | if (MHD_SC_OK != | 681 | if (MHD_SC_OK != |
682 | (sc = internal_get_fdset2 (daemon, | 682 | (sc = internal_get_fdset2 (daemon, |
683 | &rs, | 683 | &rs, |
684 | &ws, | 684 | &ws, |
685 | &es, | 685 | &es, |
686 | &maxsock, | 686 | &maxsock, |
687 | FD_SETSIZE))) | 687 | FD_SETSIZE))) |
688 | { | 688 | { |
689 | #ifdef HAVE_MESSAGES | 689 | #ifdef HAVE_MESSAGES |
690 | MHD_DLOG (daemon, | 690 | MHD_DLOG (daemon, |
691 | sc, | 691 | sc, |
692 | _("Could not obtain daemon fdsets")); | 692 | _ ("Could not obtain daemon fdsets")); |
693 | #endif | 693 | #endif |
694 | } | ||
695 | } | 694 | } |
695 | } | ||
696 | else | 696 | else |
697 | { | ||
698 | /* accept only, have one thread per connection */ | ||
699 | if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_socket)) && | ||
700 | (! daemon->was_quiesced) && | ||
701 | (! MHD_add_to_fd_set_ (ls, | ||
702 | &rs, | ||
703 | &maxsock, | ||
704 | FD_SETSIZE)) ) | ||
697 | { | 705 | { |
698 | /* accept only, have one thread per connection */ | ||
699 | if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_socket)) && | ||
700 | (! daemon->was_quiesced) && | ||
701 | (! MHD_add_to_fd_set_ (ls, | ||
702 | &rs, | ||
703 | &maxsock, | ||
704 | FD_SETSIZE)) ) | ||
705 | { | ||
706 | #ifdef HAVE_MESSAGES | 706 | #ifdef HAVE_MESSAGES |
707 | MHD_DLOG (daemon, | 707 | MHD_DLOG (daemon, |
708 | MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE, | 708 | MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE, |
709 | _("Could not add listen socket to fdset")); | 709 | _ ("Could not add listen socket to fdset")); |
710 | #endif | 710 | #endif |
711 | return MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE; | 711 | return MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE; |
712 | } | ||
713 | } | 712 | } |
714 | if ( (MHD_ITC_IS_VALID_(daemon->itc)) && | 713 | } |
714 | if ( (MHD_ITC_IS_VALID_ (daemon->itc)) && | ||
715 | (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc), | 715 | (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc), |
716 | &rs, | 716 | &rs, |
717 | &maxsock, | 717 | &maxsock, |
718 | FD_SETSIZE)) ) | 718 | FD_SETSIZE)) ) |
719 | { | 719 | { |
720 | #if defined(MHD_WINSOCK_SOCKETS) | 720 | #if defined(MHD_WINSOCK_SOCKETS) |
721 | /* fdset limit reached, new connections | 721 | /* fdset limit reached, new connections |
722 | cannot be handled. Remove listen socket FD | 722 | cannot be handled. Remove listen socket FD |
723 | from fdset and retry to add ITC FD. */ | 723 | from fdset and retry to add ITC FD. */ |
724 | if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_socket)) && | 724 | if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_socket)) && |
725 | (! daemon->was_quiesced) ) | 725 | (! daemon->was_quiesced) ) |
726 | { | 726 | { |
727 | FD_CLR (ls, | 727 | FD_CLR (ls, |
728 | &rs); | 728 | &rs); |
729 | if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_(daemon->itc), | 729 | if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc), |
730 | &rs, | 730 | &rs, |
731 | &maxsock, | 731 | &maxsock, |
732 | FD_SETSIZE)) | 732 | FD_SETSIZE)) |
733 | { | 733 | { |
734 | #endif /* MHD_WINSOCK_SOCKETS */ | 734 | #endif /* MHD_WINSOCK_SOCKETS */ |
735 | sc = MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE; | 735 | sc = MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE; |
736 | #ifdef HAVE_MESSAGES | 736 | #ifdef HAVE_MESSAGES |
737 | MHD_DLOG (daemon, | 737 | MHD_DLOG (daemon, |
738 | sc, | 738 | sc, |
739 | _("Could not add control inter-thread communication channel FD to fdset")); | 739 | _ ( |
740 | "Could not add control inter-thread communication channel FD to fdset")); | ||
740 | #endif | 741 | #endif |
741 | #if defined(MHD_WINSOCK_SOCKETS) | 742 | #if defined(MHD_WINSOCK_SOCKETS) |
742 | } | 743 | } |
743 | } | 744 | } |
744 | #endif /* MHD_WINSOCK_SOCKETS */ | 745 | #endif /* MHD_WINSOCK_SOCKETS */ |
745 | } | 746 | } |
746 | /* Stop listening if we are at the configured connection limit */ | 747 | /* Stop listening if we are at the configured connection limit */ |
747 | /* If we're at the connection limit, no point in really | 748 | /* If we're at the connection limit, no point in really |
748 | accepting new connections; however, make sure we do not miss | 749 | accepting new connections; however, make sure we do not miss |
@@ -750,35 +751,35 @@ MHD_daemon_select_ (struct MHD_Daemon *daemon, | |||
750 | only do this optimization if we have a signaling ITC in | 751 | only do this optimization if we have a signaling ITC in |
751 | place. */ | 752 | place. */ |
752 | if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_socket)) && | 753 | if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_socket)) && |
753 | (MHD_ITC_IS_VALID_(daemon->itc)) && | 754 | (MHD_ITC_IS_VALID_ (daemon->itc)) && |
754 | ( (daemon->connections == daemon->global_connection_limit) || | 755 | ( (daemon->connections == daemon->global_connection_limit) || |
755 | (daemon->at_limit) ) ) | 756 | (daemon->at_limit) ) ) |
756 | { | 757 | { |
757 | FD_CLR (ls, | 758 | FD_CLR (ls, |
758 | &rs); | 759 | &rs); |
759 | } | 760 | } |
760 | tv = NULL; | 761 | tv = NULL; |
761 | if (MHD_SC_OK != sc) | 762 | if (MHD_SC_OK != sc) |
762 | may_block = MHD_NO; | 763 | may_block = MHD_NO; |
763 | if (MHD_NO == may_block) | 764 | if (MHD_NO == may_block) |
764 | { | 765 | { |
765 | timeout.tv_usec = 0; | 766 | timeout.tv_usec = 0; |
766 | timeout.tv_sec = 0; | 767 | timeout.tv_sec = 0; |
767 | tv = &timeout; | 768 | tv = &timeout; |
768 | } | 769 | } |
769 | else if ( (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) && | 770 | else if ( (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) && |
770 | (MHD_SC_OK == | 771 | (MHD_SC_OK == |
771 | MHD_daemon_get_timeout (daemon, | 772 | MHD_daemon_get_timeout (daemon, |
772 | <imeout)) ) | 773 | <imeout)) ) |
773 | { | 774 | { |
774 | /* ltimeout is in ms */ | 775 | /* ltimeout is in ms */ |
775 | timeout.tv_usec = (ltimeout % 1000) * 1000; | 776 | timeout.tv_usec = (ltimeout % 1000) * 1000; |
776 | if (ltimeout / 1000 > TIMEVAL_TV_SEC_MAX) | 777 | if (ltimeout / 1000 > TIMEVAL_TV_SEC_MAX) |
777 | timeout.tv_sec = TIMEVAL_TV_SEC_MAX; | 778 | timeout.tv_sec = TIMEVAL_TV_SEC_MAX; |
778 | else | 779 | else |
779 | timeout.tv_sec = (_MHD_TIMEVAL_TV_SEC_TYPE)(ltimeout / 1000); | 780 | timeout.tv_sec = (_MHD_TIMEVAL_TV_SEC_TYPE) (ltimeout / 1000); |
780 | tv = &timeout; | 781 | tv = &timeout; |
781 | } | 782 | } |
782 | num_ready = MHD_SYS_select_ (maxsock + 1, | 783 | num_ready = MHD_SYS_select_ (maxsock + 1, |
783 | &rs, | 784 | &rs, |
784 | &ws, | 785 | &ws, |
@@ -787,24 +788,24 @@ MHD_daemon_select_ (struct MHD_Daemon *daemon, | |||
787 | if (daemon->shutdown) | 788 | if (daemon->shutdown) |
788 | return MHD_SC_DAEMON_ALREADY_SHUTDOWN; | 789 | return MHD_SC_DAEMON_ALREADY_SHUTDOWN; |
789 | if (num_ready < 0) | 790 | if (num_ready < 0) |
790 | { | 791 | { |
791 | const int err = MHD_socket_get_error_ (); | 792 | const int err = MHD_socket_get_error_ (); |
792 | 793 | ||
793 | if (MHD_SCKT_ERR_IS_EINTR_(err)) | 794 | if (MHD_SCKT_ERR_IS_EINTR_ (err)) |
794 | return sc; | 795 | return sc; |
795 | #ifdef HAVE_MESSAGES | 796 | #ifdef HAVE_MESSAGES |
796 | MHD_DLOG (daemon, | 797 | MHD_DLOG (daemon, |
797 | MHD_SC_UNEXPECTED_SELECT_ERROR, | 798 | MHD_SC_UNEXPECTED_SELECT_ERROR, |
798 | _("select failed: %s\n"), | 799 | _ ("select failed: %s\n"), |
799 | MHD_socket_strerr_ (err)); | 800 | MHD_socket_strerr_ (err)); |
800 | #endif | 801 | #endif |
801 | return MHD_SC_UNEXPECTED_SELECT_ERROR; | 802 | return MHD_SC_UNEXPECTED_SELECT_ERROR; |
802 | } | 803 | } |
803 | if (MHD_SC_OK != | 804 | if (MHD_SC_OK != |
804 | (sc2 = internal_run_from_select (daemon, | 805 | (sc2 = internal_run_from_select (daemon, |
805 | &rs, | 806 | &rs, |
806 | &ws, | 807 | &ws, |
807 | &es))) | 808 | &es))) |
808 | return sc2; | 809 | return sc2; |
809 | return sc; | 810 | return sc; |
810 | } | 811 | } |
diff --git a/src/lib/daemon_select.h b/src/lib/daemon_select.h index d6e9e106..7dac8a80 100644 --- a/src/lib/daemon_select.h +++ b/src/lib/daemon_select.h | |||
@@ -36,8 +36,8 @@ | |||
36 | */ | 36 | */ |
37 | enum MHD_StatusCode | 37 | enum MHD_StatusCode |
38 | MHD_daemon_select_ (struct MHD_Daemon *daemon, | 38 | MHD_daemon_select_ (struct MHD_Daemon *daemon, |
39 | int may_block) | 39 | int may_block) |
40 | MHD_NONNULL(1); | 40 | MHD_NONNULL (1); |
41 | 41 | ||
42 | 42 | ||
43 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) | 43 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) |
@@ -49,7 +49,7 @@ MHD_daemon_select_ (struct MHD_Daemon *daemon, | |||
49 | */ | 49 | */ |
50 | void | 50 | void |
51 | MHD_daemon_upgrade_connection_with_select_ (struct MHD_Connection *con) | 51 | MHD_daemon_upgrade_connection_with_select_ (struct MHD_Connection *con) |
52 | MHD_NONNULL(1); | 52 | MHD_NONNULL (1); |
53 | #endif | 53 | #endif |
54 | 54 | ||
55 | #endif | 55 | #endif |
diff --git a/src/lib/daemon_start.c b/src/lib/daemon_start.c index 52124c77..c8c498be 100644 --- a/src/lib/daemon_start.c +++ b/src/lib/daemon_start.c | |||
@@ -46,63 +46,64 @@ configure_listen_reuse (struct MHD_Daemon *daemon) | |||
46 | /* Apply the socket options according to | 46 | /* Apply the socket options according to |
47 | listening_address_reuse. */ | 47 | listening_address_reuse. */ |
48 | if (daemon->allow_address_reuse) | 48 | if (daemon->allow_address_reuse) |
49 | { | 49 | { |
50 | /* User requested to allow reusing listening address:port. */ | 50 | /* User requested to allow reusing listening address:port. */ |
51 | #ifndef MHD_WINSOCK_SOCKETS | 51 | #ifndef MHD_WINSOCK_SOCKETS |
52 | /* Use SO_REUSEADDR on non-W32 platforms, and do not fail if | 52 | /* Use SO_REUSEADDR on non-W32 platforms, and do not fail if |
53 | * it doesn't work. */ | 53 | * it doesn't work. */ |
54 | if (0 > setsockopt (daemon->listen_socket, | 54 | if (0 > setsockopt (daemon->listen_socket, |
55 | SOL_SOCKET, | 55 | SOL_SOCKET, |
56 | SO_REUSEADDR, | 56 | SO_REUSEADDR, |
57 | (void *) &on, | 57 | (void *) &on, |
58 | sizeof (on))) | 58 | sizeof (on))) |
59 | { | 59 | { |
60 | #ifdef HAVE_MESSAGES | 60 | #ifdef HAVE_MESSAGES |
61 | MHD_DLOG (daemon, | 61 | MHD_DLOG (daemon, |
62 | MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_FAILED, | 62 | MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_FAILED, |
63 | _("setsockopt failed: %s\n"), | 63 | _ ("setsockopt failed: %s\n"), |
64 | MHD_socket_last_strerr_ ()); | 64 | MHD_socket_last_strerr_ ()); |
65 | #endif | 65 | #endif |
66 | return MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_FAILED; | 66 | return MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_FAILED; |
67 | } | 67 | } |
68 | return MHD_SC_OK; | 68 | return MHD_SC_OK; |
69 | #endif /* ! MHD_WINSOCK_SOCKETS */ | 69 | #endif /* ! MHD_WINSOCK_SOCKETS */ |
70 | /* Use SO_REUSEADDR on Windows and SO_REUSEPORT on most platforms. | 70 | /* Use SO_REUSEADDR on Windows and SO_REUSEPORT on most platforms. |
71 | * Fail if SO_REUSEPORT is not defined or setsockopt fails. | 71 | * Fail if SO_REUSEPORT is not defined or setsockopt fails. |
72 | */ | 72 | */ |
73 | /* SO_REUSEADDR on W32 has the same semantics | 73 | /* SO_REUSEADDR on W32 has the same semantics |
74 | as SO_REUSEPORT on BSD/Linux */ | 74 | as SO_REUSEPORT on BSD/Linux */ |
75 | #if defined(MHD_WINSOCK_SOCKETS) || defined(SO_REUSEPORT) | 75 | #if defined(MHD_WINSOCK_SOCKETS) || defined(SO_REUSEPORT) |
76 | if (0 > setsockopt (daemon->listen_socket, | 76 | if (0 > setsockopt (daemon->listen_socket, |
77 | SOL_SOCKET, | 77 | SOL_SOCKET, |
78 | #ifndef MHD_WINSOCK_SOCKETS | 78 | #ifndef MHD_WINSOCK_SOCKETS |
79 | SO_REUSEPORT, | 79 | SO_REUSEPORT, |
80 | #else /* MHD_WINSOCK_SOCKETS */ | 80 | #else /* MHD_WINSOCK_SOCKETS */ |
81 | SO_REUSEADDR, | 81 | SO_REUSEADDR, |
82 | #endif /* MHD_WINSOCK_SOCKETS */ | 82 | #endif /* MHD_WINSOCK_SOCKETS */ |
83 | (void *) &on, | 83 | (void *) &on, |
84 | sizeof (on))) | 84 | sizeof (on))) |
85 | { | 85 | { |
86 | #ifdef HAVE_MESSAGES | 86 | #ifdef HAVE_MESSAGES |
87 | MHD_DLOG (daemon, | 87 | MHD_DLOG (daemon, |
88 | MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_FAILED, | 88 | MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_FAILED, |
89 | _("setsockopt failed: %s\n"), | 89 | _ ("setsockopt failed: %s\n"), |
90 | MHD_socket_last_strerr_ ()); | 90 | MHD_socket_last_strerr_ ()); |
91 | #endif | 91 | #endif |
92 | return MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_FAILED; | 92 | return MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_FAILED; |
93 | } | 93 | } |
94 | return MHD_SC_OK; | 94 | return MHD_SC_OK; |
95 | #else /* !MHD_WINSOCK_SOCKETS && !SO_REUSEPORT */ | 95 | #else /* !MHD_WINSOCK_SOCKETS && !SO_REUSEPORT */ |
96 | /* we're supposed to allow address:port re-use, but | 96 | /* we're supposed to allow address:port re-use, but |
97 | on this platform we cannot; fail hard */ | 97 | on this platform we cannot; fail hard */ |
98 | #ifdef HAVE_MESSAGES | 98 | #ifdef HAVE_MESSAGES |
99 | MHD_DLOG (daemon, | 99 | MHD_DLOG (daemon, |
100 | MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_NOT_SUPPORTED, | 100 | MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_NOT_SUPPORTED, |
101 | _("Cannot allow listening address reuse: SO_REUSEPORT not defined\n")); | 101 | _ ( |
102 | "Cannot allow listening address reuse: SO_REUSEPORT not defined\n")); | ||
102 | #endif | 103 | #endif |
103 | return MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_NOT_SUPPORTED; | 104 | return MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_NOT_SUPPORTED; |
104 | #endif /* !MHD_WINSOCK_SOCKETS && !SO_REUSEPORT */ | 105 | #endif /* !MHD_WINSOCK_SOCKETS && !SO_REUSEPORT */ |
105 | } | 106 | } |
106 | 107 | ||
107 | /* if (! daemon->allow_address_reuse) */ | 108 | /* if (! daemon->allow_address_reuse) */ |
108 | /* User requested to disallow reusing listening address:port. | 109 | /* User requested to disallow reusing listening address:port. |
@@ -111,32 +112,33 @@ configure_listen_reuse (struct MHD_Daemon *daemon) | |||
111 | * Fail if MHD was compiled for W32 without SO_EXCLUSIVEADDRUSE | 112 | * Fail if MHD was compiled for W32 without SO_EXCLUSIVEADDRUSE |
112 | * or setsockopt fails. | 113 | * or setsockopt fails. |
113 | */ | 114 | */ |
114 | #if (defined(MHD_WINSOCK_SOCKETS) && defined(SO_EXCLUSIVEADDRUSE)) || \ | 115 | #if (defined(MHD_WINSOCK_SOCKETS) && defined(SO_EXCLUSIVEADDRUSE)) || \ |
115 | (defined(__sun) && defined(SO_EXCLBIND)) | 116 | (defined(__sun) && defined(SO_EXCLBIND)) |
116 | if (0 > setsockopt (daemon->listen_socket, | 117 | if (0 > setsockopt (daemon->listen_socket, |
117 | SOL_SOCKET, | 118 | SOL_SOCKET, |
118 | #ifdef SO_EXCLUSIVEADDRUSE | 119 | #ifdef SO_EXCLUSIVEADDRUSE |
119 | SO_EXCLUSIVEADDRUSE, | 120 | SO_EXCLUSIVEADDRUSE, |
120 | #else /* SO_EXCLBIND */ | 121 | #else /* SO_EXCLBIND */ |
121 | SO_EXCLBIND, | 122 | SO_EXCLBIND, |
122 | #endif /* SO_EXCLBIND */ | 123 | #endif /* SO_EXCLBIND */ |
123 | (void *) &on, | 124 | (void *) &on, |
124 | sizeof (on))) | 125 | sizeof (on))) |
125 | { | 126 | { |
126 | #ifdef HAVE_MESSAGES | 127 | #ifdef HAVE_MESSAGES |
127 | MHD_DLOG (daemon, | 128 | MHD_DLOG (daemon, |
128 | MHD_SC_LISTEN_ADDRESS_REUSE_DISABLE_FAILED, | 129 | MHD_SC_LISTEN_ADDRESS_REUSE_DISABLE_FAILED, |
129 | _("setsockopt failed: %s\n"), | 130 | _ ("setsockopt failed: %s\n"), |
130 | MHD_socket_last_strerr_ ()); | 131 | MHD_socket_last_strerr_ ()); |
131 | #endif | 132 | #endif |
132 | return MHD_SC_LISTEN_ADDRESS_REUSE_DISABLE_FAILED; | 133 | return MHD_SC_LISTEN_ADDRESS_REUSE_DISABLE_FAILED; |
133 | } | 134 | } |
134 | return MHD_SC_OK; | 135 | return MHD_SC_OK; |
135 | #elif defined(MHD_WINSOCK_SOCKETS) /* SO_EXCLUSIVEADDRUSE not defined on W32? */ | 136 | #elif defined(MHD_WINSOCK_SOCKETS) /* SO_EXCLUSIVEADDRUSE not defined on W32? */ |
136 | #ifdef HAVE_MESSAGES | 137 | #ifdef HAVE_MESSAGES |
137 | MHD_DLOG (daemon, | 138 | MHD_DLOG (daemon, |
138 | MHD_SC_LISTEN_ADDRESS_REUSE_DISABLE_NOT_SUPPORTED, | 139 | MHD_SC_LISTEN_ADDRESS_REUSE_DISABLE_NOT_SUPPORTED, |
139 | _("Cannot disallow listening address reuse: SO_EXCLUSIVEADDRUSE not defined\n")); | 140 | _ ( |
141 | "Cannot disallow listening address reuse: SO_EXCLUSIVEADDRUSE not defined\n")); | ||
140 | #endif | 142 | #endif |
141 | return MHD_SC_LISTEN_ADDRESS_REUSE_DISABLE_NOT_SUPPORTED; | 143 | return MHD_SC_LISTEN_ADDRESS_REUSE_DISABLE_NOT_SUPPORTED; |
142 | #endif /* MHD_WINSOCK_SOCKETS */ | 144 | #endif /* MHD_WINSOCK_SOCKETS */ |
@@ -166,86 +168,86 @@ open_listen_socket (struct MHD_Daemon *daemon) | |||
166 | pf = -1; | 168 | pf = -1; |
167 | /* Determine address family */ | 169 | /* Determine address family */ |
168 | switch (daemon->listen_af) | 170 | switch (daemon->listen_af) |
171 | { | ||
172 | case MHD_AF_NONE: | ||
173 | if (0 == daemon->listen_sa_len) | ||
169 | { | 174 | { |
170 | case MHD_AF_NONE: | 175 | /* no listening desired, that's OK */ |
171 | if (0 == daemon->listen_sa_len) | 176 | return MHD_SC_OK; |
172 | { | 177 | } |
173 | /* no listening desired, that's OK */ | 178 | /* we have a listen address, get AF from there! */ |
174 | return MHD_SC_OK; | 179 | switch (daemon->listen_sa.ss_family) |
175 | } | 180 | { |
176 | /* we have a listen address, get AF from there! */ | 181 | case AF_INET: |
177 | switch (daemon->listen_sa.ss_family) | 182 | pf = PF_INET; |
178 | { | 183 | use_v6 = false; |
179 | case AF_INET: | 184 | break; |
180 | pf = PF_INET; | ||
181 | use_v6 = false; | ||
182 | break; | ||
183 | #ifdef AF_INET6 | 185 | #ifdef AF_INET6 |
184 | case AF_INET6: | 186 | case AF_INET6: |
185 | pf = PF_INET6; | ||
186 | use_v6 = true; | ||
187 | break; | ||
188 | #endif | ||
189 | #ifdef AF_UNIX | ||
190 | case AF_UNIX: | ||
191 | pf = PF_UNIX; | ||
192 | use_v6 = false; | ||
193 | break; | ||
194 | #endif | ||
195 | default: | ||
196 | return MHD_SC_AF_NOT_SUPPORTED_BY_BUILD; | ||
197 | } /* switch on ss_family */ | ||
198 | break; /* MHD_AF_NONE */ | ||
199 | case MHD_AF_AUTO: | ||
200 | #if HAVE_INET6 | ||
201 | pf = PF_INET6; | 187 | pf = PF_INET6; |
202 | use_v6 = true; | 188 | use_v6 = true; |
203 | #else | ||
204 | pf = PF_INET; | ||
205 | use_v6 = false; | ||
206 | #endif | ||
207 | break; | 189 | break; |
208 | case MHD_AF_INET4: | 190 | #endif |
191 | #ifdef AF_UNIX | ||
192 | case AF_UNIX: | ||
193 | pf = PF_UNIX; | ||
209 | use_v6 = false; | 194 | use_v6 = false; |
210 | pf = PF_INET; | ||
211 | break; | 195 | break; |
212 | case MHD_AF_INET6: | 196 | #endif |
213 | case MHD_AF_DUAL: | 197 | default: |
198 | return MHD_SC_AF_NOT_SUPPORTED_BY_BUILD; | ||
199 | } /* switch on ss_family */ | ||
200 | break; /* MHD_AF_NONE */ | ||
201 | case MHD_AF_AUTO: | ||
214 | #if HAVE_INET6 | 202 | #if HAVE_INET6 |
215 | pf = PF_INET6; | 203 | pf = PF_INET6; |
216 | use_v6 = true; | 204 | use_v6 = true; |
217 | break; | 205 | #else |
206 | pf = PF_INET; | ||
207 | use_v6 = false; | ||
208 | #endif | ||
209 | break; | ||
210 | case MHD_AF_INET4: | ||
211 | use_v6 = false; | ||
212 | pf = PF_INET; | ||
213 | break; | ||
214 | case MHD_AF_INET6: | ||
215 | case MHD_AF_DUAL: | ||
216 | #if HAVE_INET6 | ||
217 | pf = PF_INET6; | ||
218 | use_v6 = true; | ||
219 | break; | ||
218 | #else | 220 | #else |
219 | #ifdef HAVE_MESSAGES | 221 | #ifdef HAVE_MESSAGES |
220 | MHD_DLOG (daemon, | 222 | MHD_DLOG (daemon, |
221 | MHD_SC_IPV6_NOT_SUPPORTED_BY_BUILD, | 223 | MHD_SC_IPV6_NOT_SUPPORTED_BY_BUILD, |
222 | _("IPv6 not supported by this build\n")); | 224 | _ ("IPv6 not supported by this build\n")); |
223 | #endif | 225 | #endif |
224 | return MHD_SC_IPV6_NOT_SUPPORTED_BY_BUILD; | 226 | return MHD_SC_IPV6_NOT_SUPPORTED_BY_BUILD; |
225 | #endif | 227 | #endif |
226 | } | 228 | } |
227 | mhd_assert (-1 != pf); | 229 | mhd_assert (-1 != pf); |
228 | /* try to open listen socket */ | 230 | /* try to open listen socket */ |
229 | try_open_listen_socket: | 231 | try_open_listen_socket: |
230 | daemon->listen_socket = MHD_socket_create_listen_(pf); | 232 | daemon->listen_socket = MHD_socket_create_listen_ (pf); |
231 | if ( (MHD_INVALID_SOCKET == daemon->listen_socket) && | 233 | if ( (MHD_INVALID_SOCKET == daemon->listen_socket) && |
232 | (MHD_AF_AUTO == daemon->listen_af) && | 234 | (MHD_AF_AUTO == daemon->listen_af) && |
233 | (use_v6) ) | 235 | (use_v6) ) |
234 | { | 236 | { |
235 | use_v6 = false; | 237 | use_v6 = false; |
236 | pf = PF_INET; | 238 | pf = PF_INET; |
237 | goto try_open_listen_socket; | 239 | goto try_open_listen_socket; |
238 | } | 240 | } |
239 | if (MHD_INVALID_SOCKET == daemon->listen_socket) | 241 | if (MHD_INVALID_SOCKET == daemon->listen_socket) |
240 | { | 242 | { |
241 | #ifdef HAVE_MESSAGES | 243 | #ifdef HAVE_MESSAGES |
242 | MHD_DLOG (daemon, | 244 | MHD_DLOG (daemon, |
243 | MHD_SC_FAILED_TO_OPEN_LISTEN_SOCKET, | 245 | MHD_SC_FAILED_TO_OPEN_LISTEN_SOCKET, |
244 | _("Failed to create socket for listening: %s\n"), | 246 | _ ("Failed to create socket for listening: %s\n"), |
245 | MHD_socket_last_strerr_ ()); | 247 | MHD_socket_last_strerr_ ()); |
246 | #endif | 248 | #endif |
247 | return MHD_SC_FAILED_TO_OPEN_LISTEN_SOCKET; | 249 | return MHD_SC_FAILED_TO_OPEN_LISTEN_SOCKET; |
248 | } | 250 | } |
249 | 251 | ||
250 | if (MHD_SC_OK != | 252 | if (MHD_SC_OK != |
251 | (sc = configure_listen_reuse (daemon))) | 253 | (sc = configure_listen_reuse (daemon))) |
@@ -253,156 +255,157 @@ open_listen_socket (struct MHD_Daemon *daemon) | |||
253 | 255 | ||
254 | /* configure for dual stack (or not) */ | 256 | /* configure for dual stack (or not) */ |
255 | if (use_v6) | 257 | if (use_v6) |
256 | { | 258 | { |
257 | #if defined IPPROTO_IPV6 && defined IPV6_V6ONLY | 259 | #if defined IPPROTO_IPV6 && defined IPV6_V6ONLY |
258 | /* Note: "IPV6_V6ONLY" is declared by Windows Vista ff., see "IPPROTO_IPV6 Socket Options" | 260 | /* Note: "IPV6_V6ONLY" is declared by Windows Vista ff., see "IPPROTO_IPV6 Socket Options" |
259 | (http://msdn.microsoft.com/en-us/library/ms738574%28v=VS.85%29.aspx); | 261 | (http://msdn.microsoft.com/en-us/library/ms738574%28v=VS.85%29.aspx); |
260 | and may also be missing on older POSIX systems; good luck if you have any of those, | 262 | and may also be missing on older POSIX systems; good luck if you have any of those, |
261 | your IPv6 socket may then also bind against IPv4 anyway... */ | 263 | your IPv6 socket may then also bind against IPv4 anyway... */ |
262 | const MHD_SCKT_OPT_BOOL_ v6_only = | 264 | const MHD_SCKT_OPT_BOOL_ v6_only = |
263 | (MHD_AF_INET6 == daemon->listen_af); | 265 | (MHD_AF_INET6 == daemon->listen_af); |
264 | if (0 > setsockopt (daemon->listen_socket, | 266 | if (0 > setsockopt (daemon->listen_socket, |
265 | IPPROTO_IPV6, | 267 | IPPROTO_IPV6, |
266 | IPV6_V6ONLY, | 268 | IPV6_V6ONLY, |
267 | (const void *) &v6_only, | 269 | (const void *) &v6_only, |
268 | sizeof (v6_only))) | 270 | sizeof (v6_only))) |
269 | { | 271 | { |
270 | #ifdef HAVE_MESSAGES | 272 | #ifdef HAVE_MESSAGES |
271 | MHD_DLOG (daemon, | 273 | MHD_DLOG (daemon, |
272 | MHD_SC_LISTEN_DUAL_STACK_CONFIGURATION_FAILED, | 274 | MHD_SC_LISTEN_DUAL_STACK_CONFIGURATION_FAILED, |
273 | _("setsockopt failed: %s\n"), | 275 | _ ("setsockopt failed: %s\n"), |
274 | MHD_socket_last_strerr_ ()); | 276 | MHD_socket_last_strerr_ ()); |
275 | #endif | 277 | #endif |
276 | } | 278 | } |
277 | #else | 279 | #else |
278 | #ifdef HAVE_MESSAGES | 280 | #ifdef HAVE_MESSAGES |
279 | MHD_DLOG (daemon, | 281 | MHD_DLOG (daemon, |
280 | MHD_SC_LISTEN_DUAL_STACK_CONFIGURATION_NOT_SUPPORTED, | 282 | MHD_SC_LISTEN_DUAL_STACK_CONFIGURATION_NOT_SUPPORTED, |
281 | _("Cannot explicitly setup dual stack behavior on this platform\n")); | 283 | _ ( |
284 | "Cannot explicitly setup dual stack behavior on this platform\n")); | ||
282 | #endif | 285 | #endif |
283 | #endif | 286 | #endif |
284 | } | 287 | } |
285 | 288 | ||
286 | /* Determine address to bind to */ | 289 | /* Determine address to bind to */ |
287 | if (0 != daemon->listen_sa_len) | 290 | if (0 != daemon->listen_sa_len) |
288 | { | 291 | { |
289 | /* Bind address explicitly given */ | 292 | /* Bind address explicitly given */ |
290 | sa = (const struct sockaddr *) &daemon->listen_sa; | 293 | sa = (const struct sockaddr *) &daemon->listen_sa; |
291 | addrlen = daemon->listen_sa_len; | 294 | addrlen = daemon->listen_sa_len; |
292 | } | 295 | } |
293 | else | 296 | else |
294 | { | 297 | { |
295 | /* Compute bind address based on port and AF */ | 298 | /* Compute bind address based on port and AF */ |
296 | #if HAVE_INET6 | 299 | #if HAVE_INET6 |
297 | if (use_v6) | 300 | if (use_v6) |
298 | { | 301 | { |
299 | #ifdef IN6ADDR_ANY_INIT | 302 | #ifdef IN6ADDR_ANY_INIT |
300 | static const struct in6_addr static_in6any = IN6ADDR_ANY_INIT; | 303 | static const struct in6_addr static_in6any = IN6ADDR_ANY_INIT; |
301 | #endif | 304 | #endif |
302 | struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) &ss; | 305 | struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) &ss; |
303 | 306 | ||
304 | addrlen = sizeof (struct sockaddr_in6); | 307 | addrlen = sizeof (struct sockaddr_in6); |
305 | memset (sin6, | 308 | memset (sin6, |
306 | 0, | 309 | 0, |
307 | sizeof (struct sockaddr_in6)); | 310 | sizeof (struct sockaddr_in6)); |
308 | sin6->sin6_family = AF_INET6; | 311 | sin6->sin6_family = AF_INET6; |
309 | sin6->sin6_port = htons (daemon->listen_port); | 312 | sin6->sin6_port = htons (daemon->listen_port); |
310 | #ifdef IN6ADDR_ANY_INIT | 313 | #ifdef IN6ADDR_ANY_INIT |
311 | sin6->sin6_addr = static_in6any; | 314 | sin6->sin6_addr = static_in6any; |
312 | #endif | 315 | #endif |
313 | #if HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN | 316 | #if HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN |
314 | sin6->sin6_len = sizeof (struct sockaddr_in6); | 317 | sin6->sin6_len = sizeof (struct sockaddr_in6); |
315 | #endif | 318 | #endif |
316 | } | 319 | } |
317 | else | 320 | else |
318 | #endif | 321 | #endif |
319 | { | 322 | { |
320 | struct sockaddr_in *sin4 = (struct sockaddr_in *) &ss; | 323 | struct sockaddr_in *sin4 = (struct sockaddr_in *) &ss; |
321 | 324 | ||
322 | addrlen = sizeof (struct sockaddr_in); | 325 | addrlen = sizeof (struct sockaddr_in); |
323 | memset (sin4, | 326 | memset (sin4, |
324 | 0, | 327 | 0, |
325 | sizeof (struct sockaddr_in)); | 328 | sizeof (struct sockaddr_in)); |
326 | sin4->sin_family = AF_INET; | 329 | sin4->sin_family = AF_INET; |
327 | sin4->sin_port = htons (daemon->listen_port); | 330 | sin4->sin_port = htons (daemon->listen_port); |
328 | if (0 != INADDR_ANY) | 331 | if (0 != INADDR_ANY) |
329 | sin4->sin_addr.s_addr = htonl (INADDR_ANY); | 332 | sin4->sin_addr.s_addr = htonl (INADDR_ANY); |
330 | #if HAVE_STRUCT_SOCKADDR_IN_SIN_LEN | 333 | #if HAVE_STRUCT_SOCKADDR_IN_SIN_LEN |
331 | sin4->sin_len = sizeof (struct sockaddr_in); | 334 | sin4->sin_len = sizeof (struct sockaddr_in); |
332 | #endif | 335 | #endif |
333 | } | ||
334 | sa = (const struct sockaddr *) &ss; | ||
335 | } | 336 | } |
337 | sa = (const struct sockaddr *) &ss; | ||
338 | } | ||
336 | 339 | ||
337 | /* actually do the bind() */ | 340 | /* actually do the bind() */ |
338 | if (-1 == bind (daemon->listen_socket, | 341 | if (-1 == bind (daemon->listen_socket, |
339 | sa, | 342 | sa, |
340 | addrlen)) | 343 | addrlen)) |
341 | { | 344 | { |
342 | #ifdef HAVE_MESSAGES | 345 | #ifdef HAVE_MESSAGES |
343 | unsigned int port = 0; | 346 | unsigned int port = 0; |
344 | 347 | ||
345 | switch (sa->sa_family) | 348 | switch (sa->sa_family) |
346 | { | 349 | { |
347 | case AF_INET: | 350 | case AF_INET: |
348 | if (addrlen == sizeof (struct sockaddr_in)) | 351 | if (addrlen == sizeof (struct sockaddr_in)) |
349 | port = ntohs (((const struct sockaddr_in *) sa)->sin_port); | 352 | port = ntohs (((const struct sockaddr_in *) sa)->sin_port); |
350 | else | 353 | else |
351 | port = UINT16_MAX + 1; /* indicate size error */ | 354 | port = UINT16_MAX + 1; /* indicate size error */ |
352 | break; | 355 | break; |
353 | case AF_INET6: | 356 | case AF_INET6: |
354 | if (addrlen == sizeof (struct sockaddr_in6)) | 357 | if (addrlen == sizeof (struct sockaddr_in6)) |
355 | port = ntohs (((const struct sockaddr_in6 *) sa)->sin6_port); | 358 | port = ntohs (((const struct sockaddr_in6 *) sa)->sin6_port); |
356 | else | 359 | else |
357 | port = UINT16_MAX + 1; /* indicate size error */ | 360 | port = UINT16_MAX + 1; /* indicate size error */ |
358 | break; | 361 | break; |
359 | default: | 362 | default: |
360 | port = UINT_MAX; /* AF_UNIX? */ | 363 | port = UINT_MAX; /* AF_UNIX? */ |
361 | break; | 364 | break; |
362 | } | ||
363 | MHD_DLOG (daemon, | ||
364 | MHD_SC_LISTEN_SOCKET_BIND_FAILED, | ||
365 | _("Failed to bind to port %u: %s\n"), | ||
366 | port, | ||
367 | MHD_socket_last_strerr_ ()); | ||
368 | #endif | ||
369 | return MHD_SC_LISTEN_SOCKET_BIND_FAILED; | ||
370 | } | 365 | } |
366 | MHD_DLOG (daemon, | ||
367 | MHD_SC_LISTEN_SOCKET_BIND_FAILED, | ||
368 | _ ("Failed to bind to port %u: %s\n"), | ||
369 | port, | ||
370 | MHD_socket_last_strerr_ ()); | ||
371 | #endif | ||
372 | return MHD_SC_LISTEN_SOCKET_BIND_FAILED; | ||
373 | } | ||
371 | 374 | ||
372 | /* setup TCP_FASTOPEN */ | 375 | /* setup TCP_FASTOPEN */ |
373 | #ifdef TCP_FASTOPEN | 376 | #ifdef TCP_FASTOPEN |
374 | if (MHD_FOM_DISABLE != daemon->fast_open_method) | 377 | if (MHD_FOM_DISABLE != daemon->fast_open_method) |
378 | { | ||
379 | if (0 != setsockopt (daemon->listen_socket, | ||
380 | IPPROTO_TCP, | ||
381 | TCP_FASTOPEN, | ||
382 | &daemon->fo_queue_length, | ||
383 | sizeof (daemon->fo_queue_length))) | ||
375 | { | 384 | { |
376 | if (0 != setsockopt (daemon->listen_socket, | ||
377 | IPPROTO_TCP, | ||
378 | TCP_FASTOPEN, | ||
379 | &daemon->fo_queue_length, | ||
380 | sizeof (daemon->fo_queue_length))) | ||
381 | { | ||
382 | #ifdef HAVE_MESSAGES | 385 | #ifdef HAVE_MESSAGES |
383 | MHD_DLOG (daemon, | 386 | MHD_DLOG (daemon, |
384 | MHD_SC_FAST_OPEN_FAILURE, | 387 | MHD_SC_FAST_OPEN_FAILURE, |
385 | _("setsockopt failed: %s\n"), | 388 | _ ("setsockopt failed: %s\n"), |
386 | MHD_socket_last_strerr_ ()); | 389 | MHD_socket_last_strerr_ ()); |
387 | #endif | 390 | #endif |
388 | if (MHD_FOM_REQUIRE == daemon->fast_open_method) | 391 | if (MHD_FOM_REQUIRE == daemon->fast_open_method) |
389 | return MHD_SC_FAST_OPEN_FAILURE; | 392 | return MHD_SC_FAST_OPEN_FAILURE; |
390 | } | 393 | } |
391 | } | 394 | } |
392 | #endif | 395 | #endif |
393 | 396 | ||
394 | /* setup listening */ | 397 | /* setup listening */ |
395 | if (0 > listen (daemon->listen_socket, | 398 | if (0 > listen (daemon->listen_socket, |
396 | daemon->listen_backlog)) | 399 | daemon->listen_backlog)) |
397 | { | 400 | { |
398 | #ifdef HAVE_MESSAGES | 401 | #ifdef HAVE_MESSAGES |
399 | MHD_DLOG (daemon, | 402 | MHD_DLOG (daemon, |
400 | MHD_SC_LISTEN_FAILURE, | 403 | MHD_SC_LISTEN_FAILURE, |
401 | _("Failed to listen for connections: %s\n"), | 404 | _ ("Failed to listen for connections: %s\n"), |
402 | MHD_socket_last_strerr_ ()); | 405 | MHD_socket_last_strerr_ ()); |
403 | #endif | 406 | #endif |
404 | return MHD_SC_LISTEN_FAILURE; | 407 | return MHD_SC_LISTEN_FAILURE; |
405 | } | 408 | } |
406 | return MHD_SC_OK; | 409 | return MHD_SC_OK; |
407 | } | 410 | } |
408 | 411 | ||
@@ -426,65 +429,66 @@ get_listen_port_number (struct MHD_Daemon *daemon) | |||
426 | return; /* nothing to be done */ | 429 | return; /* nothing to be done */ |
427 | 430 | ||
428 | memset (&servaddr, | 431 | memset (&servaddr, |
429 | 0, | 432 | 0, |
430 | sizeof (struct sockaddr_storage)); | 433 | sizeof (struct sockaddr_storage)); |
431 | addrlen = sizeof (servaddr); | 434 | addrlen = sizeof (servaddr); |
432 | if (0 != getsockname (daemon->listen_socket, | 435 | if (0 != getsockname (daemon->listen_socket, |
433 | (struct sockaddr *) &servaddr, | 436 | (struct sockaddr *) &servaddr, |
434 | &addrlen)) | 437 | &addrlen)) |
435 | { | 438 | { |
436 | #ifdef HAVE_MESSAGES | 439 | #ifdef HAVE_MESSAGES |
437 | MHD_DLOG (daemon, | 440 | MHD_DLOG (daemon, |
438 | MHD_SC_LISTEN_PORT_INTROSPECTION_FAILURE, | 441 | MHD_SC_LISTEN_PORT_INTROSPECTION_FAILURE, |
439 | _("Failed to get listen port number: %s\n"), | 442 | _ ("Failed to get listen port number: %s\n"), |
440 | MHD_socket_last_strerr_ ()); | 443 | MHD_socket_last_strerr_ ()); |
441 | #endif /* HAVE_MESSAGES */ | 444 | #endif /* HAVE_MESSAGES */ |
442 | return; | 445 | return; |
443 | } | 446 | } |
444 | #ifdef MHD_POSIX_SOCKETS | 447 | #ifdef MHD_POSIX_SOCKETS |
445 | if (sizeof (servaddr) < addrlen) | 448 | if (sizeof (servaddr) < addrlen) |
446 | { | 449 | { |
447 | /* should be impossible with `struct sockaddr_storage` */ | 450 | /* should be impossible with `struct sockaddr_storage` */ |
448 | #ifdef HAVE_MESSAGES | 451 | #ifdef HAVE_MESSAGES |
449 | MHD_DLOG (daemon, | 452 | MHD_DLOG (daemon, |
450 | MHD_SC_LISTEN_PORT_INTROSPECTION_FAILURE, | 453 | MHD_SC_LISTEN_PORT_INTROSPECTION_FAILURE, |
451 | _("Failed to get listen port number (`struct sockaddr_storage` too small!?)\n")); | 454 | _ ( |
455 | "Failed to get listen port number (`struct sockaddr_storage` too small!?)\n")); | ||
452 | #endif /* HAVE_MESSAGES */ | 456 | #endif /* HAVE_MESSAGES */ |
453 | return; | 457 | return; |
454 | } | 458 | } |
455 | #endif /* MHD_POSIX_SOCKETS */ | 459 | #endif /* MHD_POSIX_SOCKETS */ |
456 | switch (servaddr.ss_family) | 460 | switch (servaddr.ss_family) |
461 | { | ||
462 | case AF_INET: | ||
457 | { | 463 | { |
458 | case AF_INET: | 464 | struct sockaddr_in *s4 = (struct sockaddr_in *) &servaddr; |
459 | { | ||
460 | struct sockaddr_in *s4 = (struct sockaddr_in *) &servaddr; | ||
461 | 465 | ||
462 | daemon->listen_port = ntohs (s4->sin_port); | 466 | daemon->listen_port = ntohs (s4->sin_port); |
463 | break; | 467 | break; |
464 | } | 468 | } |
465 | #ifdef HAVE_INET6 | 469 | #ifdef HAVE_INET6 |
466 | case AF_INET6: | 470 | case AF_INET6: |
467 | { | 471 | { |
468 | struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) &servaddr; | 472 | struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) &servaddr; |
469 | 473 | ||
470 | daemon->listen_port = ntohs(s6->sin6_port); | 474 | daemon->listen_port = ntohs (s6->sin6_port); |
471 | break; | 475 | break; |
472 | } | 476 | } |
473 | #endif /* HAVE_INET6 */ | 477 | #endif /* HAVE_INET6 */ |
474 | #ifdef AF_UNIX | 478 | #ifdef AF_UNIX |
475 | case AF_UNIX: | 479 | case AF_UNIX: |
476 | daemon->listen_port = 0; /* special value for UNIX domain sockets */ | 480 | daemon->listen_port = 0; /* special value for UNIX domain sockets */ |
477 | break; | 481 | break; |
478 | #endif | 482 | #endif |
479 | default: | 483 | default: |
480 | #ifdef HAVE_MESSAGES | 484 | #ifdef HAVE_MESSAGES |
481 | MHD_DLOG (daemon, | 485 | MHD_DLOG (daemon, |
482 | MHD_SC_LISTEN_PORT_INTROSPECTION_UNKNOWN_AF, | 486 | MHD_SC_LISTEN_PORT_INTROSPECTION_UNKNOWN_AF, |
483 | _("Unknown address family!\n")); | 487 | _ ("Unknown address family!\n")); |
484 | #endif | 488 | #endif |
485 | daemon->listen_port = 0; /* ugh */ | 489 | daemon->listen_port = 0; /* ugh */ |
486 | break; | 490 | break; |
487 | } | 491 | } |
488 | } | 492 | } |
489 | 493 | ||
490 | 494 | ||
@@ -501,7 +505,7 @@ setup_epoll_fd (struct MHD_Daemon *daemon) | |||
501 | int fd; | 505 | int fd; |
502 | 506 | ||
503 | #ifndef HAVE_MESSAGES | 507 | #ifndef HAVE_MESSAGES |
504 | (void)daemon; /* Mute compiler warning. */ | 508 | (void) daemon; /* Mute compiler warning. */ |
505 | #endif /* ! HAVE_MESSAGES */ | 509 | #endif /* ! HAVE_MESSAGES */ |
506 | 510 | ||
507 | #ifdef USE_EPOLL_CREATE1 | 511 | #ifdef USE_EPOLL_CREATE1 |
@@ -510,24 +514,24 @@ setup_epoll_fd (struct MHD_Daemon *daemon) | |||
510 | fd = epoll_create (MAX_EVENTS); | 514 | fd = epoll_create (MAX_EVENTS); |
511 | #endif /* ! USE_EPOLL_CREATE1 */ | 515 | #endif /* ! USE_EPOLL_CREATE1 */ |
512 | if (MHD_INVALID_SOCKET == fd) | 516 | if (MHD_INVALID_SOCKET == fd) |
513 | { | 517 | { |
514 | #ifdef HAVE_MESSAGES | 518 | #ifdef HAVE_MESSAGES |
515 | MHD_DLOG (daemon, | 519 | MHD_DLOG (daemon, |
516 | MHD_SC_EPOLL_CTL_CREATE_FAILED, | 520 | MHD_SC_EPOLL_CTL_CREATE_FAILED, |
517 | _("Call to epoll_create1 failed: %s\n"), | 521 | _ ("Call to epoll_create1 failed: %s\n"), |
518 | MHD_socket_last_strerr_ ()); | 522 | MHD_socket_last_strerr_ ()); |
519 | #endif | 523 | #endif |
520 | return MHD_INVALID_SOCKET; | 524 | return MHD_INVALID_SOCKET; |
521 | } | 525 | } |
522 | #if !defined(USE_EPOLL_CREATE1) | 526 | #if ! defined(USE_EPOLL_CREATE1) |
523 | if (! MHD_socket_noninheritable_ (fd)) | 527 | if (! MHD_socket_noninheritable_ (fd)) |
524 | { | 528 | { |
525 | #ifdef HAVE_MESSAGES | 529 | #ifdef HAVE_MESSAGES |
526 | MHD_DLOG (daemon, | 530 | MHD_DLOG (daemon, |
527 | MHD_SC_EPOLL_CTL_CONFIGURE_NOINHERIT_FAILED, | 531 | MHD_SC_EPOLL_CTL_CONFIGURE_NOINHERIT_FAILED, |
528 | _("Failed to set noninheritable mode on epoll FD.\n")); | 532 | _ ("Failed to set noninheritable mode on epoll FD.\n")); |
529 | #endif | 533 | #endif |
530 | } | 534 | } |
531 | #endif /* ! USE_EPOLL_CREATE1 */ | 535 | #endif /* ! USE_EPOLL_CREATE1 */ |
532 | return fd; | 536 | return fd; |
533 | } | 537 | } |
@@ -554,11 +558,11 @@ setup_epoll_to_listen (struct MHD_Daemon *daemon) | |||
554 | return MHD_SC_EPOLL_CTL_CREATE_FAILED; | 558 | return MHD_SC_EPOLL_CTL_CREATE_FAILED; |
555 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) | 559 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) |
556 | if (! daemon->disallow_upgrade) | 560 | if (! daemon->disallow_upgrade) |
557 | { | 561 | { |
558 | daemon->epoll_upgrade_fd = setup_epoll_fd (daemon); | 562 | daemon->epoll_upgrade_fd = setup_epoll_fd (daemon); |
559 | if (MHD_INVALID_SOCKET == daemon->epoll_upgrade_fd) | 563 | if (MHD_INVALID_SOCKET == daemon->epoll_upgrade_fd) |
560 | return MHD_SC_EPOLL_CTL_CREATE_FAILED; | 564 | return MHD_SC_EPOLL_CTL_CREATE_FAILED; |
561 | } | 565 | } |
562 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ | 566 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ |
563 | if ( (MHD_INVALID_SOCKET == (ls = daemon->listen_socket)) || | 567 | if ( (MHD_INVALID_SOCKET == (ls = daemon->listen_socket)) || |
564 | (daemon->was_quiesced) ) | 568 | (daemon->was_quiesced) ) |
@@ -566,37 +570,37 @@ setup_epoll_to_listen (struct MHD_Daemon *daemon) | |||
566 | event.events = EPOLLIN; | 570 | event.events = EPOLLIN; |
567 | event.data.ptr = daemon; | 571 | event.data.ptr = daemon; |
568 | if (0 != epoll_ctl (daemon->epoll_fd, | 572 | if (0 != epoll_ctl (daemon->epoll_fd, |
569 | EPOLL_CTL_ADD, | 573 | EPOLL_CTL_ADD, |
570 | ls, | 574 | ls, |
571 | &event)) | 575 | &event)) |
572 | { | 576 | { |
573 | #ifdef HAVE_MESSAGES | 577 | #ifdef HAVE_MESSAGES |
574 | MHD_DLOG (daemon, | 578 | MHD_DLOG (daemon, |
575 | MHD_SC_EPOLL_CTL_ADD_FAILED, | 579 | MHD_SC_EPOLL_CTL_ADD_FAILED, |
576 | _("Call to epoll_ctl failed: %s\n"), | 580 | _ ("Call to epoll_ctl failed: %s\n"), |
577 | MHD_socket_last_strerr_ ()); | 581 | MHD_socket_last_strerr_ ()); |
578 | #endif | 582 | #endif |
579 | return MHD_SC_EPOLL_CTL_ADD_FAILED; | 583 | return MHD_SC_EPOLL_CTL_ADD_FAILED; |
580 | } | 584 | } |
581 | daemon->listen_socket_in_epoll = true; | 585 | daemon->listen_socket_in_epoll = true; |
582 | if (MHD_ITC_IS_VALID_(daemon->itc)) | 586 | if (MHD_ITC_IS_VALID_ (daemon->itc)) |
587 | { | ||
588 | event.events = EPOLLIN; | ||
589 | event.data.ptr = (void *) daemon->epoll_itc_marker; | ||
590 | if (0 != epoll_ctl (daemon->epoll_fd, | ||
591 | EPOLL_CTL_ADD, | ||
592 | MHD_itc_r_fd_ (daemon->itc), | ||
593 | &event)) | ||
583 | { | 594 | { |
584 | event.events = EPOLLIN; | ||
585 | event.data.ptr = (void *) daemon->epoll_itc_marker; | ||
586 | if (0 != epoll_ctl (daemon->epoll_fd, | ||
587 | EPOLL_CTL_ADD, | ||
588 | MHD_itc_r_fd_ (daemon->itc), | ||
589 | &event)) | ||
590 | { | ||
591 | #ifdef HAVE_MESSAGES | 595 | #ifdef HAVE_MESSAGES |
592 | MHD_DLOG (daemon, | 596 | MHD_DLOG (daemon, |
593 | MHD_SC_EPOLL_CTL_ADD_FAILED, | 597 | MHD_SC_EPOLL_CTL_ADD_FAILED, |
594 | _("Call to epoll_ctl failed: %s\n"), | 598 | _ ("Call to epoll_ctl failed: %s\n"), |
595 | MHD_socket_last_strerr_ ()); | 599 | MHD_socket_last_strerr_ ()); |
596 | #endif | 600 | #endif |
597 | return MHD_SC_EPOLL_CTL_ADD_FAILED; | 601 | return MHD_SC_EPOLL_CTL_ADD_FAILED; |
598 | } | ||
599 | } | 602 | } |
603 | } | ||
600 | return MHD_SC_OK; | 604 | return MHD_SC_OK; |
601 | } | 605 | } |
602 | #endif | 606 | #endif |
@@ -616,35 +620,35 @@ MHD_polling_thread (void *cls) | |||
616 | 620 | ||
617 | MHD_thread_init_ (&daemon->pid); | 621 | MHD_thread_init_ (&daemon->pid); |
618 | while (! daemon->shutdown) | 622 | while (! daemon->shutdown) |
623 | { | ||
624 | switch (daemon->event_loop_syscall) | ||
619 | { | 625 | { |
620 | switch (daemon->event_loop_syscall) | 626 | case MHD_ELS_AUTO: |
621 | { | 627 | MHD_PANIC ("MHD_ELS_AUTO should have been mapped to preferred style"); |
622 | case MHD_ELS_AUTO: | 628 | break; |
623 | MHD_PANIC ("MHD_ELS_AUTO should have been mapped to preferred style"); | 629 | case MHD_ELS_SELECT: |
624 | break; | 630 | MHD_daemon_select_ (daemon, |
625 | case MHD_ELS_SELECT: | 631 | MHD_YES); |
626 | MHD_daemon_select_ (daemon, | 632 | break; |
627 | MHD_YES); | 633 | case MHD_ELS_POLL: |
628 | break; | ||
629 | case MHD_ELS_POLL: | ||
630 | #if HAVE_POLL | 634 | #if HAVE_POLL |
631 | MHD_daemon_poll_ (daemon, | 635 | MHD_daemon_poll_ (daemon, |
632 | MHD_YES); | 636 | MHD_YES); |
633 | #else | 637 | #else |
634 | MHD_PANIC ("MHD_ELS_POLL not supported, should have failed earlier"); | 638 | MHD_PANIC ("MHD_ELS_POLL not supported, should have failed earlier"); |
635 | #endif | 639 | #endif |
636 | break; | 640 | break; |
637 | case MHD_ELS_EPOLL: | 641 | case MHD_ELS_EPOLL: |
638 | #ifdef EPOLL_SUPPORT | 642 | #ifdef EPOLL_SUPPORT |
639 | MHD_daemon_epoll_ (daemon, | 643 | MHD_daemon_epoll_ (daemon, |
640 | MHD_YES); | 644 | MHD_YES); |
641 | #else | 645 | #else |
642 | MHD_PANIC ("MHD_ELS_EPOLL not supported, should have failed earlier"); | 646 | MHD_PANIC ("MHD_ELS_EPOLL not supported, should have failed earlier"); |
643 | #endif | 647 | #endif |
644 | break; | 648 | break; |
645 | } | ||
646 | MHD_connection_cleanup_ (daemon); | ||
647 | } | 649 | } |
650 | MHD_connection_cleanup_ (daemon); | ||
651 | } | ||
648 | /* Resume any pending for resume connections, join | 652 | /* Resume any pending for resume connections, join |
649 | * all connection's threads (if any) and finally cleanup | 653 | * all connection's threads (if any) and finally cleanup |
650 | * everything. */ | 654 | * everything. */ |
@@ -652,7 +656,7 @@ MHD_polling_thread (void *cls) | |||
652 | MHD_resume_suspended_connections_ (daemon); | 656 | MHD_resume_suspended_connections_ (daemon); |
653 | MHD_daemon_close_all_connections_ (daemon); | 657 | MHD_daemon_close_all_connections_ (daemon); |
654 | 658 | ||
655 | return (MHD_THRD_RTRN_TYPE_)0; | 659 | return (MHD_THRD_RTRN_TYPE_) 0; |
656 | } | 660 | } |
657 | 661 | ||
658 | 662 | ||
@@ -669,114 +673,116 @@ setup_thread_pool (struct MHD_Daemon *daemon) | |||
669 | * due to integer division). Also keep track of how many | 673 | * due to integer division). Also keep track of how many |
670 | * connections are leftover after an equal split. */ | 674 | * connections are leftover after an equal split. */ |
671 | unsigned int conns_per_thread = daemon->global_connection_limit | 675 | unsigned int conns_per_thread = daemon->global_connection_limit |
672 | / daemon->threading_mode; | 676 | / daemon->threading_mode; |
673 | unsigned int leftover_conns = daemon->global_connection_limit | 677 | unsigned int leftover_conns = daemon->global_connection_limit |
674 | % daemon->threading_mode; | 678 | % daemon->threading_mode; |
675 | int i; | 679 | int i; |
676 | enum MHD_StatusCode sc; | 680 | enum MHD_StatusCode sc; |
677 | 681 | ||
678 | /* Allocate memory for pooled objects */ | 682 | /* Allocate memory for pooled objects */ |
679 | daemon->worker_pool = MHD_calloc_ (daemon->threading_mode, | 683 | daemon->worker_pool = MHD_calloc_ (daemon->threading_mode, |
680 | sizeof (struct MHD_Daemon)); | 684 | sizeof (struct MHD_Daemon)); |
681 | if (NULL == daemon->worker_pool) | 685 | if (NULL == daemon->worker_pool) |
682 | return MHD_SC_THREAD_POOL_MALLOC_FAILURE; | 686 | return MHD_SC_THREAD_POOL_MALLOC_FAILURE; |
683 | 687 | ||
684 | /* Start the workers in the pool */ | 688 | /* Start the workers in the pool */ |
685 | for (i = 0; i < daemon->threading_mode; i++) | 689 | for (i = 0; i < daemon->threading_mode; i++) |
690 | { | ||
691 | /* Create copy of the Daemon object for each worker */ | ||
692 | struct MHD_Daemon *d = &daemon->worker_pool[i]; | ||
693 | |||
694 | memcpy (d, | ||
695 | daemon, | ||
696 | sizeof (struct MHD_Daemon)); | ||
697 | /* Adjust pooling params for worker daemons; note that memcpy() | ||
698 | has already copied MHD_USE_INTERNAL_POLLING_THREAD thread mode into | ||
699 | the worker threads. */ | ||
700 | d->master = daemon; | ||
701 | d->worker_pool_size = 0; | ||
702 | d->worker_pool = NULL; | ||
703 | /* Divide available connections evenly amongst the threads. | ||
704 | * Thread indexes in [0, leftover_conns) each get one of the | ||
705 | * leftover connections. */ | ||
706 | d->global_connection_limit = conns_per_thread; | ||
707 | if (((unsigned int) i) < leftover_conns) | ||
708 | ++d->global_connection_limit; | ||
709 | |||
710 | if (! daemon->disable_itc) | ||
686 | { | 711 | { |
687 | /* Create copy of the Daemon object for each worker */ | 712 | if (! MHD_itc_init_ (d->itc)) |
688 | struct MHD_Daemon *d = &daemon->worker_pool[i]; | 713 | { |
689 | |||
690 | memcpy (d, | ||
691 | daemon, | ||
692 | sizeof (struct MHD_Daemon)); | ||
693 | /* Adjust pooling params for worker daemons; note that memcpy() | ||
694 | has already copied MHD_USE_INTERNAL_POLLING_THREAD thread mode into | ||
695 | the worker threads. */ | ||
696 | d->master = daemon; | ||
697 | d->worker_pool_size = 0; | ||
698 | d->worker_pool = NULL; | ||
699 | /* Divide available connections evenly amongst the threads. | ||
700 | * Thread indexes in [0, leftover_conns) each get one of the | ||
701 | * leftover connections. */ | ||
702 | d->global_connection_limit = conns_per_thread; | ||
703 | if (((unsigned int) i) < leftover_conns) | ||
704 | ++d->global_connection_limit; | ||
705 | |||
706 | if (! daemon->disable_itc) | ||
707 | { | ||
708 | if (! MHD_itc_init_ (d->itc)) | ||
709 | { | ||
710 | #ifdef HAVE_MESSAGES | 714 | #ifdef HAVE_MESSAGES |
711 | MHD_DLOG (daemon, | 715 | MHD_DLOG (daemon, |
712 | MHD_SC_ITC_INITIALIZATION_FAILED, | 716 | MHD_SC_ITC_INITIALIZATION_FAILED, |
713 | _("Failed to create worker inter-thread communication channel: %s\n"), | 717 | _ ( |
714 | MHD_itc_last_strerror_() ); | 718 | "Failed to create worker inter-thread communication channel: %s\n"), |
715 | #endif | 719 | MHD_itc_last_strerror_ () ); |
716 | sc = MHD_SC_ITC_INITIALIZATION_FAILED; | 720 | #endif |
717 | goto thread_failed; | 721 | sc = MHD_SC_ITC_INITIALIZATION_FAILED; |
718 | } | 722 | goto thread_failed; |
719 | if ( (MHD_ELS_SELECT == daemon->event_loop_syscall) && | 723 | } |
720 | (! MHD_SCKT_FD_FITS_FDSET_(MHD_itc_r_fd_ (d->itc), | 724 | if ( (MHD_ELS_SELECT == daemon->event_loop_syscall) && |
721 | NULL)) ) | 725 | (! MHD_SCKT_FD_FITS_FDSET_ (MHD_itc_r_fd_ (d->itc), |
722 | { | 726 | NULL)) ) |
727 | { | ||
723 | #ifdef HAVE_MESSAGES | 728 | #ifdef HAVE_MESSAGES |
724 | MHD_DLOG (daemon, | 729 | MHD_DLOG (daemon, |
725 | MHD_SC_ITC_DESCRIPTOR_TOO_LARGE, | 730 | MHD_SC_ITC_DESCRIPTOR_TOO_LARGE, |
726 | _("File descriptor for inter-thread communication channel exceeds maximum value\n")); | 731 | _ ( |
727 | #endif | 732 | "File descriptor for inter-thread communication channel exceeds maximum value\n")); |
728 | MHD_itc_destroy_chk_ (d->itc); | 733 | #endif |
729 | sc = MHD_SC_ITC_DESCRIPTOR_TOO_LARGE; | 734 | MHD_itc_destroy_chk_ (d->itc); |
730 | goto thread_failed; | 735 | sc = MHD_SC_ITC_DESCRIPTOR_TOO_LARGE; |
731 | } | 736 | goto thread_failed; |
732 | } | 737 | } |
733 | else | 738 | } |
734 | { | 739 | else |
735 | MHD_itc_set_invalid_ (d->itc); | 740 | { |
736 | } | 741 | MHD_itc_set_invalid_ (d->itc); |
742 | } | ||
737 | 743 | ||
738 | #ifdef EPOLL_SUPPORT | 744 | #ifdef EPOLL_SUPPORT |
739 | if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) && | 745 | if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) && |
740 | (MHD_SC_OK != (sc = setup_epoll_to_listen (d))) ) | 746 | (MHD_SC_OK != (sc = setup_epoll_to_listen (d))) ) |
741 | goto thread_failed; | 747 | goto thread_failed; |
742 | #endif | 748 | #endif |
743 | 749 | ||
744 | /* Must init cleanup connection mutex for each worker */ | 750 | /* Must init cleanup connection mutex for each worker */ |
745 | if (! MHD_mutex_init_ (&d->cleanup_connection_mutex)) | 751 | if (! MHD_mutex_init_ (&d->cleanup_connection_mutex)) |
746 | { | 752 | { |
747 | #ifdef HAVE_MESSAGES | 753 | #ifdef HAVE_MESSAGES |
748 | MHD_DLOG (daemon, | 754 | MHD_DLOG (daemon, |
749 | MHD_SC_THREAD_POOL_CREATE_MUTEX_FAILURE, | 755 | MHD_SC_THREAD_POOL_CREATE_MUTEX_FAILURE, |
750 | _("MHD failed to initialize cleanup connection mutex\n")); | 756 | _ ("MHD failed to initialize cleanup connection mutex\n")); |
751 | #endif | 757 | #endif |
752 | if (! daemon->disable_itc) | 758 | if (! daemon->disable_itc) |
753 | MHD_itc_destroy_chk_ (d->itc); | 759 | MHD_itc_destroy_chk_ (d->itc); |
754 | sc = MHD_SC_THREAD_POOL_CREATE_MUTEX_FAILURE; | 760 | sc = MHD_SC_THREAD_POOL_CREATE_MUTEX_FAILURE; |
755 | goto thread_failed; | 761 | goto thread_failed; |
756 | } | 762 | } |
757 | 763 | ||
758 | /* Spawn the worker thread */ | 764 | /* Spawn the worker thread */ |
759 | if (! MHD_create_named_thread_ (&d->pid, | 765 | if (! MHD_create_named_thread_ (&d->pid, |
760 | "MHD-worker", | 766 | "MHD-worker", |
761 | daemon->thread_stack_limit_b, | 767 | daemon->thread_stack_limit_b, |
762 | &MHD_polling_thread, | 768 | &MHD_polling_thread, |
763 | d)) | 769 | d)) |
764 | { | 770 | { |
765 | #ifdef HAVE_MESSAGES | 771 | #ifdef HAVE_MESSAGES |
766 | MHD_DLOG (daemon, | 772 | MHD_DLOG (daemon, |
767 | MHD_SC_THREAD_POOL_LAUNCH_FAILURE, | 773 | MHD_SC_THREAD_POOL_LAUNCH_FAILURE, |
768 | _("Failed to create pool thread: %s\n"), | 774 | _ ("Failed to create pool thread: %s\n"), |
769 | MHD_strerror_ (errno)); | 775 | MHD_strerror_ (errno)); |
770 | #endif | 776 | #endif |
771 | /* Free memory for this worker; cleanup below handles | 777 | /* Free memory for this worker; cleanup below handles |
772 | * all previously-created workers. */ | 778 | * all previously-created workers. */ |
773 | if (! daemon->disable_itc) | 779 | if (! daemon->disable_itc) |
774 | MHD_itc_destroy_chk_ (d->itc); | 780 | MHD_itc_destroy_chk_ (d->itc); |
775 | MHD_mutex_destroy_chk_ (&d->cleanup_connection_mutex); | 781 | MHD_mutex_destroy_chk_ (&d->cleanup_connection_mutex); |
776 | sc = MHD_SC_THREAD_POOL_LAUNCH_FAILURE; | 782 | sc = MHD_SC_THREAD_POOL_LAUNCH_FAILURE; |
777 | goto thread_failed; | 783 | goto thread_failed; |
778 | } | 784 | } |
779 | } /* end for() */ | 785 | } /* end for() */ |
780 | return MHD_SC_OK; | 786 | return MHD_SC_OK; |
781 | 787 | ||
782 | thread_failed: | 788 | thread_failed: |
@@ -785,14 +791,14 @@ thread_failed: | |||
785 | assumes a 0-sized thread pool means we had been in the default | 791 | assumes a 0-sized thread pool means we had been in the default |
786 | MHD_USE_INTERNAL_POLLING_THREAD mode. */ | 792 | MHD_USE_INTERNAL_POLLING_THREAD mode. */ |
787 | if (0 == i) | 793 | if (0 == i) |
794 | { | ||
795 | if (NULL != daemon->worker_pool) | ||
788 | { | 796 | { |
789 | if (NULL != daemon->worker_pool) | 797 | free (daemon->worker_pool); |
790 | { | 798 | daemon->worker_pool = NULL; |
791 | free (daemon->worker_pool); | ||
792 | daemon->worker_pool = NULL; | ||
793 | } | ||
794 | return MHD_SC_THREAD_LAUNCH_FAILURE; | ||
795 | } | 799 | } |
800 | return MHD_SC_THREAD_LAUNCH_FAILURE; | ||
801 | } | ||
796 | /* Shutdown worker threads we've already created. Pretend | 802 | /* Shutdown worker threads we've already created. Pretend |
797 | as though we had fully initialized our daemon, but | 803 | as though we had fully initialized our daemon, but |
798 | with a smaller number of threads than had been | 804 | with a smaller number of threads than had been |
@@ -817,63 +823,65 @@ MHD_daemon_start (struct MHD_Daemon *daemon) | |||
817 | enum MHD_StatusCode sc; | 823 | enum MHD_StatusCode sc; |
818 | 824 | ||
819 | if (MHD_ELS_AUTO == daemon->event_loop_syscall) | 825 | if (MHD_ELS_AUTO == daemon->event_loop_syscall) |
820 | { | 826 | { |
821 | #if EPOLL_SUPPORT | 827 | #if EPOLL_SUPPORT |
822 | /* We do not support thread-per-connection in combination | 828 | /* We do not support thread-per-connection in combination |
823 | with epoll, so use poll in this case, otherwise prefer | 829 | with epoll, so use poll in this case, otherwise prefer |
824 | epoll. */ | 830 | epoll. */ |
825 | if (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode) | 831 | if (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode) |
826 | daemon->event_loop_syscall = MHD_ELS_POLL; | ||
827 | else | ||
828 | daemon->event_loop_syscall = MHD_ELS_EPOLL; | ||
829 | #elif HAVE_POLL | ||
830 | daemon->event_loop_syscall = MHD_ELS_POLL; | 832 | daemon->event_loop_syscall = MHD_ELS_POLL; |
833 | else | ||
834 | daemon->event_loop_syscall = MHD_ELS_EPOLL; | ||
835 | #elif HAVE_POLL | ||
836 | daemon->event_loop_syscall = MHD_ELS_POLL; | ||
831 | #else | 837 | #else |
832 | daemon->event_loop_syscall = MHD_ELS_SELECT; | 838 | daemon->event_loop_syscall = MHD_ELS_SELECT; |
833 | #endif | 839 | #endif |
834 | } | 840 | } |
835 | 841 | ||
836 | #ifdef EPOLL_SUPPORT | 842 | #ifdef EPOLL_SUPPORT |
837 | if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) && | 843 | if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) && |
838 | (0 == daemon->worker_pool_size) && | 844 | (0 == daemon->worker_pool_size) && |
839 | (MHD_INVALID_SOCKET != daemon->listen_socket) && | 845 | (MHD_INVALID_SOCKET != daemon->listen_socket) && |
840 | (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode) ) | 846 | (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode) ) |
841 | { | 847 | { |
842 | #ifdef HAVE_MESSAGES | 848 | #ifdef HAVE_MESSAGES |
843 | MHD_DLOG (daemon, | 849 | MHD_DLOG (daemon, |
844 | MHD_SC_SYSCALL_THREAD_COMBINATION_INVALID, | 850 | MHD_SC_SYSCALL_THREAD_COMBINATION_INVALID, |
845 | _("Combining MHD_USE_THREAD_PER_CONNECTION and MHD_USE_EPOLL is not supported.\n")); | 851 | _ ( |
852 | "Combining MHD_USE_THREAD_PER_CONNECTION and MHD_USE_EPOLL is not supported.\n")); | ||
846 | #endif | 853 | #endif |
847 | return MHD_SC_SYSCALL_THREAD_COMBINATION_INVALID; | 854 | return MHD_SC_SYSCALL_THREAD_COMBINATION_INVALID; |
848 | } | 855 | } |
849 | #endif | 856 | #endif |
850 | 857 | ||
851 | /* Setup ITC */ | 858 | /* Setup ITC */ |
852 | if ( (! daemon->disable_itc) && | 859 | if ( (! daemon->disable_itc) && |
853 | (0 == daemon->worker_pool_size) ) | 860 | (0 == daemon->worker_pool_size) ) |
861 | { | ||
862 | if (! MHD_itc_init_ (daemon->itc)) | ||
854 | { | 863 | { |
855 | if (! MHD_itc_init_ (daemon->itc)) | ||
856 | { | ||
857 | #ifdef HAVE_MESSAGES | 864 | #ifdef HAVE_MESSAGES |
858 | MHD_DLOG (daemon, | 865 | MHD_DLOG (daemon, |
859 | MHD_SC_ITC_INITIALIZATION_FAILED, | 866 | MHD_SC_ITC_INITIALIZATION_FAILED, |
860 | _("Failed to create inter-thread communication channel: %s\n"), | 867 | _ ("Failed to create inter-thread communication channel: %s\n"), |
861 | MHD_itc_last_strerror_ ()); | 868 | MHD_itc_last_strerror_ ()); |
862 | #endif | 869 | #endif |
863 | return MHD_SC_ITC_INITIALIZATION_FAILED; | 870 | return MHD_SC_ITC_INITIALIZATION_FAILED; |
864 | } | 871 | } |
865 | if ( (MHD_ELS_SELECT == daemon->event_loop_syscall) && | 872 | if ( (MHD_ELS_SELECT == daemon->event_loop_syscall) && |
866 | (! MHD_SCKT_FD_FITS_FDSET_(MHD_itc_r_fd_ (daemon->itc), | 873 | (! MHD_SCKT_FD_FITS_FDSET_ (MHD_itc_r_fd_ (daemon->itc), |
867 | NULL)) ) | 874 | NULL)) ) |
868 | { | 875 | { |
869 | #ifdef HAVE_MESSAGES | 876 | #ifdef HAVE_MESSAGES |
870 | MHD_DLOG (daemon, | 877 | MHD_DLOG (daemon, |
871 | MHD_SC_ITC_DESCRIPTOR_TOO_LARGE, | 878 | MHD_SC_ITC_DESCRIPTOR_TOO_LARGE, |
872 | _("File descriptor for inter-thread communication channel exceeds maximum value\n")); | 879 | _ ( |
880 | "File descriptor for inter-thread communication channel exceeds maximum value\n")); | ||
873 | #endif | 881 | #endif |
874 | return MHD_SC_ITC_DESCRIPTOR_TOO_LARGE; | 882 | return MHD_SC_ITC_DESCRIPTOR_TOO_LARGE; |
875 | } | ||
876 | } | 883 | } |
884 | } | ||
877 | 885 | ||
878 | if (MHD_SC_OK != (sc = open_listen_socket (daemon))) | 886 | if (MHD_SC_OK != (sc = open_listen_socket (daemon))) |
879 | return sc; | 887 | return sc; |
@@ -881,39 +889,39 @@ MHD_daemon_start (struct MHD_Daemon *daemon) | |||
881 | /* Check listen socket is in range (if we are limited) */ | 889 | /* Check listen socket is in range (if we are limited) */ |
882 | if ( (MHD_INVALID_SOCKET != daemon->listen_socket) && | 890 | if ( (MHD_INVALID_SOCKET != daemon->listen_socket) && |
883 | (MHD_ELS_SELECT == daemon->event_loop_syscall) && | 891 | (MHD_ELS_SELECT == daemon->event_loop_syscall) && |
884 | (! MHD_SCKT_FD_FITS_FDSET_(daemon->listen_socket, | 892 | (! MHD_SCKT_FD_FITS_FDSET_ (daemon->listen_socket, |
885 | NULL)) ) | 893 | NULL)) ) |
886 | { | 894 | { |
887 | #ifdef HAVE_MESSAGES | 895 | #ifdef HAVE_MESSAGES |
888 | MHD_DLOG (daemon, | 896 | MHD_DLOG (daemon, |
889 | MHD_SC_LISTEN_SOCKET_TOO_LARGE, | 897 | MHD_SC_LISTEN_SOCKET_TOO_LARGE, |
890 | _("Socket descriptor larger than FD_SETSIZE: %d > %d\n"), | 898 | _ ("Socket descriptor larger than FD_SETSIZE: %d > %d\n"), |
891 | daemon->listen_socket, | 899 | daemon->listen_socket, |
892 | FD_SETSIZE); | 900 | FD_SETSIZE); |
893 | #endif | 901 | #endif |
894 | return MHD_SC_LISTEN_SOCKET_TOO_LARGE; | 902 | return MHD_SC_LISTEN_SOCKET_TOO_LARGE; |
895 | } | 903 | } |
896 | 904 | ||
897 | /* set listen socket to non-blocking */ | 905 | /* set listen socket to non-blocking */ |
898 | if ( (MHD_INVALID_SOCKET != daemon->listen_socket) && | 906 | if ( (MHD_INVALID_SOCKET != daemon->listen_socket) && |
899 | (! MHD_socket_nonblocking_ (daemon->listen_socket)) ) | 907 | (! MHD_socket_nonblocking_ (daemon->listen_socket)) ) |
900 | { | 908 | { |
901 | #ifdef HAVE_MESSAGES | 909 | #ifdef HAVE_MESSAGES |
902 | MHD_DLOG (daemon, | 910 | MHD_DLOG (daemon, |
903 | MHD_SC_LISTEN_SOCKET_NONBLOCKING_FAILURE, | 911 | MHD_SC_LISTEN_SOCKET_NONBLOCKING_FAILURE, |
904 | _("Failed to set nonblocking mode on listening socket: %s\n"), | 912 | _ ("Failed to set nonblocking mode on listening socket: %s\n"), |
905 | MHD_socket_last_strerr_()); | 913 | MHD_socket_last_strerr_ ()); |
906 | #endif | 914 | #endif |
907 | if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) || | 915 | if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) || |
908 | (daemon->worker_pool_size > 0) ) | 916 | (daemon->worker_pool_size > 0) ) |
909 | { | 917 | { |
910 | /* Accept must be non-blocking. Multiple children may wake | 918 | /* Accept must be non-blocking. Multiple children may wake |
911 | * up to handle a new connection, but only one will win the | 919 | * up to handle a new connection, but only one will win the |
912 | * race. The others must immediately return. As this is | 920 | * race. The others must immediately return. As this is |
913 | * not possible, we must fail hard here. */ | 921 | * not possible, we must fail hard here. */ |
914 | return MHD_SC_LISTEN_SOCKET_NONBLOCKING_FAILURE; | 922 | return MHD_SC_LISTEN_SOCKET_NONBLOCKING_FAILURE; |
915 | } | ||
916 | } | 923 | } |
924 | } | ||
917 | 925 | ||
918 | #ifdef EPOLL_SUPPORT | 926 | #ifdef EPOLL_SUPPORT |
919 | /* Setup epoll */ | 927 | /* Setup epoll */ |
@@ -928,30 +936,31 @@ MHD_daemon_start (struct MHD_Daemon *daemon) | |||
928 | external event loop and do have a listen socket) */ | 936 | external event loop and do have a listen socket) */ |
929 | /* FIXME: why no worker thread if we have no listen socket? */ | 937 | /* FIXME: why no worker thread if we have no listen socket? */ |
930 | if ( ( (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode) || | 938 | if ( ( (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode) || |
931 | (1 == daemon->threading_mode) ) && | 939 | (1 == daemon->threading_mode) ) && |
932 | (MHD_INVALID_SOCKET != daemon->listen_socket) && | 940 | (MHD_INVALID_SOCKET != daemon->listen_socket) && |
933 | (! MHD_create_named_thread_ (&daemon->pid, | 941 | (! MHD_create_named_thread_ (&daemon->pid, |
934 | (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode) | 942 | (MHD_TM_THREAD_PER_CONNECTION == |
935 | ? "MHD-listen" | 943 | daemon->threading_mode) |
936 | : "MHD-single", | 944 | ? "MHD-listen" |
937 | daemon->thread_stack_limit_b, | 945 | : "MHD-single", |
938 | &MHD_polling_thread, | 946 | daemon->thread_stack_limit_b, |
939 | daemon) ) ) | 947 | &MHD_polling_thread, |
940 | { | 948 | daemon) ) ) |
949 | { | ||
941 | #ifdef HAVE_MESSAGES | 950 | #ifdef HAVE_MESSAGES |
942 | MHD_DLOG (daemon, | 951 | MHD_DLOG (daemon, |
943 | MHD_SC_THREAD_MAIN_LAUNCH_FAILURE, | 952 | MHD_SC_THREAD_MAIN_LAUNCH_FAILURE, |
944 | _("Failed to create listen thread: %s\n"), | 953 | _ ("Failed to create listen thread: %s\n"), |
945 | MHD_strerror_ (errno)); | 954 | MHD_strerror_ (errno)); |
946 | #endif | 955 | #endif |
947 | return MHD_SC_THREAD_MAIN_LAUNCH_FAILURE; | 956 | return MHD_SC_THREAD_MAIN_LAUNCH_FAILURE; |
948 | } | 957 | } |
949 | 958 | ||
950 | /* Setup worker threads */ | 959 | /* Setup worker threads */ |
951 | /* FIXME: why no thread pool if we have no listen socket? */ | 960 | /* FIXME: why no thread pool if we have no listen socket? */ |
952 | if ( (1 < daemon->threading_mode) && | 961 | if ( (1 < daemon->threading_mode) && |
953 | (MHD_INVALID_SOCKET != daemon->listen_socket) && | 962 | (MHD_INVALID_SOCKET != daemon->listen_socket) && |
954 | (MHD_SC_OK != (sc = setup_thread_pool (daemon))) ) | 963 | (MHD_SC_OK != (sc = setup_thread_pool (daemon))) ) |
955 | return sc; | 964 | return sc; |
956 | 965 | ||
957 | /* make sure we know our listen port (if any) */ | 966 | /* make sure we know our listen port (if any) */ |
diff --git a/src/lib/init.c b/src/lib/init.c index b23bdadf..5dcb02c4 100644 --- a/src/lib/init.c +++ b/src/lib/init.c | |||
@@ -36,7 +36,7 @@ volatile unsigned int global_init_count = 0; | |||
36 | /** | 36 | /** |
37 | * Global initialisation mutex | 37 | * Global initialisation mutex |
38 | */ | 38 | */ |
39 | MHD_MUTEX_STATIC_DEFN_INIT_(global_init_mutex_); | 39 | MHD_MUTEX_STATIC_DEFN_INIT_ (global_init_mutex_); |
40 | #endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */ | 40 | #endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */ |
41 | 41 | ||
42 | #endif | 42 | #endif |
@@ -59,21 +59,21 @@ static int mhd_winsock_inited_ = 0; | |||
59 | */ | 59 | */ |
60 | static void | 60 | static void |
61 | mhd_panic_std (void *cls, | 61 | mhd_panic_std (void *cls, |
62 | const char *file, | 62 | const char *file, |
63 | unsigned int line, | 63 | unsigned int line, |
64 | const char *reason) | 64 | const char *reason) |
65 | { | 65 | { |
66 | (void)cls; /* Mute compiler warning. */ | 66 | (void) cls; /* Mute compiler warning. */ |
67 | #ifdef HAVE_MESSAGES | 67 | #ifdef HAVE_MESSAGES |
68 | fprintf (stderr, | 68 | fprintf (stderr, |
69 | _("Fatal error in GNU libmicrohttpd %s:%u: %s\n"), | 69 | _ ("Fatal error in GNU libmicrohttpd %s:%u: %s\n"), |
70 | file, | 70 | file, |
71 | line, | 71 | line, |
72 | reason); | 72 | reason); |
73 | #else /* ! HAVE_MESSAGES */ | 73 | #else /* ! HAVE_MESSAGES */ |
74 | (void)file; /* Mute compiler warning. */ | 74 | (void) file; /* Mute compiler warning. */ |
75 | (void)line; /* Mute compiler warning. */ | 75 | (void) line; /* Mute compiler warning. */ |
76 | (void)reason; /* Mute compiler warning. */ | 76 | (void) reason; /* Mute compiler warning. */ |
77 | #endif | 77 | #endif |
78 | abort (); | 78 | abort (); |
79 | } | 79 | } |
@@ -93,13 +93,13 @@ MHD_init (void) | |||
93 | mhd_panic = &mhd_panic_std; | 93 | mhd_panic = &mhd_panic_std; |
94 | 94 | ||
95 | #if defined(_WIN32) && ! defined(__CYGWIN__) | 95 | #if defined(_WIN32) && ! defined(__CYGWIN__) |
96 | if (0 != WSAStartup (MAKEWORD(2, 2), | 96 | if (0 != WSAStartup (MAKEWORD (2, 2), |
97 | &wsd)) | 97 | &wsd)) |
98 | MHD_PANIC (_("Failed to initialize winsock\n")); | 98 | MHD_PANIC (_ ("Failed to initialize winsock\n")); |
99 | mhd_winsock_inited_ = 1; | 99 | mhd_winsock_inited_ = 1; |
100 | if ( (2 != LOBYTE(wsd.wVersion)) && | 100 | if ( (2 != LOBYTE (wsd.wVersion)) && |
101 | (2 != HIBYTE(wsd.wVersion)) ) | 101 | (2 != HIBYTE (wsd.wVersion)) ) |
102 | MHD_PANIC (_("Winsock version 2.2 is not available\n")); | 102 | MHD_PANIC (_ ("Winsock version 2.2 is not available\n")); |
103 | #endif | 103 | #endif |
104 | MHD_monotonic_sec_counter_init (); | 104 | MHD_monotonic_sec_counter_init (); |
105 | #ifdef HAVE_FREEBSD_SENDFILE | 105 | #ifdef HAVE_FREEBSD_SENDFILE |
@@ -116,14 +116,14 @@ MHD_fini (void) | |||
116 | { | 116 | { |
117 | #if defined(_WIN32) && ! defined(__CYGWIN__) | 117 | #if defined(_WIN32) && ! defined(__CYGWIN__) |
118 | if (mhd_winsock_inited_) | 118 | if (mhd_winsock_inited_) |
119 | WSACleanup(); | 119 | WSACleanup (); |
120 | #endif | 120 | #endif |
121 | MHD_monotonic_sec_counter_finish (); | 121 | MHD_monotonic_sec_counter_finish (); |
122 | } | 122 | } |
123 | 123 | ||
124 | #ifdef _AUTOINIT_FUNCS_ARE_SUPPORTED | 124 | #ifdef _AUTOINIT_FUNCS_ARE_SUPPORTED |
125 | 125 | ||
126 | _SET_INIT_AND_DEINIT_FUNCS(MHD_init, MHD_fini); | 126 | _SET_INIT_AND_DEINIT_FUNCS (MHD_init, MHD_fini); |
127 | 127 | ||
128 | #else | 128 | #else |
129 | 129 | ||
@@ -135,12 +135,12 @@ void | |||
135 | MHD_check_global_init_ (void) | 135 | MHD_check_global_init_ (void) |
136 | { | 136 | { |
137 | #ifdef MHD_MUTEX_STATIC_DEFN_INIT_ | 137 | #ifdef MHD_MUTEX_STATIC_DEFN_INIT_ |
138 | MHD_mutex_lock_chk_(&global_init_mutex_); | 138 | MHD_mutex_lock_chk_ (&global_init_mutex_); |
139 | #endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */ | 139 | #endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */ |
140 | if (0 == global_init_count++) | 140 | if (0 == global_init_count++) |
141 | MHD_init (); | 141 | MHD_init (); |
142 | #ifdef MHD_MUTEX_STATIC_DEFN_INIT_ | 142 | #ifdef MHD_MUTEX_STATIC_DEFN_INIT_ |
143 | MHD_mutex_unlock_chk_(&global_init_mutex_); | 143 | MHD_mutex_unlock_chk_ (&global_init_mutex_); |
144 | #endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */ | 144 | #endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */ |
145 | } | 145 | } |
146 | #endif | 146 | #endif |
diff --git a/src/lib/init.h b/src/lib/init.h index fae96159..2d9a9389 100644 --- a/src/lib/init.h +++ b/src/lib/init.h | |||
@@ -31,7 +31,7 @@ | |||
31 | * Do nothing - global initialisation is | 31 | * Do nothing - global initialisation is |
32 | * performed by library constructor. | 32 | * performed by library constructor. |
33 | */ | 33 | */ |
34 | #define MHD_check_global_init_() (void)0 | 34 | #define MHD_check_global_init_() (void) 0 |
35 | #else /* ! _AUTOINIT_FUNCS_ARE_SUPPORTED */ | 35 | #else /* ! _AUTOINIT_FUNCS_ARE_SUPPORTED */ |
36 | /** | 36 | /** |
37 | * Check whether global initialisation was performed | 37 | * Check whether global initialisation was performed |
diff --git a/src/lib/internal.c b/src/lib/internal.c index 75eae8a4..04d83624 100644 --- a/src/lib/internal.c +++ b/src/lib/internal.c | |||
@@ -35,50 +35,50 @@ const char * | |||
35 | MHD_state_to_string (enum MHD_CONNECTION_STATE state) | 35 | MHD_state_to_string (enum MHD_CONNECTION_STATE state) |
36 | { | 36 | { |
37 | switch (state) | 37 | switch (state) |
38 | { | 38 | { |
39 | case MHD_CONNECTION_INIT: | 39 | case MHD_CONNECTION_INIT: |
40 | return "connection init"; | 40 | return "connection init"; |
41 | case MHD_CONNECTION_URL_RECEIVED: | 41 | case MHD_CONNECTION_URL_RECEIVED: |
42 | return "connection url received"; | 42 | return "connection url received"; |
43 | case MHD_CONNECTION_HEADER_PART_RECEIVED: | 43 | case MHD_CONNECTION_HEADER_PART_RECEIVED: |
44 | return "header partially received"; | 44 | return "header partially received"; |
45 | case MHD_CONNECTION_HEADERS_RECEIVED: | 45 | case MHD_CONNECTION_HEADERS_RECEIVED: |
46 | return "headers received"; | 46 | return "headers received"; |
47 | case MHD_CONNECTION_HEADERS_PROCESSED: | 47 | case MHD_CONNECTION_HEADERS_PROCESSED: |
48 | return "headers processed"; | 48 | return "headers processed"; |
49 | case MHD_CONNECTION_CONTINUE_SENDING: | 49 | case MHD_CONNECTION_CONTINUE_SENDING: |
50 | return "continue sending"; | 50 | return "continue sending"; |
51 | case MHD_CONNECTION_CONTINUE_SENT: | 51 | case MHD_CONNECTION_CONTINUE_SENT: |
52 | return "continue sent"; | 52 | return "continue sent"; |
53 | case MHD_CONNECTION_BODY_RECEIVED: | 53 | case MHD_CONNECTION_BODY_RECEIVED: |
54 | return "body received"; | 54 | return "body received"; |
55 | case MHD_CONNECTION_FOOTER_PART_RECEIVED: | 55 | case MHD_CONNECTION_FOOTER_PART_RECEIVED: |
56 | return "footer partially received"; | 56 | return "footer partially received"; |
57 | case MHD_CONNECTION_FOOTERS_RECEIVED: | 57 | case MHD_CONNECTION_FOOTERS_RECEIVED: |
58 | return "footers received"; | 58 | return "footers received"; |
59 | case MHD_CONNECTION_HEADERS_SENDING: | 59 | case MHD_CONNECTION_HEADERS_SENDING: |
60 | return "headers sending"; | 60 | return "headers sending"; |
61 | case MHD_CONNECTION_HEADERS_SENT: | 61 | case MHD_CONNECTION_HEADERS_SENT: |
62 | return "headers sent"; | 62 | return "headers sent"; |
63 | case MHD_CONNECTION_NORMAL_BODY_READY: | 63 | case MHD_CONNECTION_NORMAL_BODY_READY: |
64 | return "normal body ready"; | 64 | return "normal body ready"; |
65 | case MHD_CONNECTION_NORMAL_BODY_UNREADY: | 65 | case MHD_CONNECTION_NORMAL_BODY_UNREADY: |
66 | return "normal body unready"; | 66 | return "normal body unready"; |
67 | case MHD_CONNECTION_CHUNKED_BODY_READY: | 67 | case MHD_CONNECTION_CHUNKED_BODY_READY: |
68 | return "chunked body ready"; | 68 | return "chunked body ready"; |
69 | case MHD_CONNECTION_CHUNKED_BODY_UNREADY: | 69 | case MHD_CONNECTION_CHUNKED_BODY_UNREADY: |
70 | return "chunked body unready"; | 70 | return "chunked body unready"; |
71 | case MHD_CONNECTION_BODY_SENT: | 71 | case MHD_CONNECTION_BODY_SENT: |
72 | return "body sent"; | 72 | return "body sent"; |
73 | case MHD_CONNECTION_FOOTERS_SENDING: | 73 | case MHD_CONNECTION_FOOTERS_SENDING: |
74 | return "footers sending"; | 74 | return "footers sending"; |
75 | case MHD_CONNECTION_FOOTERS_SENT: | 75 | case MHD_CONNECTION_FOOTERS_SENT: |
76 | return "footers sent"; | 76 | return "footers sent"; |
77 | case MHD_CONNECTION_CLOSED: | 77 | case MHD_CONNECTION_CLOSED: |
78 | return "closed"; | 78 | return "closed"; |
79 | default: | 79 | default: |
80 | return "unrecognized connection state"; | 80 | return "unrecognized connection state"; |
81 | } | 81 | } |
82 | } | 82 | } |
83 | #endif | 83 | #endif |
84 | #endif | 84 | #endif |
@@ -91,7 +91,7 @@ MHD_state_to_string (enum MHD_CONNECTION_STATE state) | |||
91 | */ | 91 | */ |
92 | void | 92 | void |
93 | MHD_DLOG (const struct MHD_Daemon *daemon, | 93 | MHD_DLOG (const struct MHD_Daemon *daemon, |
94 | enum MHD_StatusCode sc, | 94 | enum MHD_StatusCode sc, |
95 | const char *format, | 95 | const char *format, |
96 | ...) | 96 | ...) |
97 | { | 97 | { |
@@ -100,11 +100,11 @@ MHD_DLOG (const struct MHD_Daemon *daemon, | |||
100 | if (NULL == daemon->logger) | 100 | if (NULL == daemon->logger) |
101 | return; | 101 | return; |
102 | va_start (va, | 102 | va_start (va, |
103 | format); | 103 | format); |
104 | daemon->logger (daemon->logger_cls, | 104 | daemon->logger (daemon->logger_cls, |
105 | sc, | 105 | sc, |
106 | format, | 106 | format, |
107 | va); | 107 | va); |
108 | va_end (va); | 108 | va_end (va); |
109 | } | 109 | } |
110 | #endif | 110 | #endif |
@@ -120,7 +120,7 @@ MHD_unescape_plus (char *arg) | |||
120 | { | 120 | { |
121 | char *p; | 121 | char *p; |
122 | 122 | ||
123 | for (p=strchr (arg, '+'); NULL != p; p = strchr (p + 1, '+')) | 123 | for (p = strchr (arg, '+'); NULL != p; p = strchr (p + 1, '+')) |
124 | *p = ' '; | 124 | *p = ' '; |
125 | } | 125 | } |
126 | 126 | ||
@@ -141,28 +141,28 @@ MHD_http_unescape (char *val) | |||
141 | char *wpos = val; | 141 | char *wpos = val; |
142 | 142 | ||
143 | while ('\0' != *rpos) | 143 | while ('\0' != *rpos) |
144 | { | ||
145 | uint32_t num; | ||
146 | switch (*rpos) | ||
144 | { | 147 | { |
145 | uint32_t num; | 148 | case '%': |
146 | switch (*rpos) | 149 | if (2 == MHD_strx_to_uint32_n_ (rpos + 1, |
147 | { | 150 | 2, |
148 | case '%': | 151 | &num)) |
149 | if (2 == MHD_strx_to_uint32_n_ (rpos + 1, | 152 | { |
150 | 2, | 153 | *wpos = (char) ((unsigned char) num); |
151 | &num)) | 154 | wpos++; |
152 | { | 155 | rpos += 3; |
153 | *wpos = (char)((unsigned char) num); | 156 | break; |
154 | wpos++; | 157 | } |
155 | rpos += 3; | 158 | /* TODO: add bad sequence handling */ |
156 | break; | 159 | /* intentional fall through! */ |
157 | } | 160 | default: |
158 | /* TODO: add bad sequence handling */ | 161 | *wpos = *rpos; |
159 | /* intentional fall through! */ | 162 | wpos++; |
160 | default: | 163 | rpos++; |
161 | *wpos = *rpos; | ||
162 | wpos++; | ||
163 | rpos++; | ||
164 | } | ||
165 | } | 164 | } |
165 | } | ||
166 | *wpos = '\0'; /* add 0-terminator */ | 166 | *wpos = '\0'; /* add 0-terminator */ |
167 | return wpos - val; /* = strlen(val) */ | 167 | return wpos - val; /* = strlen(val) */ |
168 | } | 168 | } |
@@ -184,10 +184,10 @@ MHD_http_unescape (char *val) | |||
184 | */ | 184 | */ |
185 | bool | 185 | bool |
186 | MHD_parse_arguments_ (struct MHD_Request *request, | 186 | MHD_parse_arguments_ (struct MHD_Request *request, |
187 | enum MHD_ValueKind kind, | 187 | enum MHD_ValueKind kind, |
188 | char *args, | 188 | char *args, |
189 | MHD_ArgumentIterator_ cb, | 189 | MHD_ArgumentIterator_ cb, |
190 | unsigned int *num_headers) | 190 | unsigned int *num_headers) |
191 | { | 191 | { |
192 | struct MHD_Daemon *daemon = request->daemon; | 192 | struct MHD_Daemon *daemon = request->daemon; |
193 | char *equals; | 193 | char *equals; |
@@ -195,88 +195,88 @@ MHD_parse_arguments_ (struct MHD_Request *request, | |||
195 | 195 | ||
196 | *num_headers = 0; | 196 | *num_headers = 0; |
197 | while ( (NULL != args) && | 197 | while ( (NULL != args) && |
198 | ('\0' != args[0]) ) | 198 | ('\0' != args[0]) ) |
199 | { | ||
200 | equals = strchr (args, '='); | ||
201 | amper = strchr (args, '&'); | ||
202 | if (NULL == amper) | ||
199 | { | 203 | { |
200 | equals = strchr (args, '='); | 204 | /* last argument */ |
201 | amper = strchr (args, '&'); | 205 | if (NULL == equals) |
202 | if (NULL == amper) | 206 | { |
203 | { | 207 | /* last argument, without '=' */ |
204 | /* last argument */ | 208 | MHD_unescape_plus (args); |
205 | if (NULL == equals) | 209 | daemon->unescape_cb (daemon->unescape_cb_cls, |
206 | { | 210 | request, |
207 | /* last argument, without '=' */ | 211 | args); |
208 | MHD_unescape_plus (args); | 212 | if (! cb (request, |
209 | daemon->unescape_cb (daemon->unescape_cb_cls, | 213 | args, |
210 | request, | 214 | NULL, |
211 | args); | 215 | kind)) |
212 | if (! cb (request, | 216 | return false; |
213 | args, | 217 | (*num_headers)++; |
214 | NULL, | 218 | break; |
215 | kind)) | 219 | } |
216 | return false; | 220 | /* got 'foo=bar' */ |
217 | (*num_headers)++; | ||
218 | break; | ||
219 | } | ||
220 | /* got 'foo=bar' */ | ||
221 | equals[0] = '\0'; | ||
222 | equals++; | ||
223 | MHD_unescape_plus (args); | ||
224 | daemon->unescape_cb (daemon->unescape_cb_cls, | ||
225 | request, | ||
226 | args); | ||
227 | MHD_unescape_plus (equals); | ||
228 | daemon->unescape_cb (daemon->unescape_cb_cls, | ||
229 | request, | ||
230 | equals); | ||
231 | if (! cb (request, | ||
232 | args, | ||
233 | equals, | ||
234 | kind)) | ||
235 | return false; | ||
236 | (*num_headers)++; | ||
237 | break; | ||
238 | } | ||
239 | /* amper is non-NULL here */ | ||
240 | amper[0] = '\0'; | ||
241 | amper++; | ||
242 | if ( (NULL == equals) || | ||
243 | (equals >= amper) ) | ||
244 | { | ||
245 | /* got 'foo&bar' or 'foo&bar=val', add key 'foo' with NULL for value */ | ||
246 | MHD_unescape_plus (args); | ||
247 | daemon->unescape_cb (daemon->unescape_cb_cls, | ||
248 | request, | ||
249 | args); | ||
250 | if (! cb (request, | ||
251 | args, | ||
252 | NULL, | ||
253 | kind)) | ||
254 | return false; | ||
255 | /* continue with 'bar' */ | ||
256 | (*num_headers)++; | ||
257 | args = amper; | ||
258 | continue; | ||
259 | } | ||
260 | /* equals and amper are non-NULL here, and equals < amper, | ||
261 | so we got regular 'foo=value&bar...'-kind of argument */ | ||
262 | equals[0] = '\0'; | 221 | equals[0] = '\0'; |
263 | equals++; | 222 | equals++; |
264 | MHD_unescape_plus (args); | 223 | MHD_unescape_plus (args); |
265 | daemon->unescape_cb (daemon->unescape_cb_cls, | 224 | daemon->unescape_cb (daemon->unescape_cb_cls, |
266 | request, | 225 | request, |
267 | args); | 226 | args); |
268 | MHD_unescape_plus (equals); | 227 | MHD_unescape_plus (equals); |
269 | daemon->unescape_cb (daemon->unescape_cb_cls, | 228 | daemon->unescape_cb (daemon->unescape_cb_cls, |
270 | request, | 229 | request, |
271 | equals); | 230 | equals); |
231 | if (! cb (request, | ||
232 | args, | ||
233 | equals, | ||
234 | kind)) | ||
235 | return false; | ||
236 | (*num_headers)++; | ||
237 | break; | ||
238 | } | ||
239 | /* amper is non-NULL here */ | ||
240 | amper[0] = '\0'; | ||
241 | amper++; | ||
242 | if ( (NULL == equals) || | ||
243 | (equals >= amper) ) | ||
244 | { | ||
245 | /* got 'foo&bar' or 'foo&bar=val', add key 'foo' with NULL for value */ | ||
246 | MHD_unescape_plus (args); | ||
247 | daemon->unescape_cb (daemon->unescape_cb_cls, | ||
248 | request, | ||
249 | args); | ||
272 | if (! cb (request, | 250 | if (! cb (request, |
273 | args, | 251 | args, |
274 | equals, | 252 | NULL, |
275 | kind)) | 253 | kind)) |
276 | return false; | 254 | return false; |
255 | /* continue with 'bar' */ | ||
277 | (*num_headers)++; | 256 | (*num_headers)++; |
278 | args = amper; | 257 | args = amper; |
258 | continue; | ||
279 | } | 259 | } |
260 | /* equals and amper are non-NULL here, and equals < amper, | ||
261 | so we got regular 'foo=value&bar...'-kind of argument */ | ||
262 | equals[0] = '\0'; | ||
263 | equals++; | ||
264 | MHD_unescape_plus (args); | ||
265 | daemon->unescape_cb (daemon->unescape_cb_cls, | ||
266 | request, | ||
267 | args); | ||
268 | MHD_unescape_plus (equals); | ||
269 | daemon->unescape_cb (daemon->unescape_cb_cls, | ||
270 | request, | ||
271 | equals); | ||
272 | if (! cb (request, | ||
273 | args, | ||
274 | equals, | ||
275 | kind)) | ||
276 | return false; | ||
277 | (*num_headers)++; | ||
278 | args = amper; | ||
279 | } | ||
280 | return true; | 280 | return true; |
281 | } | 281 | } |
282 | 282 | ||
diff --git a/src/lib/internal.h b/src/lib/internal.h index bd3bd1c6..b5ec3039 100644 --- a/src/lib/internal.h +++ b/src/lib/internal.h | |||
@@ -58,14 +58,16 @@ | |||
58 | * | 58 | * |
59 | * @param msg error message (const char *) | 59 | * @param msg error message (const char *) |
60 | */ | 60 | */ |
61 | #define MHD_PANIC(msg) do { mhd_panic (mhd_panic_cls, __FILE__, __LINE__, msg); BUILTIN_NOT_REACHED; } while (0) | 61 | #define MHD_PANIC(msg) do { mhd_panic (mhd_panic_cls, __FILE__, __LINE__, msg); \ |
62 | BUILTIN_NOT_REACHED; } while (0) | ||
62 | #else | 63 | #else |
63 | /** | 64 | /** |
64 | * Trigger 'panic' action based on fatal errors. | 65 | * Trigger 'panic' action based on fatal errors. |
65 | * | 66 | * |
66 | * @param msg error message (const char *) | 67 | * @param msg error message (const char *) |
67 | */ | 68 | */ |
68 | #define MHD_PANIC(msg) do { mhd_panic (mhd_panic_cls, __FILE__, __LINE__, NULL); BUILTIN_NOT_REACHED; } while (0) | 69 | #define MHD_PANIC(msg) do { mhd_panic (mhd_panic_cls, __FILE__, __LINE__, NULL); \ |
70 | BUILTIN_NOT_REACHED; } while (0) | ||
69 | #endif | 71 | #endif |
70 | 72 | ||
71 | #include "mhd_threads.h" | 73 | #include "mhd_threads.h" |
@@ -82,8 +84,8 @@ | |||
82 | */ | 84 | */ |
83 | void | 85 | void |
84 | MHD_DLOG (const struct MHD_Daemon *daemon, | 86 | MHD_DLOG (const struct MHD_Daemon *daemon, |
85 | enum MHD_StatusCode sc, | 87 | enum MHD_StatusCode sc, |
86 | const char *format, | 88 | const char *format, |
87 | ...); | 89 | ...); |
88 | #endif | 90 | #endif |
89 | 91 | ||
@@ -93,9 +95,9 @@ MHD_DLOG (const struct MHD_Daemon *daemon, | |||
93 | * @param fd the FD to close | 95 | * @param fd the FD to close |
94 | */ | 96 | */ |
95 | #define MHD_fd_close_chk_(fd) do { \ | 97 | #define MHD_fd_close_chk_(fd) do { \ |
96 | if ( (0 != close ((fd)) && (EBADF == errno)) ) \ | 98 | if ( (0 != close ((fd)) && (EBADF == errno)) ) \ |
97 | MHD_PANIC(_("Failed to close FD.\n")); \ | 99 | MHD_PANIC (_ ("Failed to close FD.\n")); \ |
98 | } while(0) | 100 | } while (0) |
99 | 101 | ||
100 | /** | 102 | /** |
101 | * Should we perform additional sanity checks at runtime (on our internal | 103 | * Should we perform additional sanity checks at runtime (on our internal |
@@ -128,10 +130,11 @@ extern MHD_PanicCallback mhd_panic; | |||
128 | extern void *mhd_panic_cls; | 130 | extern void *mhd_panic_cls; |
129 | 131 | ||
130 | /* If we have Clang or gcc >= 4.5, use __buildin_unreachable() */ | 132 | /* If we have Clang or gcc >= 4.5, use __buildin_unreachable() */ |
131 | #if defined(__clang__) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) | 133 | #if defined(__clang__) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= \ |
132 | #define BUILTIN_NOT_REACHED __builtin_unreachable() | 134 | 5) |
135 | #define BUILTIN_NOT_REACHED __builtin_unreachable () | ||
133 | #elif defined(_MSC_FULL_VER) | 136 | #elif defined(_MSC_FULL_VER) |
134 | #define BUILTIN_NOT_REACHED __assume(0) | 137 | #define BUILTIN_NOT_REACHED __assume (0) |
135 | #else | 138 | #else |
136 | #define BUILTIN_NOT_REACHED | 139 | #define BUILTIN_NOT_REACHED |
137 | #endif | 140 | #endif |
@@ -140,7 +143,7 @@ extern void *mhd_panic_cls; | |||
140 | /** | 143 | /** |
141 | * Determine length of static string / macro strings at compile time. | 144 | * Determine length of static string / macro strings at compile time. |
142 | */ | 145 | */ |
143 | #define MHD_STATICSTR_LEN_(macro) (sizeof(macro)/sizeof(char) - 1) | 146 | #define MHD_STATICSTR_LEN_(macro) (sizeof(macro) / sizeof(char) - 1) |
144 | #endif /* ! MHD_STATICSTR_LEN_ */ | 147 | #endif /* ! MHD_STATICSTR_LEN_ */ |
145 | 148 | ||
146 | 149 | ||
@@ -1534,8 +1537,8 @@ struct MHD_Daemon | |||
1534 | * @return #MHD_SC_OK on success, otherwise an error code | 1537 | * @return #MHD_SC_OK on success, otherwise an error code |
1535 | */ | 1538 | */ |
1536 | typedef enum MHD_StatusCode | 1539 | typedef enum MHD_StatusCode |
1537 | (*ActionCallback) (void *cls, | 1540 | (*ActionCallback)(void *cls, |
1538 | struct MHD_Request *request); | 1541 | struct MHD_Request *request); |
1539 | 1542 | ||
1540 | 1543 | ||
1541 | /** | 1544 | /** |
@@ -1703,9 +1706,9 @@ struct MHD_Response | |||
1703 | */ | 1706 | */ |
1704 | typedef bool | 1707 | typedef bool |
1705 | (*MHD_ArgumentIterator_)(struct MHD_Request *request, | 1708 | (*MHD_ArgumentIterator_)(struct MHD_Request *request, |
1706 | const char *key, | 1709 | const char *key, |
1707 | const char *value, | 1710 | const char *value, |
1708 | enum MHD_ValueKind kind); | 1711 | enum MHD_ValueKind kind); |
1709 | 1712 | ||
1710 | 1713 | ||
1711 | /** | 1714 | /** |
@@ -1724,10 +1727,10 @@ typedef bool | |||
1724 | */ | 1727 | */ |
1725 | bool | 1728 | bool |
1726 | MHD_parse_arguments_ (struct MHD_Request *request, | 1729 | MHD_parse_arguments_ (struct MHD_Request *request, |
1727 | enum MHD_ValueKind kind, | 1730 | enum MHD_ValueKind kind, |
1728 | char *args, | 1731 | char *args, |
1729 | MHD_ArgumentIterator_ cb, | 1732 | MHD_ArgumentIterator_ cb, |
1730 | unsigned int *num_headers); | 1733 | unsigned int *num_headers); |
1731 | 1734 | ||
1732 | 1735 | ||
1733 | 1736 | ||
@@ -1740,15 +1743,15 @@ MHD_parse_arguments_ (struct MHD_Request *request, | |||
1740 | * @param element element to insert | 1743 | * @param element element to insert |
1741 | */ | 1744 | */ |
1742 | #define DLL_insert(head,tail,element) do { \ | 1745 | #define DLL_insert(head,tail,element) do { \ |
1743 | mhd_assert (NULL == (element)->next); \ | 1746 | mhd_assert (NULL == (element)->next); \ |
1744 | mhd_assert (NULL == (element)->prev); \ | 1747 | mhd_assert (NULL == (element)->prev); \ |
1745 | (element)->next = (head); \ | 1748 | (element)->next = (head); \ |
1746 | (element)->prev = NULL; \ | 1749 | (element)->prev = NULL; \ |
1747 | if ((tail) == NULL) \ | 1750 | if ((tail) == NULL) \ |
1748 | (tail) = element; \ | 1751 | (tail) = element; \ |
1749 | else \ | 1752 | else \ |
1750 | (head)->prev = element; \ | 1753 | (head)->prev = element; \ |
1751 | (head) = (element); } while (0) | 1754 | (head) = (element); } while (0) |
1752 | 1755 | ||
1753 | 1756 | ||
1754 | /** | 1757 | /** |
@@ -1760,18 +1763,18 @@ MHD_parse_arguments_ (struct MHD_Request *request, | |||
1760 | * @param element element to remove | 1763 | * @param element element to remove |
1761 | */ | 1764 | */ |
1762 | #define DLL_remove(head,tail,element) do { \ | 1765 | #define DLL_remove(head,tail,element) do { \ |
1763 | mhd_assert ( (NULL != (element)->next) || ((element) == (tail))); \ | 1766 | mhd_assert ( (NULL != (element)->next) || ((element) == (tail))); \ |
1764 | mhd_assert ( (NULL != (element)->prev) || ((element) == (head))); \ | 1767 | mhd_assert ( (NULL != (element)->prev) || ((element) == (head))); \ |
1765 | if ((element)->prev == NULL) \ | 1768 | if ((element)->prev == NULL) \ |
1766 | (head) = (element)->next; \ | 1769 | (head) = (element)->next; \ |
1767 | else \ | 1770 | else \ |
1768 | (element)->prev->next = (element)->next; \ | 1771 | (element)->prev->next = (element)->next; \ |
1769 | if ((element)->next == NULL) \ | 1772 | if ((element)->next == NULL) \ |
1770 | (tail) = (element)->prev; \ | 1773 | (tail) = (element)->prev; \ |
1771 | else \ | 1774 | else \ |
1772 | (element)->next->prev = (element)->prev; \ | 1775 | (element)->next->prev = (element)->prev; \ |
1773 | (element)->next = NULL; \ | 1776 | (element)->next = NULL; \ |
1774 | (element)->prev = NULL; } while (0) | 1777 | (element)->prev = NULL; } while (0) |
1775 | 1778 | ||
1776 | 1779 | ||
1777 | 1780 | ||
@@ -1784,15 +1787,15 @@ MHD_parse_arguments_ (struct MHD_Request *request, | |||
1784 | * @param element element to insert | 1787 | * @param element element to insert |
1785 | */ | 1788 | */ |
1786 | #define XDLL_insert(head,tail,element) do { \ | 1789 | #define XDLL_insert(head,tail,element) do { \ |
1787 | mhd_assert (NULL == (element)->nextX); \ | 1790 | mhd_assert (NULL == (element)->nextX); \ |
1788 | mhd_assert (NULL == (element)->prevX); \ | 1791 | mhd_assert (NULL == (element)->prevX); \ |
1789 | (element)->nextX = (head); \ | 1792 | (element)->nextX = (head); \ |
1790 | (element)->prevX = NULL; \ | 1793 | (element)->prevX = NULL; \ |
1791 | if (NULL == (tail)) \ | 1794 | if (NULL == (tail)) \ |
1792 | (tail) = element; \ | 1795 | (tail) = element; \ |
1793 | else \ | 1796 | else \ |
1794 | (head)->prevX = element; \ | 1797 | (head)->prevX = element; \ |
1795 | (head) = (element); } while (0) | 1798 | (head) = (element); } while (0) |
1796 | 1799 | ||
1797 | 1800 | ||
1798 | /** | 1801 | /** |
@@ -1804,18 +1807,18 @@ MHD_parse_arguments_ (struct MHD_Request *request, | |||
1804 | * @param element element to remove | 1807 | * @param element element to remove |
1805 | */ | 1808 | */ |
1806 | #define XDLL_remove(head,tail,element) do { \ | 1809 | #define XDLL_remove(head,tail,element) do { \ |
1807 | mhd_assert ( (NULL != (element)->nextX) || ((element) == (tail))); \ | 1810 | mhd_assert ( (NULL != (element)->nextX) || ((element) == (tail))); \ |
1808 | mhd_assert ( (NULL != (element)->prevX) || ((element) == (head))); \ | 1811 | mhd_assert ( (NULL != (element)->prevX) || ((element) == (head))); \ |
1809 | if (NULL == (element)->prevX) \ | 1812 | if (NULL == (element)->prevX) \ |
1810 | (head) = (element)->nextX; \ | 1813 | (head) = (element)->nextX; \ |
1811 | else \ | 1814 | else \ |
1812 | (element)->prevX->nextX = (element)->nextX; \ | 1815 | (element)->prevX->nextX = (element)->nextX; \ |
1813 | if (NULL == (element)->nextX) \ | 1816 | if (NULL == (element)->nextX) \ |
1814 | (tail) = (element)->prevX; \ | 1817 | (tail) = (element)->prevX; \ |
1815 | else \ | 1818 | else \ |
1816 | (element)->nextX->prevX = (element)->prevX; \ | 1819 | (element)->nextX->prevX = (element)->prevX; \ |
1817 | (element)->nextX = NULL; \ | 1820 | (element)->nextX = NULL; \ |
1818 | (element)->prevX = NULL; } while (0) | 1821 | (element)->prevX = NULL; } while (0) |
1819 | 1822 | ||
1820 | 1823 | ||
1821 | /** | 1824 | /** |
@@ -1827,13 +1830,13 @@ MHD_parse_arguments_ (struct MHD_Request *request, | |||
1827 | * @param element element to insert | 1830 | * @param element element to insert |
1828 | */ | 1831 | */ |
1829 | #define EDLL_insert(head,tail,element) do { \ | 1832 | #define EDLL_insert(head,tail,element) do { \ |
1830 | (element)->nextE = (head); \ | 1833 | (element)->nextE = (head); \ |
1831 | (element)->prevE = NULL; \ | 1834 | (element)->prevE = NULL; \ |
1832 | if ((tail) == NULL) \ | 1835 | if ((tail) == NULL) \ |
1833 | (tail) = element; \ | 1836 | (tail) = element; \ |
1834 | else \ | 1837 | else \ |
1835 | (head)->prevE = element; \ | 1838 | (head)->prevE = element; \ |
1836 | (head) = (element); } while (0) | 1839 | (head) = (element); } while (0) |
1837 | 1840 | ||
1838 | 1841 | ||
1839 | /** | 1842 | /** |
@@ -1845,16 +1848,16 @@ MHD_parse_arguments_ (struct MHD_Request *request, | |||
1845 | * @param element element to remove | 1848 | * @param element element to remove |
1846 | */ | 1849 | */ |
1847 | #define EDLL_remove(head,tail,element) do { \ | 1850 | #define EDLL_remove(head,tail,element) do { \ |
1848 | if ((element)->prevE == NULL) \ | 1851 | if ((element)->prevE == NULL) \ |
1849 | (head) = (element)->nextE; \ | 1852 | (head) = (element)->nextE; \ |
1850 | else \ | 1853 | else \ |
1851 | (element)->prevE->nextE = (element)->nextE; \ | 1854 | (element)->prevE->nextE = (element)->nextE; \ |
1852 | if ((element)->nextE == NULL) \ | 1855 | if ((element)->nextE == NULL) \ |
1853 | (tail) = (element)->prevE; \ | 1856 | (tail) = (element)->prevE; \ |
1854 | else \ | 1857 | else \ |
1855 | (element)->nextE->prevE = (element)->prevE; \ | 1858 | (element)->nextE->prevE = (element)->prevE; \ |
1856 | (element)->nextE = NULL; \ | 1859 | (element)->nextE = NULL; \ |
1857 | (element)->prevE = NULL; } while (0) | 1860 | (element)->prevE = NULL; } while (0) |
1858 | 1861 | ||
1859 | 1862 | ||
1860 | 1863 | ||
diff --git a/src/lib/md5.c b/src/lib/md5.c index a7eb35fe..3d0f7493 100644 --- a/src/lib/md5.c +++ b/src/lib/md5.c | |||
@@ -20,21 +20,21 @@ | |||
20 | #include "md5.h" | 20 | #include "md5.h" |
21 | #include "mhd_byteorder.h" | 21 | #include "mhd_byteorder.h" |
22 | 22 | ||
23 | #define PUT_64BIT_LE(cp, value) do { \ | 23 | #define PUT_64BIT_LE(cp, value) do { \ |
24 | (cp)[7] = (uint8_t)((value) >> 56); \ | 24 | (cp)[7] = (uint8_t) ((value) >> 56); \ |
25 | (cp)[6] = (uint8_t)((value) >> 48); \ | 25 | (cp)[6] = (uint8_t) ((value) >> 48); \ |
26 | (cp)[5] = (uint8_t)((value) >> 40); \ | 26 | (cp)[5] = (uint8_t) ((value) >> 40); \ |
27 | (cp)[4] = (uint8_t)((value) >> 32); \ | 27 | (cp)[4] = (uint8_t) ((value) >> 32); \ |
28 | (cp)[3] = (uint8_t)((value) >> 24); \ | 28 | (cp)[3] = (uint8_t) ((value) >> 24); \ |
29 | (cp)[2] = (uint8_t)((value) >> 16); \ | 29 | (cp)[2] = (uint8_t) ((value) >> 16); \ |
30 | (cp)[1] = (uint8_t)((value) >> 8); \ | 30 | (cp)[1] = (uint8_t) ((value) >> 8); \ |
31 | (cp)[0] = (uint8_t)((value)); } while (0) | 31 | (cp)[0] = (uint8_t) ((value)); } while (0) |
32 | 32 | ||
33 | #define PUT_32BIT_LE(cp, value) do { \ | 33 | #define PUT_32BIT_LE(cp, value) do { \ |
34 | (cp)[3] = (uint8_t)((value) >> 24); \ | 34 | (cp)[3] = (uint8_t) ((value) >> 24); \ |
35 | (cp)[2] = (uint8_t)((value) >> 16); \ | 35 | (cp)[2] = (uint8_t) ((value) >> 16); \ |
36 | (cp)[1] = (uint8_t)((value) >> 8); \ | 36 | (cp)[1] = (uint8_t) ((value) >> 8); \ |
37 | (cp)[0] = (uint8_t)((value)); } while (0) | 37 | (cp)[0] = (uint8_t) ((value)); } while (0) |
38 | 38 | ||
39 | static uint8_t PADDING[MD5_BLOCK_SIZE] = { | 39 | static uint8_t PADDING[MD5_BLOCK_SIZE] = { |
40 | 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 40 | 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
@@ -47,9 +47,9 @@ static uint8_t PADDING[MD5_BLOCK_SIZE] = { | |||
47 | * initialization constants. | 47 | * initialization constants. |
48 | */ | 48 | */ |
49 | void | 49 | void |
50 | MHD_MD5Init(struct MD5Context *ctx) | 50 | MHD_MD5Init (struct MD5Context *ctx) |
51 | { | 51 | { |
52 | if (!ctx) | 52 | if (! ctx) |
53 | return; | 53 | return; |
54 | 54 | ||
55 | ctx->count = 0; | 55 | ctx->count = 0; |
@@ -64,26 +64,26 @@ MHD_MD5Init(struct MD5Context *ctx) | |||
64 | * of bytes. | 64 | * of bytes. |
65 | */ | 65 | */ |
66 | void | 66 | void |
67 | MHD_MD5Update(struct MD5Context *ctx, const unsigned char *input, size_t len) | 67 | MHD_MD5Update (struct MD5Context *ctx, const unsigned char *input, size_t len) |
68 | { | 68 | { |
69 | size_t have, need; | 69 | size_t have, need; |
70 | 70 | ||
71 | if (!ctx || !input) | 71 | if (! ctx || ! input) |
72 | return; | 72 | return; |
73 | 73 | ||
74 | /* Check how many bytes we already have and how many more we need. */ | 74 | /* Check how many bytes we already have and how many more we need. */ |
75 | have = (size_t)((ctx->count >> 3) & (MD5_BLOCK_SIZE - 1)); | 75 | have = (size_t) ((ctx->count >> 3) & (MD5_BLOCK_SIZE - 1)); |
76 | need = MD5_BLOCK_SIZE - have; | 76 | need = MD5_BLOCK_SIZE - have; |
77 | 77 | ||
78 | /* Update bitcount */ | 78 | /* Update bitcount */ |
79 | ctx->count += (uint64_t)len << 3; | 79 | ctx->count += (uint64_t) len << 3; |
80 | 80 | ||
81 | if (len >= need) | 81 | if (len >= need) |
82 | { | 82 | { |
83 | if (have != 0) | 83 | if (have != 0) |
84 | { | 84 | { |
85 | memcpy(ctx->buffer + have, input, need); | 85 | memcpy (ctx->buffer + have, input, need); |
86 | MD5Transform(ctx->state, ctx->buffer); | 86 | MD5Transform (ctx->state, ctx->buffer); |
87 | input += need; | 87 | input += need; |
88 | len -= need; | 88 | len -= need; |
89 | have = 0; | 89 | have = 0; |
@@ -92,7 +92,7 @@ MHD_MD5Update(struct MD5Context *ctx, const unsigned char *input, size_t len) | |||
92 | /* Process data in MD5_BLOCK_SIZE-byte chunks. */ | 92 | /* Process data in MD5_BLOCK_SIZE-byte chunks. */ |
93 | while (len >= MD5_BLOCK_SIZE) | 93 | while (len >= MD5_BLOCK_SIZE) |
94 | { | 94 | { |
95 | MD5Transform(ctx->state, input); | 95 | MD5Transform (ctx->state, input); |
96 | input += MD5_BLOCK_SIZE; | 96 | input += MD5_BLOCK_SIZE; |
97 | len -= MD5_BLOCK_SIZE; | 97 | len -= MD5_BLOCK_SIZE; |
98 | } | 98 | } |
@@ -100,7 +100,7 @@ MHD_MD5Update(struct MD5Context *ctx, const unsigned char *input, size_t len) | |||
100 | 100 | ||
101 | /* Handle any remaining bytes of data. */ | 101 | /* Handle any remaining bytes of data. */ |
102 | if (len != 0) | 102 | if (len != 0) |
103 | memcpy(ctx->buffer + have, input, len); | 103 | memcpy (ctx->buffer + have, input, len); |
104 | } | 104 | } |
105 | 105 | ||
106 | /* | 106 | /* |
@@ -108,42 +108,42 @@ MHD_MD5Update(struct MD5Context *ctx, const unsigned char *input, size_t len) | |||
108 | * 1 0* (64-bit count of bits processed, MSB-first) | 108 | * 1 0* (64-bit count of bits processed, MSB-first) |
109 | */ | 109 | */ |
110 | void | 110 | void |
111 | MD5Pad(struct MD5Context *ctx) | 111 | MD5Pad (struct MD5Context *ctx) |
112 | { | 112 | { |
113 | uint8_t count[8]; | 113 | uint8_t count[8]; |
114 | size_t padlen; | 114 | size_t padlen; |
115 | 115 | ||
116 | if (!ctx) | 116 | if (! ctx) |
117 | return; | 117 | return; |
118 | 118 | ||
119 | /* Convert count to 8 bytes in little endian order. */ | 119 | /* Convert count to 8 bytes in little endian order. */ |
120 | PUT_64BIT_LE(count, ctx->count); | 120 | PUT_64BIT_LE (count, ctx->count); |
121 | 121 | ||
122 | /* Pad out to 56 mod 64. */ | 122 | /* Pad out to 56 mod 64. */ |
123 | padlen = MD5_BLOCK_SIZE - | 123 | padlen = MD5_BLOCK_SIZE |
124 | ((ctx->count >> 3) & (MD5_BLOCK_SIZE - 1)); | 124 | - ((ctx->count >> 3) & (MD5_BLOCK_SIZE - 1)); |
125 | if (padlen < 1 + 8) | 125 | if (padlen < 1 + 8) |
126 | padlen += MD5_BLOCK_SIZE; | 126 | padlen += MD5_BLOCK_SIZE; |
127 | MHD_MD5Update(ctx, PADDING, padlen - 8); /* padlen - 8 <= 64 */ | 127 | MHD_MD5Update (ctx, PADDING, padlen - 8); /* padlen - 8 <= 64 */ |
128 | MHD_MD5Update(ctx, count, 8); | 128 | MHD_MD5Update (ctx, count, 8); |
129 | } | 129 | } |
130 | 130 | ||
131 | /* | 131 | /* |
132 | * Final wrapup--call MD5Pad, fill in digest and zero out ctx. | 132 | * Final wrapup--call MD5Pad, fill in digest and zero out ctx. |
133 | */ | 133 | */ |
134 | void | 134 | void |
135 | MHD_MD5Final(unsigned char digest[MD5_DIGEST_SIZE], struct MD5Context *ctx) | 135 | MHD_MD5Final (unsigned char digest[MD5_DIGEST_SIZE], struct MD5Context *ctx) |
136 | { | 136 | { |
137 | int i; | 137 | int i; |
138 | 138 | ||
139 | if (!ctx || !digest) | 139 | if (! ctx || ! digest) |
140 | return; | 140 | return; |
141 | 141 | ||
142 | MD5Pad(ctx); | 142 | MD5Pad (ctx); |
143 | for (i = 0; i < 4; i++) | 143 | for (i = 0; i < 4; i++) |
144 | PUT_32BIT_LE(digest + i * 4, ctx->state[i]); | 144 | PUT_32BIT_LE (digest + i * 4, ctx->state[i]); |
145 | 145 | ||
146 | memset(ctx, 0, sizeof(*ctx)); | 146 | memset (ctx, 0, sizeof(*ctx)); |
147 | } | 147 | } |
148 | 148 | ||
149 | 149 | ||
@@ -151,13 +151,13 @@ MHD_MD5Final(unsigned char digest[MD5_DIGEST_SIZE], struct MD5Context *ctx) | |||
151 | 151 | ||
152 | /* #define F1(x, y, z) (x & y | ~x & z) */ | 152 | /* #define F1(x, y, z) (x & y | ~x & z) */ |
153 | #define F1(x, y, z) (z ^ (x & (y ^ z))) | 153 | #define F1(x, y, z) (z ^ (x & (y ^ z))) |
154 | #define F2(x, y, z) F1(z, x, y) | 154 | #define F2(x, y, z) F1 (z, x, y) |
155 | #define F3(x, y, z) (x ^ y ^ z) | 155 | #define F3(x, y, z) (x ^ y ^ z) |
156 | #define F4(x, y, z) (y ^ (x | ~z)) | 156 | #define F4(x, y, z) (y ^ (x | ~z)) |
157 | 157 | ||
158 | /* This is the central step in the MD5 algorithm. */ | 158 | /* This is the central step in the MD5 algorithm. */ |
159 | #define MD5STEP(f, w, x, y, z, data, s) \ | 159 | #define MD5STEP(f, w, x, y, z, data, s) \ |
160 | ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x ) | 160 | (w += f (x, y, z) + data, w = w << s | w >> (32 - s), w += x) |
161 | 161 | ||
162 | /* | 162 | /* |
163 | * The core of the MD5 algorithm, this alters an existing MD5 hash to | 163 | * The core of the MD5 algorithm, this alters an existing MD5 hash to |
@@ -165,20 +165,20 @@ MHD_MD5Final(unsigned char digest[MD5_DIGEST_SIZE], struct MD5Context *ctx) | |||
165 | * the data and converts bytes into longwords for this routine. | 165 | * the data and converts bytes into longwords for this routine. |
166 | */ | 166 | */ |
167 | void | 167 | void |
168 | MD5Transform(uint32_t state[4], const uint8_t block[MD5_BLOCK_SIZE]) | 168 | MD5Transform (uint32_t state[4], const uint8_t block[MD5_BLOCK_SIZE]) |
169 | { | 169 | { |
170 | uint32_t a, b, c, d, in[MD5_BLOCK_SIZE / 4]; | 170 | uint32_t a, b, c, d, in[MD5_BLOCK_SIZE / 4]; |
171 | 171 | ||
172 | #if _MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN | 172 | #if _MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN |
173 | memcpy(in, block, sizeof(in)); | 173 | memcpy (in, block, sizeof(in)); |
174 | #else | 174 | #else |
175 | for (a = 0; a < MD5_BLOCK_SIZE / 4; a++) | 175 | for (a = 0; a < MD5_BLOCK_SIZE / 4; a++) |
176 | { | 176 | { |
177 | in[a] = (uint32_t)( | 177 | in[a] = (uint32_t) ( |
178 | (uint32_t)(block[a * 4 + 0]) | | 178 | (uint32_t) (block[a * 4 + 0]) |
179 | (uint32_t)(block[a * 4 + 1]) << 8 | | 179 | | (uint32_t) (block[a * 4 + 1]) << 8 |
180 | (uint32_t)(block[a * 4 + 2]) << 16 | | 180 | | (uint32_t) (block[a * 4 + 2]) << 16 |
181 | (uint32_t)(block[a * 4 + 3]) << 24); | 181 | | (uint32_t) (block[a * 4 + 3]) << 24); |
182 | } | 182 | } |
183 | #endif | 183 | #endif |
184 | 184 | ||
@@ -187,73 +187,73 @@ MD5Transform(uint32_t state[4], const uint8_t block[MD5_BLOCK_SIZE]) | |||
187 | c = state[2]; | 187 | c = state[2]; |
188 | d = state[3]; | 188 | d = state[3]; |
189 | 189 | ||
190 | MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); | 190 | MD5STEP (F1, a, b, c, d, in[0] + 0xd76aa478, 7); |
191 | MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); | 191 | MD5STEP (F1, d, a, b, c, in[1] + 0xe8c7b756, 12); |
192 | MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); | 192 | MD5STEP (F1, c, d, a, b, in[2] + 0x242070db, 17); |
193 | MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); | 193 | MD5STEP (F1, b, c, d, a, in[3] + 0xc1bdceee, 22); |
194 | MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); | 194 | MD5STEP (F1, a, b, c, d, in[4] + 0xf57c0faf, 7); |
195 | MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); | 195 | MD5STEP (F1, d, a, b, c, in[5] + 0x4787c62a, 12); |
196 | MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); | 196 | MD5STEP (F1, c, d, a, b, in[6] + 0xa8304613, 17); |
197 | MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); | 197 | MD5STEP (F1, b, c, d, a, in[7] + 0xfd469501, 22); |
198 | MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); | 198 | MD5STEP (F1, a, b, c, d, in[8] + 0x698098d8, 7); |
199 | MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); | 199 | MD5STEP (F1, d, a, b, c, in[9] + 0x8b44f7af, 12); |
200 | MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); | 200 | MD5STEP (F1, c, d, a, b, in[10] + 0xffff5bb1, 17); |
201 | MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); | 201 | MD5STEP (F1, b, c, d, a, in[11] + 0x895cd7be, 22); |
202 | MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); | 202 | MD5STEP (F1, a, b, c, d, in[12] + 0x6b901122, 7); |
203 | MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); | 203 | MD5STEP (F1, d, a, b, c, in[13] + 0xfd987193, 12); |
204 | MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); | 204 | MD5STEP (F1, c, d, a, b, in[14] + 0xa679438e, 17); |
205 | MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); | 205 | MD5STEP (F1, b, c, d, a, in[15] + 0x49b40821, 22); |
206 | 206 | ||
207 | MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); | 207 | MD5STEP (F2, a, b, c, d, in[1] + 0xf61e2562, 5); |
208 | MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); | 208 | MD5STEP (F2, d, a, b, c, in[6] + 0xc040b340, 9); |
209 | MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); | 209 | MD5STEP (F2, c, d, a, b, in[11] + 0x265e5a51, 14); |
210 | MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); | 210 | MD5STEP (F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); |
211 | MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); | 211 | MD5STEP (F2, a, b, c, d, in[5] + 0xd62f105d, 5); |
212 | MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); | 212 | MD5STEP (F2, d, a, b, c, in[10] + 0x02441453, 9); |
213 | MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); | 213 | MD5STEP (F2, c, d, a, b, in[15] + 0xd8a1e681, 14); |
214 | MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); | 214 | MD5STEP (F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); |
215 | MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); | 215 | MD5STEP (F2, a, b, c, d, in[9] + 0x21e1cde6, 5); |
216 | MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); | 216 | MD5STEP (F2, d, a, b, c, in[14] + 0xc33707d6, 9); |
217 | MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); | 217 | MD5STEP (F2, c, d, a, b, in[3] + 0xf4d50d87, 14); |
218 | MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); | 218 | MD5STEP (F2, b, c, d, a, in[8] + 0x455a14ed, 20); |
219 | MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); | 219 | MD5STEP (F2, a, b, c, d, in[13] + 0xa9e3e905, 5); |
220 | MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); | 220 | MD5STEP (F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); |
221 | MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); | 221 | MD5STEP (F2, c, d, a, b, in[7] + 0x676f02d9, 14); |
222 | MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); | 222 | MD5STEP (F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); |
223 | 223 | ||
224 | MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); | 224 | MD5STEP (F3, a, b, c, d, in[5] + 0xfffa3942, 4); |
225 | MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); | 225 | MD5STEP (F3, d, a, b, c, in[8] + 0x8771f681, 11); |
226 | MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); | 226 | MD5STEP (F3, c, d, a, b, in[11] + 0x6d9d6122, 16); |
227 | MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); | 227 | MD5STEP (F3, b, c, d, a, in[14] + 0xfde5380c, 23); |
228 | MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); | 228 | MD5STEP (F3, a, b, c, d, in[1] + 0xa4beea44, 4); |
229 | MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); | 229 | MD5STEP (F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); |
230 | MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); | 230 | MD5STEP (F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); |
231 | MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); | 231 | MD5STEP (F3, b, c, d, a, in[10] + 0xbebfbc70, 23); |
232 | MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); | 232 | MD5STEP (F3, a, b, c, d, in[13] + 0x289b7ec6, 4); |
233 | MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); | 233 | MD5STEP (F3, d, a, b, c, in[0] + 0xeaa127fa, 11); |
234 | MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); | 234 | MD5STEP (F3, c, d, a, b, in[3] + 0xd4ef3085, 16); |
235 | MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); | 235 | MD5STEP (F3, b, c, d, a, in[6] + 0x04881d05, 23); |
236 | MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); | 236 | MD5STEP (F3, a, b, c, d, in[9] + 0xd9d4d039, 4); |
237 | MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); | 237 | MD5STEP (F3, d, a, b, c, in[12] + 0xe6db99e5, 11); |
238 | MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); | 238 | MD5STEP (F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); |
239 | MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); | 239 | MD5STEP (F3, b, c, d, a, in[2] + 0xc4ac5665, 23); |
240 | 240 | ||
241 | MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); | 241 | MD5STEP (F4, a, b, c, d, in[0] + 0xf4292244, 6); |
242 | MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); | 242 | MD5STEP (F4, d, a, b, c, in[7] + 0x432aff97, 10); |
243 | MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); | 243 | MD5STEP (F4, c, d, a, b, in[14] + 0xab9423a7, 15); |
244 | MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); | 244 | MD5STEP (F4, b, c, d, a, in[5] + 0xfc93a039, 21); |
245 | MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); | 245 | MD5STEP (F4, a, b, c, d, in[12] + 0x655b59c3, 6); |
246 | MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); | 246 | MD5STEP (F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); |
247 | MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); | 247 | MD5STEP (F4, c, d, a, b, in[10] + 0xffeff47d, 15); |
248 | MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); | 248 | MD5STEP (F4, b, c, d, a, in[1] + 0x85845dd1, 21); |
249 | MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); | 249 | MD5STEP (F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); |
250 | MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); | 250 | MD5STEP (F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); |
251 | MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); | 251 | MD5STEP (F4, c, d, a, b, in[6] + 0xa3014314, 15); |
252 | MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); | 252 | MD5STEP (F4, b, c, d, a, in[13] + 0x4e0811a1, 21); |
253 | MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); | 253 | MD5STEP (F4, a, b, c, d, in[4] + 0xf7537e82, 6); |
254 | MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); | 254 | MD5STEP (F4, d, a, b, c, in[11] + 0xbd3af235, 10); |
255 | MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); | 255 | MD5STEP (F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); |
256 | MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); | 256 | MD5STEP (F4, b, c, d, a, in[9] + 0xeb86d391, 21); |
257 | 257 | ||
258 | state[0] += a; | 258 | state[0] += a; |
259 | state[1] += b; | 259 | state[1] += b; |
diff --git a/src/lib/md5.h b/src/lib/md5.h index 7a6f84e6..8e95b29b 100644 --- a/src/lib/md5.h +++ b/src/lib/md5.h | |||
@@ -20,45 +20,47 @@ | |||
20 | 20 | ||
21 | #include "platform.h" | 21 | #include "platform.h" |
22 | 22 | ||
23 | #define MD5_BLOCK_SIZE 64 | 23 | #define MD5_BLOCK_SIZE 64 |
24 | #define MD5_DIGEST_SIZE 16 | 24 | #define MD5_DIGEST_SIZE 16 |
25 | #define MD5_DIGEST_STRING_LENGTH (MD5_DIGEST_SIZE * 2 + 1) | 25 | #define MD5_DIGEST_STRING_LENGTH (MD5_DIGEST_SIZE * 2 + 1) |
26 | 26 | ||
27 | struct MD5Context | 27 | struct MD5Context |
28 | { | 28 | { |
29 | uint32_t state[4]; /* state */ | 29 | uint32_t state[4]; /* state */ |
30 | uint64_t count; /* number of bits, mod 2^64 */ | 30 | uint64_t count; /* number of bits, mod 2^64 */ |
31 | uint8_t buffer[MD5_BLOCK_SIZE]; /* input buffer */ | 31 | uint8_t buffer[MD5_BLOCK_SIZE]; /* input buffer */ |
32 | }; | 32 | }; |
33 | 33 | ||
34 | /* | 34 | /* |
35 | * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious | 35 | * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious |
36 | * initialization constants. | 36 | * initialization constants. |
37 | */ | 37 | */ |
38 | void MHD_MD5Init(struct MD5Context *ctx); | 38 | void MHD_MD5Init (struct MD5Context *ctx); |
39 | 39 | ||
40 | /* | 40 | /* |
41 | * Update context to reflect the concatenation of another buffer full | 41 | * Update context to reflect the concatenation of another buffer full |
42 | * of bytes. | 42 | * of bytes. |
43 | */ | 43 | */ |
44 | void MHD_MD5Update(struct MD5Context *ctx, const unsigned char *input, size_t len); | 44 | void MHD_MD5Update (struct MD5Context *ctx, const unsigned char *input, size_t |
45 | len); | ||
45 | 46 | ||
46 | /* | 47 | /* |
47 | * Pad pad to 64-byte boundary with the bit pattern | 48 | * Pad pad to 64-byte boundary with the bit pattern |
48 | * 1 0* (64-bit count of bits processed, MSB-first) | 49 | * 1 0* (64-bit count of bits processed, MSB-first) |
49 | */ | 50 | */ |
50 | void MD5Pad(struct MD5Context *ctx); | 51 | void MD5Pad (struct MD5Context *ctx); |
51 | 52 | ||
52 | /* | 53 | /* |
53 | * Final wrapup--call MD5Pad, fill in digest and zero out ctx. | 54 | * Final wrapup--call MD5Pad, fill in digest and zero out ctx. |
54 | */ | 55 | */ |
55 | void MHD_MD5Final(unsigned char digest[MD5_DIGEST_SIZE], struct MD5Context *ctx); | 56 | void MHD_MD5Final (unsigned char digest[MD5_DIGEST_SIZE], struct |
57 | MD5Context *ctx); | ||
56 | 58 | ||
57 | /* | 59 | /* |
58 | * The core of the MD5 algorithm, this alters an existing MD5 hash to | 60 | * The core of the MD5 algorithm, this alters an existing MD5 hash to |
59 | * reflect the addition of 16 longwords of new data. MHD_MD5Update blocks | 61 | * reflect the addition of 16 longwords of new data. MHD_MD5Update blocks |
60 | * the data and converts bytes into longwords for this routine. | 62 | * the data and converts bytes into longwords for this routine. |
61 | */ | 63 | */ |
62 | void MD5Transform(uint32_t state[4], const uint8_t block[MD5_BLOCK_SIZE]); | 64 | void MD5Transform (uint32_t state[4], const uint8_t block[MD5_BLOCK_SIZE]); |
63 | 65 | ||
64 | #endif /* !MHD_MD5_H */ | 66 | #endif /* !MHD_MD5_H */ |
diff --git a/src/lib/memorypool.c b/src/lib/memorypool.c index 8ef1e2d1..9f7472e1 100644 --- a/src/lib/memorypool.c +++ b/src/lib/memorypool.c | |||
@@ -25,11 +25,11 @@ | |||
25 | #include "memorypool.h" | 25 | #include "memorypool.h" |
26 | 26 | ||
27 | /* define MAP_ANONYMOUS for Mac OS X */ | 27 | /* define MAP_ANONYMOUS for Mac OS X */ |
28 | #if defined(MAP_ANON) && !defined(MAP_ANONYMOUS) | 28 | #if defined(MAP_ANON) && ! defined(MAP_ANONYMOUS) |
29 | #define MAP_ANONYMOUS MAP_ANON | 29 | #define MAP_ANONYMOUS MAP_ANON |
30 | #endif | 30 | #endif |
31 | #ifndef MAP_FAILED | 31 | #ifndef MAP_FAILED |
32 | #define MAP_FAILED ((void*)-1) | 32 | #define MAP_FAILED ((void*) -1) |
33 | #endif | 33 | #endif |
34 | 34 | ||
35 | /** | 35 | /** |
@@ -40,7 +40,7 @@ | |||
40 | /** | 40 | /** |
41 | * Round up 'n' to a multiple of ALIGN_SIZE. | 41 | * Round up 'n' to a multiple of ALIGN_SIZE. |
42 | */ | 42 | */ |
43 | #define ROUND_TO_ALIGN(n) ((n+(ALIGN_SIZE-1)) & (~(ALIGN_SIZE-1))) | 43 | #define ROUND_TO_ALIGN(n) ((n + (ALIGN_SIZE - 1)) & (~(ALIGN_SIZE - 1))) |
44 | 44 | ||
45 | 45 | ||
46 | /** | 46 | /** |
@@ -110,11 +110,11 @@ MHD_pool_create (size_t max) | |||
110 | if (max <= 32 * 1024) | 110 | if (max <= 32 * 1024) |
111 | pool->memory = MAP_FAILED; | 111 | pool->memory = MAP_FAILED; |
112 | else | 112 | else |
113 | #if defined(MAP_ANONYMOUS) && !defined(_WIN32) | 113 | #if defined(MAP_ANONYMOUS) && ! defined(_WIN32) |
114 | pool->memory = mmap (NULL, | 114 | pool->memory = mmap (NULL, |
115 | max, | 115 | max, |
116 | PROT_READ | PROT_WRITE, | 116 | PROT_READ | PROT_WRITE, |
117 | MAP_PRIVATE | MAP_ANONYMOUS, | 117 | MAP_PRIVATE | MAP_ANONYMOUS, |
118 | -1, | 118 | -1, |
119 | 0); | 119 | 0); |
120 | #elif defined(_WIN32) | 120 | #elif defined(_WIN32) |
@@ -128,19 +128,19 @@ MHD_pool_create (size_t max) | |||
128 | #endif | 128 | #endif |
129 | if ( (MAP_FAILED == pool->memory) || | 129 | if ( (MAP_FAILED == pool->memory) || |
130 | (NULL == pool->memory)) | 130 | (NULL == pool->memory)) |
131 | { | ||
132 | pool->memory = malloc (max); | ||
133 | if (NULL == pool->memory) | ||
131 | { | 134 | { |
132 | pool->memory = malloc (max); | 135 | free (pool); |
133 | if (NULL == pool->memory) | 136 | return NULL; |
134 | { | ||
135 | free (pool); | ||
136 | return NULL; | ||
137 | } | ||
138 | pool->is_mmap = false; | ||
139 | } | 137 | } |
138 | pool->is_mmap = false; | ||
139 | } | ||
140 | else | 140 | else |
141 | { | 141 | { |
142 | pool->is_mmap = true; | 142 | pool->is_mmap = true; |
143 | } | 143 | } |
144 | pool->pos = 0; | 144 | pool->pos = 0; |
145 | pool->end = max; | 145 | pool->end = max; |
146 | pool->size = max; | 146 | pool->size = max; |
@@ -161,7 +161,7 @@ MHD_pool_destroy (struct MemoryPool *pool) | |||
161 | if (! pool->is_mmap) | 161 | if (! pool->is_mmap) |
162 | free (pool->memory); | 162 | free (pool->memory); |
163 | else | 163 | else |
164 | #if defined(MAP_ANONYMOUS) && !defined(_WIN32) | 164 | #if defined(MAP_ANONYMOUS) && ! defined(_WIN32) |
165 | munmap (pool->memory, | 165 | munmap (pool->memory, |
166 | pool->size); | 166 | pool->size); |
167 | #elif defined(_WIN32) | 167 | #elif defined(_WIN32) |
@@ -201,7 +201,7 @@ MHD_pool_get_free (struct MemoryPool *pool) | |||
201 | */ | 201 | */ |
202 | void * | 202 | void * |
203 | MHD_pool_allocate (struct MemoryPool *pool, | 203 | MHD_pool_allocate (struct MemoryPool *pool, |
204 | size_t size, | 204 | size_t size, |
205 | int from_end) | 205 | int from_end) |
206 | { | 206 | { |
207 | void *ret; | 207 | void *ret; |
@@ -214,15 +214,15 @@ MHD_pool_allocate (struct MemoryPool *pool, | |||
214 | (pool->pos + asize < pool->pos)) | 214 | (pool->pos + asize < pool->pos)) |
215 | return NULL; | 215 | return NULL; |
216 | if (from_end == MHD_YES) | 216 | if (from_end == MHD_YES) |
217 | { | 217 | { |
218 | ret = &pool->memory[pool->end - asize]; | 218 | ret = &pool->memory[pool->end - asize]; |
219 | pool->end -= asize; | 219 | pool->end -= asize; |
220 | } | 220 | } |
221 | else | 221 | else |
222 | { | 222 | { |
223 | ret = &pool->memory[pool->pos]; | 223 | ret = &pool->memory[pool->pos]; |
224 | pool->pos += asize; | 224 | pool->pos += asize; |
225 | } | 225 | } |
226 | return ret; | 226 | return ret; |
227 | } | 227 | } |
228 | 228 | ||
@@ -247,8 +247,8 @@ MHD_pool_allocate (struct MemoryPool *pool, | |||
247 | void * | 247 | void * |
248 | MHD_pool_reallocate (struct MemoryPool *pool, | 248 | MHD_pool_reallocate (struct MemoryPool *pool, |
249 | void *old, | 249 | void *old, |
250 | size_t old_size, | 250 | size_t old_size, |
251 | size_t new_size) | 251 | size_t new_size) |
252 | { | 252 | { |
253 | void *ret; | 253 | void *ret; |
254 | size_t asize; | 254 | size_t asize; |
@@ -263,35 +263,35 @@ MHD_pool_reallocate (struct MemoryPool *pool, | |||
263 | 263 | ||
264 | if ( (pool->pos >= old_size) && | 264 | if ( (pool->pos >= old_size) && |
265 | (&pool->memory[pool->pos - old_size] == old) ) | 265 | (&pool->memory[pool->pos - old_size] == old) ) |
266 | { | ||
267 | /* was the previous allocation - optimize! */ | ||
268 | if (pool->pos + asize - old_size <= pool->end) | ||
266 | { | 269 | { |
267 | /* was the previous allocation - optimize! */ | 270 | /* fits */ |
268 | if (pool->pos + asize - old_size <= pool->end) | 271 | pool->pos += asize - old_size; |
269 | { | 272 | if (asize < old_size) /* shrinking - zero again! */ |
270 | /* fits */ | 273 | memset (&pool->memory[pool->pos], |
271 | pool->pos += asize - old_size; | 274 | 0, |
272 | if (asize < old_size) /* shrinking - zero again! */ | 275 | old_size - asize); |
273 | memset (&pool->memory[pool->pos], | 276 | return old; |
274 | 0, | ||
275 | old_size - asize); | ||
276 | return old; | ||
277 | } | ||
278 | /* does not fit */ | ||
279 | return NULL; | ||
280 | } | 277 | } |
278 | /* does not fit */ | ||
279 | return NULL; | ||
280 | } | ||
281 | if (asize <= old_size) | 281 | if (asize <= old_size) |
282 | return old; /* cannot shrink, no need to move */ | 282 | return old; /* cannot shrink, no need to move */ |
283 | if ((pool->pos + asize >= pool->pos) && | 283 | if ((pool->pos + asize >= pool->pos) && |
284 | (pool->pos + asize <= pool->end)) | 284 | (pool->pos + asize <= pool->end)) |
285 | { | 285 | { |
286 | /* fits */ | 286 | /* fits */ |
287 | ret = &pool->memory[pool->pos]; | 287 | ret = &pool->memory[pool->pos]; |
288 | if (0 != old_size) | 288 | if (0 != old_size) |
289 | memmove (ret, | 289 | memmove (ret, |
290 | old, | 290 | old, |
291 | old_size); | 291 | old_size); |
292 | pool->pos += asize; | 292 | pool->pos += asize; |
293 | return ret; | 293 | return ret; |
294 | } | 294 | } |
295 | /* does not fit */ | 295 | /* does not fit */ |
296 | return NULL; | 296 | return NULL; |
297 | } | 297 | } |
@@ -312,19 +312,19 @@ MHD_pool_reallocate (struct MemoryPool *pool, | |||
312 | */ | 312 | */ |
313 | void * | 313 | void * |
314 | MHD_pool_reset (struct MemoryPool *pool, | 314 | MHD_pool_reset (struct MemoryPool *pool, |
315 | void *keep, | 315 | void *keep, |
316 | size_t copy_bytes, | 316 | size_t copy_bytes, |
317 | size_t new_size) | 317 | size_t new_size) |
318 | { | 318 | { |
319 | if ( (NULL != keep) && | 319 | if ( (NULL != keep) && |
320 | (keep != pool->memory) ) | 320 | (keep != pool->memory) ) |
321 | { | 321 | { |
322 | if (0 != copy_bytes) | 322 | if (0 != copy_bytes) |
323 | memmove (pool->memory, | 323 | memmove (pool->memory, |
324 | keep, | 324 | keep, |
325 | copy_bytes); | 325 | copy_bytes); |
326 | keep = pool->memory; | 326 | keep = pool->memory; |
327 | } | 327 | } |
328 | pool->end = pool->size; | 328 | pool->end = pool->size; |
329 | /* technically not needed, but safer to zero out */ | 329 | /* technically not needed, but safer to zero out */ |
330 | if (pool->size > copy_bytes) | 330 | if (pool->size > copy_bytes) |
diff --git a/src/lib/memorypool.h b/src/lib/memorypool.h index 36136af8..774b05ba 100644 --- a/src/lib/memorypool.h +++ b/src/lib/memorypool.h | |||
@@ -70,7 +70,7 @@ MHD_pool_destroy (struct MemoryPool *pool); | |||
70 | */ | 70 | */ |
71 | void * | 71 | void * |
72 | MHD_pool_allocate (struct MemoryPool *pool, | 72 | MHD_pool_allocate (struct MemoryPool *pool, |
73 | size_t size, | 73 | size_t size, |
74 | int from_end); | 74 | int from_end); |
75 | 75 | ||
76 | 76 | ||
@@ -93,9 +93,9 @@ MHD_pool_allocate (struct MemoryPool *pool, | |||
93 | */ | 93 | */ |
94 | void * | 94 | void * |
95 | MHD_pool_reallocate (struct MemoryPool *pool, | 95 | MHD_pool_reallocate (struct MemoryPool *pool, |
96 | void *old, | 96 | void *old, |
97 | size_t old_size, | 97 | size_t old_size, |
98 | size_t new_size); | 98 | size_t new_size); |
99 | 99 | ||
100 | 100 | ||
101 | /** | 101 | /** |
@@ -123,8 +123,8 @@ MHD_pool_get_free (struct MemoryPool *pool); | |||
123 | */ | 123 | */ |
124 | void * | 124 | void * |
125 | MHD_pool_reset (struct MemoryPool *pool, | 125 | MHD_pool_reset (struct MemoryPool *pool, |
126 | void *keep, | 126 | void *keep, |
127 | size_t copy_bytes, | 127 | size_t copy_bytes, |
128 | size_t new_size); | 128 | size_t new_size); |
129 | 129 | ||
130 | #endif | 130 | #endif |
diff --git a/src/lib/mhd_assert.h b/src/lib/mhd_assert.h index c720ce5c..e99632d0 100644 --- a/src/lib/mhd_assert.h +++ b/src/lib/mhd_assert.h | |||
@@ -28,21 +28,21 @@ | |||
28 | 28 | ||
29 | #include "mhd_options.h" | 29 | #include "mhd_options.h" |
30 | #ifdef NDEBUG | 30 | #ifdef NDEBUG |
31 | # define mhd_assert(ignore) ((void)0) | 31 | # define mhd_assert(ignore) ((void) 0) |
32 | #else /* _DEBUG */ | 32 | #else /* _DEBUG */ |
33 | # ifdef HAVE_ASSERT | 33 | # ifdef HAVE_ASSERT |
34 | # include <assert.h> | 34 | # include <assert.h> |
35 | # define mhd_assert(CHK) assert(CHK) | 35 | # define mhd_assert(CHK) assert (CHK) |
36 | # else /* ! HAVE_ASSERT */ | 36 | # else /* ! HAVE_ASSERT */ |
37 | # include <stdio.h> | 37 | # include <stdio.h> |
38 | # include <stdlib.h> | 38 | # include <stdlib.h> |
39 | # define mhd_assert(CHK) \ | 39 | # define mhd_assert(CHK) \ |
40 | do { \ | 40 | do { \ |
41 | if (!(CHK)) { \ | 41 | if (! (CHK)) { \ |
42 | fprintf(stderr, "%s:%u Assertion failed: %s\nProgram aborted.\n", \ | 42 | fprintf (stderr, "%s:%u Assertion failed: %s\nProgram aborted.\n", \ |
43 | __FILE__, (unsigned)__LINE__, #CHK); \ | 43 | __FILE__, (unsigned) __LINE__, #CHK); \ |
44 | fflush(stderr); abort(); } \ | 44 | fflush (stderr); abort (); } \ |
45 | } while(0) | 45 | } while (0) |
46 | # endif /* ! HAVE_ASSERT */ | 46 | # endif /* ! HAVE_ASSERT */ |
47 | #endif /* _DEBUG */ | 47 | #endif /* _DEBUG */ |
48 | 48 | ||
diff --git a/src/lib/mhd_byteorder.h b/src/lib/mhd_byteorder.h index 66689804..230ae803 100644 --- a/src/lib/mhd_byteorder.h +++ b/src/lib/mhd_byteorder.h | |||
@@ -71,7 +71,8 @@ | |||
71 | #if defined(__BYTE_ORDER__) | 71 | #if defined(__BYTE_ORDER__) |
72 | #if defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ | 72 | #if defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ |
73 | #define _MHD_BYTE_ORDER _MHD_BIG_ENDIAN | 73 | #define _MHD_BYTE_ORDER _MHD_BIG_ENDIAN |
74 | #elif defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ | 74 | #elif defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == \ |
75 | __ORDER_LITTLE_ENDIAN__ | ||
75 | #define _MHD_BYTE_ORDER _MHD_LITTLE_ENDIAN | 76 | #define _MHD_BYTE_ORDER _MHD_LITTLE_ENDIAN |
76 | #elif defined(__ORDER_PDP_ENDIAN__) && __BYTE_ORDER__ == __ORDER_PDP_ENDIAN__ | 77 | #elif defined(__ORDER_PDP_ENDIAN__) && __BYTE_ORDER__ == __ORDER_PDP_ENDIAN__ |
77 | #define _MHD_BYTE_ORDER _MHD_PDP_ENDIAN | 78 | #define _MHD_BYTE_ORDER _MHD_PDP_ENDIAN |
@@ -106,36 +107,40 @@ | |||
106 | /* Byte order specification didn't detected in system headers */ | 107 | /* Byte order specification didn't detected in system headers */ |
107 | /* Try some guessing */ | 108 | /* Try some guessing */ |
108 | 109 | ||
109 | #if (defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__)) || \ | 110 | #if (defined(__BIG_ENDIAN__) && ! defined(__LITTLE_ENDIAN__)) || \ |
110 | (defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN)) | 111 | (defined(_BIG_ENDIAN) && ! defined(_LITTLE_ENDIAN)) |
111 | /* Seems that we are on big endian platform */ | 112 | /* Seems that we are on big endian platform */ |
112 | #define _MHD_BYTE_ORDER _MHD_BIG_ENDIAN | 113 | #define _MHD_BYTE_ORDER _MHD_BIG_ENDIAN |
113 | #elif (defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)) || \ | 114 | #elif (defined(__LITTLE_ENDIAN__) && ! defined(__BIG_ENDIAN__)) || \ |
114 | (defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)) | 115 | (defined(_LITTLE_ENDIAN) && ! defined(_BIG_ENDIAN)) |
115 | /* Seems that we are on little endian platform */ | 116 | /* Seems that we are on little endian platform */ |
116 | #define _MHD_BYTE_ORDER _MHD_LITTLE_ENDIAN | 117 | #define _MHD_BYTE_ORDER _MHD_LITTLE_ENDIAN |
117 | #elif defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || \ | 118 | #elif defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || \ |
118 | defined(_M_X64) || defined(_M_AMD64) || defined(i386) || defined(__i386) || \ | 119 | defined(__x86_64) || \ |
119 | defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) || \ | 120 | defined(_M_X64) || defined(_M_AMD64) || defined(i386) || defined(__i386) || \ |
120 | defined(_M_IX86) || defined(_X86_) || defined (__THW_INTEL__) | 121 | defined(__i386__) || defined(__i486__) || defined(__i586__) || \ |
122 | defined(__i686__) || \ | ||
123 | defined(_M_IX86) || defined(_X86_) || defined (__THW_INTEL__) | ||
121 | /* x86 family is little endian */ | 124 | /* x86 family is little endian */ |
122 | #define _MHD_BYTE_ORDER _MHD_LITTLE_ENDIAN | 125 | #define _MHD_BYTE_ORDER _MHD_LITTLE_ENDIAN |
123 | #elif defined(__ARMEB__) || defined(__THUMBEB__) || defined(__AARCH64EB__) || \ | 126 | #elif defined(__ARMEB__) || defined(__THUMBEB__) || defined(__AARCH64EB__) || \ |
124 | defined(_MIPSEB) || defined(__MIPSEB) || defined(__MIPSEB__) | 127 | defined(_MIPSEB) || defined(__MIPSEB) || defined(__MIPSEB__) |
125 | /* Looks like we are on ARM/MIPS in big endian mode */ | 128 | /* Looks like we are on ARM/MIPS in big endian mode */ |
126 | #define _MHD_BYTE_ORDER _MHD_BIG_ENDIAN | 129 | #define _MHD_BYTE_ORDER _MHD_BIG_ENDIAN |
127 | #elif defined(__ARMEL__) || defined(__THUMBEL__) || defined(__AARCH64EL__) || \ | 130 | #elif defined(__ARMEL__) || defined(__THUMBEL__) || defined(__AARCH64EL__) || \ |
128 | defined(_MIPSEL) || defined(__MIPSEL) || defined(__MIPSEL__) | 131 | defined(_MIPSEL) || defined(__MIPSEL) || defined(__MIPSEL__) |
129 | /* Looks like we are on ARM/MIPS in little endian mode */ | 132 | /* Looks like we are on ARM/MIPS in little endian mode */ |
130 | #define _MHD_BYTE_ORDER _MHD_LITTLE_ENDIAN | 133 | #define _MHD_BYTE_ORDER _MHD_LITTLE_ENDIAN |
131 | #elif defined(__m68k__) || defined(M68000) || defined(__hppa__) || defined(__hppa) || \ | 134 | #elif defined(__m68k__) || defined(M68000) || defined(__hppa__) || \ |
132 | defined(__HPPA__) || defined(__370__) || defined(__THW_370__) || \ | 135 | defined(__hppa) || \ |
133 | defined(__s390__) || defined(__s390x__) || defined(__SYSC_ZARCH__) | 136 | defined(__HPPA__) || defined(__370__) || defined(__THW_370__) || \ |
137 | defined(__s390__) || defined(__s390x__) || defined(__SYSC_ZARCH__) | ||
134 | /* Looks like we are on big endian platform */ | 138 | /* Looks like we are on big endian platform */ |
135 | #define _MHD_BYTE_ORDER _MHD_BIG_ENDIAN | 139 | #define _MHD_BYTE_ORDER _MHD_BIG_ENDIAN |
136 | #elif defined(__ia64__) || defined(_IA64) || defined(__IA64__) || defined(__ia64) || \ | 140 | #elif defined(__ia64__) || defined(_IA64) || defined(__IA64__) || \ |
137 | defined(_M_IA64) || defined(__itanium__) || defined(__bfin__) || \ | 141 | defined(__ia64) || \ |
138 | defined(__BFIN__) || defined(bfin) || defined(BFIN) | 142 | defined(_M_IA64) || defined(__itanium__) || defined(__bfin__) || \ |
143 | defined(__BFIN__) || defined(bfin) || defined(BFIN) | ||
139 | /* Looks like we are on little endian platform */ | 144 | /* Looks like we are on little endian platform */ |
140 | #define _MHD_BYTE_ORDER _MHD_LITTLE_ENDIAN | 145 | #define _MHD_BYTE_ORDER _MHD_LITTLE_ENDIAN |
141 | #elif defined(_WIN32) | 146 | #elif defined(_WIN32) |
@@ -151,9 +156,11 @@ | |||
151 | #ifdef _MHD_BYTE_ORDER | 156 | #ifdef _MHD_BYTE_ORDER |
152 | /* Some safety checks */ | 157 | /* Some safety checks */ |
153 | #if defined(WORDS_BIGENDIAN) && _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN | 158 | #if defined(WORDS_BIGENDIAN) && _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN |
154 | #error Configure detected big endian byte order but headers specify different byte order | 159 | #error \ |
155 | #elif !defined(WORDS_BIGENDIAN) && _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN | 160 | Configure detected big endian byte order but headers specify different byte order |
156 | #error Configure did not detect big endian byte order but headers specify big endian byte order | 161 | #elif ! defined(WORDS_BIGENDIAN) && _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN |
162 | #error \ | ||
163 | Configure did not detect big endian byte order but headers specify big endian byte order | ||
157 | #endif /* !WORDS_BIGENDIAN && _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN */ | 164 | #endif /* !WORDS_BIGENDIAN && _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN */ |
158 | #endif /* _MHD_BYTE_ORDER */ | 165 | #endif /* _MHD_BYTE_ORDER */ |
159 | 166 | ||
diff --git a/src/lib/mhd_compat.c b/src/lib/mhd_compat.c index 3abdc367..6f6c6f9c 100644 --- a/src/lib/mhd_compat.c +++ b/src/lib/mhd_compat.c | |||
@@ -25,7 +25,7 @@ | |||
25 | */ | 25 | */ |
26 | 26 | ||
27 | #include "mhd_compat.h" | 27 | #include "mhd_compat.h" |
28 | #if defined(_WIN32) && !defined(__CYGWIN__) | 28 | #if defined(_WIN32) && ! defined(__CYGWIN__) |
29 | #include <stdint.h> | 29 | #include <stdint.h> |
30 | #include <time.h> | 30 | #include <time.h> |
31 | #ifndef HAVE_SNPRINTF | 31 | #ifndef HAVE_SNPRINTF |
@@ -38,7 +38,7 @@ | |||
38 | #include <string.h> /* for memset() */ | 38 | #include <string.h> /* for memset() */ |
39 | #endif /* ! HAVE_CALLOC */ | 39 | #endif /* ! HAVE_CALLOC */ |
40 | 40 | ||
41 | #if defined(_WIN32) && !defined(__CYGWIN__) | 41 | #if defined(_WIN32) && ! defined(__CYGWIN__) |
42 | 42 | ||
43 | #ifndef HAVE_SNPRINTF | 43 | #ifndef HAVE_SNPRINTF |
44 | /* Emulate snprintf function on W32 */ | 44 | /* Emulate snprintf function on W32 */ |
@@ -61,16 +61,16 @@ W32_snprintf (char *__restrict s, | |||
61 | format, | 61 | format, |
62 | args); | 62 | args); |
63 | va_end (args); | 63 | va_end (args); |
64 | if ((int)n == ret) | 64 | if ((int) n == ret) |
65 | s[n - 1] = 0; | 65 | s[n - 1] = 0; |
66 | if (ret >= 0) | 66 | if (ret >= 0) |
67 | return ret; | 67 | return ret; |
68 | } | 68 | } |
69 | va_start(args, | 69 | va_start (args, |
70 | format); | 70 | format); |
71 | ret = _vscprintf (format, | 71 | ret = _vscprintf (format, |
72 | args); | 72 | args); |
73 | va_end(args); | 73 | va_end (args); |
74 | if ( (0 <= ret) && | 74 | if ( (0 <= ret) && |
75 | (0 != n) && | 75 | (0 != n) && |
76 | (NULL == s) ) | 76 | (NULL == s) ) |
@@ -85,30 +85,30 @@ W32_snprintf (char *__restrict s, | |||
85 | #ifndef HAVE_CALLOC | 85 | #ifndef HAVE_CALLOC |
86 | 86 | ||
87 | #ifdef __has_builtin | 87 | #ifdef __has_builtin |
88 | # if __has_builtin(__builtin_mul_overflow) | 88 | # if __has_builtin (__builtin_mul_overflow) |
89 | # define MHD_HAVE_NUL_OVERFLOW 1 | 89 | # define MHD_HAVE_NUL_OVERFLOW 1 |
90 | # endif | 90 | # endif |
91 | #elif __GNUC__+0 >= 5 | 91 | #elif __GNUC__ + 0 >= 5 |
92 | # define MHD_HAVE_NUL_OVERFLOW 1 | 92 | # define MHD_HAVE_NUL_OVERFLOW 1 |
93 | #endif /* __GNUC__ >= 5 */ | 93 | #endif /* __GNUC__ >= 5 */ |
94 | 94 | ||
95 | 95 | ||
96 | void *MHD_calloc_(size_t nelem, size_t elsize) | 96 | void *MHD_calloc_ (size_t nelem, size_t elsize) |
97 | { | 97 | { |
98 | size_t alloc_size; | 98 | size_t alloc_size; |
99 | void *ptr; | 99 | void *ptr; |
100 | #ifdef MHD_HAVE_NUL_OVERFLOW | 100 | #ifdef MHD_HAVE_NUL_OVERFLOW |
101 | if (__builtin_mul_overflow(nelem, elsize, &alloc_size) || 0 == alloc_size) | 101 | if (__builtin_mul_overflow (nelem, elsize, &alloc_size) ||(0 == alloc_size)) |
102 | return NULL; | 102 | return NULL; |
103 | #else /* ! MHD_HAVE_NUL_OVERFLOW */ | 103 | #else /* ! MHD_HAVE_NUL_OVERFLOW */ |
104 | alloc_size = nelem * elsize; | 104 | alloc_size = nelem * elsize; |
105 | if (0 == alloc_size || elsize != alloc_size / nelem) | 105 | if ((0 == alloc_size)||(elsize != alloc_size / nelem)) |
106 | return NULL; | 106 | return NULL; |
107 | #endif /* ! MHD_HAVE_NUL_OVERFLOW */ | 107 | #endif /* ! MHD_HAVE_NUL_OVERFLOW */ |
108 | ptr = malloc (alloc_size); | 108 | ptr = malloc (alloc_size); |
109 | if (NULL == ptr) | 109 | if (NULL == ptr) |
110 | return NULL; | 110 | return NULL; |
111 | memset(ptr, 0, alloc_size); | 111 | memset (ptr, 0, alloc_size); |
112 | return ptr; | 112 | return ptr; |
113 | } | 113 | } |
114 | #endif /* ! HAVE_CALLOC */ | 114 | #endif /* ! HAVE_CALLOC */ |
diff --git a/src/lib/mhd_compat.h b/src/lib/mhd_compat.h index b4e2c66c..6b38a03e 100644 --- a/src/lib/mhd_compat.h +++ b/src/lib/mhd_compat.h | |||
@@ -40,8 +40,8 @@ | |||
40 | #include <string.h> | 40 | #include <string.h> |
41 | #endif /* HAVE_STRING_H */ | 41 | #endif /* HAVE_STRING_H */ |
42 | 42 | ||
43 | /* MHD_strerror_ is strerror */ | 43 | /* MHD_strerror_ is strerror */ |
44 | #define MHD_strerror_(errnum) strerror((errnum)) | 44 | #define MHD_strerror_(errnum) strerror ((errnum)) |
45 | 45 | ||
46 | /* Platform-independent snprintf name */ | 46 | /* Platform-independent snprintf name */ |
47 | #if defined(HAVE_SNPRINTF) | 47 | #if defined(HAVE_SNPRINTF) |
@@ -49,10 +49,12 @@ | |||
49 | #else /* ! HAVE_SNPRINTF */ | 49 | #else /* ! HAVE_SNPRINTF */ |
50 | #if defined(_WIN32) && ! defined(__CYGWIN__) | 50 | #if defined(_WIN32) && ! defined(__CYGWIN__) |
51 | /* Emulate snprintf function on W32 */ | 51 | /* Emulate snprintf function on W32 */ |
52 | int W32_snprintf(char *__restrict s, size_t n, const char *__restrict format, ...); | 52 | int W32_snprintf (char *__restrict s, size_t n, const char *__restrict format, |
53 | ...); | ||
53 | #define MHD_snprintf_ W32_snprintf | 54 | #define MHD_snprintf_ W32_snprintf |
54 | #else /* ! _WIN32 || __CYGWIN__ */ | 55 | #else /* ! _WIN32 || __CYGWIN__ */ |
55 | #error Your platform does not support snprintf() and MHD does not know how to emulate it on your platform. | 56 | #error \ |
57 | Your platform does not support snprintf() and MHD does not know how to emulate it on your platform. | ||
56 | #endif /* ! _WIN32 || __CYGWIN__ */ | 58 | #endif /* ! _WIN32 || __CYGWIN__ */ |
57 | #endif /* ! HAVE_SNPRINTF */ | 59 | #endif /* ! HAVE_SNPRINTF */ |
58 | 60 | ||
@@ -61,14 +63,14 @@ int W32_snprintf(char *__restrict s, size_t n, const char *__restrict format, .. | |||
61 | * Generate pseudo random number at least 30-bit wide. | 63 | * Generate pseudo random number at least 30-bit wide. |
62 | * @return pseudo random number at least 30-bit wide. | 64 | * @return pseudo random number at least 30-bit wide. |
63 | */ | 65 | */ |
64 | #define MHD_random_() random() | 66 | #define MHD_random_() random () |
65 | #else /* HAVE_RANDOM */ | 67 | #else /* HAVE_RANDOM */ |
66 | #ifdef HAVE_RAND | 68 | #ifdef HAVE_RAND |
67 | /** | 69 | /** |
68 | * Generate pseudo random number at least 30-bit wide. | 70 | * Generate pseudo random number at least 30-bit wide. |
69 | * @return pseudo random number at least 30-bit wide. | 71 | * @return pseudo random number at least 30-bit wide. |
70 | */ | 72 | */ |
71 | #define MHD_random_() ( (((long)rand()) << 15) + (long)rand() ) | 73 | #define MHD_random_() ( (((long) rand ()) << 15) + (long) rand () ) |
72 | #endif /* HAVE_RAND */ | 74 | #endif /* HAVE_RAND */ |
73 | #endif /* HAVE_RANDOM */ | 75 | #endif /* HAVE_RANDOM */ |
74 | 76 | ||
@@ -76,12 +78,12 @@ int W32_snprintf(char *__restrict s, size_t n, const char *__restrict format, .. | |||
76 | /** | 78 | /** |
77 | * MHD_calloc_ is platform-independent calloc() | 79 | * MHD_calloc_ is platform-independent calloc() |
78 | */ | 80 | */ |
79 | #define MHD_calloc_(n,s) calloc((n),(s)) | 81 | #define MHD_calloc_(n,s) calloc ((n),(s)) |
80 | #else /* ! HAVE_CALLOC */ | 82 | #else /* ! HAVE_CALLOC */ |
81 | /** | 83 | /** |
82 | * MHD_calloc_ is platform-independent calloc() | 84 | * MHD_calloc_ is platform-independent calloc() |
83 | */ | 85 | */ |
84 | void *MHD_calloc_(size_t nelem, size_t elsize); | 86 | void *MHD_calloc_ (size_t nelem, size_t elsize); |
85 | #endif /* ! HAVE_CALLOC */ | 87 | #endif /* ! HAVE_CALLOC */ |
86 | 88 | ||
87 | #endif /* MHD_COMPAT_H */ | 89 | #endif /* MHD_COMPAT_H */ |
diff --git a/src/lib/mhd_itc.c b/src/lib/mhd_itc.c index 8aeee576..6c81ef62 100644 --- a/src/lib/mhd_itc.c +++ b/src/lib/mhd_itc.c | |||
@@ -34,7 +34,7 @@ | |||
34 | 34 | ||
35 | 35 | ||
36 | #if defined(_MHD_ITC_PIPE) | 36 | #if defined(_MHD_ITC_PIPE) |
37 | #if !defined(_WIN32) || defined(__CYGWIN__) | 37 | #if ! defined(_WIN32) || defined(__CYGWIN__) |
38 | 38 | ||
39 | #ifndef HAVE_PIPE2_FUNC | 39 | #ifndef HAVE_PIPE2_FUNC |
40 | /** | 40 | /** |
@@ -48,7 +48,7 @@ MHD_itc_nonblocking_ (struct MHD_itc_ itc) | |||
48 | { | 48 | { |
49 | unsigned int i; | 49 | unsigned int i; |
50 | 50 | ||
51 | for (i=0;i<2;i++) | 51 | for (i = 0; i<2; i++) |
52 | { | 52 | { |
53 | int flags; | 53 | int flags; |
54 | 54 | ||
@@ -63,7 +63,7 @@ MHD_itc_nonblocking_ (struct MHD_itc_ itc) | |||
63 | flags | O_NONBLOCK)) ) | 63 | flags | O_NONBLOCK)) ) |
64 | return 0; | 64 | return 0; |
65 | } | 65 | } |
66 | return !0; | 66 | return ! 0; |
67 | } | 67 | } |
68 | #endif /* ! HAVE_PIPE2_FUNC */ | 68 | #endif /* ! HAVE_PIPE2_FUNC */ |
69 | #endif /* !_WIN32 || __CYGWIN__ */ | 69 | #endif /* !_WIN32 || __CYGWIN__ */ |
diff --git a/src/lib/mhd_itc.h b/src/lib/mhd_itc.h index 01331f13..8e303ef9 100644 --- a/src/lib/mhd_itc.h +++ b/src/lib/mhd_itc.h | |||
@@ -41,8 +41,9 @@ | |||
41 | # include <stdlib.h> | 41 | # include <stdlib.h> |
42 | /* Simple implementation of MHD_PANIC, to be used outside lib */ | 42 | /* Simple implementation of MHD_PANIC, to be used outside lib */ |
43 | # define MHD_PANIC(msg) do { fprintf (stderr, \ | 43 | # define MHD_PANIC(msg) do { fprintf (stderr, \ |
44 | "Abnormal termination at %d line in file %s: %s\n", \ | 44 | "Abnormal termination at %d line in file %s: %s\n", \ |
45 | (int)__LINE__, __FILE__, msg); abort();} while(0) | 45 | (int) __LINE__, __FILE__, msg); abort (); \ |
46 | } while (0) | ||
46 | #endif /* ! MHD_PANIC */ | 47 | #endif /* ! MHD_PANIC */ |
47 | 48 | ||
48 | #if defined(_MHD_ITC_EVENTFD) | 49 | #if defined(_MHD_ITC_EVENTFD) |
@@ -63,12 +64,13 @@ | |||
63 | * @param itc the itc to initialise | 64 | * @param itc the itc to initialise |
64 | * @return non-zero if succeeded, zero otherwise | 65 | * @return non-zero if succeeded, zero otherwise |
65 | */ | 66 | */ |
66 | #define MHD_itc_init_(itc) (-1 != ((itc).fd = eventfd (0, EFD_CLOEXEC | EFD_NONBLOCK))) | 67 | #define MHD_itc_init_(itc) (-1 != ((itc).fd = eventfd (0, EFD_CLOEXEC \ |
68 | | EFD_NONBLOCK))) | ||
67 | 69 | ||
68 | /** | 70 | /** |
69 | * Get description string of last errno for itc operations. | 71 | * Get description string of last errno for itc operations. |
70 | */ | 72 | */ |
71 | #define MHD_itc_last_strerror_() strerror(errno) | 73 | #define MHD_itc_last_strerror_() strerror (errno) |
72 | 74 | ||
73 | /** | 75 | /** |
74 | * Internal static const helper for MHD_itc_activate_() | 76 | * Internal static const helper for MHD_itc_activate_() |
@@ -82,7 +84,8 @@ static const uint64_t _MHD_itc_wr_data = 1; | |||
82 | * @return non-zero if succeeded, zero otherwise | 84 | * @return non-zero if succeeded, zero otherwise |
83 | */ | 85 | */ |
84 | #define MHD_itc_activate_(itc, str) \ | 86 | #define MHD_itc_activate_(itc, str) \ |
85 | ((write((itc).fd, (const void*)&_MHD_itc_wr_data, 8) > 0) || (EAGAIN == errno)) | 87 | ((write ((itc).fd, (const void*) &_MHD_itc_wr_data, 8) > 0) || (EAGAIN == \ |
88 | errno)) | ||
86 | 89 | ||
87 | /** | 90 | /** |
88 | * Return read FD of @a itc which can be used for poll(), select() etc. | 91 | * Return read FD of @a itc which can be used for poll(), select() etc. |
@@ -104,8 +107,8 @@ static const uint64_t _MHD_itc_wr_data = 1; | |||
104 | */ | 107 | */ |
105 | #define MHD_itc_clear_(itc) \ | 108 | #define MHD_itc_clear_(itc) \ |
106 | do { uint64_t __b; int __r; \ | 109 | do { uint64_t __b; int __r; \ |
107 | __r = read((itc).fd, &__b, sizeof(__b)); \ | 110 | __r = read ((itc).fd, &__b, sizeof(__b)); \ |
108 | (void)__r; } while(0) | 111 | (void) __r; } while (0) |
109 | 112 | ||
110 | /** | 113 | /** |
111 | * Destroy previously initialised ITC. Note that close() | 114 | * Destroy previously initialised ITC. Note that close() |
@@ -155,20 +158,20 @@ static const uint64_t _MHD_itc_wr_data = 1; | |||
155 | * @return non-zero if succeeded, zero otherwise | 158 | * @return non-zero if succeeded, zero otherwise |
156 | */ | 159 | */ |
157 | #ifdef HAVE_PIPE2_FUNC | 160 | #ifdef HAVE_PIPE2_FUNC |
158 | # define MHD_itc_init_(itc) (!pipe2((itc).fd, O_CLOEXEC | O_NONBLOCK)) | 161 | # define MHD_itc_init_(itc) (! pipe2 ((itc).fd, O_CLOEXEC | O_NONBLOCK)) |
159 | #else /* ! HAVE_PIPE2_FUNC */ | 162 | #else /* ! HAVE_PIPE2_FUNC */ |
160 | # define MHD_itc_init_(itc) \ | 163 | # define MHD_itc_init_(itc) \ |
161 | ( (!pipe((itc).fd)) ? \ | 164 | ( (! pipe ((itc).fd)) ? \ |
162 | (MHD_itc_nonblocking_((itc)) ? \ | 165 | (MHD_itc_nonblocking_ ((itc)) ? \ |
163 | (!0) : \ | 166 | (! 0) : \ |
164 | (MHD_itc_destroy_((itc)), 0) ) \ | 167 | (MHD_itc_destroy_ ((itc)), 0) ) \ |
165 | : (0) ) | 168 | : (0) ) |
166 | #endif /* ! HAVE_PIPE2_FUNC */ | 169 | #endif /* ! HAVE_PIPE2_FUNC */ |
167 | 170 | ||
168 | /** | 171 | /** |
169 | * Get description string of last errno for itc operations. | 172 | * Get description string of last errno for itc operations. |
170 | */ | 173 | */ |
171 | #define MHD_itc_last_strerror_() strerror(errno) | 174 | #define MHD_itc_last_strerror_() strerror (errno) |
172 | 175 | ||
173 | /** | 176 | /** |
174 | * Activate signal on @a itc | 177 | * Activate signal on @a itc |
@@ -177,7 +180,7 @@ static const uint64_t _MHD_itc_wr_data = 1; | |||
177 | * @return non-zero if succeeded, zero otherwise | 180 | * @return non-zero if succeeded, zero otherwise |
178 | */ | 181 | */ |
179 | #define MHD_itc_activate_(itc, str) \ | 182 | #define MHD_itc_activate_(itc, str) \ |
180 | ((write((itc).fd[1], (const void*)(str), 1) > 0) || (EAGAIN == errno)) | 183 | ((write ((itc).fd[1], (const void*) (str), 1) > 0) || (EAGAIN == errno)) |
181 | 184 | ||
182 | 185 | ||
183 | /** | 186 | /** |
@@ -200,8 +203,8 @@ static const uint64_t _MHD_itc_wr_data = 1; | |||
200 | */ | 203 | */ |
201 | #define MHD_itc_clear_(itc) do \ | 204 | #define MHD_itc_clear_(itc) do \ |
202 | { long __b; \ | 205 | { long __b; \ |
203 | while(0 < read((itc).fd[0], &__b, sizeof(__b))) \ | 206 | while (0 < read ((itc).fd[0], &__b, sizeof(__b))) \ |
204 | {} } while(0) | 207 | {} } while (0) |
205 | 208 | ||
206 | /** | 209 | /** |
207 | * Destroy previously initialised ITC | 210 | * Destroy previously initialised ITC |
@@ -210,8 +213,8 @@ static const uint64_t _MHD_itc_wr_data = 1; | |||
210 | */ | 213 | */ |
211 | #define MHD_itc_destroy_(itc) \ | 214 | #define MHD_itc_destroy_(itc) \ |
212 | ( (0 == close ((itc).fd[0])) ? \ | 215 | ( (0 == close ((itc).fd[0])) ? \ |
213 | (0 == close ((itc).fd[1])) : \ | 216 | (0 == close ((itc).fd[1])) : \ |
214 | ((close ((itc).fd[1])), 0) ) | 217 | ((close ((itc).fd[1])), 0) ) |
215 | 218 | ||
216 | /** | 219 | /** |
217 | * Check whether ITC has valid value. | 220 | * Check whether ITC has valid value. |
@@ -231,14 +234,14 @@ static const uint64_t _MHD_itc_wr_data = 1; | |||
231 | #define MHD_itc_set_invalid_(itc) ((itc).fd[0] = (itc).fd[1] = -1) | 234 | #define MHD_itc_set_invalid_(itc) ((itc).fd[0] = (itc).fd[1] = -1) |
232 | 235 | ||
233 | #ifndef HAVE_PIPE2_FUNC | 236 | #ifndef HAVE_PIPE2_FUNC |
234 | /** | 237 | /** |
235 | * Change itc FD options to be non-blocking. | 238 | * Change itc FD options to be non-blocking. |
236 | * | 239 | * |
237 | * @param fd the FD to manipulate | 240 | * @param fd the FD to manipulate |
238 | * @return non-zero if succeeded, zero otherwise | 241 | * @return non-zero if succeeded, zero otherwise |
239 | */ | 242 | */ |
240 | int | 243 | int |
241 | MHD_itc_nonblocking_ (struct MHD_itc_ itc); | 244 | MHD_itc_nonblocking_ (struct MHD_itc_ itc); |
242 | #endif /* ! HAVE_PIPE2_FUNC */ | 245 | #endif /* ! HAVE_PIPE2_FUNC */ |
243 | 246 | ||
244 | 247 | ||
@@ -255,20 +258,20 @@ static const uint64_t _MHD_itc_wr_data = 1; | |||
255 | * @return non-zero if succeeded, zero otherwise | 258 | * @return non-zero if succeeded, zero otherwise |
256 | */ | 259 | */ |
257 | #ifdef MHD_socket_pair_nblk_ | 260 | #ifdef MHD_socket_pair_nblk_ |
258 | # define MHD_itc_init_(itc) MHD_socket_pair_nblk_((itc).sk) | 261 | # define MHD_itc_init_(itc) MHD_socket_pair_nblk_ ((itc).sk) |
259 | #else /* ! MHD_socket_pair_nblk_ */ | 262 | #else /* ! MHD_socket_pair_nblk_ */ |
260 | # define MHD_itc_init_(itc) \ | 263 | # define MHD_itc_init_(itc) \ |
261 | (MHD_socket_pair_((itc).sk) ? \ | 264 | (MHD_socket_pair_ ((itc).sk) ? \ |
262 | (MHD_itc_nonblocking_((itc)) ? \ | 265 | (MHD_itc_nonblocking_ ((itc)) ? \ |
263 | (!0) : \ | 266 | (! 0) : \ |
264 | (MHD_itc_destroy_((itc)), 0) ) \ | 267 | (MHD_itc_destroy_ ((itc)), 0) ) \ |
265 | : (0)) | 268 | : (0)) |
266 | #endif /* ! MHD_socket_pair_nblk_ */ | 269 | #endif /* ! MHD_socket_pair_nblk_ */ |
267 | 270 | ||
268 | /** | 271 | /** |
269 | * Get description string of last error for itc operations. | 272 | * Get description string of last error for itc operations. |
270 | */ | 273 | */ |
271 | #define MHD_itc_last_strerror_() MHD_socket_last_strerr_() | 274 | #define MHD_itc_last_strerror_() MHD_socket_last_strerr_ () |
272 | 275 | ||
273 | /** | 276 | /** |
274 | * Activate signal on @a itc | 277 | * Activate signal on @a itc |
@@ -277,8 +280,8 @@ static const uint64_t _MHD_itc_wr_data = 1; | |||
277 | * @return non-zero if succeeded, zero otherwise | 280 | * @return non-zero if succeeded, zero otherwise |
278 | */ | 281 | */ |
279 | #define MHD_itc_activate_(itc, str) \ | 282 | #define MHD_itc_activate_(itc, str) \ |
280 | ((MHD_send_((itc).sk[1], (str), 1) > 0) || \ | 283 | ((MHD_send_ ((itc).sk[1], (str), 1) > 0) || \ |
281 | (MHD_SCKT_ERR_IS_EAGAIN_(MHD_socket_get_error_()))) | 284 | (MHD_SCKT_ERR_IS_EAGAIN_ (MHD_socket_get_error_ ()))) |
282 | 285 | ||
283 | /** | 286 | /** |
284 | * Return read FD of @a itc which can be used for poll(), select() etc. | 287 | * Return read FD of @a itc which can be used for poll(), select() etc. |
@@ -300,10 +303,10 @@ static const uint64_t _MHD_itc_wr_data = 1; | |||
300 | */ | 303 | */ |
301 | #define MHD_itc_clear_(itc) do \ | 304 | #define MHD_itc_clear_(itc) do \ |
302 | { long __b; \ | 305 | { long __b; \ |
303 | while(0 < recv((itc).sk[0], \ | 306 | while (0 < recv ((itc).sk[0], \ |
304 | (char*)&__b, \ | 307 | (char*) &__b, \ |
305 | sizeof(__b), 0)) \ | 308 | sizeof(__b), 0)) \ |
306 | {} } while(0) | 309 | {} } while (0) |
307 | 310 | ||
308 | /** | 311 | /** |
309 | * Destroy previously initialised ITC | 312 | * Destroy previously initialised ITC |
@@ -311,9 +314,9 @@ static const uint64_t _MHD_itc_wr_data = 1; | |||
311 | * @return non-zero if succeeded, zero otherwise | 314 | * @return non-zero if succeeded, zero otherwise |
312 | */ | 315 | */ |
313 | #define MHD_itc_destroy_(itc) \ | 316 | #define MHD_itc_destroy_(itc) \ |
314 | ( MHD_socket_close_((itc).sk[0]) ? \ | 317 | (MHD_socket_close_ ((itc).sk[0]) ? \ |
315 | MHD_socket_close_((itc).sk[1]) : \ | 318 | MHD_socket_close_ ((itc).sk[1]) : \ |
316 | ((void)MHD_socket_close_((itc).sk[1]), 0) ) | 319 | ((void) MHD_socket_close_ ((itc).sk[1]), 0) ) |
317 | 320 | ||
318 | 321 | ||
319 | /** | 322 | /** |
@@ -331,10 +334,12 @@ static const uint64_t _MHD_itc_wr_data = 1; | |||
331 | * Set @a itc to invalid value. | 334 | * Set @a itc to invalid value. |
332 | * @param itc the itc to set | 335 | * @param itc the itc to set |
333 | */ | 336 | */ |
334 | #define MHD_itc_set_invalid_(itc) ((itc).sk[0] = (itc).sk[1] = MHD_INVALID_SOCKET) | 337 | #define MHD_itc_set_invalid_(itc) ((itc).sk[0] = (itc).sk[1] = \ |
338 | MHD_INVALID_SOCKET) | ||
335 | 339 | ||
336 | #ifndef MHD_socket_pair_nblk_ | 340 | #ifndef MHD_socket_pair_nblk_ |
337 | # define MHD_itc_nonblocking_(pip) (MHD_socket_nonblocking_((pip).sk[0]) && MHD_socket_nonblocking_((pip).sk[1])) | 341 | # define MHD_itc_nonblocking_(pip) (MHD_socket_nonblocking_ ((pip).sk[0]) && \ |
342 | MHD_socket_nonblocking_ ((pip).sk[1])) | ||
338 | #endif /* ! MHD_socket_pair_nblk_ */ | 343 | #endif /* ! MHD_socket_pair_nblk_ */ |
339 | 344 | ||
340 | #endif /* _MHD_ITC_SOCKETPAIR */ | 345 | #endif /* _MHD_ITC_SOCKETPAIR */ |
@@ -345,9 +350,9 @@ static const uint64_t _MHD_itc_wr_data = 1; | |||
345 | * @param itc the itc to destroy | 350 | * @param itc the itc to destroy |
346 | */ | 351 | */ |
347 | #define MHD_itc_destroy_chk_(itc) do { \ | 352 | #define MHD_itc_destroy_chk_(itc) do { \ |
348 | if (!MHD_itc_destroy_(itc)) \ | 353 | if (! MHD_itc_destroy_ (itc)) \ |
349 | MHD_PANIC(_("Failed to destroy ITC.\n")); \ | 354 | MHD_PANIC (_ ("Failed to destroy ITC.\n")); \ |
350 | } while(0) | 355 | } while (0) |
351 | 356 | ||
352 | /** | 357 | /** |
353 | * Check whether ITC has invalid value. | 358 | * Check whether ITC has invalid value. |
@@ -358,6 +363,6 @@ static const uint64_t _MHD_itc_wr_data = 1; | |||
358 | * @return boolean true if @a itc has invalid value, | 363 | * @return boolean true if @a itc has invalid value, |
359 | * boolean false otherwise. | 364 | * boolean false otherwise. |
360 | */ | 365 | */ |
361 | #define MHD_ITC_IS_INVALID_(itc) (! MHD_ITC_IS_VALID_(itc)) | 366 | #define MHD_ITC_IS_INVALID_(itc) (! MHD_ITC_IS_VALID_ (itc)) |
362 | 367 | ||
363 | #endif /* MHD_ITC_H */ | 368 | #endif /* MHD_ITC_H */ |
diff --git a/src/lib/mhd_itc_types.h b/src/lib/mhd_itc_types.h index 04966d36..36d4218b 100644 --- a/src/lib/mhd_itc_types.h +++ b/src/lib/mhd_itc_types.h | |||
@@ -32,7 +32,7 @@ | |||
32 | #include "mhd_options.h" | 32 | #include "mhd_options.h" |
33 | 33 | ||
34 | /* Force socketpair on native W32 */ | 34 | /* Force socketpair on native W32 */ |
35 | #if defined(_WIN32) && !defined(__CYGWIN__) && !defined(_MHD_ITC_SOCKETPAIR) | 35 | #if defined(_WIN32) && ! defined(__CYGWIN__) && ! defined(_MHD_ITC_SOCKETPAIR) |
36 | #error _MHD_ITC_SOCKETPAIR is not defined on naitive W32 platform | 36 | #error _MHD_ITC_SOCKETPAIR is not defined on naitive W32 platform |
37 | #endif /* _WIN32 && !__CYGWIN__ && !_MHD_ITC_SOCKETPAIR */ | 37 | #endif /* _WIN32 && !__CYGWIN__ && !_MHD_ITC_SOCKETPAIR */ |
38 | 38 | ||
diff --git a/src/lib/mhd_limits.h b/src/lib/mhd_limits.h index 41d33a8f..87b41447 100644 --- a/src/lib/mhd_limits.h +++ b/src/lib/mhd_limits.h | |||
@@ -32,17 +32,17 @@ | |||
32 | #include <limits.h> | 32 | #include <limits.h> |
33 | #endif /* HAVE_LIMITS_H */ | 33 | #endif /* HAVE_LIMITS_H */ |
34 | 34 | ||
35 | #define MHD_UNSIGNED_TYPE_MAX_(type) ((type)-1) | 35 | #define MHD_UNSIGNED_TYPE_MAX_(type) ((type) - 1) |
36 | /* Assume 8 bits per byte, no padding bits. */ | 36 | /* Assume 8 bits per byte, no padding bits. */ |
37 | #define MHD_SIGNED_TYPE_MAX_(type) \ | 37 | #define MHD_SIGNED_TYPE_MAX_(type) \ |
38 | ( (type)((( ((type)1) << (sizeof(type)*8 - 2)) - 1)*2 + 1) ) | 38 | ( (type) ((( ((type) 1) << (sizeof(type) * 8 - 2)) - 1) * 2 + 1) ) |
39 | #define MHD_TYPE_IS_SIGNED_(type) (((type)0)>((type)-1)) | 39 | #define MHD_TYPE_IS_SIGNED_(type) (((type) 0)>((type) - 1)) |
40 | 40 | ||
41 | #ifndef UINT_MAX | 41 | #ifndef UINT_MAX |
42 | #ifdef __UINT_MAX__ | 42 | #ifdef __UINT_MAX__ |
43 | #define UINT_MAX __UINT_MAX__ | 43 | #define UINT_MAX __UINT_MAX__ |
44 | #else /* ! __UINT_MAX__ */ | 44 | #else /* ! __UINT_MAX__ */ |
45 | #define UINT_MAX MHD_UNSIGNED_TYPE_MAX_(unsigned int) | 45 | #define UINT_MAX MHD_UNSIGNED_TYPE_MAX_ (unsigned int) |
46 | #endif /* ! __UINT_MAX__ */ | 46 | #endif /* ! __UINT_MAX__ */ |
47 | #endif /* !UINT_MAX */ | 47 | #endif /* !UINT_MAX */ |
48 | 48 | ||
@@ -50,19 +50,19 @@ | |||
50 | #ifdef __LONG_MAX__ | 50 | #ifdef __LONG_MAX__ |
51 | #define LONG_MAX __LONG_MAX__ | 51 | #define LONG_MAX __LONG_MAX__ |
52 | #else /* ! __LONG_MAX__ */ | 52 | #else /* ! __LONG_MAX__ */ |
53 | #define LONG_MAX MHD_SIGNED_TYPE_MAX(long) | 53 | #define LONG_MAX MHD_SIGNED_TYPE_MAX (long) |
54 | #endif /* ! __LONG_MAX__ */ | 54 | #endif /* ! __LONG_MAX__ */ |
55 | #endif /* !OFF_T_MAX */ | 55 | #endif /* !OFF_T_MAX */ |
56 | 56 | ||
57 | #ifndef ULLONG_MAX | 57 | #ifndef ULLONG_MAX |
58 | #define ULLONG_MAX MHD_UNSIGNED_TYPE_MAX_(MHD_UNSIGNED_LONG_LONG) | 58 | #define ULLONG_MAX MHD_UNSIGNED_TYPE_MAX_ (MHD_UNSIGNED_LONG_LONG) |
59 | #endif /* !ULLONG_MAX */ | 59 | #endif /* !ULLONG_MAX */ |
60 | 60 | ||
61 | #ifndef INT32_MAX | 61 | #ifndef INT32_MAX |
62 | #ifdef __INT32_MAX__ | 62 | #ifdef __INT32_MAX__ |
63 | #define INT32_MAX __INT32_MAX__ | 63 | #define INT32_MAX __INT32_MAX__ |
64 | #else /* ! __INT32_MAX__ */ | 64 | #else /* ! __INT32_MAX__ */ |
65 | #define INT32_MAX ((int32_t)0x7FFFFFFF) | 65 | #define INT32_MAX ((int32_t) 0x7FFFFFFF) |
66 | #endif /* ! __INT32_MAX__ */ | 66 | #endif /* ! __INT32_MAX__ */ |
67 | #endif /* !INT32_MAX */ | 67 | #endif /* !INT32_MAX */ |
68 | 68 | ||
@@ -70,7 +70,7 @@ | |||
70 | #ifdef __UINT32_MAX__ | 70 | #ifdef __UINT32_MAX__ |
71 | #define UINT32_MAX __UINT32_MAX__ | 71 | #define UINT32_MAX __UINT32_MAX__ |
72 | #else /* ! __UINT32_MAX__ */ | 72 | #else /* ! __UINT32_MAX__ */ |
73 | #define UINT32_MAX ((int32_t)0xFFFFFFFF) | 73 | #define UINT32_MAX ((int32_t) 0xFFFFFFFF) |
74 | #endif /* ! __UINT32_MAX__ */ | 74 | #endif /* ! __UINT32_MAX__ */ |
75 | #endif /* !UINT32_MAX */ | 75 | #endif /* !UINT32_MAX */ |
76 | 76 | ||
@@ -78,7 +78,7 @@ | |||
78 | #ifdef __UINT64_MAX__ | 78 | #ifdef __UINT64_MAX__ |
79 | #define UINT64_MAX __UINT64_MAX__ | 79 | #define UINT64_MAX __UINT64_MAX__ |
80 | #else /* ! __UINT64_MAX__ */ | 80 | #else /* ! __UINT64_MAX__ */ |
81 | #define UINT64_MAX ((uint64_t)0xFFFFFFFFFFFFFFFF) | 81 | #define UINT64_MAX ((uint64_t) 0xFFFFFFFFFFFFFFFF) |
82 | #endif /* ! __UINT64_MAX__ */ | 82 | #endif /* ! __UINT64_MAX__ */ |
83 | #endif /* !UINT64_MAX */ | 83 | #endif /* !UINT64_MAX */ |
84 | 84 | ||
@@ -86,7 +86,7 @@ | |||
86 | #ifdef __INT64_MAX__ | 86 | #ifdef __INT64_MAX__ |
87 | #define INT64_MAX __INT64_MAX__ | 87 | #define INT64_MAX __INT64_MAX__ |
88 | #else /* ! __INT64_MAX__ */ | 88 | #else /* ! __INT64_MAX__ */ |
89 | #define INT64_MAX ((int64_t)0x7FFFFFFFFFFFFFFF) | 89 | #define INT64_MAX ((int64_t) 0x7FFFFFFFFFFFFFFF) |
90 | #endif /* ! __UINT64_MAX__ */ | 90 | #endif /* ! __UINT64_MAX__ */ |
91 | #endif /* !INT64_MAX */ | 91 | #endif /* !INT64_MAX */ |
92 | 92 | ||
@@ -96,8 +96,8 @@ | |||
96 | #elif defined(UINTPTR_MAX) | 96 | #elif defined(UINTPTR_MAX) |
97 | #define SIZE_MAX UINTPTR_MAX | 97 | #define SIZE_MAX UINTPTR_MAX |
98 | #else /* ! __SIZE_MAX__ */ | 98 | #else /* ! __SIZE_MAX__ */ |
99 | #define SIZE_MAX MHD_UNSIGNED_TYPE_MAX_(size_t) | 99 | #define SIZE_MAX MHD_UNSIGNED_TYPE_MAX_ (size_t) |
100 | #endif /* ! __SIZE_MAX__ */ | 100 | #endif /* ! __SIZE_MAX__ */ |
101 | #endif /* !SIZE_MAX */ | 101 | #endif /* !SIZE_MAX */ |
102 | 102 | ||
103 | #ifndef SSIZE_MAX | 103 | #ifndef SSIZE_MAX |
@@ -108,7 +108,7 @@ | |||
108 | #elif defined(INTPTR_MAX) | 108 | #elif defined(INTPTR_MAX) |
109 | #define SSIZE_MAX INTPTR_MAX | 109 | #define SSIZE_MAX INTPTR_MAX |
110 | #else | 110 | #else |
111 | #define SSIZE_MAN MHD_SIGNED_TYPE_MAX_(ssize_t) | 111 | #define SSIZE_MAN MHD_SIGNED_TYPE_MAX_ (ssize_t) |
112 | #endif | 112 | #endif |
113 | #endif /* ! SSIZE_MAX */ | 113 | #endif /* ! SSIZE_MAX */ |
114 | 114 | ||
@@ -120,19 +120,19 @@ | |||
120 | #elif defined(__APPLE__) && defined(__MACH__) | 120 | #elif defined(__APPLE__) && defined(__MACH__) |
121 | #define OFF_T_MAX INT64_MAX | 121 | #define OFF_T_MAX INT64_MAX |
122 | #else | 122 | #else |
123 | #define OFF_T_MAX MHD_SIGNED_TYPE_MAX_(off_t) | 123 | #define OFF_T_MAX MHD_SIGNED_TYPE_MAX_ (off_t) |
124 | #endif | 124 | #endif |
125 | #endif /* !OFF_T_MAX */ | 125 | #endif /* !OFF_T_MAX */ |
126 | 126 | ||
127 | #if defined(_LARGEFILE64_SOURCE) && !defined(OFF64_T_MAX) | 127 | #if defined(_LARGEFILE64_SOURCE) && ! defined(OFF64_T_MAX) |
128 | #define OFF64_T_MAX MHD_SIGNED_TYPE_MAX_(uint64_t) | 128 | #define OFF64_T_MAX MHD_SIGNED_TYPE_MAX_ (uint64_t) |
129 | #endif /* _LARGEFILE64_SOURCE && !OFF64_T_MAX */ | 129 | #endif /* _LARGEFILE64_SOURCE && !OFF64_T_MAX */ |
130 | 130 | ||
131 | #ifndef TIME_T_MAX | 131 | #ifndef TIME_T_MAX |
132 | #define TIME_T_MAX ((time_t) \ | 132 | #define TIME_T_MAX ((time_t) \ |
133 | ( MHD_TYPE_IS_SIGNED_(time_t) ? \ | 133 | (MHD_TYPE_IS_SIGNED_ (time_t) ? \ |
134 | MHD_SIGNED_TYPE_MAX_(time_t) : \ | 134 | MHD_SIGNED_TYPE_MAX_ (time_t) : \ |
135 | MHD_UNSIGNED_TYPE_MAX_(time_t))) | 135 | MHD_UNSIGNED_TYPE_MAX_ (time_t))) |
136 | #endif /* !TIME_T_MAX */ | 136 | #endif /* !TIME_T_MAX */ |
137 | 137 | ||
138 | #ifndef TIMEVAL_TV_SEC_MAX | 138 | #ifndef TIMEVAL_TV_SEC_MAX |
diff --git a/src/lib/mhd_locks.h b/src/lib/mhd_locks.h index 21db56c4..8c9b0844 100644 --- a/src/lib/mhd_locks.h +++ b/src/lib/mhd_locks.h | |||
@@ -59,14 +59,15 @@ | |||
59 | # include <stdlib.h> | 59 | # include <stdlib.h> |
60 | /* Simple implementation of MHD_PANIC, to be used outside lib */ | 60 | /* Simple implementation of MHD_PANIC, to be used outside lib */ |
61 | # define MHD_PANIC(msg) do { fprintf (stderr, \ | 61 | # define MHD_PANIC(msg) do { fprintf (stderr, \ |
62 | "Abnormal termination at %d line in file %s: %s\n", \ | 62 | "Abnormal termination at %d line in file %s: %s\n", \ |
63 | (int)__LINE__, __FILE__, msg); abort();} while(0) | 63 | (int) __LINE__, __FILE__, msg); abort (); \ |
64 | } while (0) | ||
64 | #endif /* ! MHD_PANIC */ | 65 | #endif /* ! MHD_PANIC */ |
65 | 66 | ||
66 | #if defined(MHD_PTHREAD_MUTEX_) | 67 | #if defined(MHD_PTHREAD_MUTEX_) |
67 | typedef pthread_mutex_t MHD_mutex_; | 68 | typedef pthread_mutex_t MHD_mutex_; |
68 | #elif defined(MHD_W32_MUTEX_) | 69 | #elif defined(MHD_W32_MUTEX_) |
69 | typedef CRITICAL_SECTION MHD_mutex_; | 70 | typedef CRITICAL_SECTION MHD_mutex_; |
70 | #endif | 71 | #endif |
71 | 72 | ||
72 | #if defined(MHD_PTHREAD_MUTEX_) | 73 | #if defined(MHD_PTHREAD_MUTEX_) |
@@ -75,14 +76,15 @@ | |||
75 | * @param pmutex pointer to the mutex | 76 | * @param pmutex pointer to the mutex |
76 | * @return nonzero on success, zero otherwise | 77 | * @return nonzero on success, zero otherwise |
77 | */ | 78 | */ |
78 | #define MHD_mutex_init_(pmutex) (!(pthread_mutex_init((pmutex), NULL))) | 79 | #define MHD_mutex_init_(pmutex) (! (pthread_mutex_init ((pmutex), NULL))) |
79 | #elif defined(MHD_W32_MUTEX_) | 80 | #elif defined(MHD_W32_MUTEX_) |
80 | /** | 81 | /** |
81 | * Initialise new mutex. | 82 | * Initialise new mutex. |
82 | * @param pmutex pointer to mutex | 83 | * @param pmutex pointer to mutex |
83 | * @return nonzero on success, zero otherwise | 84 | * @return nonzero on success, zero otherwise |
84 | */ | 85 | */ |
85 | #define MHD_mutex_init_(pmutex) (InitializeCriticalSectionAndSpinCount((pmutex),16)) | 86 | #define MHD_mutex_init_(pmutex) (InitializeCriticalSectionAndSpinCount ( \ |
87 | (pmutex),16)) | ||
86 | #endif | 88 | #endif |
87 | 89 | ||
88 | #if defined(MHD_PTHREAD_MUTEX_) | 90 | #if defined(MHD_PTHREAD_MUTEX_) |
@@ -90,7 +92,8 @@ | |||
90 | /** | 92 | /** |
91 | * Define static mutex and statically initialise it. | 93 | * Define static mutex and statically initialise it. |
92 | */ | 94 | */ |
93 | # define MHD_MUTEX_STATIC_DEFN_INIT_(m) static MHD_mutex_ m = PTHREAD_MUTEX_INITIALIZER | 95 | # define MHD_MUTEX_STATIC_DEFN_INIT_(m) static MHD_mutex_ m = \ |
96 | PTHREAD_MUTEX_INITIALIZER | ||
94 | # endif /* PTHREAD_MUTEX_INITIALIZER */ | 97 | # endif /* PTHREAD_MUTEX_INITIALIZER */ |
95 | #endif | 98 | #endif |
96 | 99 | ||
@@ -100,14 +103,14 @@ | |||
100 | * @param pmutex pointer to mutex | 103 | * @param pmutex pointer to mutex |
101 | * @return nonzero on success, zero otherwise | 104 | * @return nonzero on success, zero otherwise |
102 | */ | 105 | */ |
103 | #define MHD_mutex_destroy_(pmutex) (!(pthread_mutex_destroy((pmutex)))) | 106 | #define MHD_mutex_destroy_(pmutex) (! (pthread_mutex_destroy ((pmutex)))) |
104 | #elif defined(MHD_W32_MUTEX_) | 107 | #elif defined(MHD_W32_MUTEX_) |
105 | /** | 108 | /** |
106 | * Destroy previously initialised mutex. | 109 | * Destroy previously initialised mutex. |
107 | * @param pmutex pointer to mutex | 110 | * @param pmutex pointer to mutex |
108 | * @return Always nonzero | 111 | * @return Always nonzero |
109 | */ | 112 | */ |
110 | #define MHD_mutex_destroy_(pmutex) (DeleteCriticalSection((pmutex)), !0) | 113 | #define MHD_mutex_destroy_(pmutex) (DeleteCriticalSection ((pmutex)), ! 0) |
111 | #endif | 114 | #endif |
112 | 115 | ||
113 | /** | 116 | /** |
@@ -116,9 +119,9 @@ | |||
116 | * @param pmutex pointer to mutex | 119 | * @param pmutex pointer to mutex |
117 | */ | 120 | */ |
118 | #define MHD_mutex_destroy_chk_(pmutex) do { \ | 121 | #define MHD_mutex_destroy_chk_(pmutex) do { \ |
119 | if (!MHD_mutex_destroy_(pmutex)) \ | 122 | if (! MHD_mutex_destroy_ (pmutex)) \ |
120 | MHD_PANIC(_("Failed to destroy mutex.\n")); \ | 123 | MHD_PANIC (_ ("Failed to destroy mutex.\n")); \ |
121 | } while(0) | 124 | } while (0) |
122 | 125 | ||
123 | 126 | ||
124 | #if defined(MHD_PTHREAD_MUTEX_) | 127 | #if defined(MHD_PTHREAD_MUTEX_) |
@@ -129,7 +132,7 @@ | |||
129 | * @param pmutex pointer to mutex | 132 | * @param pmutex pointer to mutex |
130 | * @return nonzero on success, zero otherwise | 133 | * @return nonzero on success, zero otherwise |
131 | */ | 134 | */ |
132 | #define MHD_mutex_lock_(pmutex) (!(pthread_mutex_lock((pmutex)))) | 135 | #define MHD_mutex_lock_(pmutex) (! (pthread_mutex_lock ((pmutex)))) |
133 | #elif defined(MHD_W32_MUTEX_) | 136 | #elif defined(MHD_W32_MUTEX_) |
134 | /** | 137 | /** |
135 | * Acquire lock on previously initialised mutex. | 138 | * Acquire lock on previously initialised mutex. |
@@ -138,7 +141,7 @@ | |||
138 | * @param pmutex pointer to mutex | 141 | * @param pmutex pointer to mutex |
139 | * @return Always nonzero | 142 | * @return Always nonzero |
140 | */ | 143 | */ |
141 | #define MHD_mutex_lock_(pmutex) (EnterCriticalSection((pmutex)), !0) | 144 | #define MHD_mutex_lock_(pmutex) (EnterCriticalSection ((pmutex)), ! 0) |
142 | #endif | 145 | #endif |
143 | 146 | ||
144 | /** | 147 | /** |
@@ -149,9 +152,9 @@ | |||
149 | * @param pmutex pointer to mutex | 152 | * @param pmutex pointer to mutex |
150 | */ | 153 | */ |
151 | #define MHD_mutex_lock_chk_(pmutex) do { \ | 154 | #define MHD_mutex_lock_chk_(pmutex) do { \ |
152 | if (!MHD_mutex_lock_(pmutex)) \ | 155 | if (! MHD_mutex_lock_ (pmutex)) \ |
153 | MHD_PANIC(_("Failed to lock mutex.\n")); \ | 156 | MHD_PANIC (_ ("Failed to lock mutex.\n")); \ |
154 | } while(0) | 157 | } while (0) |
155 | 158 | ||
156 | #if defined(MHD_PTHREAD_MUTEX_) | 159 | #if defined(MHD_PTHREAD_MUTEX_) |
157 | /** | 160 | /** |
@@ -159,14 +162,14 @@ | |||
159 | * @param pmutex pointer to mutex | 162 | * @param pmutex pointer to mutex |
160 | * @return nonzero on success, zero otherwise | 163 | * @return nonzero on success, zero otherwise |
161 | */ | 164 | */ |
162 | #define MHD_mutex_unlock_(pmutex) (!(pthread_mutex_unlock((pmutex)))) | 165 | #define MHD_mutex_unlock_(pmutex) (! (pthread_mutex_unlock ((pmutex)))) |
163 | #elif defined(MHD_W32_MUTEX_) | 166 | #elif defined(MHD_W32_MUTEX_) |
164 | /** | 167 | /** |
165 | * Unlock previously initialised and locked mutex. | 168 | * Unlock previously initialised and locked mutex. |
166 | * @param pmutex pointer to mutex | 169 | * @param pmutex pointer to mutex |
167 | * @return Always nonzero | 170 | * @return Always nonzero |
168 | */ | 171 | */ |
169 | #define MHD_mutex_unlock_(pmutex) (LeaveCriticalSection((pmutex)), !0) | 172 | #define MHD_mutex_unlock_(pmutex) (LeaveCriticalSection ((pmutex)), ! 0) |
170 | #endif | 173 | #endif |
171 | 174 | ||
172 | /** | 175 | /** |
@@ -175,9 +178,9 @@ | |||
175 | * @param pmutex pointer to mutex | 178 | * @param pmutex pointer to mutex |
176 | */ | 179 | */ |
177 | #define MHD_mutex_unlock_chk_(pmutex) do { \ | 180 | #define MHD_mutex_unlock_chk_(pmutex) do { \ |
178 | if (!MHD_mutex_unlock_(pmutex)) \ | 181 | if (! MHD_mutex_unlock_ (pmutex)) \ |
179 | MHD_PANIC(_("Failed to unlock mutex.\n")); \ | 182 | MHD_PANIC (_ ("Failed to unlock mutex.\n")); \ |
180 | } while(0) | 183 | } while (0) |
181 | 184 | ||
182 | 185 | ||
183 | #endif /* ! MHD_LOCKS_H */ | 186 | #endif /* ! MHD_LOCKS_H */ |
diff --git a/src/lib/mhd_mono_clock.c b/src/lib/mhd_mono_clock.c index 97dbfb9f..eee911fb 100644 --- a/src/lib/mhd_mono_clock.c +++ b/src/lib/mhd_mono_clock.c | |||
@@ -76,7 +76,8 @@ static clockid_t mono_clock_id = _MHD_UNWANTED_CLOCK; | |||
76 | #endif /* HAVE_CLOCK_GETTIME */ | 76 | #endif /* HAVE_CLOCK_GETTIME */ |
77 | 77 | ||
78 | /* sync clocks; reduce chance of value wrap */ | 78 | /* sync clocks; reduce chance of value wrap */ |
79 | #if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_CLOCK_GET_TIME) || defined(HAVE_GETHRTIME) | 79 | #if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_CLOCK_GET_TIME) || \ |
80 | defined(HAVE_GETHRTIME) | ||
80 | static time_t mono_clock_start; | 81 | static time_t mono_clock_start; |
81 | #endif /* HAVE_CLOCK_GETTIME || HAVE_CLOCK_GET_TIME || HAVE_GETHRTIME */ | 82 | #endif /* HAVE_CLOCK_GETTIME || HAVE_CLOCK_GET_TIME || HAVE_GETHRTIME */ |
82 | static time_t sys_clock_start; | 83 | static time_t sys_clock_start; |
@@ -124,9 +125,9 @@ enum _MHD_mono_clock_source | |||
124 | */ | 125 | */ |
125 | _MHD_CLOCK_GETTICKCOUNT64, | 126 | _MHD_CLOCK_GETTICKCOUNT64, |
126 | 127 | ||
127 | /** | 128 | /** |
128 | * QueryPerformanceCounter() / QueryPerformanceFrequency() | 129 | * QueryPerformanceCounter() / QueryPerformanceFrequency() |
129 | */ | 130 | */ |
130 | _MHD_CLOCK_PERFCOUNTER | 131 | _MHD_CLOCK_PERFCOUNTER |
131 | }; | 132 | }; |
132 | 133 | ||
@@ -153,8 +154,8 @@ MHD_monotonic_sec_counter_init (void) | |||
153 | /* just a little syntactic trick to get the | 154 | /* just a little syntactic trick to get the |
154 | various following ifdef's to work out nicely */ | 155 | various following ifdef's to work out nicely */ |
155 | if (0) | 156 | if (0) |
156 | { | 157 | { |
157 | } | 158 | } |
158 | else | 159 | else |
159 | #ifdef HAVE_CLOCK_GETTIME | 160 | #ifdef HAVE_CLOCK_GETTIME |
160 | #ifdef CLOCK_MONOTONIC_COARSE | 161 | #ifdef CLOCK_MONOTONIC_COARSE |
@@ -163,11 +164,11 @@ MHD_monotonic_sec_counter_init (void) | |||
163 | /* but preferred since it's fast */ | 164 | /* but preferred since it's fast */ |
164 | if (0 == clock_gettime (CLOCK_MONOTONIC_COARSE, | 165 | if (0 == clock_gettime (CLOCK_MONOTONIC_COARSE, |
165 | &ts)) | 166 | &ts)) |
166 | { | 167 | { |
167 | mono_clock_id = CLOCK_MONOTONIC_COARSE; | 168 | mono_clock_id = CLOCK_MONOTONIC_COARSE; |
168 | mono_clock_start = ts.tv_sec; | 169 | mono_clock_start = ts.tv_sec; |
169 | mono_clock_source = _MHD_CLOCK_GETTIME; | 170 | mono_clock_source = _MHD_CLOCK_GETTIME; |
170 | } | 171 | } |
171 | else | 172 | else |
172 | #endif /* CLOCK_MONOTONIC_COARSE */ | 173 | #endif /* CLOCK_MONOTONIC_COARSE */ |
173 | #ifdef CLOCK_MONOTONIC_FAST | 174 | #ifdef CLOCK_MONOTONIC_FAST |
@@ -175,11 +176,11 @@ MHD_monotonic_sec_counter_init (void) | |||
175 | /* Can be affected by frequency adjustment, but preferred since it's fast */ | 176 | /* Can be affected by frequency adjustment, but preferred since it's fast */ |
176 | if (0 == clock_gettime (CLOCK_MONOTONIC_FAST, | 177 | if (0 == clock_gettime (CLOCK_MONOTONIC_FAST, |
177 | &ts)) | 178 | &ts)) |
178 | { | 179 | { |
179 | mono_clock_id = CLOCK_MONOTONIC_FAST; | 180 | mono_clock_id = CLOCK_MONOTONIC_FAST; |
180 | mono_clock_start = ts.tv_sec; | 181 | mono_clock_start = ts.tv_sec; |
181 | mono_clock_source = _MHD_CLOCK_GETTIME; | 182 | mono_clock_source = _MHD_CLOCK_GETTIME; |
182 | } | 183 | } |
183 | else | 184 | else |
184 | #endif /* CLOCK_MONOTONIC_COARSE */ | 185 | #endif /* CLOCK_MONOTONIC_COARSE */ |
185 | #ifdef CLOCK_MONOTONIC_RAW | 186 | #ifdef CLOCK_MONOTONIC_RAW |
@@ -187,11 +188,11 @@ MHD_monotonic_sec_counter_init (void) | |||
187 | /* Not affected by frequency adjustment, but don't count time in suspend */ | 188 | /* Not affected by frequency adjustment, but don't count time in suspend */ |
188 | if (0 == clock_gettime (CLOCK_MONOTONIC_RAW, | 189 | if (0 == clock_gettime (CLOCK_MONOTONIC_RAW, |
189 | &ts)) | 190 | &ts)) |
190 | { | 191 | { |
191 | mono_clock_id = CLOCK_MONOTONIC_RAW; | 192 | mono_clock_id = CLOCK_MONOTONIC_RAW; |
192 | mono_clock_start = ts.tv_sec; | 193 | mono_clock_start = ts.tv_sec; |
193 | mono_clock_source = _MHD_CLOCK_GETTIME; | 194 | mono_clock_source = _MHD_CLOCK_GETTIME; |
194 | } | 195 | } |
195 | else | 196 | else |
196 | #endif /* CLOCK_MONOTONIC_RAW */ | 197 | #endif /* CLOCK_MONOTONIC_RAW */ |
197 | #ifdef CLOCK_BOOTTIME | 198 | #ifdef CLOCK_BOOTTIME |
@@ -200,11 +201,11 @@ MHD_monotonic_sec_counter_init (void) | |||
200 | /* but can be slower value-getting than other clocks */ | 201 | /* but can be slower value-getting than other clocks */ |
201 | if (0 == clock_gettime (CLOCK_BOOTTIME, | 202 | if (0 == clock_gettime (CLOCK_BOOTTIME, |
202 | &ts)) | 203 | &ts)) |
203 | { | 204 | { |
204 | mono_clock_id = CLOCK_BOOTTIME; | 205 | mono_clock_id = CLOCK_BOOTTIME; |
205 | mono_clock_start = ts.tv_sec; | 206 | mono_clock_start = ts.tv_sec; |
206 | mono_clock_source = _MHD_CLOCK_GETTIME; | 207 | mono_clock_source = _MHD_CLOCK_GETTIME; |
207 | } | 208 | } |
208 | else | 209 | else |
209 | #endif /* CLOCK_BOOTTIME */ | 210 | #endif /* CLOCK_BOOTTIME */ |
210 | #ifdef CLOCK_MONOTONIC | 211 | #ifdef CLOCK_MONOTONIC |
@@ -213,11 +214,11 @@ MHD_monotonic_sec_counter_init (void) | |||
213 | /* On Linux it's not truly monotonic as it doesn't count time in suspend */ | 214 | /* On Linux it's not truly monotonic as it doesn't count time in suspend */ |
214 | if (0 == clock_gettime (CLOCK_MONOTONIC, | 215 | if (0 == clock_gettime (CLOCK_MONOTONIC, |
215 | &ts)) | 216 | &ts)) |
216 | { | 217 | { |
217 | mono_clock_id = CLOCK_MONOTONIC; | 218 | mono_clock_id = CLOCK_MONOTONIC; |
218 | mono_clock_start = ts.tv_sec; | 219 | mono_clock_start = ts.tv_sec; |
219 | mono_clock_source = _MHD_CLOCK_GETTIME; | 220 | mono_clock_source = _MHD_CLOCK_GETTIME; |
220 | } | 221 | } |
221 | else | 222 | else |
222 | #endif /* CLOCK_BOOTTIME */ | 223 | #endif /* CLOCK_BOOTTIME */ |
223 | #endif /* HAVE_CLOCK_GETTIME */ | 224 | #endif /* HAVE_CLOCK_GETTIME */ |
@@ -225,15 +226,15 @@ MHD_monotonic_sec_counter_init (void) | |||
225 | /* Darwin-specific monotonic clock */ | 226 | /* Darwin-specific monotonic clock */ |
226 | /* Should be monotonic as clock_set_time function always unconditionally */ | 227 | /* Should be monotonic as clock_set_time function always unconditionally */ |
227 | /* failed on latest kernels */ | 228 | /* failed on latest kernels */ |
228 | if ( (KERN_SUCCESS == host_get_clock_service (mach_host_self(), | 229 | if ( (KERN_SUCCESS == host_get_clock_service (mach_host_self (), |
229 | SYSTEM_CLOCK, | 230 | SYSTEM_CLOCK, |
230 | &mono_clock_service)) && | 231 | &mono_clock_service)) && |
231 | (KERN_SUCCESS == clock_get_time (mono_clock_service, | 232 | (KERN_SUCCESS == clock_get_time (mono_clock_service, |
232 | &cur_time)) ) | 233 | &cur_time)) ) |
233 | { | 234 | { |
234 | mono_clock_start = cur_time.tv_sec; | 235 | mono_clock_start = cur_time.tv_sec; |
235 | mono_clock_source = _MHD_CLOCK_GET_TIME; | 236 | mono_clock_source = _MHD_CLOCK_GET_TIME; |
236 | } | 237 | } |
237 | else | 238 | else |
238 | #endif /* HAVE_CLOCK_GET_TIME */ | 239 | #endif /* HAVE_CLOCK_GET_TIME */ |
239 | #ifdef _WIN32 | 240 | #ifdef _WIN32 |
@@ -241,25 +242,25 @@ MHD_monotonic_sec_counter_init (void) | |||
241 | /* W32 Vista or later specific monotonic clock */ | 242 | /* W32 Vista or later specific monotonic clock */ |
242 | /* Available since Vista, ~15ms accuracy */ | 243 | /* Available since Vista, ~15ms accuracy */ |
243 | if (1) | 244 | if (1) |
244 | { | 245 | { |
245 | tick_start = GetTickCount64 (); | 246 | tick_start = GetTickCount64 (); |
246 | mono_clock_source = _MHD_CLOCK_GETTICKCOUNT64; | 247 | mono_clock_source = _MHD_CLOCK_GETTICKCOUNT64; |
247 | } | 248 | } |
248 | else | 249 | else |
249 | #else /* _WIN32_WINNT < 0x0600 */ | 250 | #else /* _WIN32_WINNT < 0x0600 */ |
250 | /* W32 specific monotonic clock */ | 251 | /* W32 specific monotonic clock */ |
251 | /* Available on Windows 2000 and later */ | 252 | /* Available on Windows 2000 and later */ |
252 | if (1) | 253 | if (1) |
253 | { | 254 | { |
254 | LARGE_INTEGER freq; | 255 | LARGE_INTEGER freq; |
255 | LARGE_INTEGER perf_counter; | 256 | LARGE_INTEGER perf_counter; |
256 | 257 | ||
257 | QueryPerformanceFrequency (&freq); /* never fail on XP and later */ | 258 | QueryPerformanceFrequency (&freq); /* never fail on XP and later */ |
258 | QueryPerformanceCounter (&perf_counter); /* never fail on XP and later */ | 259 | QueryPerformanceCounter (&perf_counter); /* never fail on XP and later */ |
259 | perf_freq = freq.QuadPart; | 260 | perf_freq = freq.QuadPart; |
260 | perf_start = perf_counter.QuadPart; | 261 | perf_start = perf_counter.QuadPart; |
261 | mono_clock_source = _MHD_CLOCK_PERFCOUNTER; | 262 | mono_clock_source = _MHD_CLOCK_PERFCOUNTER; |
262 | } | 263 | } |
263 | else | 264 | else |
264 | #endif /* _WIN32_WINNT < 0x0600 */ | 265 | #endif /* _WIN32_WINNT < 0x0600 */ |
265 | #endif /* _WIN32 */ | 266 | #endif /* _WIN32 */ |
@@ -269,11 +270,11 @@ MHD_monotonic_sec_counter_init (void) | |||
269 | /* Not preferred due to be potentially resource-hungry */ | 270 | /* Not preferred due to be potentially resource-hungry */ |
270 | if (0 == clock_gettime (CLOCK_HIGHRES, | 271 | if (0 == clock_gettime (CLOCK_HIGHRES, |
271 | &ts)) | 272 | &ts)) |
272 | { | 273 | { |
273 | mono_clock_id = CLOCK_HIGHRES; | 274 | mono_clock_id = CLOCK_HIGHRES; |
274 | mono_clock_start = ts.tv_sec; | 275 | mono_clock_start = ts.tv_sec; |
275 | mono_clock_source = _MHD_CLOCK_GETTIME; | 276 | mono_clock_source = _MHD_CLOCK_GETTIME; |
276 | } | 277 | } |
277 | else | 278 | else |
278 | #endif /* CLOCK_HIGHRES */ | 279 | #endif /* CLOCK_HIGHRES */ |
279 | #endif /* HAVE_CLOCK_GETTIME */ | 280 | #endif /* HAVE_CLOCK_GETTIME */ |
@@ -281,26 +282,26 @@ MHD_monotonic_sec_counter_init (void) | |||
281 | /* HP-UX and Solaris monotonic clock */ | 282 | /* HP-UX and Solaris monotonic clock */ |
282 | /* Not preferred due to be potentially resource-hungry */ | 283 | /* Not preferred due to be potentially resource-hungry */ |
283 | if (1) | 284 | if (1) |
284 | { | 285 | { |
285 | hrtime_start = gethrtime (); | 286 | hrtime_start = gethrtime (); |
286 | mono_clock_source = _MHD_CLOCK_GETHRTIME; | 287 | mono_clock_source = _MHD_CLOCK_GETHRTIME; |
287 | } | 288 | } |
288 | else | 289 | else |
289 | #endif /* HAVE_GETHRTIME */ | 290 | #endif /* HAVE_GETHRTIME */ |
290 | { | 291 | { |
291 | /* no suitable clock source was found */ | 292 | /* no suitable clock source was found */ |
292 | mono_clock_source = _MHD_CLOCK_NO_SOURCE; | 293 | mono_clock_source = _MHD_CLOCK_NO_SOURCE; |
293 | } | 294 | } |
294 | 295 | ||
295 | #ifdef HAVE_CLOCK_GET_TIME | 296 | #ifdef HAVE_CLOCK_GET_TIME |
296 | if ( (_MHD_CLOCK_GET_TIME != mono_clock_source) && | 297 | if ( (_MHD_CLOCK_GET_TIME != mono_clock_source) && |
297 | (_MHD_INVALID_CLOCK_SERV != mono_clock_service) ) | 298 | (_MHD_INVALID_CLOCK_SERV != mono_clock_service) ) |
298 | { | 299 | { |
299 | /* clock service was initialised but clock_get_time failed */ | 300 | /* clock service was initialised but clock_get_time failed */ |
300 | mach_port_deallocate (mach_task_self(), | 301 | mach_port_deallocate (mach_task_self (), |
301 | mono_clock_service); | 302 | mono_clock_service); |
302 | mono_clock_service = _MHD_INVALID_CLOCK_SERV; | 303 | mono_clock_service = _MHD_INVALID_CLOCK_SERV; |
303 | } | 304 | } |
304 | #else | 305 | #else |
305 | (void) mono_clock_source; /* avoid compiler warning */ | 306 | (void) mono_clock_source; /* avoid compiler warning */ |
306 | #endif /* HAVE_CLOCK_GET_TIME */ | 307 | #endif /* HAVE_CLOCK_GET_TIME */ |
@@ -317,11 +318,11 @@ MHD_monotonic_sec_counter_finish (void) | |||
317 | { | 318 | { |
318 | #ifdef HAVE_CLOCK_GET_TIME | 319 | #ifdef HAVE_CLOCK_GET_TIME |
319 | if (_MHD_INVALID_CLOCK_SERV != mono_clock_service) | 320 | if (_MHD_INVALID_CLOCK_SERV != mono_clock_service) |
320 | { | 321 | { |
321 | mach_port_deallocate (mach_task_self(), | 322 | mach_port_deallocate (mach_task_self (), |
322 | mono_clock_service); | 323 | mono_clock_service); |
323 | mono_clock_service = _MHD_INVALID_CLOCK_SERV; | 324 | mono_clock_service = _MHD_INVALID_CLOCK_SERV; |
324 | } | 325 | } |
325 | #endif /* HAVE_CLOCK_GET_TIME */ | 326 | #endif /* HAVE_CLOCK_GET_TIME */ |
326 | } | 327 | } |
327 | 328 | ||
@@ -340,37 +341,38 @@ MHD_monotonic_sec_counter (void) | |||
340 | struct timespec ts; | 341 | struct timespec ts; |
341 | 342 | ||
342 | if ( (_MHD_UNWANTED_CLOCK != mono_clock_id) && | 343 | if ( (_MHD_UNWANTED_CLOCK != mono_clock_id) && |
343 | (0 == clock_gettime (mono_clock_id , | 344 | (0 == clock_gettime (mono_clock_id, |
344 | &ts)) ) | 345 | &ts)) ) |
345 | return ts.tv_sec - mono_clock_start; | 346 | return ts.tv_sec - mono_clock_start; |
346 | #endif /* HAVE_CLOCK_GETTIME */ | 347 | #endif /* HAVE_CLOCK_GETTIME */ |
347 | #ifdef HAVE_CLOCK_GET_TIME | 348 | #ifdef HAVE_CLOCK_GET_TIME |
348 | if (_MHD_INVALID_CLOCK_SERV != mono_clock_service) | 349 | if (_MHD_INVALID_CLOCK_SERV != mono_clock_service) |
349 | { | 350 | { |
350 | mach_timespec_t cur_time; | 351 | mach_timespec_t cur_time; |
351 | 352 | ||
352 | if (KERN_SUCCESS == clock_get_time(mono_clock_service, | 353 | if (KERN_SUCCESS == clock_get_time (mono_clock_service, |
353 | &cur_time)) | 354 | &cur_time)) |
354 | return cur_time.tv_sec - mono_clock_start; | 355 | return cur_time.tv_sec - mono_clock_start; |
355 | } | 356 | } |
356 | #endif /* HAVE_CLOCK_GET_TIME */ | 357 | #endif /* HAVE_CLOCK_GET_TIME */ |
357 | #if defined(_WIN32) | 358 | #if defined(_WIN32) |
358 | #if _WIN32_WINNT >= 0x0600 | 359 | #if _WIN32_WINNT >= 0x0600 |
359 | if (1) | 360 | if (1) |
360 | return (time_t)(((uint64_t)(GetTickCount64() - tick_start)) / 1000); | 361 | return (time_t) (((uint64_t) (GetTickCount64 () - tick_start)) / 1000); |
361 | #else /* _WIN32_WINNT < 0x0600 */ | 362 | #else /* _WIN32_WINNT < 0x0600 */ |
362 | if (0 != perf_freq) | 363 | if (0 != perf_freq) |
363 | { | 364 | { |
364 | LARGE_INTEGER perf_counter; | 365 | LARGE_INTEGER perf_counter; |
365 | 366 | ||
366 | QueryPerformanceCounter (&perf_counter); /* never fail on XP and later */ | 367 | QueryPerformanceCounter (&perf_counter); /* never fail on XP and later */ |
367 | return (time_t)(((uint64_t)(perf_counter.QuadPart - perf_start)) / perf_freq); | 368 | return (time_t) (((uint64_t) (perf_counter.QuadPart - perf_start)) |
368 | } | 369 | / perf_freq); |
370 | } | ||
369 | #endif /* _WIN32_WINNT < 0x0600 */ | 371 | #endif /* _WIN32_WINNT < 0x0600 */ |
370 | #endif /* _WIN32 */ | 372 | #endif /* _WIN32 */ |
371 | #ifdef HAVE_GETHRTIME | 373 | #ifdef HAVE_GETHRTIME |
372 | if (1) | 374 | if (1) |
373 | return (time_t)(((uint64_t) (gethrtime () - hrtime_start)) / 1000000000); | 375 | return (time_t) (((uint64_t) (gethrtime () - hrtime_start)) / 1000000000); |
374 | #endif /* HAVE_GETHRTIME */ | 376 | #endif /* HAVE_GETHRTIME */ |
375 | 377 | ||
376 | return time (NULL) - sys_clock_start; | 378 | return time (NULL) - sys_clock_start; |
diff --git a/src/lib/mhd_mono_clock.h b/src/lib/mhd_mono_clock.h index f4722af2..92485e00 100644 --- a/src/lib/mhd_mono_clock.h +++ b/src/lib/mhd_mono_clock.h | |||
@@ -37,14 +37,14 @@ | |||
37 | * Initialise monotonic seconds counter. | 37 | * Initialise monotonic seconds counter. |
38 | */ | 38 | */ |
39 | void | 39 | void |
40 | MHD_monotonic_sec_counter_init(void); | 40 | MHD_monotonic_sec_counter_init (void); |
41 | 41 | ||
42 | 42 | ||
43 | /** | 43 | /** |
44 | * Deinitialise monotonic seconds counter by freeing any allocated resources | 44 | * Deinitialise monotonic seconds counter by freeing any allocated resources |
45 | */ | 45 | */ |
46 | void | 46 | void |
47 | MHD_monotonic_sec_counter_finish(void); | 47 | MHD_monotonic_sec_counter_finish (void); |
48 | 48 | ||
49 | 49 | ||
50 | /** | 50 | /** |
@@ -55,6 +55,6 @@ MHD_monotonic_sec_counter_finish(void); | |||
55 | * @return number of seconds from some fixed moment | 55 | * @return number of seconds from some fixed moment |
56 | */ | 56 | */ |
57 | time_t | 57 | time_t |
58 | MHD_monotonic_sec_counter(void); | 58 | MHD_monotonic_sec_counter (void); |
59 | 59 | ||
60 | #endif /* MHD_MONO_CLOCK_H */ | 60 | #endif /* MHD_MONO_CLOCK_H */ |
diff --git a/src/lib/mhd_sockets.c b/src/lib/mhd_sockets.c index 356d288f..248b9a68 100644 --- a/src/lib/mhd_sockets.c +++ b/src/lib/mhd_sockets.c | |||
@@ -37,10 +37,10 @@ | |||
37 | * @param err the WinSock error code. | 37 | * @param err the WinSock error code. |
38 | * @return pointer to string description of specified WinSock error. | 38 | * @return pointer to string description of specified WinSock error. |
39 | */ | 39 | */ |
40 | const char* MHD_W32_strerror_winsock_(int err) | 40 | const char*MHD_W32_strerror_winsock_ (int err) |
41 | { | 41 | { |
42 | switch (err) | 42 | switch (err) |
43 | { | 43 | { |
44 | case 0: | 44 | case 0: |
45 | return "No error"; | 45 | return "No error"; |
46 | case WSA_INVALID_HANDLE: | 46 | case WSA_INVALID_HANDLE: |
@@ -233,7 +233,7 @@ const char* MHD_W32_strerror_winsock_(int err) | |||
233 | return "Invalid QoS shaping rate object"; | 233 | return "Invalid QoS shaping rate object"; |
234 | case WSA_QOS_RESERVED_PETYPE: | 234 | case WSA_QOS_RESERVED_PETYPE: |
235 | return "Reserved policy QoS element type"; | 235 | return "Reserved policy QoS element type"; |
236 | } | 236 | } |
237 | return "Unknown winsock error"; | 237 | return "Unknown winsock error"; |
238 | } | 238 | } |
239 | 239 | ||
@@ -246,113 +246,114 @@ const char* MHD_W32_strerror_winsock_(int err) | |||
246 | * @return non-zero if succeeded, zero otherwise | 246 | * @return non-zero if succeeded, zero otherwise |
247 | */ | 247 | */ |
248 | int | 248 | int |
249 | MHD_W32_socket_pair_(SOCKET sockets_pair[2], int non_blk) | 249 | MHD_W32_socket_pair_ (SOCKET sockets_pair[2], int non_blk) |
250 | { | 250 | { |
251 | int i; | 251 | int i; |
252 | 252 | ||
253 | if (! sockets_pair) | 253 | if (! sockets_pair) |
254 | { | 254 | { |
255 | WSASetLastError (WSAEFAULT); | 255 | WSASetLastError (WSAEFAULT); |
256 | return 0; | 256 | return 0; |
257 | } | 257 | } |
258 | 258 | ||
259 | #define PAIRMAXTRYIES 800 | 259 | #define PAIRMAXTRYIES 800 |
260 | for (i = 0; i < PAIRMAXTRYIES; i++) | 260 | for (i = 0; i < PAIRMAXTRYIES; i++) |
261 | { | ||
262 | struct sockaddr_in listen_addr; | ||
263 | SOCKET listen_s; | ||
264 | static const int c_addinlen = sizeof(struct sockaddr_in); /* help compiler to optimize */ | ||
265 | int addr_len = c_addinlen; | ||
266 | unsigned long on_val = 1; | ||
267 | unsigned long off_val = 0; | ||
268 | |||
269 | listen_s = socket (AF_INET, | ||
270 | SOCK_STREAM, | ||
271 | IPPROTO_TCP); | ||
272 | if (INVALID_SOCKET == listen_s) | ||
273 | break; /* can't create even single socket */ | ||
274 | |||
275 | listen_addr.sin_family = AF_INET; | ||
276 | listen_addr.sin_port = 0; /* same as htons(0) */ | ||
277 | listen_addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK); | ||
278 | if ( ((0 == bind (listen_s, | ||
279 | (struct sockaddr*) &listen_addr, | ||
280 | c_addinlen)) && | ||
281 | (0 == listen (listen_s, | ||
282 | 1) ) && | ||
283 | (0 == getsockname (listen_s, | ||
284 | (struct sockaddr*) &listen_addr, | ||
285 | &addr_len))) ) | ||
261 | { | 286 | { |
262 | struct sockaddr_in listen_addr; | 287 | SOCKET client_s = socket (AF_INET, |
263 | SOCKET listen_s; | 288 | SOCK_STREAM, |
264 | static const int c_addinlen = sizeof(struct sockaddr_in); /* help compiler to optimize */ | 289 | IPPROTO_TCP); |
265 | int addr_len = c_addinlen; | 290 | struct sockaddr_in accepted_from_addr; |
266 | unsigned long on_val = 1; | 291 | struct sockaddr_in client_addr; |
267 | unsigned long off_val = 0; | 292 | SOCKET server_s; |
268 | 293 | ||
269 | listen_s = socket (AF_INET, | 294 | if (INVALID_SOCKET == client_s) |
270 | SOCK_STREAM, | 295 | { |
271 | IPPROTO_TCP); | 296 | /* try again */ |
272 | if (INVALID_SOCKET == listen_s) | 297 | closesocket (listen_s); |
273 | break; /* can't create even single socket */ | 298 | continue; |
274 | 299 | } | |
275 | listen_addr.sin_family = AF_INET; | 300 | |
276 | listen_addr.sin_port = 0; /* same as htons(0) */ | 301 | if ( (0 != ioctlsocket (client_s, |
277 | listen_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); | 302 | FIONBIO, |
278 | if ( (0 == bind (listen_s, | 303 | &on_val)) || |
279 | (struct sockaddr*) &listen_addr, | 304 | ( (0 != connect (client_s, |
280 | c_addinlen) && | 305 | (struct sockaddr*) &listen_addr, |
281 | (0 == listen (listen_s, | 306 | c_addinlen)) && |
282 | 1) ) && | 307 | (WSAGetLastError () != WSAEWOULDBLOCK)) ) |
283 | (0 == getsockname (listen_s, | 308 | { |
284 | (struct sockaddr*) &listen_addr, | 309 | /* try again */ |
285 | &addr_len))) ) | 310 | closesocket (listen_s); |
286 | { | 311 | closesocket (client_s); |
287 | SOCKET client_s = socket(AF_INET, | 312 | continue; |
288 | SOCK_STREAM, | 313 | } |
289 | IPPROTO_TCP); | 314 | |
290 | struct sockaddr_in accepted_from_addr; | 315 | addr_len = c_addinlen; |
291 | struct sockaddr_in client_addr; | 316 | server_s = accept (listen_s, |
292 | SOCKET server_s; | 317 | (struct sockaddr*) &accepted_from_addr, |
293 | 318 | &addr_len); | |
294 | if (INVALID_SOCKET == client_s) | 319 | if (INVALID_SOCKET == server_s) |
295 | { | 320 | { |
296 | /* try again */ | 321 | /* try again */ |
297 | closesocket (listen_s); | 322 | closesocket (listen_s); |
298 | continue; | 323 | closesocket (client_s); |
299 | } | 324 | continue; |
300 | 325 | } | |
301 | if ( (0 != ioctlsocket (client_s, | 326 | |
302 | FIONBIO, | 327 | addr_len = c_addinlen; |
303 | &on_val)) || | 328 | if ( (0 == getsockname (client_s, |
304 | ( (0 != connect (client_s, | 329 | (struct sockaddr*) &client_addr, |
305 | (struct sockaddr*) &listen_addr, | 330 | &addr_len)) && |
306 | c_addinlen)) && | 331 | (accepted_from_addr.sin_family == client_addr.sin_family) && |
307 | (WSAGetLastError() != WSAEWOULDBLOCK)) ) | 332 | (accepted_from_addr.sin_port == client_addr.sin_port) && |
308 | { | 333 | (accepted_from_addr.sin_addr.s_addr == |
309 | /* try again */ | 334 | client_addr.sin_addr.s_addr) && |
310 | closesocket (listen_s); | 335 | ( (0 != non_blk) ? |
311 | closesocket (client_s); | 336 | (0 == ioctlsocket (server_s, |
312 | continue; | 337 | FIONBIO, |
313 | } | 338 | &on_val)) : |
314 | 339 | (0 == ioctlsocket (client_s, | |
315 | addr_len = c_addinlen; | 340 | FIONBIO, |
316 | server_s = accept (listen_s, | 341 | &off_val)) ) ) |
317 | (struct sockaddr*) &accepted_from_addr, | 342 | { |
318 | &addr_len); | 343 | closesocket (listen_s); |
319 | if (INVALID_SOCKET == server_s) | 344 | sockets_pair[0] = server_s; |
320 | { | 345 | sockets_pair[1] = client_s; |
321 | /* try again */ | 346 | return ! 0; |
322 | closesocket (listen_s); | 347 | } |
323 | closesocket (client_s); | 348 | closesocket (server_s); |
324 | continue; | 349 | closesocket (client_s); |
325 | } | ||
326 | |||
327 | addr_len = c_addinlen; | ||
328 | if ( (0 == getsockname (client_s, | ||
329 | (struct sockaddr*) &client_addr, | ||
330 | &addr_len)) && | ||
331 | (accepted_from_addr.sin_family == client_addr.sin_family) && | ||
332 | (accepted_from_addr.sin_port == client_addr.sin_port) && | ||
333 | (accepted_from_addr.sin_addr.s_addr == client_addr.sin_addr.s_addr) && | ||
334 | ( (0 != non_blk) ? | ||
335 | (0 == ioctlsocket(server_s, | ||
336 | FIONBIO, | ||
337 | &on_val)) : | ||
338 | (0 == ioctlsocket(client_s, | ||
339 | FIONBIO, | ||
340 | &off_val)) ) ) | ||
341 | { | ||
342 | closesocket (listen_s); | ||
343 | sockets_pair[0] = server_s; | ||
344 | sockets_pair[1] = client_s; | ||
345 | return !0; | ||
346 | } | ||
347 | closesocket (server_s); | ||
348 | closesocket (client_s); | ||
349 | } | ||
350 | closesocket(listen_s); | ||
351 | } | 350 | } |
351 | closesocket (listen_s); | ||
352 | } | ||
352 | 353 | ||
353 | sockets_pair[0] = INVALID_SOCKET; | 354 | sockets_pair[0] = INVALID_SOCKET; |
354 | sockets_pair[1] = INVALID_SOCKET; | 355 | sockets_pair[1] = INVALID_SOCKET; |
355 | WSASetLastError(WSAECONNREFUSED); | 356 | WSASetLastError (WSAECONNREFUSED); |
356 | 357 | ||
357 | return 0; | 358 | return 0; |
358 | } | 359 | } |
@@ -383,9 +384,9 @@ MHD_add_to_fd_set_ (MHD_socket fd, | |||
383 | set, | 384 | set, |
384 | fd_setsize)) | 385 | fd_setsize)) |
385 | return 0; | 386 | return 0; |
386 | MHD_SCKT_ADD_FD_TO_FDSET_SETSIZE_(fd, | 387 | MHD_SCKT_ADD_FD_TO_FDSET_SETSIZE_ (fd, |
387 | set, | 388 | set, |
388 | fd_setsize); | 389 | fd_setsize); |
389 | if ( (NULL != max_fd) && | 390 | if ( (NULL != max_fd) && |
390 | ( (fd > *max_fd) || | 391 | ( (fd > *max_fd) || |
391 | (MHD_INVALID_SOCKET == *max_fd) ) ) | 392 | (MHD_INVALID_SOCKET == *max_fd) ) ) |
@@ -424,7 +425,7 @@ MHD_socket_nonblocking_ (MHD_socket sock) | |||
424 | &flags)) | 425 | &flags)) |
425 | return 0; | 426 | return 0; |
426 | #endif /* MHD_WINSOCK_SOCKETS */ | 427 | #endif /* MHD_WINSOCK_SOCKETS */ |
427 | return !0; | 428 | return ! 0; |
428 | } | 429 | } |
429 | 430 | ||
430 | 431 | ||
@@ -452,12 +453,12 @@ MHD_socket_noninheritable_ (MHD_socket sock) | |||
452 | flags | FD_CLOEXEC)) ) | 453 | flags | FD_CLOEXEC)) ) |
453 | return 0; | 454 | return 0; |
454 | #elif defined(MHD_WINSOCK_SOCKETS) | 455 | #elif defined(MHD_WINSOCK_SOCKETS) |
455 | if (! SetHandleInformation ((HANDLE)sock, | 456 | if (! SetHandleInformation ((HANDLE) sock, |
456 | HANDLE_FLAG_INHERIT, | 457 | HANDLE_FLAG_INHERIT, |
457 | 0)) | 458 | 0)) |
458 | return 0; | 459 | return 0; |
459 | #endif /* MHD_WINSOCK_SOCKETS */ | 460 | #endif /* MHD_WINSOCK_SOCKETS */ |
460 | return !0; | 461 | return ! 0; |
461 | } | 462 | } |
462 | 463 | ||
463 | 464 | ||
@@ -477,7 +478,7 @@ MHD_socket_create_listen_ (int pf) | |||
477 | fd = socket (pf, | 478 | fd = socket (pf, |
478 | SOCK_STREAM | SOCK_CLOEXEC, | 479 | SOCK_STREAM | SOCK_CLOEXEC, |
479 | 0); | 480 | 0); |
480 | cloexec_set = !0; | 481 | cloexec_set = ! 0; |
481 | #elif defined(MHD_WINSOCK_SOCKETS) && defined (WSA_FLAG_NO_HANDLE_INHERIT) | 482 | #elif defined(MHD_WINSOCK_SOCKETS) && defined (WSA_FLAG_NO_HANDLE_INHERIT) |
482 | fd = WSASocketW (pf, | 483 | fd = WSASocketW (pf, |
483 | SOCK_STREAM, | 484 | SOCK_STREAM, |
@@ -485,27 +486,27 @@ MHD_socket_create_listen_ (int pf) | |||
485 | NULL, | 486 | NULL, |
486 | 0, | 487 | 0, |
487 | WSA_FLAG_NO_HANDLE_INHERIT); | 488 | WSA_FLAG_NO_HANDLE_INHERIT); |
488 | cloexec_set = !0; | 489 | cloexec_set = ! 0; |
489 | #else /* !SOCK_CLOEXEC */ | 490 | #else /* !SOCK_CLOEXEC */ |
490 | fd = MHD_INVALID_SOCKET; | 491 | fd = MHD_INVALID_SOCKET; |
491 | #endif /* !SOCK_CLOEXEC */ | 492 | #endif /* !SOCK_CLOEXEC */ |
492 | if (MHD_INVALID_SOCKET == fd) | 493 | if (MHD_INVALID_SOCKET == fd) |
493 | { | 494 | { |
494 | fd = socket (pf, | 495 | fd = socket (pf, |
495 | SOCK_STREAM, | 496 | SOCK_STREAM, |
496 | 0); | 497 | 0); |
497 | cloexec_set = 0; | 498 | cloexec_set = 0; |
498 | } | 499 | } |
499 | if (MHD_INVALID_SOCKET == fd) | 500 | if (MHD_INVALID_SOCKET == fd) |
500 | return MHD_INVALID_SOCKET; | 501 | return MHD_INVALID_SOCKET; |
501 | #ifdef MHD_socket_nosignal_ | 502 | #ifdef MHD_socket_nosignal_ |
502 | if(! MHD_socket_nosignal_(fd)) | 503 | if (! MHD_socket_nosignal_ (fd)) |
503 | { | 504 | { |
504 | const int err = MHD_socket_get_error_ (); | 505 | const int err = MHD_socket_get_error_ (); |
505 | (void) MHD_socket_close_ (fd); | 506 | (void) MHD_socket_close_ (fd); |
506 | MHD_socket_fset_error_ (err); | 507 | MHD_socket_fset_error_ (err); |
507 | return MHD_INVALID_SOCKET; | 508 | return MHD_INVALID_SOCKET; |
508 | } | 509 | } |
509 | #endif /* MHD_socket_nosignal_ */ | 510 | #endif /* MHD_socket_nosignal_ */ |
510 | if (! cloexec_set) | 511 | if (! cloexec_set) |
511 | (void) MHD_socket_noninheritable_ (fd); | 512 | (void) MHD_socket_noninheritable_ (fd); |
diff --git a/src/lib/mhd_sockets.h b/src/lib/mhd_sockets.h index 9be34144..ebe40275 100644 --- a/src/lib/mhd_sockets.h +++ b/src/lib/mhd_sockets.h | |||
@@ -36,8 +36,8 @@ | |||
36 | 36 | ||
37 | #include <errno.h> | 37 | #include <errno.h> |
38 | 38 | ||
39 | #if !defined(MHD_POSIX_SOCKETS) && !defined(MHD_WINSOCK_SOCKETS) | 39 | #if ! defined(MHD_POSIX_SOCKETS) && ! defined(MHD_WINSOCK_SOCKETS) |
40 | # if !defined(_WIN32) || defined(__CYGWIN__) | 40 | # if ! defined(_WIN32) || defined(__CYGWIN__) |
41 | # define MHD_POSIX_SOCKETS 1 | 41 | # define MHD_POSIX_SOCKETS 1 |
42 | # else /* defined(_WIN32) && !defined(__CYGWIN__) */ | 42 | # else /* defined(_WIN32) && !defined(__CYGWIN__) */ |
43 | # define MHD_WINSOCK_SOCKETS 1 | 43 | # define MHD_WINSOCK_SOCKETS 1 |
@@ -92,7 +92,7 @@ | |||
92 | # include <sys/epoll.h> | 92 | # include <sys/epoll.h> |
93 | # endif | 93 | # endif |
94 | # ifdef HAVE_NETINET_TCP_H | 94 | # ifdef HAVE_NETINET_TCP_H |
95 | /* for TCP_FASTOPEN and TCP_CORK */ | 95 | /* for TCP_FASTOPEN and TCP_CORK */ |
96 | # include <netinet/tcp.h> | 96 | # include <netinet/tcp.h> |
97 | # endif | 97 | # endif |
98 | # ifdef HAVE_STRING_H | 98 | # ifdef HAVE_STRING_H |
@@ -111,10 +111,10 @@ | |||
111 | #endif | 111 | #endif |
112 | 112 | ||
113 | #include <stddef.h> | 113 | #include <stddef.h> |
114 | #if defined(_MSC_FULL_VER) && !defined (_SSIZE_T_DEFINED) | 114 | #if defined(_MSC_FULL_VER) && ! defined (_SSIZE_T_DEFINED) |
115 | # include <stdint.h> | 115 | # include <stdint.h> |
116 | # define _SSIZE_T_DEFINED | 116 | # define _SSIZE_T_DEFINED |
117 | typedef intptr_t ssize_t; | 117 | typedef intptr_t ssize_t; |
118 | #endif /* !_SSIZE_T_DEFINED */ | 118 | #endif /* !_SSIZE_T_DEFINED */ |
119 | 119 | ||
120 | #include "mhd_limits.h" | 120 | #include "mhd_limits.h" |
@@ -123,7 +123,7 @@ | |||
123 | # define _MHD_SYS_DEFAULT_FD_SETSIZE FD_SETSIZE | 123 | # define _MHD_SYS_DEFAULT_FD_SETSIZE FD_SETSIZE |
124 | #else /* ! _MHD_FD_SETSIZE_IS_DEFAULT */ | 124 | #else /* ! _MHD_FD_SETSIZE_IS_DEFAULT */ |
125 | # include "sysfdsetsize.h" | 125 | # include "sysfdsetsize.h" |
126 | # define _MHD_SYS_DEFAULT_FD_SETSIZE get_system_fdsetsize_value() | 126 | # define _MHD_SYS_DEFAULT_FD_SETSIZE get_system_fdsetsize_value () |
127 | #endif /* ! _MHD_FD_SETSIZE_IS_DEFAULT */ | 127 | #endif /* ! _MHD_FD_SETSIZE_IS_DEFAULT */ |
128 | 128 | ||
129 | #ifndef MHD_PANIC | 129 | #ifndef MHD_PANIC |
@@ -131,8 +131,9 @@ | |||
131 | # include <stdlib.h> | 131 | # include <stdlib.h> |
132 | /* Simple implementation of MHD_PANIC, to be used outside lib */ | 132 | /* Simple implementation of MHD_PANIC, to be used outside lib */ |
133 | # define MHD_PANIC(msg) do { fprintf (stderr, \ | 133 | # define MHD_PANIC(msg) do { fprintf (stderr, \ |
134 | "Abnormal termination at %d line in file %s: %s\n", \ | 134 | "Abnormal termination at %d line in file %s: %s\n", \ |
135 | (int)__LINE__, __FILE__, msg); abort();} while(0) | 135 | (int) __LINE__, __FILE__, msg); abort (); \ |
136 | } while (0) | ||
136 | #endif /* ! MHD_PANIC */ | 137 | #endif /* ! MHD_PANIC */ |
137 | 138 | ||
138 | #ifndef MHD_SOCKET_DEFINED | 139 | #ifndef MHD_SOCKET_DEFINED |
@@ -140,10 +141,10 @@ | |||
140 | * MHD_socket is type for socket FDs | 141 | * MHD_socket is type for socket FDs |
141 | */ | 142 | */ |
142 | # if defined(MHD_POSIX_SOCKETS) | 143 | # if defined(MHD_POSIX_SOCKETS) |
143 | typedef int MHD_socket; | 144 | typedef int MHD_socket; |
144 | # define MHD_INVALID_SOCKET (-1) | 145 | # define MHD_INVALID_SOCKET (-1) |
145 | # elif defined(MHD_WINSOCK_SOCKETS) | 146 | # elif defined(MHD_WINSOCK_SOCKETS) |
146 | typedef SOCKET MHD_socket; | 147 | typedef SOCKET MHD_socket; |
147 | # define MHD_INVALID_SOCKET (INVALID_SOCKET) | 148 | # define MHD_INVALID_SOCKET (INVALID_SOCKET) |
148 | # endif /* MHD_WINSOCK_SOCKETS */ | 149 | # endif /* MHD_WINSOCK_SOCKETS */ |
149 | 150 | ||
@@ -168,17 +169,18 @@ | |||
168 | # define MAYBE_MSG_NOSIGNAL 0 | 169 | # define MAYBE_MSG_NOSIGNAL 0 |
169 | #endif /* ! MSG_NOSIGNAL */ | 170 | #endif /* ! MSG_NOSIGNAL */ |
170 | 171 | ||
171 | #if !defined(SHUT_WR) && defined(SD_SEND) | 172 | #if ! defined(SHUT_WR) && defined(SD_SEND) |
172 | # define SHUT_WR SD_SEND | 173 | # define SHUT_WR SD_SEND |
173 | #endif | 174 | #endif |
174 | #if !defined(SHUT_RD) && defined(SD_RECEIVE) | 175 | #if ! defined(SHUT_RD) && defined(SD_RECEIVE) |
175 | # define SHUT_RD SD_RECEIVE | 176 | # define SHUT_RD SD_RECEIVE |
176 | #endif | 177 | #endif |
177 | #if !defined(SHUT_RDWR) && defined(SD_BOTH) | 178 | #if ! defined(SHUT_RDWR) && defined(SD_BOTH) |
178 | # define SHUT_RDWR SD_BOTH | 179 | # define SHUT_RDWR SD_BOTH |
179 | #endif | 180 | #endif |
180 | 181 | ||
181 | #if HAVE_ACCEPT4+0 != 0 && (defined(HAVE_SOCK_NONBLOCK) || defined(SOCK_CLOEXEC)) | 182 | #if HAVE_ACCEPT4 + 0 != 0 && (defined(HAVE_SOCK_NONBLOCK) || \ |
183 | defined(SOCK_CLOEXEC)) | ||
182 | # define USE_ACCEPT4 1 | 184 | # define USE_ACCEPT4 1 |
183 | #endif | 185 | #endif |
184 | 186 | ||
@@ -198,25 +200,25 @@ | |||
198 | * MHD_SCKT_OPT_BOOL_ is type for bool parameters for setsockopt()/getsockopt() | 200 | * MHD_SCKT_OPT_BOOL_ is type for bool parameters for setsockopt()/getsockopt() |
199 | */ | 201 | */ |
200 | #ifdef MHD_POSIX_SOCKETS | 202 | #ifdef MHD_POSIX_SOCKETS |
201 | typedef int MHD_SCKT_OPT_BOOL_; | 203 | typedef int MHD_SCKT_OPT_BOOL_; |
202 | #else /* MHD_WINSOCK_SOCKETS */ | 204 | #else /* MHD_WINSOCK_SOCKETS */ |
203 | typedef BOOL MHD_SCKT_OPT_BOOL_; | 205 | typedef BOOL MHD_SCKT_OPT_BOOL_; |
204 | #endif /* MHD_WINSOCK_SOCKETS */ | 206 | #endif /* MHD_WINSOCK_SOCKETS */ |
205 | 207 | ||
206 | /** | 208 | /** |
207 | * MHD_SCKT_SEND_SIZE_ is type used to specify size for send and recv | 209 | * MHD_SCKT_SEND_SIZE_ is type used to specify size for send and recv |
208 | * functions | 210 | * functions |
209 | */ | 211 | */ |
210 | #if !defined(MHD_WINSOCK_SOCKETS) | 212 | #if ! defined(MHD_WINSOCK_SOCKETS) |
211 | typedef size_t MHD_SCKT_SEND_SIZE_; | 213 | typedef size_t MHD_SCKT_SEND_SIZE_; |
212 | #else | 214 | #else |
213 | typedef int MHD_SCKT_SEND_SIZE_; | 215 | typedef int MHD_SCKT_SEND_SIZE_; |
214 | #endif | 216 | #endif |
215 | 217 | ||
216 | /** | 218 | /** |
217 | * MHD_SCKT_SEND_MAX_SIZE_ is maximum send()/recv() size value. | 219 | * MHD_SCKT_SEND_MAX_SIZE_ is maximum send()/recv() size value. |
218 | */ | 220 | */ |
219 | #if !defined(MHD_WINSOCK_SOCKETS) | 221 | #if ! defined(MHD_WINSOCK_SOCKETS) |
220 | # define MHD_SCKT_SEND_MAX_SIZE_ SSIZE_MAX | 222 | # define MHD_SCKT_SEND_MAX_SIZE_ SSIZE_MAX |
221 | #else | 223 | #else |
222 | # define MHD_SCKT_SEND_MAX_SIZE_ INT_MAX | 224 | # define MHD_SCKT_SEND_MAX_SIZE_ INT_MAX |
@@ -232,10 +234,10 @@ | |||
232 | * counted as success, only EBADF counts as an error!), | 234 | * counted as success, only EBADF counts as an error!), |
233 | * boolean false otherwise. | 235 | * boolean false otherwise. |
234 | */ | 236 | */ |
235 | #if !defined(MHD_WINSOCK_SOCKETS) | 237 | #if ! defined(MHD_WINSOCK_SOCKETS) |
236 | # define MHD_socket_close_(fd) ((0 == close((fd))) || (EBADF != errno)) | 238 | # define MHD_socket_close_(fd) ((0 == close ((fd))) || (EBADF != errno)) |
237 | #else | 239 | #else |
238 | # define MHD_socket_close_(fd) (0 == closesocket((fd))) | 240 | # define MHD_socket_close_(fd) (0 == closesocket ((fd))) |
239 | #endif | 241 | #endif |
240 | 242 | ||
241 | /** | 243 | /** |
@@ -244,9 +246,9 @@ | |||
244 | * @param fd socket to close | 246 | * @param fd socket to close |
245 | */ | 247 | */ |
246 | #define MHD_socket_close_chk_(fd) do { \ | 248 | #define MHD_socket_close_chk_(fd) do { \ |
247 | if (!MHD_socket_close_(fd)) \ | 249 | if (! MHD_socket_close_ (fd)) \ |
248 | MHD_PANIC(_("Close socket failed.\n")); \ | 250 | MHD_PANIC (_ ("Close socket failed.\n")); \ |
249 | } while(0) | 251 | } while (0) |
250 | 252 | ||
251 | 253 | ||
252 | /** | 254 | /** |
@@ -257,7 +259,8 @@ | |||
257 | * @return ssize_t type value | 259 | * @return ssize_t type value |
258 | */ | 260 | */ |
259 | #define MHD_send_(s,b,l) \ | 261 | #define MHD_send_(s,b,l) \ |
260 | ((ssize_t)send((s),(const void*)(b),((MHD_SCKT_SEND_SIZE_)l), MAYBE_MSG_NOSIGNAL)) | 262 | ((ssize_t) send ((s),(const void*) (b),((MHD_SCKT_SEND_SIZE_) l), \ |
263 | MAYBE_MSG_NOSIGNAL)) | ||
261 | 264 | ||
262 | 265 | ||
263 | /** | 266 | /** |
@@ -268,7 +271,7 @@ | |||
268 | * @return ssize_t type value | 271 | * @return ssize_t type value |
269 | */ | 272 | */ |
270 | #define MHD_recv_(s,b,l) \ | 273 | #define MHD_recv_(s,b,l) \ |
271 | ((ssize_t)recv((s),(void*)(b),((MHD_SCKT_SEND_SIZE_)l), 0)) | 274 | ((ssize_t) recv ((s),(void*) (b),((MHD_SCKT_SEND_SIZE_) l), 0)) |
272 | 275 | ||
273 | 276 | ||
274 | /** | 277 | /** |
@@ -281,11 +284,18 @@ | |||
281 | * boolean false otherwise. | 284 | * boolean false otherwise. |
282 | */ | 285 | */ |
283 | #if defined(MHD_POSIX_SOCKETS) | 286 | #if defined(MHD_POSIX_SOCKETS) |
284 | # define MHD_SCKT_FD_FITS_FDSET_SETSIZE_(fd,pset,setsize) ((fd) < ((MHD_socket)setsize)) | 287 | # define MHD_SCKT_FD_FITS_FDSET_SETSIZE_(fd,pset,setsize) ((fd) < \ |
288 | ((MHD_socket) \ | ||
289 | setsize)) | ||
285 | #elif defined(MHD_WINSOCK_SOCKETS) | 290 | #elif defined(MHD_WINSOCK_SOCKETS) |
286 | # define MHD_SCKT_FD_FITS_FDSET_SETSIZE_(fd,pset,setsize) ( ((void*)(pset)==(void*)0) || \ | 291 | # define MHD_SCKT_FD_FITS_FDSET_SETSIZE_(fd,pset,setsize) ( ((void*) (pset)== \ |
287 | (((fd_set*)(pset))->fd_count < ((unsigned)setsize)) || \ | 292 | (void*) 0) || \ |
288 | (FD_ISSET((fd),(pset))) ) | 293 | (((fd_set*) (pset)) \ |
294 | ->fd_count < \ | ||
295 | ((unsigned) \ | ||
296 | setsize)) || \ | ||
297 | (FD_ISSET ((fd), \ | ||
298 | (pset))) ) | ||
289 | #endif | 299 | #endif |
290 | 300 | ||
291 | /** | 301 | /** |
@@ -296,7 +306,9 @@ | |||
296 | * @return boolean true if FD can be added to fd_set, | 306 | * @return boolean true if FD can be added to fd_set, |
297 | * boolean false otherwise. | 307 | * boolean false otherwise. |
298 | */ | 308 | */ |
299 | #define MHD_SCKT_FD_FITS_FDSET_(fd,pset) MHD_SCKT_FD_FITS_FDSET_SETSIZE_((fd),(pset),FD_SETSIZE) | 309 | #define MHD_SCKT_FD_FITS_FDSET_(fd,pset) MHD_SCKT_FD_FITS_FDSET_SETSIZE_ ((fd), \ |
310 | (pset), \ | ||
311 | FD_SETSIZE) | ||
300 | 312 | ||
301 | /** | 313 | /** |
302 | * Add FD to fd_set with specified FD_SETSIZE. | 314 | * Add FD to fd_set with specified FD_SETSIZE. |
@@ -307,34 +319,35 @@ | |||
307 | * system definition of FD_SET() is not used. | 319 | * system definition of FD_SET() is not used. |
308 | */ | 320 | */ |
309 | #if defined(MHD_POSIX_SOCKETS) | 321 | #if defined(MHD_POSIX_SOCKETS) |
310 | # define MHD_SCKT_ADD_FD_TO_FDSET_SETSIZE_(fd,pset,setsize) FD_SET((fd),(pset)) | 322 | # define MHD_SCKT_ADD_FD_TO_FDSET_SETSIZE_(fd,pset,setsize) FD_SET ((fd), \ |
323 | (pset)) | ||
311 | #elif defined(MHD_WINSOCK_SOCKETS) | 324 | #elif defined(MHD_WINSOCK_SOCKETS) |
312 | # define MHD_SCKT_ADD_FD_TO_FDSET_SETSIZE_(fd,pset,setsize) \ | 325 | # define MHD_SCKT_ADD_FD_TO_FDSET_SETSIZE_(fd,pset,setsize) \ |
313 | do { \ | 326 | do { \ |
314 | u_int _i_ = 0; \ | 327 | u_int _i_ = 0; \ |
315 | fd_set* const _s_ = (fd_set*)(pset); \ | 328 | fd_set*const _s_ = (fd_set*) (pset); \ |
316 | while((_i_ < _s_->fd_count) && ((fd) != _s_->fd_array[_i_])) {++_i_;} \ | 329 | while ((_i_ < _s_->fd_count) && ((fd) != _s_->fd_array [_i_])) {++_i_;} \ |
317 | if ((_i_ == _s_->fd_count)) {_s_->fd_array[_s_->fd_count++] = (fd);} \ | 330 | if ((_i_ == _s_->fd_count)) {_s_->fd_array [_s_->fd_count ++] = (fd);} \ |
318 | } while(0) | 331 | } while (0) |
319 | #endif | 332 | #endif |
320 | 333 | ||
321 | /* MHD_SYS_select_ is wrapper macro for system select() function */ | 334 | /* MHD_SYS_select_ is wrapper macro for system select() function */ |
322 | #if !defined(MHD_WINSOCK_SOCKETS) | 335 | #if ! defined(MHD_WINSOCK_SOCKETS) |
323 | # define MHD_SYS_select_(n,r,w,e,t) select((n),(r),(w),(e),(t)) | 336 | # define MHD_SYS_select_(n,r,w,e,t) select ((n),(r),(w),(e),(t)) |
324 | #else | 337 | #else |
325 | # define MHD_SYS_select_(n,r,w,e,t) \ | 338 | # define MHD_SYS_select_(n,r,w,e,t) \ |
326 | ( ( (((void*)(r) == (void*)0) || ((fd_set*)(r))->fd_count == 0) && \ | 339 | ( ( (((void*) (r) == (void*) 0) || ((fd_set*) (r))->fd_count == 0) && \ |
327 | (((void*)(w) == (void*)0) || ((fd_set*)(w))->fd_count == 0) && \ | 340 | (((void*) (w) == (void*) 0) || ((fd_set*) (w))->fd_count == 0) && \ |
328 | (((void*)(e) == (void*)0) || ((fd_set*)(e))->fd_count == 0) ) ? \ | 341 | (((void*) (e) == (void*) 0) || ((fd_set*) (e))->fd_count == 0) ) ? \ |
329 | ( ((void*)(t) == (void*)0) ? 0 : \ | 342 | ( ((void*) (t) == (void*) 0) ? 0 : \ |
330 | (Sleep(((struct timeval*)(t))->tv_sec * 1000 + \ | 343 | (Sleep (((struct timeval*) (t))->tv_sec * 1000 \ |
331 | ((struct timeval*)(t))->tv_usec / 1000), 0) ) : \ | 344 | + ((struct timeval*) (t))->tv_usec / 1000), 0) ) : \ |
332 | (select((int)0,(r),(w),(e),(t))) ) | 345 | (select ((int) 0,(r),(w),(e),(t))) ) |
333 | #endif | 346 | #endif |
334 | 347 | ||
335 | #if defined(HAVE_POLL) | 348 | #if defined(HAVE_POLL) |
336 | /* MHD_sys_poll_ is wrapper macro for system poll() function */ | 349 | /* MHD_sys_poll_ is wrapper macro for system poll() function */ |
337 | # if !defined(MHD_WINSOCK_SOCKETS) | 350 | # if ! defined(MHD_WINSOCK_SOCKETS) |
338 | # define MHD_sys_poll_ poll | 351 | # define MHD_sys_poll_ poll |
339 | # else /* MHD_WINSOCK_SOCKETS */ | 352 | # else /* MHD_WINSOCK_SOCKETS */ |
340 | # define MHD_sys_poll_ WSAPoll | 353 | # define MHD_sys_poll_ WSAPoll |
@@ -363,16 +376,19 @@ | |||
363 | # elif defined(__linux__) | 376 | # elif defined(__linux__) |
364 | # define MHD_POLL_EVENTS_ERR_DISC POLLPRI | 377 | # define MHD_POLL_EVENTS_ERR_DISC POLLPRI |
365 | # else /* ! __linux__ */ | 378 | # else /* ! __linux__ */ |
366 | # define MHD_POLL_EVENTS_ERR_DISC (MHD_POLLPRI_OR_ZERO | MHD_POLLRDBAND_OR_ZERO) | 379 | # define MHD_POLL_EVENTS_ERR_DISC (MHD_POLLPRI_OR_ZERO \ |
380 | | MHD_POLLRDBAND_OR_ZERO) | ||
367 | # endif /* ! __linux__ */ | 381 | # endif /* ! __linux__ */ |
368 | /* MHD_POLL_REVENTS_ERR_DISC is 'revents' mask for errors and disconnect. | 382 | /* MHD_POLL_REVENTS_ERR_DISC is 'revents' mask for errors and disconnect. |
369 | * Note: Out-of-band data is treated as error. */ | 383 | * Note: Out-of-band data is treated as error. */ |
370 | # define MHD_POLL_REVENTS_ERR_DISC \ | 384 | # define MHD_POLL_REVENTS_ERR_DISC \ |
371 | (MHD_POLLPRI_OR_ZERO | MHD_POLLRDBAND_OR_ZERO | MHD_POLLNVAL_OR_ZERO | POLLERR | POLLHUP) | 385 | (MHD_POLLPRI_OR_ZERO | MHD_POLLRDBAND_OR_ZERO | MHD_POLLNVAL_OR_ZERO \ |
386 | | POLLERR | POLLHUP) | ||
372 | /* MHD_POLL_REVENTS_ERRROR is 'revents' mask for errors. | 387 | /* MHD_POLL_REVENTS_ERRROR is 'revents' mask for errors. |
373 | * Note: Out-of-band data is treated as error. */ | 388 | * Note: Out-of-band data is treated as error. */ |
374 | # define MHD_POLL_REVENTS_ERRROR \ | 389 | # define MHD_POLL_REVENTS_ERRROR \ |
375 | (MHD_POLLPRI_OR_ZERO | MHD_POLLRDBAND_OR_ZERO | MHD_POLLNVAL_OR_ZERO | POLLERR) | 390 | (MHD_POLLPRI_OR_ZERO | MHD_POLLRDBAND_OR_ZERO | MHD_POLLNVAL_OR_ZERO \ |
391 | | POLLERR) | ||
376 | #endif /* HAVE_POLL */ | 392 | #endif /* HAVE_POLL */ |
377 | 393 | ||
378 | #define MHD_SCKT_MISSING_ERR_CODE_ 31450 | 394 | #define MHD_SCKT_MISSING_ERR_CODE_ 31450 |
@@ -506,30 +522,30 @@ | |||
506 | #if defined(MHD_POSIX_SOCKETS) | 522 | #if defined(MHD_POSIX_SOCKETS) |
507 | # define MHD_socket_get_error_() (errno) | 523 | # define MHD_socket_get_error_() (errno) |
508 | #elif defined(MHD_WINSOCK_SOCKETS) | 524 | #elif defined(MHD_WINSOCK_SOCKETS) |
509 | # define MHD_socket_get_error_() WSAGetLastError() | 525 | # define MHD_socket_get_error_() WSAGetLastError () |
510 | #endif | 526 | #endif |
511 | 527 | ||
512 | #ifdef MHD_WINSOCK_SOCKETS | 528 | #ifdef MHD_WINSOCK_SOCKETS |
513 | /* POSIX-W32 sockets compatibility functions */ | 529 | /* POSIX-W32 sockets compatibility functions */ |
514 | 530 | ||
515 | /** | 531 | /** |
516 | * Return pointer to string description of specified WinSock error | 532 | * Return pointer to string description of specified WinSock error |
517 | * @param err the WinSock error code. | 533 | * @param err the WinSock error code. |
518 | * @return pointer to string description of specified WinSock error. | 534 | * @return pointer to string description of specified WinSock error. |
519 | */ | 535 | */ |
520 | const char* MHD_W32_strerror_winsock_(int err); | 536 | const char*MHD_W32_strerror_winsock_ (int err); |
521 | #endif /* MHD_WINSOCK_SOCKETS */ | 537 | #endif /* MHD_WINSOCK_SOCKETS */ |
522 | 538 | ||
523 | /* MHD_socket_last_strerr_ is description string of specified socket error code */ | 539 | /* MHD_socket_last_strerr_ is description string of specified socket error code */ |
524 | #if defined(MHD_POSIX_SOCKETS) | 540 | #if defined(MHD_POSIX_SOCKETS) |
525 | # define MHD_socket_strerr_(err) strerror((err)) | 541 | # define MHD_socket_strerr_(err) strerror ((err)) |
526 | #elif defined(MHD_WINSOCK_SOCKETS) | 542 | #elif defined(MHD_WINSOCK_SOCKETS) |
527 | # define MHD_socket_strerr_(err) MHD_W32_strerror_winsock_((err)) | 543 | # define MHD_socket_strerr_(err) MHD_W32_strerror_winsock_ ((err)) |
528 | #endif | 544 | #endif |
529 | 545 | ||
530 | /* MHD_socket_last_strerr_ is description string of last errno (non-W32) / | 546 | /* MHD_socket_last_strerr_ is description string of last errno (non-W32) / |
531 | * description string of last socket error (W32) */ | 547 | * description string of last socket error (W32) */ |
532 | #define MHD_socket_last_strerr_() MHD_socket_strerr_(MHD_socket_get_error_()) | 548 | #define MHD_socket_last_strerr_() MHD_socket_strerr_ (MHD_socket_get_error_ ()) |
533 | 549 | ||
534 | /** | 550 | /** |
535 | * MHD_socket_fset_error_() set socket system native error code. | 551 | * MHD_socket_fset_error_() set socket system native error code. |
@@ -537,7 +553,7 @@ | |||
537 | #if defined(MHD_POSIX_SOCKETS) | 553 | #if defined(MHD_POSIX_SOCKETS) |
538 | # define MHD_socket_fset_error_(err) (errno = (err)) | 554 | # define MHD_socket_fset_error_(err) (errno = (err)) |
539 | #elif defined(MHD_WINSOCK_SOCKETS) | 555 | #elif defined(MHD_WINSOCK_SOCKETS) |
540 | # define MHD_socket_fset_error_(err) (WSASetLastError((err))) | 556 | # define MHD_socket_fset_error_(err) (WSASetLastError ((err))) |
541 | #endif | 557 | #endif |
542 | 558 | ||
543 | /** | 559 | /** |
@@ -549,7 +565,8 @@ | |||
549 | * and error was not set. | 565 | * and error was not set. |
550 | */ | 566 | */ |
551 | #define MHD_socket_try_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ != (err)) ? \ | 567 | #define MHD_socket_try_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ != (err)) ? \ |
552 | (MHD_socket_fset_error_((err)), !0) : 0 ) | 568 | (MHD_socket_fset_error_ ((err)), ! 0) : \ |
569 | 0) | ||
553 | 570 | ||
554 | /** | 571 | /** |
555 | * MHD_socket_set_error_() set socket system native error code to | 572 | * MHD_socket_set_error_() set socket system native error code to |
@@ -562,7 +579,8 @@ | |||
562 | (errno = ENOSYS) : (errno = (err)) ) | 579 | (errno = ENOSYS) : (errno = (err)) ) |
563 | # elif defined(EOPNOTSUPP) | 580 | # elif defined(EOPNOTSUPP) |
564 | # define MHD_socket_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ == (err)) ? \ | 581 | # define MHD_socket_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ == (err)) ? \ |
565 | (errno = EOPNOTSUPP) : (errno = (err)) ) | 582 | (errno = EOPNOTSUPP) : (errno = \ |
583 | (err)) ) | ||
566 | # elif defined (EFAULT) | 584 | # elif defined (EFAULT) |
567 | # define MHD_socket_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ == (err)) ? \ | 585 | # define MHD_socket_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ == (err)) ? \ |
568 | (errno = EFAULT) : (errno = (err)) ) | 586 | (errno = EFAULT) : (errno = (err)) ) |
@@ -570,13 +588,14 @@ | |||
570 | # define MHD_socket_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ == (err)) ? \ | 588 | # define MHD_socket_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ == (err)) ? \ |
571 | (errno = EINVAL) : (errno = (err)) ) | 589 | (errno = EINVAL) : (errno = (err)) ) |
572 | # else /* !EOPNOTSUPP && !EFAULT && !EINVAL */ | 590 | # else /* !EOPNOTSUPP && !EFAULT && !EINVAL */ |
573 | # warning No suitable replacement for missing socket error code is found. Edit this file and add replacement code which is defined on system. | 591 | # warning \ |
592 | No suitable replacement for missing socket error code is found. Edit this file and add replacement code which is defined on system. | ||
574 | # define MHD_socket_set_error_(err) (errno = (err)) | 593 | # define MHD_socket_set_error_(err) (errno = (err)) |
575 | # endif /* !EOPNOTSUPP && !EFAULT && !EINVAL*/ | 594 | # endif /* !EOPNOTSUPP && !EFAULT && !EINVAL*/ |
576 | #elif defined(MHD_WINSOCK_SOCKETS) | 595 | #elif defined(MHD_WINSOCK_SOCKETS) |
577 | # define MHD_socket_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ == (err)) ? \ | 596 | # define MHD_socket_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ == (err)) ? \ |
578 | (WSASetLastError((WSAEOPNOTSUPP))) : \ | 597 | (WSASetLastError ((WSAEOPNOTSUPP))) : \ |
579 | (WSASetLastError((err))) ) | 598 | (WSASetLastError ((err))) ) |
580 | #endif | 599 | #endif |
581 | 600 | ||
582 | /** | 601 | /** |
@@ -600,7 +619,8 @@ | |||
600 | * last socket error equals to MHD_SCKT_E*_ @a code; | 619 | * last socket error equals to MHD_SCKT_E*_ @a code; |
601 | * boolean false otherwise | 620 | * boolean false otherwise |
602 | */ | 621 | */ |
603 | #define MHD_SCKT_LAST_ERR_IS_(code) MHD_SCKT_ERR_IS_(MHD_socket_get_error_() ,(code)) | 622 | #define MHD_SCKT_LAST_ERR_IS_(code) MHD_SCKT_ERR_IS_ (MHD_socket_get_error_ (), \ |
623 | (code)) | ||
604 | 624 | ||
605 | /* Specific error code checks */ | 625 | /* Specific error code checks */ |
606 | 626 | ||
@@ -610,7 +630,7 @@ | |||
610 | * @return boolean true if @a err is equal to sockets' EINTR code; | 630 | * @return boolean true if @a err is equal to sockets' EINTR code; |
611 | * boolean false otherwise. | 631 | * boolean false otherwise. |
612 | */ | 632 | */ |
613 | #define MHD_SCKT_ERR_IS_EINTR_(err) MHD_SCKT_ERR_IS_((err),MHD_SCKT_EINTR_) | 633 | #define MHD_SCKT_ERR_IS_EINTR_(err) MHD_SCKT_ERR_IS_ ((err),MHD_SCKT_EINTR_) |
614 | 634 | ||
615 | /** | 635 | /** |
616 | * Check whether given socket error is equal to system's | 636 | * Check whether given socket error is equal to system's |
@@ -619,10 +639,12 @@ | |||
619 | * boolean false otherwise. | 639 | * boolean false otherwise. |
620 | */ | 640 | */ |
621 | #if MHD_SCKT_EAGAIN_ == MHD_SCKT_EWOULDBLOCK_ | 641 | #if MHD_SCKT_EAGAIN_ == MHD_SCKT_EWOULDBLOCK_ |
622 | # define MHD_SCKT_ERR_IS_EAGAIN_(err) MHD_SCKT_ERR_IS_((err),MHD_SCKT_EAGAIN_) | 642 | # define MHD_SCKT_ERR_IS_EAGAIN_(err) MHD_SCKT_ERR_IS_ ((err),MHD_SCKT_EAGAIN_) |
623 | #else /* MHD_SCKT_EAGAIN_ != MHD_SCKT_EWOULDBLOCK_ */ | 643 | #else /* MHD_SCKT_EAGAIN_ != MHD_SCKT_EWOULDBLOCK_ */ |
624 | # define MHD_SCKT_ERR_IS_EAGAIN_(err) ( MHD_SCKT_ERR_IS_((err),MHD_SCKT_EAGAIN_) || \ | 644 | # define MHD_SCKT_ERR_IS_EAGAIN_(err) (MHD_SCKT_ERR_IS_ ((err), \ |
625 | MHD_SCKT_ERR_IS_((err),MHD_SCKT_EWOULDBLOCK_) ) | 645 | MHD_SCKT_EAGAIN_) || \ |
646 | MHD_SCKT_ERR_IS_ ((err), \ | ||
647 | MHD_SCKT_EWOULDBLOCK_) ) | ||
626 | #endif /* MHD_SCKT_EAGAIN_ != MHD_SCKT_EWOULDBLOCK_ */ | 648 | #endif /* MHD_SCKT_EAGAIN_ != MHD_SCKT_EWOULDBLOCK_ */ |
627 | 649 | ||
628 | /** | 650 | /** |
@@ -630,10 +652,17 @@ | |||
630 | * @return boolean true if @a err is any kind of "low resource" error, | 652 | * @return boolean true if @a err is any kind of "low resource" error, |
631 | * boolean false otherwise. | 653 | * boolean false otherwise. |
632 | */ | 654 | */ |
633 | #define MHD_SCKT_ERR_IS_LOW_RESOURCES_(err) ( MHD_SCKT_ERR_IS_((err),MHD_SCKT_EMFILE_) || \ | 655 | #define MHD_SCKT_ERR_IS_LOW_RESOURCES_(err) (MHD_SCKT_ERR_IS_ ((err), \ |
634 | MHD_SCKT_ERR_IS_((err),MHD_SCKT_ENFILE_) || \ | 656 | MHD_SCKT_EMFILE_) \ |
635 | MHD_SCKT_ERR_IS_((err),MHD_SCKT_ENOMEM_) || \ | 657 | || \ |
636 | MHD_SCKT_ERR_IS_((err),MHD_SCKT_ENOBUFS_) ) | 658 | MHD_SCKT_ERR_IS_ ((err), \ |
659 | MHD_SCKT_ENFILE_) \ | ||
660 | || \ | ||
661 | MHD_SCKT_ERR_IS_ ((err), \ | ||
662 | MHD_SCKT_ENOMEM_) \ | ||
663 | || \ | ||
664 | MHD_SCKT_ERR_IS_ ((err), \ | ||
665 | MHD_SCKT_ENOBUFS_) ) | ||
637 | 666 | ||
638 | /** | 667 | /** |
639 | * Check whether is given socket error is type of "incoming connection | 668 | * Check whether is given socket error is type of "incoming connection |
@@ -642,9 +671,11 @@ | |||
642 | * boolean false otherwise. | 671 | * boolean false otherwise. |
643 | */ | 672 | */ |
644 | #if defined(MHD_POSIX_SOCKETS) | 673 | #if defined(MHD_POSIX_SOCKETS) |
645 | # define MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_(err) MHD_SCKT_ERR_IS_((err),MHD_SCKT_ECONNABORTED_) | 674 | # define MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_(err) MHD_SCKT_ERR_IS_ ((err), \ |
675 | MHD_SCKT_ECONNABORTED_) | ||
646 | #elif defined(MHD_WINSOCK_SOCKETS) | 676 | #elif defined(MHD_WINSOCK_SOCKETS) |
647 | # define MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_(err) MHD_SCKT_ERR_IS_((err),MHD_SCKT_ECONNRESET_) | 677 | # define MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_(err) MHD_SCKT_ERR_IS_ ((err), \ |
678 | MHD_SCKT_ECONNRESET_) | ||
648 | #endif | 679 | #endif |
649 | 680 | ||
650 | /** | 681 | /** |
@@ -653,8 +684,11 @@ | |||
653 | * @return boolean true is @a err match described socket error code, | 684 | * @return boolean true is @a err match described socket error code, |
654 | * boolean false otherwise. | 685 | * boolean false otherwise. |
655 | */ | 686 | */ |
656 | #define MHD_SCKT_ERR_IS_REMOTE_DISCNN_(err) ( MHD_SCKT_ERR_IS_((err),MHD_SCKT_ECONNRESET_) || \ | 687 | #define MHD_SCKT_ERR_IS_REMOTE_DISCNN_(err) (MHD_SCKT_ERR_IS_ ((err), \ |
657 | MHD_SCKT_ERR_IS_((err),MHD_SCKT_ECONNABORTED_)) | 688 | MHD_SCKT_ECONNRESET_) \ |
689 | || \ | ||
690 | MHD_SCKT_ERR_IS_ ((err), \ | ||
691 | MHD_SCKT_ECONNABORTED_)) | ||
658 | 692 | ||
659 | /* Specific error code set */ | 693 | /* Specific error code set */ |
660 | 694 | ||
@@ -663,12 +697,16 @@ | |||
663 | * available on platform. | 697 | * available on platform. |
664 | */ | 698 | */ |
665 | #if MHD_SCKT_MISSING_ERR_CODE_ != MHD_SCKT_ENOMEM_ | 699 | #if MHD_SCKT_MISSING_ERR_CODE_ != MHD_SCKT_ENOMEM_ |
666 | # define MHD_socket_set_error_to_ENOMEM() MHD_socket_set_error_(MHD_SCKT_ENOMEM_) | 700 | # define MHD_socket_set_error_to_ENOMEM() MHD_socket_set_error_ ( \ |
701 | MHD_SCKT_ENOMEM_) | ||
667 | #elif MHD_SCKT_MISSING_ERR_CODE_ != MHD_SCKT_ENOBUFS_ | 702 | #elif MHD_SCKT_MISSING_ERR_CODE_ != MHD_SCKT_ENOBUFS_ |
668 | # define MHD_socket_set_error_to_ENOMEM() MHD_socket_set_error_(MHD_SCKT_ENOBUFS_) | 703 | # define MHD_socket_set_error_to_ENOMEM() MHD_socket_set_error_ ( \ |
704 | MHD_SCKT_ENOBUFS_) | ||
669 | #else | 705 | #else |
670 | # warning No suitable replacement for ENOMEM error codes is found. Edit this file and add replacement code which is defined on system. | 706 | # warning \ |
671 | # define MHD_socket_set_error_to_ENOMEM() MHD_socket_set_error_(MHD_SCKT_ENOMEM_) | 707 | No suitable replacement for ENOMEM error codes is found. Edit this file and add replacement code which is defined on system. |
708 | # define MHD_socket_set_error_to_ENOMEM() MHD_socket_set_error_ ( \ | ||
709 | MHD_SCKT_ENOMEM_) | ||
672 | #endif | 710 | #endif |
673 | 711 | ||
674 | /* Socket functions */ | 712 | /* Socket functions */ |
@@ -680,22 +718,26 @@ | |||
680 | #endif /* AF_UNIX */ | 718 | #endif /* AF_UNIX */ |
681 | 719 | ||
682 | #if defined(MHD_POSIX_SOCKETS) && defined(MHD_SCKT_LOCAL) | 720 | #if defined(MHD_POSIX_SOCKETS) && defined(MHD_SCKT_LOCAL) |
683 | # define MHD_socket_pair_(fdarr) (!socketpair(MHD_SCKT_LOCAL, SOCK_STREAM, 0, (fdarr))) | 721 | # define MHD_socket_pair_(fdarr) (! socketpair (MHD_SCKT_LOCAL, SOCK_STREAM, 0, \ |
722 | (fdarr))) | ||
684 | # if defined(HAVE_SOCK_NONBLOCK) | 723 | # if defined(HAVE_SOCK_NONBLOCK) |
685 | # define MHD_socket_pair_nblk_(fdarr) (!socketpair(MHD_SCKT_LOCAL, SOCK_STREAM | SOCK_NONBLOCK, 0, (fdarr))) | 724 | # define MHD_socket_pair_nblk_(fdarr) (! socketpair (MHD_SCKT_LOCAL, \ |
725 | SOCK_STREAM \ | ||
726 | | SOCK_NONBLOCK, 0, \ | ||
727 | (fdarr))) | ||
686 | # endif /* HAVE_SOCK_NONBLOCK*/ | 728 | # endif /* HAVE_SOCK_NONBLOCK*/ |
687 | #elif defined(MHD_WINSOCK_SOCKETS) | 729 | #elif defined(MHD_WINSOCK_SOCKETS) |
688 | /** | 730 | /** |
689 | * Create pair of mutually connected TCP/IP sockets on loopback address | 731 | * Create pair of mutually connected TCP/IP sockets on loopback address |
690 | * @param sockets_pair array to receive resulted sockets | 732 | * @param sockets_pair array to receive resulted sockets |
691 | * @param non_blk if set to non-zero value, sockets created in non-blocking mode | 733 | * @param non_blk if set to non-zero value, sockets created in non-blocking mode |
692 | * otherwise sockets will be in blocking mode | 734 | * otherwise sockets will be in blocking mode |
693 | * @return non-zero if succeeded, zero otherwise | 735 | * @return non-zero if succeeded, zero otherwise |
694 | */ | 736 | */ |
695 | int MHD_W32_socket_pair_(SOCKET sockets_pair[2], int non_blk); | 737 | int MHD_W32_socket_pair_ (SOCKET sockets_pair[2], int non_blk); |
696 | 738 | ||
697 | # define MHD_socket_pair_(fdarr) MHD_W32_socket_pair_((fdarr), 0) | 739 | # define MHD_socket_pair_(fdarr) MHD_W32_socket_pair_ ((fdarr), 0) |
698 | # define MHD_socket_pair_nblk_(fdarr) MHD_W32_socket_pair_((fdarr), 1) | 740 | # define MHD_socket_pair_nblk_(fdarr) MHD_W32_socket_pair_ ((fdarr), 1) |
699 | #endif | 741 | #endif |
700 | 742 | ||
701 | /** | 743 | /** |
@@ -737,7 +779,7 @@ MHD_socket_noninheritable_ (MHD_socket sock); | |||
737 | 779 | ||
738 | 780 | ||
739 | #if defined(SOL_SOCKET) && defined(SO_NOSIGPIPE) | 781 | #if defined(SOL_SOCKET) && defined(SO_NOSIGPIPE) |
740 | static const int _MHD_socket_int_one = 1; | 782 | static const int _MHD_socket_int_one = 1; |
741 | /** | 783 | /** |
742 | * Change socket options to no signal on remote disconnect. | 784 | * Change socket options to no signal on remote disconnect. |
743 | * | 785 | * |
@@ -745,7 +787,8 @@ MHD_socket_noninheritable_ (MHD_socket sock); | |||
745 | * @return non-zero if succeeded, zero otherwise | 787 | * @return non-zero if succeeded, zero otherwise |
746 | */ | 788 | */ |
747 | # define MHD_socket_nosignal_(sock) \ | 789 | # define MHD_socket_nosignal_(sock) \ |
748 | (!setsockopt((sock),SOL_SOCKET,SO_NOSIGPIPE,&_MHD_socket_int_one,sizeof(_MHD_socket_int_one))) | 790 | (! setsockopt ((sock),SOL_SOCKET,SO_NOSIGPIPE,&_MHD_socket_int_one, \ |
791 | sizeof(_MHD_socket_int_one))) | ||
749 | #endif /* SOL_SOCKET && SO_NOSIGPIPE */ | 792 | #endif /* SOL_SOCKET && SO_NOSIGPIPE */ |
750 | 793 | ||
751 | /** | 794 | /** |
diff --git a/src/lib/mhd_str.c b/src/lib/mhd_str.c index d0b03ead..6f2d7b98 100644 --- a/src/lib/mhd_str.c +++ b/src/lib/mhd_str.c | |||
@@ -117,8 +117,8 @@ _MHD_static_inline bool | |||
117 | isasciixdigit (char c) | 117 | isasciixdigit (char c) |
118 | { | 118 | { |
119 | return isasciidigit (c) || | 119 | return isasciidigit (c) || |
120 | ( (c >= 'A') && (c <= 'F') ) || | 120 | ( (c >= 'A') && (c <= 'F') ) || |
121 | ( (c >= 'a') && (c <= 'f') ); | 121 | ( (c >= 'a') && (c <= 'f') ); |
122 | } | 122 | } |
123 | 123 | ||
124 | 124 | ||
@@ -181,7 +181,7 @@ _MHD_static_inline int | |||
181 | todigitvalue (char c) | 181 | todigitvalue (char c) |
182 | { | 182 | { |
183 | if (isasciidigit (c)) | 183 | if (isasciidigit (c)) |
184 | return (unsigned char)(c - '0'); | 184 | return (unsigned char) (c - '0'); |
185 | 185 | ||
186 | return -1; | 186 | return -1; |
187 | } | 187 | } |
@@ -198,11 +198,11 @@ _MHD_static_inline int | |||
198 | toxdigitvalue (char c) | 198 | toxdigitvalue (char c) |
199 | { | 199 | { |
200 | if (isasciidigit (c)) | 200 | if (isasciidigit (c)) |
201 | return (unsigned char)(c - '0'); | 201 | return (unsigned char) (c - '0'); |
202 | if ( (c >= 'A') && (c <= 'F') ) | 202 | if ( (c >= 'A') && (c <= 'F') ) |
203 | return (unsigned char)(c - 'A' + 10); | 203 | return (unsigned char) (c - 'A' + 10); |
204 | if ( (c >= 'a') && (c <= 'f') ) | 204 | if ( (c >= 'a') && (c <= 'f') ) |
205 | return (unsigned char)(c - 'a' + 10); | 205 | return (unsigned char) (c - 'a' + 10); |
206 | 206 | ||
207 | return -1; | 207 | return -1; |
208 | } | 208 | } |
@@ -216,7 +216,7 @@ toxdigitvalue (char c) | |||
216 | * @return boolean true if character is lower case letter, | 216 | * @return boolean true if character is lower case letter, |
217 | * boolean false otherwise | 217 | * boolean false otherwise |
218 | */ | 218 | */ |
219 | #define isasciilower(c) (((char)(c)) >= 'a' && ((char)(c)) <= 'z') | 219 | #define isasciilower(c) (((char) (c)) >= 'a' && ((char) (c)) <= 'z') |
220 | 220 | ||
221 | 221 | ||
222 | /** | 222 | /** |
@@ -226,7 +226,7 @@ toxdigitvalue (char c) | |||
226 | * @return boolean true if character is upper case letter, | 226 | * @return boolean true if character is upper case letter, |
227 | * boolean false otherwise | 227 | * boolean false otherwise |
228 | */ | 228 | */ |
229 | #define isasciiupper(c) (((char)(c)) >= 'A' && ((char)(c)) <= 'Z') | 229 | #define isasciiupper(c) (((char) (c)) >= 'A' && ((char) (c)) <= 'Z') |
230 | 230 | ||
231 | 231 | ||
232 | /** | 232 | /** |
@@ -236,7 +236,7 @@ toxdigitvalue (char c) | |||
236 | * @return boolean true if character is letter, boolean false | 236 | * @return boolean true if character is letter, boolean false |
237 | * otherwise | 237 | * otherwise |
238 | */ | 238 | */ |
239 | #define isasciialpha(c) (isasciilower(c) || isasciiupper(c)) | 239 | #define isasciialpha(c) (isasciilower (c) || isasciiupper (c)) |
240 | 240 | ||
241 | 241 | ||
242 | /** | 242 | /** |
@@ -246,7 +246,7 @@ toxdigitvalue (char c) | |||
246 | * @return boolean true if character is decimal digit, boolean false | 246 | * @return boolean true if character is decimal digit, boolean false |
247 | * otherwise | 247 | * otherwise |
248 | */ | 248 | */ |
249 | #define isasciidigit(c) (((char)(c)) >= '0' && ((char)(c)) <= '9') | 249 | #define isasciidigit(c) (((char) (c)) >= '0' && ((char) (c)) <= '9') |
250 | 250 | ||
251 | 251 | ||
252 | /** | 252 | /** |
@@ -256,9 +256,9 @@ toxdigitvalue (char c) | |||
256 | * @return boolean true if character is hexadecimal digit, | 256 | * @return boolean true if character is hexadecimal digit, |
257 | * boolean false otherwise | 257 | * boolean false otherwise |
258 | */ | 258 | */ |
259 | #define isasciixdigit(c) (isasciidigit((c)) || \ | 259 | #define isasciixdigit(c) (isasciidigit ((c)) || \ |
260 | (((char)(c)) >= 'A' && ((char)(c)) <= 'F') || \ | 260 | (((char) (c)) >= 'A' && ((char) (c)) <= 'F') || \ |
261 | (((char)(c)) >= 'a' && ((char)(c)) <= 'f') ) | 261 | (((char) (c)) >= 'a' && ((char) (c)) <= 'f') ) |
262 | 262 | ||
263 | 263 | ||
264 | /** | 264 | /** |
@@ -268,7 +268,7 @@ toxdigitvalue (char c) | |||
268 | * @return boolean true if character is decimal digit or letter, | 268 | * @return boolean true if character is decimal digit or letter, |
269 | * boolean false otherwise | 269 | * boolean false otherwise |
270 | */ | 270 | */ |
271 | #define isasciialnum(c) (isasciialpha(c) || isasciidigit(c)) | 271 | #define isasciialnum(c) (isasciialpha (c) || isasciidigit (c)) |
272 | 272 | ||
273 | 273 | ||
274 | /** | 274 | /** |
@@ -280,7 +280,8 @@ toxdigitvalue (char c) | |||
280 | * @param c character to convert | 280 | * @param c character to convert |
281 | * @return converted to lower case character | 281 | * @return converted to lower case character |
282 | */ | 282 | */ |
283 | #define toasciilower(c) ((isasciiupper(c)) ? (((char)(c)) - 'A' + 'a') : ((char)(c))) | 283 | #define toasciilower(c) ((isasciiupper (c)) ? (((char) (c)) - 'A' + 'a') : \ |
284 | ((char) (c))) | ||
284 | 285 | ||
285 | 286 | ||
286 | /** | 287 | /** |
@@ -292,7 +293,8 @@ toxdigitvalue (char c) | |||
292 | * @param c character to convert | 293 | * @param c character to convert |
293 | * @return converted to upper case character | 294 | * @return converted to upper case character |
294 | */ | 295 | */ |
295 | #define toasciiupper(c) ((isasciilower(c)) ? (((char)(c)) - 'a' + 'A') : ((char)(c))) | 296 | #define toasciiupper(c) ((isasciilower (c)) ? (((char) (c)) - 'a' + 'A') : \ |
297 | ((char) (c))) | ||
296 | 298 | ||
297 | 299 | ||
298 | /** | 300 | /** |
@@ -301,7 +303,8 @@ toxdigitvalue (char c) | |||
301 | * @param c character to convert | 303 | * @param c character to convert |
302 | * @return value of hexadecimal digit or -1 if @ c is not hexadecimal digit | 304 | * @return value of hexadecimal digit or -1 if @ c is not hexadecimal digit |
303 | */ | 305 | */ |
304 | #define todigitvalue(c) (isasciidigit(c) ? (int)(((char)(c)) - '0') : (int)(-1)) | 306 | #define todigitvalue(c) (isasciidigit (c) ? (int) (((char) (c)) - '0') : \ |
307 | (int) (-1)) | ||
305 | 308 | ||
306 | 309 | ||
307 | /** | 310 | /** |
@@ -309,11 +312,12 @@ toxdigitvalue (char c) | |||
309 | * @param c character to convert | 312 | * @param c character to convert |
310 | * @return value of hexadecimal digit or -1 if @ c is not hexadecimal digit | 313 | * @return value of hexadecimal digit or -1 if @ c is not hexadecimal digit |
311 | */ | 314 | */ |
312 | #define toxdigitvalue(c) ( isasciidigit(c) ? (int)(((char)(c)) - '0') : \ | 315 | #define toxdigitvalue(c) (isasciidigit (c) ? (int) (((char) (c)) - '0') : \ |
313 | ( (((char)(c)) >= 'A' && ((char)(c)) <= 'F') ? \ | 316 | ( (((char) (c)) >= 'A' && ((char) (c)) <= 'F') ? \ |
314 | (int)(((unsigned char)(c)) - 'A' + 10) : \ | 317 | (int) (((unsigned char) (c)) - 'A' + 10) : \ |
315 | ( (((char)(c)) >= 'a' && ((char)(c)) <= 'f') ? \ | 318 | ( (((char) (c)) >= 'a' && ((char) (c)) <= 'f') ? \ |
316 | (int)(((unsigned char)(c)) - 'a' + 10) : (int)(-1) ))) | 319 | (int) (((unsigned char) (c)) - 'a' + 10) : \ |
320 | (int) (-1) ))) | ||
317 | #endif /* !INLINE_FUNC */ | 321 | #endif /* !INLINE_FUNC */ |
318 | 322 | ||
319 | 323 | ||
@@ -326,19 +330,19 @@ toxdigitvalue (char c) | |||
326 | * @return non-zero if two strings are equal, zero otherwise. | 330 | * @return non-zero if two strings are equal, zero otherwise. |
327 | */ | 331 | */ |
328 | int | 332 | int |
329 | MHD_str_equal_caseless_ (const char * str1, | 333 | MHD_str_equal_caseless_ (const char *str1, |
330 | const char * str2) | 334 | const char *str2) |
331 | { | 335 | { |
332 | while (0 != (*str1)) | 336 | while (0 != (*str1)) |
333 | { | 337 | { |
334 | const char c1 = *str1; | 338 | const char c1 = *str1; |
335 | const char c2 = *str2; | 339 | const char c2 = *str2; |
336 | if ( (c1 != c2) && | 340 | if ( (c1 != c2) && |
337 | (toasciilower (c1) != toasciilower (c2)) ) | 341 | (toasciilower (c1) != toasciilower (c2)) ) |
338 | return 0; | 342 | return 0; |
339 | str1++; | 343 | str1++; |
340 | str2++; | 344 | str2++; |
341 | } | 345 | } |
342 | return 0 == (*str2); | 346 | return 0 == (*str2); |
343 | } | 347 | } |
344 | #endif /* ! MHD_FAVOR_SMALL_CODE */ | 348 | #endif /* ! MHD_FAVOR_SMALL_CODE */ |
@@ -356,23 +360,23 @@ MHD_str_equal_caseless_ (const char * str1, | |||
356 | * @return non-zero if two strings are equal, zero otherwise. | 360 | * @return non-zero if two strings are equal, zero otherwise. |
357 | */ | 361 | */ |
358 | int | 362 | int |
359 | MHD_str_equal_caseless_n_ (const char * const str1, | 363 | MHD_str_equal_caseless_n_ (const char *const str1, |
360 | const char * const str2, | 364 | const char *const str2, |
361 | size_t maxlen) | 365 | size_t maxlen) |
362 | { | 366 | { |
363 | size_t i; | 367 | size_t i; |
364 | 368 | ||
365 | for (i = 0; i < maxlen; ++i) | 369 | for (i = 0; i < maxlen; ++i) |
366 | { | 370 | { |
367 | const char c1 = str1[i]; | 371 | const char c1 = str1[i]; |
368 | const char c2 = str2[i]; | 372 | const char c2 = str2[i]; |
369 | if (0 == c2) | 373 | if (0 == c2) |
370 | return 0 == c1; | 374 | return 0 == c1; |
371 | if ( (c1 != c2) && | 375 | if ( (c1 != c2) && |
372 | (toasciilower (c1) != toasciilower (c2)) ) | 376 | (toasciilower (c1) != toasciilower (c2)) ) |
373 | return 0; | 377 | return 0; |
374 | } | 378 | } |
375 | return !0; | 379 | return ! 0; |
376 | } | 380 | } |
377 | 381 | ||
378 | 382 | ||
@@ -390,46 +394,49 @@ MHD_str_equal_caseless_n_ (const char * const str1, | |||
390 | * @return non-zero if two strings are equal, zero otherwise. | 394 | * @return non-zero if two strings are equal, zero otherwise. |
391 | */ | 395 | */ |
392 | bool | 396 | bool |
393 | MHD_str_has_token_caseless_ (const char * str, | 397 | MHD_str_has_token_caseless_ (const char *str, |
394 | const char * const token, | 398 | const char *const token, |
395 | size_t token_len) | 399 | size_t token_len) |
396 | { | 400 | { |
397 | if (0 == token_len) | 401 | if (0 == token_len) |
398 | return false; | 402 | return false; |
399 | 403 | ||
400 | while (0 != *str) | 404 | while (0 != *str) |
405 | { | ||
406 | size_t i; | ||
407 | /* Skip all whitespaces and empty tokens. */ | ||
408 | while (' ' == *str || '\t' == *str || ',' == *str) | ||
409 | str++; | ||
410 | |||
411 | /* Check for token match. */ | ||
412 | i = 0; | ||
413 | while (1) | ||
401 | { | 414 | { |
402 | size_t i; | 415 | const char sc = *(str++); |
403 | /* Skip all whitespaces and empty tokens. */ | 416 | const char tc = token[i++]; |
404 | while (' ' == *str || '\t' == *str || ',' == *str) str++; | 417 | |
405 | 418 | if (0 == sc) | |
406 | /* Check for token match. */ | 419 | return false; |
407 | i = 0; | 420 | if ( (sc != tc) && |
408 | while (1) | 421 | (toasciilower (sc) != toasciilower (tc)) ) |
409 | { | 422 | break; |
410 | const char sc = *(str++); | 423 | if (i >= token_len) |
411 | const char tc = token[i++]; | 424 | { |
412 | 425 | /* Check whether substring match token fully or | |
413 | if (0 == sc) | 426 | * has additional unmatched chars at tail. */ |
414 | return false; | 427 | while (' ' == *str || '\t' == *str) |
415 | if ( (sc != tc) && | 428 | str++; |
416 | (toasciilower (sc) != toasciilower (tc)) ) | 429 | /* End of (sub)string? */ |
417 | break; | 430 | if ((0 == *str) ||(',' == *str) ) |
418 | if (i >= token_len) | 431 | return true; |
419 | { | 432 | /* Unmatched chars at end of substring. */ |
420 | /* Check whether substring match token fully or | 433 | break; |
421 | * has additional unmatched chars at tail. */ | 434 | } |
422 | while (' ' == *str || '\t' == *str) str++; | ||
423 | /* End of (sub)string? */ | ||
424 | if (0 == *str || ',' == *str) | ||
425 | return true; | ||
426 | /* Unmatched chars at end of substring. */ | ||
427 | break; | ||
428 | } | ||
429 | } | ||
430 | /* Find next substring. */ | ||
431 | while (0 != *str && ',' != *str) str++; | ||
432 | } | 435 | } |
436 | /* Find next substring. */ | ||
437 | while (0 != *str && ',' != *str) | ||
438 | str++; | ||
439 | } | ||
433 | return false; | 440 | return false; |
434 | } | 441 | } |
435 | 442 | ||
@@ -450,25 +457,25 @@ size_t | |||
450 | MHD_str_to_uint64_ (const char *str, | 457 | MHD_str_to_uint64_ (const char *str, |
451 | uint64_t *out_val) | 458 | uint64_t *out_val) |
452 | { | 459 | { |
453 | const char * const start = str; | 460 | const char *const start = str; |
454 | uint64_t res; | 461 | uint64_t res; |
455 | 462 | ||
456 | if (!str || !out_val || !isasciidigit(str[0])) | 463 | if (! str || ! out_val || ! isasciidigit (str[0])) |
457 | return 0; | 464 | return 0; |
458 | 465 | ||
459 | res = 0; | 466 | res = 0; |
460 | do | 467 | do |
461 | { | 468 | { |
462 | const int digit = (unsigned char)(*str) - '0'; | 469 | const int digit = (unsigned char) (*str) - '0'; |
463 | if ( (res > (UINT64_MAX / 10)) || | 470 | if ( (res > (UINT64_MAX / 10)) || |
464 | ( (res == (UINT64_MAX / 10)) && | 471 | ( (res == (UINT64_MAX / 10)) && |
465 | ((uint64_t)digit > (UINT64_MAX % 10)) ) ) | 472 | ((uint64_t) digit > (UINT64_MAX % 10)) ) ) |
466 | return 0; | 473 | return 0; |
467 | 474 | ||
468 | res *= 10; | 475 | res *= 10; |
469 | res += digit; | 476 | res += digit; |
470 | str++; | 477 | str++; |
471 | } while (isasciidigit (*str)); | 478 | } while (isasciidigit (*str)); |
472 | 479 | ||
473 | *out_val = res; | 480 | *out_val = res; |
474 | return str - start; | 481 | return str - start; |
@@ -489,34 +496,34 @@ MHD_str_to_uint64_ (const char *str, | |||
489 | * then possible to store in uint64_t or @a out_val is NULL | 496 | * then possible to store in uint64_t or @a out_val is NULL |
490 | */ | 497 | */ |
491 | size_t | 498 | size_t |
492 | MHD_str_to_uint64_n_ (const char * str, | 499 | MHD_str_to_uint64_n_ (const char *str, |
493 | size_t maxlen, | 500 | size_t maxlen, |
494 | uint64_t *out_val) | 501 | uint64_t *out_val) |
495 | { | 502 | { |
496 | uint64_t res; | 503 | uint64_t res; |
497 | size_t i; | 504 | size_t i; |
498 | 505 | ||
499 | if (!str || !maxlen || !out_val || !isasciidigit (str[0])) | 506 | if (! str || ! maxlen || ! out_val || ! isasciidigit (str[0])) |
500 | return 0; | 507 | return 0; |
501 | 508 | ||
502 | res = 0; | 509 | res = 0; |
503 | i = 0; | 510 | i = 0; |
504 | do | 511 | do |
505 | { | 512 | { |
506 | const int digit = (unsigned char)str[i] - '0'; | 513 | const int digit = (unsigned char) str[i] - '0'; |
507 | 514 | ||
508 | if ( (res > (UINT64_MAX / 10)) || | 515 | if ( (res > (UINT64_MAX / 10)) || |
509 | ( (res == (UINT64_MAX / 10)) && | 516 | ( (res == (UINT64_MAX / 10)) && |
510 | ((uint64_t)digit > (UINT64_MAX % 10)) ) ) | 517 | ((uint64_t) digit > (UINT64_MAX % 10)) ) ) |
511 | return 0; | 518 | return 0; |
512 | 519 | ||
513 | res *= 10; | 520 | res *= 10; |
514 | res += digit; | 521 | res += digit; |
515 | i++; | 522 | i++; |
516 | } while ( (i < maxlen) && | 523 | } while ( (i < maxlen) && |
517 | isasciidigit (str[i]) ); | 524 | isasciidigit (str[i]) ); |
518 | 525 | ||
519 | *out_val= res; | 526 | *out_val = res; |
520 | return i; | 527 | return i; |
521 | } | 528 | } |
522 | 529 | ||
@@ -532,31 +539,32 @@ MHD_str_to_uint64_n_ (const char * str, | |||
532 | * then possible to store in uint32_t or @a out_val is NULL | 539 | * then possible to store in uint32_t or @a out_val is NULL |
533 | */ | 540 | */ |
534 | size_t | 541 | size_t |
535 | MHD_strx_to_uint32_ (const char * str, | 542 | MHD_strx_to_uint32_ (const char *str, |
536 | uint32_t *out_val) | 543 | uint32_t *out_val) |
537 | { | 544 | { |
538 | const char * const start = str; | 545 | const char *const start = str; |
539 | uint32_t res; | 546 | uint32_t res; |
540 | int digit; | 547 | int digit; |
541 | 548 | ||
542 | if (!str || !out_val) | 549 | if (! str || ! out_val) |
543 | return 0; | 550 | return 0; |
544 | 551 | ||
545 | res = 0; | 552 | res = 0; |
546 | digit = toxdigitvalue (*str); | 553 | digit = toxdigitvalue (*str); |
547 | while (digit >= 0) | 554 | while (digit >= 0) |
555 | { | ||
556 | if ( (res < (UINT32_MAX / 16)) || | ||
557 | ((res == (UINT32_MAX / 16)) &&( (uint32_t) digit <= (UINT32_MAX | ||
558 | % 16)) ) ) | ||
548 | { | 559 | { |
549 | if ( (res < (UINT32_MAX / 16)) || | 560 | res *= 16; |
550 | (res == (UINT32_MAX / 16) && (uint32_t)digit <= (UINT32_MAX % 16)) ) | 561 | res += digit; |
551 | { | ||
552 | res *= 16; | ||
553 | res += digit; | ||
554 | } | ||
555 | else | ||
556 | return 0; | ||
557 | str++; | ||
558 | digit = toxdigitvalue (*str); | ||
559 | } | 562 | } |
563 | else | ||
564 | return 0; | ||
565 | str++; | ||
566 | digit = toxdigitvalue (*str); | ||
567 | } | ||
560 | 568 | ||
561 | if (str - start > 0) | 569 | if (str - start > 0) |
562 | *out_val = res; | 570 | *out_val = res; |
@@ -585,21 +593,22 @@ MHD_strx_to_uint32_n_ (const char *str, | |||
585 | size_t i; | 593 | size_t i; |
586 | uint32_t res; | 594 | uint32_t res; |
587 | int digit; | 595 | int digit; |
588 | if (!str || !out_val) | 596 | if (! str || ! out_val) |
589 | return 0; | 597 | return 0; |
590 | 598 | ||
591 | res = 0; | 599 | res = 0; |
592 | i = 0; | 600 | i = 0; |
593 | while (i < maxlen && (digit = toxdigitvalue (str[i])) >= 0) | 601 | while (i < maxlen && (digit = toxdigitvalue (str[i])) >= 0) |
594 | { | 602 | { |
595 | if ( (res > (UINT32_MAX / 16)) || | 603 | if ( (res > (UINT32_MAX / 16)) || |
596 | (res == (UINT32_MAX / 16) && (uint32_t)digit > (UINT32_MAX % 16)) ) | 604 | ((res == (UINT32_MAX / 16)) &&( (uint32_t) digit > (UINT32_MAX |
597 | return 0; | 605 | % 16)) ) ) |
606 | return 0; | ||
598 | 607 | ||
599 | res *= 16; | 608 | res *= 16; |
600 | res += digit; | 609 | res += digit; |
601 | i++; | 610 | i++; |
602 | } | 611 | } |
603 | 612 | ||
604 | if (i) | 613 | if (i) |
605 | *out_val = res; | 614 | *out_val = res; |
@@ -621,27 +630,28 @@ size_t | |||
621 | MHD_strx_to_uint64_ (const char *str, | 630 | MHD_strx_to_uint64_ (const char *str, |
622 | uint64_t *out_val) | 631 | uint64_t *out_val) |
623 | { | 632 | { |
624 | const char * const start = str; | 633 | const char *const start = str; |
625 | uint64_t res; | 634 | uint64_t res; |
626 | int digit; | 635 | int digit; |
627 | if (!str || !out_val) | 636 | if (! str || ! out_val) |
628 | return 0; | 637 | return 0; |
629 | 638 | ||
630 | res = 0; | 639 | res = 0; |
631 | digit = toxdigitvalue (*str); | 640 | digit = toxdigitvalue (*str); |
632 | while (digit >= 0) | 641 | while (digit >= 0) |
642 | { | ||
643 | if ( (res < (UINT64_MAX / 16)) || | ||
644 | ((res == (UINT64_MAX / 16)) &&( (uint64_t) digit <= (UINT64_MAX | ||
645 | % 16)) ) ) | ||
633 | { | 646 | { |
634 | if ( (res < (UINT64_MAX / 16)) || | 647 | res *= 16; |
635 | (res == (UINT64_MAX / 16) && (uint64_t)digit <= (UINT64_MAX % 16)) ) | 648 | res += digit; |
636 | { | ||
637 | res *= 16; | ||
638 | res += digit; | ||
639 | } | ||
640 | else | ||
641 | return 0; | ||
642 | str++; | ||
643 | digit = toxdigitvalue (*str); | ||
644 | } | 649 | } |
650 | else | ||
651 | return 0; | ||
652 | str++; | ||
653 | digit = toxdigitvalue (*str); | ||
654 | } | ||
645 | 655 | ||
646 | if (str - start > 0) | 656 | if (str - start > 0) |
647 | *out_val = res; | 657 | *out_val = res; |
@@ -663,28 +673,29 @@ MHD_strx_to_uint64_ (const char *str, | |||
663 | * then possible to store in uint64_t or @a out_val is NULL | 673 | * then possible to store in uint64_t or @a out_val is NULL |
664 | */ | 674 | */ |
665 | size_t | 675 | size_t |
666 | MHD_strx_to_uint64_n_ (const char * str, | 676 | MHD_strx_to_uint64_n_ (const char *str, |
667 | size_t maxlen, | 677 | size_t maxlen, |
668 | uint64_t *out_val) | 678 | uint64_t *out_val) |
669 | { | 679 | { |
670 | size_t i; | 680 | size_t i; |
671 | uint64_t res; | 681 | uint64_t res; |
672 | int digit; | 682 | int digit; |
673 | if (!str || !out_val) | 683 | if (! str || ! out_val) |
674 | return 0; | 684 | return 0; |
675 | 685 | ||
676 | res = 0; | 686 | res = 0; |
677 | i = 0; | 687 | i = 0; |
678 | while (i < maxlen && (digit = toxdigitvalue (str[i])) >= 0) | 688 | while (i < maxlen && (digit = toxdigitvalue (str[i])) >= 0) |
679 | { | 689 | { |
680 | if ( (res > (UINT64_MAX / 16)) || | 690 | if ( (res > (UINT64_MAX / 16)) || |
681 | (res == (UINT64_MAX / 16) && (uint64_t)digit > (UINT64_MAX % 16)) ) | 691 | ((res == (UINT64_MAX / 16)) &&( (uint64_t) digit > (UINT64_MAX |
682 | return 0; | 692 | % 16)) ) ) |
693 | return 0; | ||
683 | 694 | ||
684 | res *= 16; | 695 | res *= 16; |
685 | res += digit; | 696 | res += digit; |
686 | i++; | 697 | i++; |
687 | } | 698 | } |
688 | 699 | ||
689 | if (i) | 700 | if (i) |
690 | *out_val = res; | 701 | *out_val = res; |
@@ -713,7 +724,7 @@ MHD_strx_to_uint64_n_ (const char * str, | |||
713 | size_t | 724 | size_t |
714 | MHD_str_to_uvalue_n_ (const char *str, | 725 | MHD_str_to_uvalue_n_ (const char *str, |
715 | size_t maxlen, | 726 | size_t maxlen, |
716 | void * out_val, | 727 | void *out_val, |
717 | size_t val_size, | 728 | size_t val_size, |
718 | uint64_t max_val, | 729 | uint64_t max_val, |
719 | int base) | 730 | int base) |
@@ -725,34 +736,34 @@ MHD_str_to_uvalue_n_ (const char *str, | |||
725 | const uint64_t max_v_mod_b = max_val % base; | 736 | const uint64_t max_v_mod_b = max_val % base; |
726 | /* 'digit->value' must be function, not macro */ | 737 | /* 'digit->value' must be function, not macro */ |
727 | int (*const dfunc)(char) = (base == 16) ? | 738 | int (*const dfunc)(char) = (base == 16) ? |
728 | toxdigitvalue : todigitvalue; | 739 | toxdigitvalue : todigitvalue; |
729 | 740 | ||
730 | if ( !str || !out_val || | 741 | if ( ! str || ! out_val || |
731 | (base != 16 && base != 10) ) | 742 | ((base != 16)&&(base != 10)) ) |
732 | return 0; | 743 | return 0; |
733 | 744 | ||
734 | res = 0; | 745 | res = 0; |
735 | i = 0; | 746 | i = 0; |
736 | while (maxlen > i && 0 <= (digit = dfunc (str[i]))) | 747 | while (maxlen > i && 0 <= (digit = dfunc (str[i]))) |
737 | { | 748 | { |
738 | if ( ((max_v_div_b) < res) || | 749 | if ( ((max_v_div_b) < res) || |
739 | ((max_v_div_b) == res && (max_v_mod_b) < (uint64_t)digit) ) | 750 | (( (max_v_div_b) == res) &&( (max_v_mod_b) < (uint64_t) digit) ) ) |
740 | return 0; | 751 | return 0; |
741 | 752 | ||
742 | res *= base; | 753 | res *= base; |
743 | res += digit; | 754 | res += digit; |
744 | i++; | 755 | i++; |
745 | } | 756 | } |
746 | 757 | ||
747 | if (i) | 758 | if (i) |
748 | { | 759 | { |
749 | if (8 == val_size) | 760 | if (8 == val_size) |
750 | *(uint64_t*)out_val = res; | 761 | *(uint64_t*) out_val = res; |
751 | else if (4 == val_size) | 762 | else if (4 == val_size) |
752 | *(uint32_t*)out_val = (uint32_t)res; | 763 | *(uint32_t*) out_val = (uint32_t) res; |
753 | else | 764 | else |
754 | return 0; | 765 | return 0; |
755 | } | 766 | } |
756 | return i; | 767 | return i; |
757 | } | 768 | } |
758 | #endif /* MHD_FAVOR_SMALL_CODE */ | 769 | #endif /* MHD_FAVOR_SMALL_CODE */ |
diff --git a/src/lib/mhd_str.h b/src/lib/mhd_str.h index 410cc36e..f0f6511d 100644 --- a/src/lib/mhd_str.h +++ b/src/lib/mhd_str.h | |||
@@ -42,7 +42,7 @@ | |||
42 | /** | 42 | /** |
43 | * Determine length of static string / macro strings at compile time. | 43 | * Determine length of static string / macro strings at compile time. |
44 | */ | 44 | */ |
45 | #define MHD_STATICSTR_LEN_(macro) (sizeof(macro)/sizeof(char) - 1) | 45 | #define MHD_STATICSTR_LEN_(macro) (sizeof(macro) / sizeof(char) - 1) |
46 | #endif /* ! MHD_STATICSTR_LEN_ */ | 46 | #endif /* ! MHD_STATICSTR_LEN_ */ |
47 | 47 | ||
48 | /* | 48 | /* |
@@ -58,11 +58,12 @@ | |||
58 | * @return non-zero if two strings are equal, zero otherwise. | 58 | * @return non-zero if two strings are equal, zero otherwise. |
59 | */ | 59 | */ |
60 | int | 60 | int |
61 | MHD_str_equal_caseless_ (const char * str1, | 61 | MHD_str_equal_caseless_ (const char *str1, |
62 | const char * str2); | 62 | const char *str2); |
63 | #else /* MHD_FAVOR_SMALL_CODE */ | 63 | #else /* MHD_FAVOR_SMALL_CODE */ |
64 | /* Reuse MHD_str_equal_caseless_n_() to reduce size */ | 64 | /* Reuse MHD_str_equal_caseless_n_() to reduce size */ |
65 | #define MHD_str_equal_caseless_(s1,s2) MHD_str_equal_caseless_n_((s1),(s2), SIZE_MAX) | 65 | #define MHD_str_equal_caseless_(s1,s2) MHD_str_equal_caseless_n_ ((s1),(s2), \ |
66 | SIZE_MAX) | ||
66 | #endif /* MHD_FAVOR_SMALL_CODE */ | 67 | #endif /* MHD_FAVOR_SMALL_CODE */ |
67 | 68 | ||
68 | 69 | ||
@@ -77,9 +78,9 @@ MHD_str_equal_caseless_ (const char * str1, | |||
77 | * @return non-zero if two strings are equal, zero otherwise. | 78 | * @return non-zero if two strings are equal, zero otherwise. |
78 | */ | 79 | */ |
79 | int | 80 | int |
80 | MHD_str_equal_caseless_n_ (const char * const str1, | 81 | MHD_str_equal_caseless_n_ (const char *const str1, |
81 | const char * const str2, | 82 | const char *const str2, |
82 | size_t maxlen); | 83 | size_t maxlen); |
83 | 84 | ||
84 | 85 | ||
85 | /** | 86 | /** |
@@ -96,8 +97,8 @@ MHD_str_equal_caseless_n_ (const char * const str1, | |||
96 | * @return non-zero if two strings are equal, zero otherwise. | 97 | * @return non-zero if two strings are equal, zero otherwise. |
97 | */ | 98 | */ |
98 | bool | 99 | bool |
99 | MHD_str_has_token_caseless_ (const char * str, | 100 | MHD_str_has_token_caseless_ (const char *str, |
100 | const char * const token, | 101 | const char *const token, |
101 | size_t token_len); | 102 | size_t token_len); |
102 | 103 | ||
103 | /** | 104 | /** |
@@ -111,7 +112,7 @@ MHD_str_has_token_caseless_ (const char * str, | |||
111 | * @return non-zero if two strings are equal, zero otherwise. | 112 | * @return non-zero if two strings are equal, zero otherwise. |
112 | */ | 113 | */ |
113 | #define MHD_str_has_s_token_caseless_(str,tkn) \ | 114 | #define MHD_str_has_s_token_caseless_(str,tkn) \ |
114 | MHD_str_has_token_caseless_((str),(tkn),MHD_STATICSTR_LEN_(tkn)) | 115 | MHD_str_has_token_caseless_ ((str),(tkn),MHD_STATICSTR_LEN_ (tkn)) |
115 | 116 | ||
116 | #ifndef MHD_FAVOR_SMALL_CODE | 117 | #ifndef MHD_FAVOR_SMALL_CODE |
117 | /* Use individual function for each case to improve speed */ | 118 | /* Use individual function for each case to improve speed */ |
@@ -126,13 +127,13 @@ MHD_str_has_token_caseless_ (const char * str, | |||
126 | * then possible to store in uint64_t or @a out_val is NULL | 127 | * then possible to store in uint64_t or @a out_val is NULL |
127 | */ | 128 | */ |
128 | size_t | 129 | size_t |
129 | MHD_str_to_uint64_ (const char * str, | 130 | MHD_str_to_uint64_ (const char *str, |
130 | uint64_t * out_val); | 131 | uint64_t *out_val); |
131 | 132 | ||
132 | /** | 133 | /** |
133 | * Convert not more then @a maxlen decimal US-ASCII digits in string to | 134 | * Convert not more then @a maxlen decimal US-ASCII digits in string to |
134 | * number in uint64_t. | 135 | * number in uint64_t. |
135 | * Conversion stopped at first non-digit character or after @a maxlen | 136 | * Conversion stopped at first non-digit character or after @a maxlen |
136 | * digits. | 137 | * digits. |
137 | * @param str string to convert | 138 | * @param str string to convert |
138 | * @param maxlen maximum number of characters to process | 139 | * @param maxlen maximum number of characters to process |
@@ -142,9 +143,9 @@ MHD_str_to_uint64_ (const char * str, | |||
142 | * then possible to store in uint64_t or @a out_val is NULL | 143 | * then possible to store in uint64_t or @a out_val is NULL |
143 | */ | 144 | */ |
144 | size_t | 145 | size_t |
145 | MHD_str_to_uint64_n_ (const char * str, | 146 | MHD_str_to_uint64_n_ (const char *str, |
146 | size_t maxlen, | 147 | size_t maxlen, |
147 | uint64_t * out_val); | 148 | uint64_t *out_val); |
148 | 149 | ||
149 | 150 | ||
150 | /** | 151 | /** |
@@ -152,19 +153,19 @@ MHD_str_to_uint64_n_ (const char * str, | |||
152 | * Conversion stopped at first non-digit character. | 153 | * Conversion stopped at first non-digit character. |
153 | * @param str string to convert | 154 | * @param str string to convert |
154 | * @param out_val pointer to uint32_t to store result of conversion | 155 | * @param out_val pointer to uint32_t to store result of conversion |
155 | * @return non-zero number of characters processed on succeed, | 156 | * @return non-zero number of characters processed on succeed, |
156 | * zero if no digit is found, resulting value is larger | 157 | * zero if no digit is found, resulting value is larger |
157 | * then possible to store in uint32_t or @a out_val is NULL | 158 | * then possible to store in uint32_t or @a out_val is NULL |
158 | */ | 159 | */ |
159 | size_t | 160 | size_t |
160 | MHD_strx_to_uint32_ (const char * str, | 161 | MHD_strx_to_uint32_ (const char *str, |
161 | uint32_t * out_val); | 162 | uint32_t *out_val); |
162 | 163 | ||
163 | 164 | ||
164 | /** | 165 | /** |
165 | * Convert not more then @a maxlen hexadecimal US-ASCII digits in string | 166 | * Convert not more then @a maxlen hexadecimal US-ASCII digits in string |
166 | * to number in uint32_t. | 167 | * to number in uint32_t. |
167 | * Conversion stopped at first non-digit character or after @a maxlen | 168 | * Conversion stopped at first non-digit character or after @a maxlen |
168 | * digits. | 169 | * digits. |
169 | * @param str string to convert | 170 | * @param str string to convert |
170 | * @param maxlen maximum number of characters to process | 171 | * @param maxlen maximum number of characters to process |
@@ -174,9 +175,9 @@ MHD_strx_to_uint32_ (const char * str, | |||
174 | * then possible to store in uint32_t or @a out_val is NULL | 175 | * then possible to store in uint32_t or @a out_val is NULL |
175 | */ | 176 | */ |
176 | size_t | 177 | size_t |
177 | MHD_strx_to_uint32_n_ (const char * str, | 178 | MHD_strx_to_uint32_n_ (const char *str, |
178 | size_t maxlen, | 179 | size_t maxlen, |
179 | uint32_t * out_val); | 180 | uint32_t *out_val); |
180 | 181 | ||
181 | 182 | ||
182 | /** | 183 | /** |
@@ -184,19 +185,19 @@ MHD_strx_to_uint32_n_ (const char * str, | |||
184 | * Conversion stopped at first non-digit character. | 185 | * Conversion stopped at first non-digit character. |
185 | * @param str string to convert | 186 | * @param str string to convert |
186 | * @param out_val pointer to uint64_t to store result of conversion | 187 | * @param out_val pointer to uint64_t to store result of conversion |
187 | * @return non-zero number of characters processed on succeed, | 188 | * @return non-zero number of characters processed on succeed, |
188 | * zero if no digit is found, resulting value is larger | 189 | * zero if no digit is found, resulting value is larger |
189 | * then possible to store in uint64_t or @a out_val is NULL | 190 | * then possible to store in uint64_t or @a out_val is NULL |
190 | */ | 191 | */ |
191 | size_t | 192 | size_t |
192 | MHD_strx_to_uint64_ (const char * str, | 193 | MHD_strx_to_uint64_ (const char *str, |
193 | uint64_t * out_val); | 194 | uint64_t *out_val); |
194 | 195 | ||
195 | 196 | ||
196 | /** | 197 | /** |
197 | * Convert not more then @a maxlen hexadecimal US-ASCII digits in string | 198 | * Convert not more then @a maxlen hexadecimal US-ASCII digits in string |
198 | * to number in uint64_t. | 199 | * to number in uint64_t. |
199 | * Conversion stopped at first non-digit character or after @a maxlen | 200 | * Conversion stopped at first non-digit character or after @a maxlen |
200 | * digits. | 201 | * digits. |
201 | * @param str string to convert | 202 | * @param str string to convert |
202 | * @param maxlen maximum number of characters to process | 203 | * @param maxlen maximum number of characters to process |
@@ -206,9 +207,9 @@ MHD_strx_to_uint64_ (const char * str, | |||
206 | * then possible to store in uint64_t or @a out_val is NULL | 207 | * then possible to store in uint64_t or @a out_val is NULL |
207 | */ | 208 | */ |
208 | size_t | 209 | size_t |
209 | MHD_strx_to_uint64_n_ (const char * str, | 210 | MHD_strx_to_uint64_n_ (const char *str, |
210 | size_t maxlen, | 211 | size_t maxlen, |
211 | uint64_t * out_val); | 212 | uint64_t *out_val); |
212 | 213 | ||
213 | #else /* MHD_FAVOR_SMALL_CODE */ | 214 | #else /* MHD_FAVOR_SMALL_CODE */ |
214 | /* Use one universal function and macros to reduce size */ | 215 | /* Use one universal function and macros to reduce size */ |
@@ -216,7 +217,7 @@ MHD_strx_to_uint64_n_ (const char * str, | |||
216 | /** | 217 | /** |
217 | * Generic function for converting not more then @a maxlen | 218 | * Generic function for converting not more then @a maxlen |
218 | * hexadecimal or decimal US-ASCII digits in string to number. | 219 | * hexadecimal or decimal US-ASCII digits in string to number. |
219 | * Conversion stopped at first non-digit character or after @a maxlen | 220 | * Conversion stopped at first non-digit character or after @a maxlen |
220 | * digits. | 221 | * digits. |
221 | * To be used only within macro. | 222 | * To be used only within macro. |
222 | * @param str the string to convert | 223 | * @param str the string to convert |
@@ -230,36 +231,44 @@ MHD_strx_to_uint64_n_ (const char * str, | |||
230 | * then @ max_val or @a out_val is NULL | 231 | * then @ max_val or @a out_val is NULL |
231 | */ | 232 | */ |
232 | size_t | 233 | size_t |
233 | MHD_str_to_uvalue_n_ (const char * str, | 234 | MHD_str_to_uvalue_n_ (const char *str, |
234 | size_t maxlen, | 235 | size_t maxlen, |
235 | void * out_val, | 236 | void *out_val, |
236 | size_t val_size, | 237 | size_t val_size, |
237 | uint64_t max_val, | 238 | uint64_t max_val, |
238 | int base); | 239 | int base); |
239 | 240 | ||
240 | #define MHD_str_to_uint64_(s,ov) MHD_str_to_uvalue_n_((s),SIZE_MAX,(ov),\ | 241 | #define MHD_str_to_uint64_(s,ov) MHD_str_to_uvalue_n_ ((s),SIZE_MAX,(ov), \ |
241 | sizeof(uint64_t),UINT64_MAX,10) | 242 | sizeof(uint64_t), \ |
243 | UINT64_MAX,10) | ||
242 | 244 | ||
243 | #define MHD_str_to_uint64_n_(s,ml,ov) MHD_str_to_uvalue_n_((s),(ml),(ov),\ | 245 | #define MHD_str_to_uint64_n_(s,ml,ov) MHD_str_to_uvalue_n_ ((s),(ml),(ov), \ |
244 | sizeof(uint64_t),UINT64_MAX,10) | 246 | sizeof(uint64_t), \ |
247 | UINT64_MAX,10) | ||
245 | 248 | ||
246 | #define MHD_strx_to_sizet_(s,ov) MHD_str_to_uvalue_n_((s),SIZE_MAX,(ov),\ | 249 | #define MHD_strx_to_sizet_(s,ov) MHD_str_to_uvalue_n_ ((s),SIZE_MAX,(ov), \ |
247 | sizeof(size_t),SIZE_MAX,16) | 250 | sizeof(size_t),SIZE_MAX, \ |
251 | 16) | ||
248 | 252 | ||
249 | #define MHD_strx_to_sizet_n_(s,ml,ov) MHD_str_to_uvalue_n_((s),(ml),(ov),\ | 253 | #define MHD_strx_to_sizet_n_(s,ml,ov) MHD_str_to_uvalue_n_ ((s),(ml),(ov), \ |
250 | sizeof(size_t),SIZE_MAX,16) | 254 | sizeof(size_t), \ |
255 | SIZE_MAX,16) | ||
251 | 256 | ||
252 | #define MHD_strx_to_uint32_(s,ov) MHD_str_to_uvalue_n_((s),SIZE_MAX,(ov),\ | 257 | #define MHD_strx_to_uint32_(s,ov) MHD_str_to_uvalue_n_ ((s),SIZE_MAX,(ov), \ |
253 | sizeof(uint32_t),UINT32_MAX,16) | 258 | sizeof(uint32_t), \ |
259 | UINT32_MAX,16) | ||
254 | 260 | ||
255 | #define MHD_strx_to_uint32_n_(s,ml,ov) MHD_str_to_uvalue_n_((s),(ml),(ov),\ | 261 | #define MHD_strx_to_uint32_n_(s,ml,ov) MHD_str_to_uvalue_n_ ((s),(ml),(ov), \ |
256 | sizeof(uint32_t),UINT32_MAX,16) | 262 | sizeof(uint32_t), \ |
263 | UINT32_MAX,16) | ||
257 | 264 | ||
258 | #define MHD_strx_to_uint64_(s,ov) MHD_str_to_uvalue_n_((s),SIZE_MAX,(ov),\ | 265 | #define MHD_strx_to_uint64_(s,ov) MHD_str_to_uvalue_n_ ((s),SIZE_MAX,(ov), \ |
259 | sizeof(uint64_t),UINT64_MAX,16) | 266 | sizeof(uint64_t), \ |
267 | UINT64_MAX,16) | ||
260 | 268 | ||
261 | #define MHD_strx_to_uint64_n_(s,ml,ov) MHD_str_to_uvalue_n_((s),(ml),(ov),\ | 269 | #define MHD_strx_to_uint64_n_(s,ml,ov) MHD_str_to_uvalue_n_ ((s),(ml),(ov), \ |
262 | sizeof(uint64_t),UINT64_MAX,16) | 270 | sizeof(uint64_t), \ |
271 | UINT64_MAX,16) | ||
263 | 272 | ||
264 | #endif /* MHD_FAVOR_SMALL_CODE */ | 273 | #endif /* MHD_FAVOR_SMALL_CODE */ |
265 | 274 | ||
diff --git a/src/lib/mhd_threads.c b/src/lib/mhd_threads.c index 6578e4b1..a90090f4 100644 --- a/src/lib/mhd_threads.c +++ b/src/lib/mhd_threads.c | |||
@@ -46,12 +46,14 @@ | |||
46 | #else /* MHD_USE_THREAD_NAME_ */ | 46 | #else /* MHD_USE_THREAD_NAME_ */ |
47 | 47 | ||
48 | #if defined(MHD_USE_POSIX_THREADS) | 48 | #if defined(MHD_USE_POSIX_THREADS) |
49 | #if defined(HAVE_PTHREAD_ATTR_SETNAME_NP_NETBSD) || defined(HAVE_PTHREAD_ATTR_SETNAME_NP_IBMI) | 49 | #if defined(HAVE_PTHREAD_ATTR_SETNAME_NP_NETBSD) || \ |
50 | defined(HAVE_PTHREAD_ATTR_SETNAME_NP_IBMI) | ||
50 | # define MHD_USE_THREAD_ATTR_SETNAME 1 | 51 | # define MHD_USE_THREAD_ATTR_SETNAME 1 |
51 | #endif /* HAVE_PTHREAD_ATTR_SETNAME_NP_NETBSD || HAVE_PTHREAD_ATTR_SETNAME_NP_IBMI */ | 52 | #endif /* HAVE_PTHREAD_ATTR_SETNAME_NP_NETBSD || HAVE_PTHREAD_ATTR_SETNAME_NP_IBMI */ |
52 | 53 | ||
53 | #if defined(HAVE_PTHREAD_SETNAME_NP_GNU) || defined(HAVE_PTHREAD_SET_NAME_NP_FREEBSD) \ | 54 | #if defined(HAVE_PTHREAD_SETNAME_NP_GNU) || \ |
54 | || defined(HAVE_PTHREAD_SETNAME_NP_NETBSD) | 55 | defined(HAVE_PTHREAD_SET_NAME_NP_FREEBSD) \ |
56 | || defined(HAVE_PTHREAD_SETNAME_NP_NETBSD) | ||
55 | 57 | ||
56 | /** | 58 | /** |
57 | * Set thread name | 59 | * Set thread name |
@@ -61,25 +63,25 @@ | |||
61 | * @return non-zero on success, zero otherwise | 63 | * @return non-zero on success, zero otherwise |
62 | */ | 64 | */ |
63 | static int | 65 | static int |
64 | MHD_set_thread_name_(const MHD_thread_ID_ thread_id, | 66 | MHD_set_thread_name_ (const MHD_thread_ID_ thread_id, |
65 | const char *thread_name) | 67 | const char *thread_name) |
66 | { | 68 | { |
67 | if (NULL == thread_name) | 69 | if (NULL == thread_name) |
68 | return 0; | 70 | return 0; |
69 | 71 | ||
70 | #if defined(HAVE_PTHREAD_SETNAME_NP_GNU) | 72 | #if defined(HAVE_PTHREAD_SETNAME_NP_GNU) |
71 | return !pthread_setname_np (thread_id, thread_name); | 73 | return ! pthread_setname_np (thread_id, thread_name); |
72 | #elif defined(HAVE_PTHREAD_SET_NAME_NP_FREEBSD) | 74 | #elif defined(HAVE_PTHREAD_SET_NAME_NP_FREEBSD) |
73 | /* FreeBSD and OpenBSD use different name and void return type */ | 75 | /* FreeBSD and OpenBSD use different name and void return type */ |
74 | pthread_set_name_np (thread_id, thread_name); | 76 | pthread_set_name_np (thread_id, thread_name); |
75 | return !0; | 77 | return ! 0; |
76 | #elif defined(HAVE_PTHREAD_SETNAME_NP_NETBSD) | 78 | #elif defined(HAVE_PTHREAD_SETNAME_NP_NETBSD) |
77 | /* NetBSD use 3 arguments: second argument is string in printf-like format, | 79 | /* NetBSD use 3 arguments: second argument is string in printf-like format, |
78 | * third argument is single argument for printf; | 80 | * third argument is single argument for printf; |
79 | * OSF1 use 3 arguments too, but last one always must be zero (NULL). | 81 | * OSF1 use 3 arguments too, but last one always must be zero (NULL). |
80 | * MHD doesn't use '%' in thread names, so both form are used in same way. | 82 | * MHD doesn't use '%' in thread names, so both form are used in same way. |
81 | */ | 83 | */ |
82 | return !pthread_setname_np (thread_id, thread_name, 0); | 84 | return ! pthread_setname_np (thread_id, thread_name, 0); |
83 | #endif /* HAVE_PTHREAD_SETNAME_NP_NETBSD */ | 85 | #endif /* HAVE_PTHREAD_SETNAME_NP_NETBSD */ |
84 | } | 86 | } |
85 | 87 | ||
@@ -90,10 +92,10 @@ MHD_set_thread_name_(const MHD_thread_ID_ thread_id, | |||
90 | * @param n name to set | 92 | * @param n name to set |
91 | * @return non-zero on success, zero otherwise | 93 | * @return non-zero on success, zero otherwise |
92 | */ | 94 | */ |
93 | #define MHD_set_cur_thread_name_(n) MHD_set_thread_name_(pthread_self(),(n)) | 95 | #define MHD_set_cur_thread_name_(n) MHD_set_thread_name_ (pthread_self (),(n)) |
94 | #else /* __QNXNTO__ */ | 96 | #else /* __QNXNTO__ */ |
95 | /* Special case for QNX Neutrino - using zero for thread ID sets name faster. */ | 97 | /* Special case for QNX Neutrino - using zero for thread ID sets name faster. */ |
96 | #define MHD_set_cur_thread_name_(n) MHD_set_thread_name_(0,(n)) | 98 | #define MHD_set_cur_thread_name_(n) MHD_set_thread_name_ (0,(n)) |
97 | #endif /* __QNXNTO__ */ | 99 | #endif /* __QNXNTO__ */ |
98 | #elif defined(HAVE_PTHREAD_SETNAME_NP_DARWIN) | 100 | #elif defined(HAVE_PTHREAD_SETNAME_NP_DARWIN) |
99 | 101 | ||
@@ -102,7 +104,7 @@ MHD_set_thread_name_(const MHD_thread_ID_ thread_id, | |||
102 | * @param n name to set | 104 | * @param n name to set |
103 | * @return non-zero on success, zero otherwise | 105 | * @return non-zero on success, zero otherwise |
104 | */ | 106 | */ |
105 | #define MHD_set_cur_thread_name_(n) (!(pthread_setname_np((n)))) | 107 | #define MHD_set_cur_thread_name_(n) (! (pthread_setname_np ((n)))) |
106 | #endif /* HAVE_PTHREAD_SETNAME_NP_DARWIN */ | 108 | #endif /* HAVE_PTHREAD_SETNAME_NP_DARWIN */ |
107 | 109 | ||
108 | #elif defined(MHD_USE_W32_THREADS) | 110 | #elif defined(MHD_USE_W32_THREADS) |
@@ -117,8 +119,8 @@ MHD_set_thread_name_(const MHD_thread_ID_ thread_id, | |||
117 | * @return non-zero on success, zero otherwise | 119 | * @return non-zero on success, zero otherwise |
118 | */ | 120 | */ |
119 | static int | 121 | static int |
120 | MHD_set_thread_name_(const MHD_thread_ID_ thread_id, | 122 | MHD_set_thread_name_ (const MHD_thread_ID_ thread_id, |
121 | const char *thread_name) | 123 | const char *thread_name) |
122 | { | 124 | { |
123 | static const DWORD VC_SETNAME_EXC = 0x406D1388; | 125 | static const DWORD VC_SETNAME_EXC = 0x406D1388; |
124 | #pragma pack(push,8) | 126 | #pragma pack(push,8) |
@@ -149,7 +151,7 @@ MHD_set_thread_name_(const MHD_thread_ID_ thread_id, | |||
149 | __except (EXCEPTION_EXECUTE_HANDLER) | 151 | __except (EXCEPTION_EXECUTE_HANDLER) |
150 | {} | 152 | {} |
151 | 153 | ||
152 | return !0; | 154 | return ! 0; |
153 | } | 155 | } |
154 | 156 | ||
155 | 157 | ||
@@ -158,7 +160,7 @@ MHD_set_thread_name_(const MHD_thread_ID_ thread_id, | |||
158 | * @param n name to set | 160 | * @param n name to set |
159 | * @return non-zero on success, zero otherwise | 161 | * @return non-zero on success, zero otherwise |
160 | */ | 162 | */ |
161 | #define MHD_set_cur_thread_name_(n) MHD_set_thread_name_(-1,(n)) | 163 | #define MHD_set_cur_thread_name_(n) MHD_set_thread_name_ (-1,(n)) |
162 | #endif /* _MSC_FULL_VER */ | 164 | #endif /* _MSC_FULL_VER */ |
163 | #endif /* MHD_USE_W32_THREADS */ | 165 | #endif /* MHD_USE_W32_THREADS */ |
164 | 166 | ||
@@ -184,21 +186,21 @@ MHD_create_thread_ (MHD_thread_handle_ID_ *thread, | |||
184 | int res; | 186 | int res; |
185 | 187 | ||
186 | if (0 != stack_size) | 188 | if (0 != stack_size) |
189 | { | ||
190 | pthread_attr_t attr; | ||
191 | res = pthread_attr_init (&attr); | ||
192 | if (0 == res) | ||
187 | { | 193 | { |
188 | pthread_attr_t attr; | 194 | res = pthread_attr_setstacksize (&attr, |
189 | res = pthread_attr_init (&attr); | 195 | stack_size); |
190 | if (0 == res) | 196 | if (0 == res) |
191 | { | 197 | res = pthread_create (&(thread->handle), |
192 | res = pthread_attr_setstacksize (&attr, | 198 | &attr, |
193 | stack_size); | 199 | start_routine, |
194 | if (0 == res) | 200 | arg); |
195 | res = pthread_create (&(thread->handle), | 201 | pthread_attr_destroy (&attr); |
196 | &attr, | ||
197 | start_routine, | ||
198 | arg); | ||
199 | pthread_attr_destroy (&attr); | ||
200 | } | ||
201 | } | 202 | } |
203 | } | ||
202 | else | 204 | else |
203 | res = pthread_create (&(thread->handle), | 205 | res = pthread_create (&(thread->handle), |
204 | NULL, | 206 | NULL, |
@@ -208,28 +210,28 @@ MHD_create_thread_ (MHD_thread_handle_ID_ *thread, | |||
208 | if (0 != res) | 210 | if (0 != res) |
209 | errno = res; | 211 | errno = res; |
210 | 212 | ||
211 | return !res; | 213 | return ! res; |
212 | #elif defined(MHD_USE_W32_THREADS) | 214 | #elif defined(MHD_USE_W32_THREADS) |
213 | #if SIZE_MAX != UINT_MAX | 215 | #if SIZE_MAX != UINT_MAX |
214 | if (stack_size > UINT_MAX) | 216 | if (stack_size > UINT_MAX) |
215 | { | 217 | { |
216 | errno = EINVAL; | 218 | errno = EINVAL; |
217 | return 0; | 219 | return 0; |
218 | } | 220 | } |
219 | #endif /* SIZE_MAX != UINT_MAX */ | 221 | #endif /* SIZE_MAX != UINT_MAX */ |
220 | 222 | ||
221 | thread->handle = (MHD_thread_handle_) | 223 | thread->handle = (MHD_thread_handle_) |
222 | _beginthreadex (NULL, | 224 | _beginthreadex (NULL, |
223 | (unsigned int) stack_size, | 225 | (unsigned int) stack_size, |
224 | start_routine, | 226 | start_routine, |
225 | arg, | 227 | arg, |
226 | 0, | 228 | 0, |
227 | NULL); | 229 | NULL); |
228 | 230 | ||
229 | if ((MHD_thread_handle_)-1 == thread->handle) | 231 | if ((MHD_thread_handle_) - 1 == thread->handle) |
230 | return 0; | 232 | return 0; |
231 | 233 | ||
232 | return !0; | 234 | return ! 0; |
233 | #endif | 235 | #endif |
234 | } | 236 | } |
235 | 237 | ||
@@ -258,21 +260,21 @@ struct MHD_named_helper_param_ | |||
258 | static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_ | 260 | static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_ |
259 | named_thread_starter (void *data) | 261 | named_thread_starter (void *data) |
260 | { | 262 | { |
261 | struct MHD_named_helper_param_ * const param = | 263 | struct MHD_named_helper_param_ *const param = |
262 | (struct MHD_named_helper_param_ *) data; | 264 | (struct MHD_named_helper_param_ *) data; |
263 | void * arg; | 265 | void *arg; |
264 | MHD_THREAD_START_ROUTINE_ thr_func; | 266 | MHD_THREAD_START_ROUTINE_ thr_func; |
265 | 267 | ||
266 | if (NULL == data) | 268 | if (NULL == data) |
267 | return (MHD_THRD_RTRN_TYPE_)0; | 269 | return (MHD_THRD_RTRN_TYPE_) 0; |
268 | 270 | ||
269 | MHD_set_cur_thread_name_ (param->name); | 271 | MHD_set_cur_thread_name_ (param->name); |
270 | 272 | ||
271 | arg = param->arg; | 273 | arg = param->arg; |
272 | thr_func = param->start_routine; | 274 | thr_func = param->start_routine; |
273 | free(data); | 275 | free (data); |
274 | 276 | ||
275 | return thr_func(arg); | 277 | return thr_func (arg); |
276 | } | 278 | } |
277 | #endif /* ! MHD_USE_THREAD_ATTR_SETNAME */ | 279 | #endif /* ! MHD_USE_THREAD_ATTR_SETNAME */ |
278 | 280 | ||
@@ -289,7 +291,7 @@ named_thread_starter (void *data) | |||
289 | */ | 291 | */ |
290 | int | 292 | int |
291 | MHD_create_named_thread_ (MHD_thread_handle_ID_ *thread, | 293 | MHD_create_named_thread_ (MHD_thread_handle_ID_ *thread, |
292 | const char* thread_name, | 294 | const char*thread_name, |
293 | size_t stack_size, | 295 | size_t stack_size, |
294 | MHD_THREAD_START_ROUTINE_ start_routine, | 296 | MHD_THREAD_START_ROUTINE_ start_routine, |
295 | void *arg) | 297 | void *arg) |
@@ -300,41 +302,41 @@ MHD_create_named_thread_ (MHD_thread_handle_ID_ *thread, | |||
300 | 302 | ||
301 | res = pthread_attr_init (&attr); | 303 | res = pthread_attr_init (&attr); |
302 | if (0 == res) | 304 | if (0 == res) |
303 | { | 305 | { |
304 | #if defined(HAVE_PTHREAD_ATTR_SETNAME_NP_NETBSD) | 306 | #if defined(HAVE_PTHREAD_ATTR_SETNAME_NP_NETBSD) |
305 | /* NetBSD use 3 arguments: second argument is string in printf-like format, | 307 | /* NetBSD use 3 arguments: second argument is string in printf-like format, |
306 | * third argument is single argument for printf; | 308 | * third argument is single argument for printf; |
307 | * OSF1 use 3 arguments too, but last one always must be zero (NULL). | 309 | * OSF1 use 3 arguments too, but last one always must be zero (NULL). |
308 | * MHD doesn't use '%' in thread names, so both form are used in same way. | 310 | * MHD doesn't use '%' in thread names, so both form are used in same way. |
309 | */ | 311 | */ |
310 | res = pthread_attr_setname_np (&attr, thread_name, 0); | 312 | res = pthread_attr_setname_np (&attr, thread_name, 0); |
311 | #elif defined(HAVE_PTHREAD_ATTR_SETNAME_NP_IBMI) | 313 | #elif defined(HAVE_PTHREAD_ATTR_SETNAME_NP_IBMI) |
312 | res = pthread_attr_setname_np (&attr, thread_name); | 314 | res = pthread_attr_setname_np (&attr, thread_name); |
313 | #else | 315 | #else |
314 | #error No pthread_attr_setname_np() function. | 316 | #error No pthread_attr_setname_np() function. |
315 | #endif | 317 | #endif |
316 | if (res == 0 && 0 != stack_size) | 318 | if ((res == 0) &&(0 != stack_size) ) |
317 | res = pthread_attr_setstacksize (&attr, | 319 | res = pthread_attr_setstacksize (&attr, |
318 | stack_size); | 320 | stack_size); |
319 | if (0 == res) | 321 | if (0 == res) |
320 | res = pthread_create (&(thread->handle), | 322 | res = pthread_create (&(thread->handle), |
321 | &attr, | 323 | &attr, |
322 | start_routine, | 324 | start_routine, |
323 | arg); | 325 | arg); |
324 | pthread_attr_destroy (&attr); | 326 | pthread_attr_destroy (&attr); |
325 | } | 327 | } |
326 | if (0 != res) | 328 | if (0 != res) |
327 | errno = res; | 329 | errno = res; |
328 | 330 | ||
329 | return !res; | 331 | return ! res; |
330 | #else /* ! MHD_USE_THREAD_ATTR_SETNAME */ | 332 | #else /* ! MHD_USE_THREAD_ATTR_SETNAME */ |
331 | struct MHD_named_helper_param_ *param; | 333 | struct MHD_named_helper_param_ *param; |
332 | 334 | ||
333 | if (NULL == thread_name) | 335 | if (NULL == thread_name) |
334 | { | 336 | { |
335 | errno = EINVAL; | 337 | errno = EINVAL; |
336 | return 0; | 338 | return 0; |
337 | } | 339 | } |
338 | 340 | ||
339 | param = malloc (sizeof (struct MHD_named_helper_param_)); | 341 | param = malloc (sizeof (struct MHD_named_helper_param_)); |
340 | if (NULL == param) | 342 | if (NULL == param) |
@@ -347,16 +349,16 @@ MHD_create_named_thread_ (MHD_thread_handle_ID_ *thread, | |||
347 | /* Set thread name in thread itself to avoid problems with | 349 | /* Set thread name in thread itself to avoid problems with |
348 | * threads which terminated before name is set in other thread. | 350 | * threads which terminated before name is set in other thread. |
349 | */ | 351 | */ |
350 | if (! MHD_create_thread_(thread, | 352 | if (! MHD_create_thread_ (thread, |
351 | stack_size, | 353 | stack_size, |
352 | &named_thread_starter, | 354 | &named_thread_starter, |
353 | (void*)param)) | 355 | (void*) param)) |
354 | { | 356 | { |
355 | free (param); | 357 | free (param); |
356 | return 0; | 358 | return 0; |
357 | } | 359 | } |
358 | 360 | ||
359 | return !0; | 361 | return ! 0; |
360 | #endif /* ! MHD_USE_THREAD_ATTR_SETNAME */ | 362 | #endif /* ! MHD_USE_THREAD_ATTR_SETNAME */ |
361 | } | 363 | } |
362 | 364 | ||
diff --git a/src/lib/mhd_threads.h b/src/lib/mhd_threads.h index 6d69b9ed..79520d53 100644 --- a/src/lib/mhd_threads.h +++ b/src/lib/mhd_threads.h | |||
@@ -58,23 +58,26 @@ | |||
58 | 58 | ||
59 | #ifndef MHD_NO_THREAD_NAMES | 59 | #ifndef MHD_NO_THREAD_NAMES |
60 | # if defined(MHD_USE_POSIX_THREADS) | 60 | # if defined(MHD_USE_POSIX_THREADS) |
61 | # if defined(HAVE_PTHREAD_SETNAME_NP_GNU) || defined(HAVE_PTHREAD_SET_NAME_NP_FREEBSD) || \ | 61 | # if defined(HAVE_PTHREAD_SETNAME_NP_GNU) || \ |
62 | defined(HAVE_PTHREAD_SETNAME_NP_DARWIN) || defined(HAVE_PTHREAD_SETNAME_NP_NETBSD) || \ | 62 | defined(HAVE_PTHREAD_SET_NAME_NP_FREEBSD) || \ |
63 | defined(HAVE_PTHREAD_ATTR_SETNAME_NP_NETBSD) || defined(HAVE_PTHREAD_ATTR_SETNAME_NP_IBMI) | 63 | defined(HAVE_PTHREAD_SETNAME_NP_DARWIN) || \ |
64 | defined(HAVE_PTHREAD_SETNAME_NP_NETBSD) || \ | ||
65 | defined(HAVE_PTHREAD_ATTR_SETNAME_NP_NETBSD) || \ | ||
66 | defined(HAVE_PTHREAD_ATTR_SETNAME_NP_IBMI) | ||
64 | # define MHD_USE_THREAD_NAME_ | 67 | # define MHD_USE_THREAD_NAME_ |
65 | # endif /* HAVE_PTHREAD_SETNAME_NP */ | 68 | # endif /* HAVE_PTHREAD_SETNAME_NP */ |
66 | # elif defined(MHD_USE_W32_THREADS) | 69 | # elif defined(MHD_USE_W32_THREADS) |
67 | # ifdef _MSC_FULL_VER | 70 | # ifdef _MSC_FULL_VER |
68 | /* Thread names only available with VC compiler */ | 71 | /* Thread names only available with VC compiler */ |
69 | # define MHD_USE_THREAD_NAME_ | 72 | # define MHD_USE_THREAD_NAME_ |
70 | # endif /* _MSC_FULL_VER */ | 73 | # endif /* _MSC_FULL_VER */ |
71 | # endif | 74 | # endif |
72 | #endif | 75 | #endif |
73 | 76 | ||
74 | #if defined(MHD_USE_POSIX_THREADS) | 77 | #if defined(MHD_USE_POSIX_THREADS) |
75 | typedef pthread_t MHD_thread_handle_; | 78 | typedef pthread_t MHD_thread_handle_; |
76 | #elif defined(MHD_USE_W32_THREADS) | 79 | #elif defined(MHD_USE_W32_THREADS) |
77 | typedef HANDLE MHD_thread_handle_; | 80 | typedef HANDLE MHD_thread_handle_; |
78 | #endif | 81 | #endif |
79 | 82 | ||
80 | #if defined(MHD_USE_POSIX_THREADS) | 83 | #if defined(MHD_USE_POSIX_THREADS) |
@@ -86,9 +89,9 @@ | |||
86 | #endif | 89 | #endif |
87 | 90 | ||
88 | #if defined(MHD_USE_POSIX_THREADS) | 91 | #if defined(MHD_USE_POSIX_THREADS) |
89 | typedef pthread_t MHD_thread_ID_; | 92 | typedef pthread_t MHD_thread_ID_; |
90 | #elif defined(MHD_USE_W32_THREADS) | 93 | #elif defined(MHD_USE_W32_THREADS) |
91 | typedef DWORD MHD_thread_ID_; | 94 | typedef DWORD MHD_thread_ID_; |
92 | #endif | 95 | #endif |
93 | 96 | ||
94 | /* Depending on implementation, pthread_create() MAY set thread ID into | 97 | /* Depending on implementation, pthread_create() MAY set thread ID into |
@@ -100,27 +103,27 @@ | |||
100 | * to save some resources. */ | 103 | * to save some resources. */ |
101 | #if defined(MHD_USE_POSIX_THREADS) | 104 | #if defined(MHD_USE_POSIX_THREADS) |
102 | # ifdef MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD | 105 | # ifdef MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD |
103 | union _MHD_thread_handle_ID_ | 106 | union _MHD_thread_handle_ID_ |
104 | { | 107 | { |
105 | MHD_thread_handle_ handle; /**< To be used in other threads */ | 108 | MHD_thread_handle_ handle; /**< To be used in other threads */ |
106 | MHD_thread_ID_ ID; /**< To be used in thread itself */ | 109 | MHD_thread_ID_ ID; /**< To be used in thread itself */ |
107 | }; | 110 | }; |
108 | typedef union _MHD_thread_handle_ID_ MHD_thread_handle_ID_; | 111 | typedef union _MHD_thread_handle_ID_ MHD_thread_handle_ID_; |
109 | # else /* ! MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD */ | 112 | # else /* ! MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD */ |
110 | struct _MHD_thread_handle_ID_ | 113 | struct _MHD_thread_handle_ID_ |
111 | { | 114 | { |
112 | MHD_thread_handle_ handle; /**< To be used in other threads */ | 115 | MHD_thread_handle_ handle; /**< To be used in other threads */ |
113 | MHD_thread_ID_ ID; /**< To be used in thread itself */ | 116 | MHD_thread_ID_ ID; /**< To be used in thread itself */ |
114 | }; | 117 | }; |
115 | typedef struct _MHD_thread_handle_ID_ MHD_thread_handle_ID_; | 118 | typedef struct _MHD_thread_handle_ID_ MHD_thread_handle_ID_; |
116 | # endif /* ! MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD */ | 119 | # endif /* ! MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD */ |
117 | #elif defined(MHD_USE_W32_THREADS) | 120 | #elif defined(MHD_USE_W32_THREADS) |
118 | struct _MHD_thread_handle_ID_ | 121 | struct _MHD_thread_handle_ID_ |
119 | { | 122 | { |
120 | MHD_thread_handle_ handle; /**< To be used in other threads */ | 123 | MHD_thread_handle_ handle; /**< To be used in other threads */ |
121 | MHD_thread_ID_ ID; /**< To be used in thread itself */ | 124 | MHD_thread_ID_ ID; /**< To be used in thread itself */ |
122 | }; | 125 | }; |
123 | typedef struct _MHD_thread_handle_ID_ MHD_thread_handle_ID_; | 126 | typedef struct _MHD_thread_handle_ID_ MHD_thread_handle_ID_; |
124 | #endif | 127 | #endif |
125 | 128 | ||
126 | #if defined(MHD_USE_POSIX_THREADS) | 129 | #if defined(MHD_USE_POSIX_THREADS) |
@@ -129,14 +132,17 @@ | |||
129 | * @param thread handle to watch | 132 | * @param thread handle to watch |
130 | * @return nonzero on success, zero otherwise | 133 | * @return nonzero on success, zero otherwise |
131 | */ | 134 | */ |
132 | #define MHD_join_thread_(thread) (!pthread_join((thread), NULL)) | 135 | #define MHD_join_thread_(thread) (! pthread_join ((thread), NULL)) |
133 | #elif defined(MHD_USE_W32_THREADS) | 136 | #elif defined(MHD_USE_W32_THREADS) |
134 | /** | 137 | /** |
135 | * Wait until specified thread is ended and free thread handle on success. | 138 | * Wait until specified thread is ended and free thread handle on success. |
136 | * @param thread handle to watch | 139 | * @param thread handle to watch |
137 | * @return nonzero on success, zero otherwise | 140 | * @return nonzero on success, zero otherwise |
138 | */ | 141 | */ |
139 | #define MHD_join_thread_(thread) (WAIT_OBJECT_0 == WaitForSingleObject((thread), INFINITE) ? (CloseHandle((thread)), !0) : 0) | 142 | #define MHD_join_thread_(thread) (WAIT_OBJECT_0 == WaitForSingleObject ( \ |
143 | (thread), INFINITE) ? (CloseHandle ( \ | ||
144 | (thread)), ! 0) : \ | ||
145 | 0) | ||
140 | #endif | 146 | #endif |
141 | 147 | ||
142 | #if defined(MHD_USE_POSIX_THREADS) | 148 | #if defined(MHD_USE_POSIX_THREADS) |
@@ -145,14 +151,14 @@ | |||
145 | * @param ID thread ID to match | 151 | * @param ID thread ID to match |
146 | * @return nonzero on match, zero otherwise | 152 | * @return nonzero on match, zero otherwise |
147 | */ | 153 | */ |
148 | #define MHD_thread_ID_match_current_(ID) (pthread_equal((ID), pthread_self())) | 154 | #define MHD_thread_ID_match_current_(ID) (pthread_equal ((ID), pthread_self ())) |
149 | #elif defined(MHD_USE_W32_THREADS) | 155 | #elif defined(MHD_USE_W32_THREADS) |
150 | /** | 156 | /** |
151 | * Check whether provided thread ID match current thread. | 157 | * Check whether provided thread ID match current thread. |
152 | * @param ID thread ID to match | 158 | * @param ID thread ID to match |
153 | * @return nonzero on match, zero otherwise | 159 | * @return nonzero on match, zero otherwise |
154 | */ | 160 | */ |
155 | #define MHD_thread_ID_match_current_(ID) (GetCurrentThreadId() == (ID)) | 161 | #define MHD_thread_ID_match_current_(ID) (GetCurrentThreadId () == (ID)) |
156 | #endif | 162 | #endif |
157 | 163 | ||
158 | #if defined(MHD_USE_POSIX_THREADS) | 164 | #if defined(MHD_USE_POSIX_THREADS) |
@@ -161,20 +167,22 @@ | |||
161 | * Initialise thread ID. | 167 | * Initialise thread ID. |
162 | * @param thread_handle_ID_ptr pointer to thread handle-ID | 168 | * @param thread_handle_ID_ptr pointer to thread handle-ID |
163 | */ | 169 | */ |
164 | #define MHD_thread_init_(thread_handle_ID_ptr) (void)0 | 170 | #define MHD_thread_init_(thread_handle_ID_ptr) (void) 0 |
165 | # else /* ! MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD */ | 171 | # else /* ! MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD */ |
166 | /** | 172 | /** |
167 | * Initialise thread ID. | 173 | * Initialise thread ID. |
168 | * @param thread_handle_ID_ptr pointer to thread handle-ID | 174 | * @param thread_handle_ID_ptr pointer to thread handle-ID |
169 | */ | 175 | */ |
170 | #define MHD_thread_init_(thread_handle_ID_ptr) ((thread_handle_ID_ptr)->ID=pthread_self()) | 176 | #define MHD_thread_init_(thread_handle_ID_ptr) ((thread_handle_ID_ptr)->ID = \ |
177 | pthread_self ()) | ||
171 | # endif /* ! MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD */ | 178 | # endif /* ! MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD */ |
172 | #elif defined(MHD_USE_W32_THREADS) | 179 | #elif defined(MHD_USE_W32_THREADS) |
173 | /** | 180 | /** |
174 | * Initialise thread ID. | 181 | * Initialise thread ID. |
175 | * @param thread_handle_ID_ptr pointer to thread handle-ID | 182 | * @param thread_handle_ID_ptr pointer to thread handle-ID |
176 | */ | 183 | */ |
177 | #define MHD_thread_init_(thread_handle_ID_ptr) ((thread_handle_ID_ptr)->ID=GetCurrentThreadId()) | 184 | #define MHD_thread_init_(thread_handle_ID_ptr) ((thread_handle_ID_ptr)->ID = \ |
185 | GetCurrentThreadId ()) | ||
178 | #endif | 186 | #endif |
179 | 187 | ||
180 | /** | 188 | /** |
@@ -205,7 +213,7 @@ MHD_create_thread_ (MHD_thread_handle_ID_ *thread, | |||
205 | void *arg); | 213 | void *arg); |
206 | 214 | ||
207 | #ifndef MHD_USE_THREAD_NAME_ | 215 | #ifndef MHD_USE_THREAD_NAME_ |
208 | #define MHD_create_named_thread_(t,n,s,r,a) MHD_create_thread_((t),(s),(r),(a)) | 216 | #define MHD_create_named_thread_(t,n,s,r,a) MHD_create_thread_ ((t),(s),(r),(a)) |
209 | #else /* MHD_USE_THREAD_NAME_ */ | 217 | #else /* MHD_USE_THREAD_NAME_ */ |
210 | /** | 218 | /** |
211 | * Create a named thread and set the attributes according to our options. | 219 | * Create a named thread and set the attributes according to our options. |
@@ -219,7 +227,7 @@ MHD_create_thread_ (MHD_thread_handle_ID_ *thread, | |||
219 | */ | 227 | */ |
220 | int | 228 | int |
221 | MHD_create_named_thread_ (MHD_thread_handle_ID_ *thread, | 229 | MHD_create_named_thread_ (MHD_thread_handle_ID_ *thread, |
222 | const char* thread_name, | 230 | const char*thread_name, |
223 | size_t stack_size, | 231 | size_t stack_size, |
224 | MHD_THREAD_START_ROUTINE_ start_routine, | 232 | MHD_THREAD_START_ROUTINE_ start_routine, |
225 | void *arg); | 233 | void *arg); |
diff --git a/src/lib/reason_phrase.c b/src/lib/reason_phrase.c index 97ace0a3..e3692837 100644 --- a/src/lib/reason_phrase.c +++ b/src/lib/reason_phrase.c | |||
@@ -27,7 +27,7 @@ | |||
27 | #include "internal.h" | 27 | #include "internal.h" |
28 | 28 | ||
29 | #ifndef NULL | 29 | #ifndef NULL |
30 | #define NULL ((void*)0) | 30 | #define NULL ((void*) 0) |
31 | #endif | 31 | #endif |
32 | 32 | ||
33 | static const char *const invalid_hundred[] = { | 33 | static const char *const invalid_hundred[] = { |
diff --git a/src/lib/request.c b/src/lib/request.c index 02cce55c..5b932bfa 100644 --- a/src/lib/request.c +++ b/src/lib/request.c | |||
@@ -40,9 +40,9 @@ | |||
40 | */ | 40 | */ |
41 | unsigned int | 41 | unsigned int |
42 | MHD_request_get_values (struct MHD_Request *request, | 42 | MHD_request_get_values (struct MHD_Request *request, |
43 | enum MHD_ValueKind kind, | 43 | enum MHD_ValueKind kind, |
44 | MHD_KeyValueIterator iterator, | 44 | MHD_KeyValueIterator iterator, |
45 | void *iterator_cls) | 45 | void *iterator_cls) |
46 | { | 46 | { |
47 | int ret; | 47 | int ret; |
48 | struct MHD_HTTP_Header *pos; | 48 | struct MHD_HTTP_Header *pos; |
@@ -51,18 +51,18 @@ MHD_request_get_values (struct MHD_Request *request, | |||
51 | for (pos = request->headers_received; | 51 | for (pos = request->headers_received; |
52 | NULL != pos; | 52 | NULL != pos; |
53 | pos = pos->next) | 53 | pos = pos->next) |
54 | { | ||
55 | if (0 != (pos->kind & kind)) | ||
54 | { | 56 | { |
55 | if (0 != (pos->kind & kind)) | 57 | ret++; |
56 | { | 58 | if ( (NULL != iterator) && |
57 | ret++; | 59 | (MHD_YES != iterator (iterator_cls, |
58 | if ( (NULL != iterator) && | 60 | pos->kind, |
59 | (MHD_YES != iterator (iterator_cls, | 61 | pos->header, |
60 | pos->kind, | 62 | pos->value)) ) |
61 | pos->header, | 63 | return ret; |
62 | pos->value)) ) | ||
63 | return ret; | ||
64 | } | ||
65 | } | 64 | } |
65 | } | ||
66 | return ret; | 66 | return ret; |
67 | } | 67 | } |
68 | 68 | ||
@@ -94,9 +94,9 @@ MHD_request_get_values (struct MHD_Request *request, | |||
94 | */ | 94 | */ |
95 | enum MHD_Bool | 95 | enum MHD_Bool |
96 | MHD_request_set_value (struct MHD_Request *request, | 96 | MHD_request_set_value (struct MHD_Request *request, |
97 | enum MHD_ValueKind kind, | 97 | enum MHD_ValueKind kind, |
98 | const char *key, | 98 | const char *key, |
99 | const char *value) | 99 | const char *value) |
100 | { | 100 | { |
101 | struct MHD_HTTP_Header *pos; | 101 | struct MHD_HTTP_Header *pos; |
102 | 102 | ||
@@ -111,15 +111,15 @@ MHD_request_set_value (struct MHD_Request *request, | |||
111 | pos->next = NULL; | 111 | pos->next = NULL; |
112 | /* append 'pos' to the linked list of headers */ | 112 | /* append 'pos' to the linked list of headers */ |
113 | if (NULL == request->headers_received_tail) | 113 | if (NULL == request->headers_received_tail) |
114 | { | 114 | { |
115 | request->headers_received = pos; | 115 | request->headers_received = pos; |
116 | request->headers_received_tail = pos; | 116 | request->headers_received_tail = pos; |
117 | } | 117 | } |
118 | else | 118 | else |
119 | { | 119 | { |
120 | request->headers_received_tail->next = pos; | 120 | request->headers_received_tail->next = pos; |
121 | request->headers_received_tail = pos; | 121 | request->headers_received_tail = pos; |
122 | } | 122 | } |
123 | return MHD_YES; | 123 | return MHD_YES; |
124 | } | 124 | } |
125 | 125 | ||
@@ -136,27 +136,25 @@ MHD_request_set_value (struct MHD_Request *request, | |||
136 | */ | 136 | */ |
137 | const char * | 137 | const char * |
138 | MHD_request_lookup_value (struct MHD_Request *request, | 138 | MHD_request_lookup_value (struct MHD_Request *request, |
139 | enum MHD_ValueKind kind, | 139 | enum MHD_ValueKind kind, |
140 | const char *key) | 140 | const char *key) |
141 | { | 141 | { |
142 | struct MHD_HTTP_Header *pos; | 142 | struct MHD_HTTP_Header *pos; |
143 | 143 | ||
144 | for (pos = request->headers_received; | 144 | for (pos = request->headers_received; |
145 | NULL != pos; | 145 | NULL != pos; |
146 | pos = pos->next) | 146 | pos = pos->next) |
147 | { | 147 | { |
148 | if ((0 != (pos->kind & kind)) && | 148 | if ((0 != (pos->kind & kind)) && |
149 | ( (key == pos->header) || | 149 | ( (key == pos->header) || |
150 | ( (NULL != pos->header) && | 150 | ( (NULL != pos->header) && |
151 | (NULL != key) && | 151 | (NULL != key) && |
152 | (MHD_str_equal_caseless_(key, | 152 | (MHD_str_equal_caseless_ (key, |
153 | pos->header))))) | 153 | pos->header))))) |
154 | return pos->value; | 154 | return pos->value; |
155 | } | 155 | } |
156 | return NULL; | 156 | return NULL; |
157 | } | 157 | } |
158 | 158 | ||
159 | 159 | ||
160 | /* end of request.c */ | 160 | /* end of request.c */ |
161 | |||
162 | |||
diff --git a/src/lib/request_info.c b/src/lib/request_info.c index 5f481d98..51aae075 100644 --- a/src/lib/request_info.c +++ b/src/lib/request_info.c | |||
@@ -42,11 +42,11 @@ | |||
42 | */ | 42 | */ |
43 | enum MHD_Bool | 43 | enum MHD_Bool |
44 | MHD_request_get_information_sz (struct MHD_Request *request, | 44 | MHD_request_get_information_sz (struct MHD_Request *request, |
45 | enum MHD_RequestInformationType info_type, | 45 | enum MHD_RequestInformationType info_type, |
46 | union MHD_RequestInformation *return_value, | 46 | union MHD_RequestInformation *return_value, |
47 | size_t return_value_size) | 47 | size_t return_value_size) |
48 | { | 48 | { |
49 | #define CHECK_SIZE(type) if (sizeof(type) < return_value_size) \ | 49 | #define CHECK_SIZE(type) if (sizeof(type) < return_value_size) \ |
50 | return MHD_NO | 50 | return MHD_NO |
51 | 51 | ||
52 | switch (info_type) | 52 | switch (info_type) |
@@ -70,8 +70,8 @@ MHD_request_get_information_sz (struct MHD_Request *request, | |||
70 | case MHD_REQUEST_INFORMATION_HEADER_SIZE: | 70 | case MHD_REQUEST_INFORMATION_HEADER_SIZE: |
71 | CHECK_SIZE (size_t); | 71 | CHECK_SIZE (size_t); |
72 | if ( (MHD_REQUEST_HEADERS_RECEIVED > request->state) || | 72 | if ( (MHD_REQUEST_HEADERS_RECEIVED > request->state) || |
73 | (MHD_REQUEST_CLOSED == request->state) ) | 73 | (MHD_REQUEST_CLOSED == request->state) ) |
74 | return MHD_NO; /* invalid, too early! */ | 74 | return MHD_NO; /* invalid, too early! */ |
75 | return_value->header_size = request->header_size; | 75 | return_value->header_size = request->header_size; |
76 | return MHD_YES; | 76 | return MHD_YES; |
77 | 77 | ||
diff --git a/src/lib/request_resume.c b/src/lib/request_resume.c index a69107b9..be513f53 100644 --- a/src/lib/request_resume.c +++ b/src/lib/request_resume.c | |||
@@ -45,21 +45,23 @@ MHD_request_resume (struct MHD_Request *request) | |||
45 | struct MHD_Daemon *daemon = request->daemon; | 45 | struct MHD_Daemon *daemon = request->daemon; |
46 | 46 | ||
47 | if (daemon->disallow_suspend_resume) | 47 | if (daemon->disallow_suspend_resume) |
48 | MHD_PANIC (_("Cannot resume connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n")); | 48 | MHD_PANIC (_ ( |
49 | "Cannot resume connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n")); | ||
49 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); | 50 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); |
50 | request->connection->resuming = true; | 51 | request->connection->resuming = true; |
51 | daemon->resuming = true; | 52 | daemon->resuming = true; |
52 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); | 53 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); |
53 | if ( (MHD_ITC_IS_VALID_(daemon->itc)) && | 54 | if ( (MHD_ITC_IS_VALID_ (daemon->itc)) && |
54 | (! MHD_itc_activate_ (daemon->itc, | 55 | (! MHD_itc_activate_ (daemon->itc, |
55 | "r")) ) | 56 | "r")) ) |
56 | { | 57 | { |
57 | #ifdef HAVE_MESSAGES | 58 | #ifdef HAVE_MESSAGES |
58 | MHD_DLOG (daemon, | 59 | MHD_DLOG (daemon, |
59 | MHD_SC_ITC_USE_FAILED, | 60 | MHD_SC_ITC_USE_FAILED, |
60 | _("Failed to signal resume via inter-thread communication channel.")); | 61 | _ ( |
62 | "Failed to signal resume via inter-thread communication channel.")); | ||
61 | #endif | 63 | #endif |
62 | } | 64 | } |
63 | } | 65 | } |
64 | 66 | ||
65 | 67 | ||
@@ -80,115 +82,118 @@ MHD_resume_suspended_connections_ (struct MHD_Daemon *daemon) | |||
80 | struct MHD_Connection *pos; | 82 | struct MHD_Connection *pos; |
81 | struct MHD_Connection *prev = NULL; | 83 | struct MHD_Connection *prev = NULL; |
82 | bool ret; | 84 | bool ret; |
83 | const bool used_thr_p_c = (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode); | 85 | const bool used_thr_p_c = (MHD_TM_THREAD_PER_CONNECTION == |
86 | daemon->threading_mode); | ||
84 | 87 | ||
85 | mhd_assert (NULL == daemon->worker_pool); | 88 | mhd_assert (NULL == daemon->worker_pool); |
86 | ret = false; | 89 | ret = false; |
87 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); | 90 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); |
88 | 91 | ||
89 | if (daemon->resuming) | 92 | if (daemon->resuming) |
90 | { | 93 | { |
91 | prev = daemon->suspended_connections_tail; | 94 | prev = daemon->suspended_connections_tail; |
92 | /* During shutdown check for resuming is forced. */ | 95 | /* During shutdown check for resuming is forced. */ |
93 | mhd_assert((NULL != prev) || (daemon->shutdown)); | 96 | mhd_assert ((NULL != prev) || (daemon->shutdown)); |
94 | } | 97 | } |
95 | 98 | ||
96 | daemon->resuming = false; | 99 | daemon->resuming = false; |
97 | 100 | ||
98 | while (NULL != (pos = prev)) | 101 | while (NULL != (pos = prev)) |
99 | { | 102 | { |
100 | #ifdef UPGRADE_SUPPORT | 103 | #ifdef UPGRADE_SUPPORT |
101 | struct MHD_UpgradeResponseHandle * const urh = pos->request.urh; | 104 | struct MHD_UpgradeResponseHandle *const urh = pos->request.urh; |
102 | #else /* ! UPGRADE_SUPPORT */ | 105 | #else /* ! UPGRADE_SUPPORT */ |
103 | static const void * const urh = NULL; | 106 | static const void *const urh = NULL; |
104 | #endif /* ! UPGRADE_SUPPORT */ | 107 | #endif /* ! UPGRADE_SUPPORT */ |
105 | prev = pos->prev; | 108 | prev = pos->prev; |
106 | if ( (! pos->resuming) | 109 | if ( (! pos->resuming) |
107 | #ifdef UPGRADE_SUPPORT | 110 | #ifdef UPGRADE_SUPPORT |
108 | || ( (NULL != urh) && | 111 | || ( (NULL != urh) && |
109 | ( (! urh->was_closed) || | 112 | ( (! urh->was_closed) || |
110 | (! urh->clean_ready) ) ) | 113 | (! urh->clean_ready) ) ) |
111 | #endif /* UPGRADE_SUPPORT */ | 114 | #endif /* UPGRADE_SUPPORT */ |
112 | ) | 115 | ) |
113 | continue; | 116 | continue; |
114 | ret = true; | 117 | ret = true; |
115 | mhd_assert (pos->suspended); | 118 | mhd_assert (pos->suspended); |
116 | DLL_remove (daemon->suspended_connections_head, | 119 | DLL_remove (daemon->suspended_connections_head, |
117 | daemon->suspended_connections_tail, | 120 | daemon->suspended_connections_tail, |
121 | pos); | ||
122 | pos->suspended = false; | ||
123 | if (NULL == urh) | ||
124 | { | ||
125 | DLL_insert (daemon->connections_head, | ||
126 | daemon->connections_tail, | ||
118 | pos); | 127 | pos); |
119 | pos->suspended = false; | 128 | if (! used_thr_p_c) |
120 | if (NULL == urh) | 129 | { |
121 | { | 130 | /* Reset timeout timer on resume. */ |
122 | DLL_insert (daemon->connections_head, | 131 | if (0 != pos->connection_timeout) |
123 | daemon->connections_tail, | 132 | pos->last_activity = MHD_monotonic_sec_counter (); |
124 | pos); | 133 | |
125 | if (! used_thr_p_c) | 134 | if (pos->connection_timeout == daemon->connection_default_timeout) |
126 | { | 135 | XDLL_insert (daemon->normal_timeout_head, |
127 | /* Reset timeout timer on resume. */ | 136 | daemon->normal_timeout_tail, |
128 | if (0 != pos->connection_timeout) | 137 | pos); |
129 | pos->last_activity = MHD_monotonic_sec_counter(); | 138 | else |
130 | 139 | XDLL_insert (daemon->manual_timeout_head, | |
131 | if (pos->connection_timeout == daemon->connection_default_timeout) | 140 | daemon->manual_timeout_tail, |
132 | XDLL_insert (daemon->normal_timeout_head, | 141 | pos); |
133 | daemon->normal_timeout_tail, | 142 | } |
134 | pos); | ||
135 | else | ||
136 | XDLL_insert (daemon->manual_timeout_head, | ||
137 | daemon->manual_timeout_tail, | ||
138 | pos); | ||
139 | } | ||
140 | #ifdef EPOLL_SUPPORT | 143 | #ifdef EPOLL_SUPPORT |
141 | if (MHD_ELS_EPOLL == daemon->event_loop_syscall) | 144 | if (MHD_ELS_EPOLL == daemon->event_loop_syscall) |
142 | { | 145 | { |
143 | if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) | 146 | if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) |
144 | MHD_PANIC ("Resumed connection was already in EREADY set\n"); | 147 | MHD_PANIC ("Resumed connection was already in EREADY set\n"); |
145 | /* we always mark resumed connections as ready, as we | 148 | /* we always mark resumed connections as ready, as we |
146 | might have missed the edge poll event during suspension */ | 149 | might have missed the edge poll event during suspension */ |
147 | EDLL_insert (daemon->eready_head, | 150 | EDLL_insert (daemon->eready_head, |
148 | daemon->eready_tail, | 151 | daemon->eready_tail, |
149 | pos); | 152 | pos); |
150 | pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL | \ | 153 | pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL \ |
151 | MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_WRITE_READY; | 154 | | MHD_EPOLL_STATE_READ_READY |
152 | pos->epoll_state &= ~MHD_EPOLL_STATE_SUSPENDED; | 155 | | MHD_EPOLL_STATE_WRITE_READY; |
153 | } | 156 | pos->epoll_state &= ~MHD_EPOLL_STATE_SUSPENDED; |
157 | } | ||
154 | #endif | 158 | #endif |
155 | } | 159 | } |
156 | #ifdef UPGRADE_SUPPORT | 160 | #ifdef UPGRADE_SUPPORT |
157 | else | 161 | else |
158 | { | 162 | { |
159 | struct MHD_Response *response = pos->request.response; | 163 | struct MHD_Response *response = pos->request.response; |
160 | 164 | ||
161 | /* Data forwarding was finished (for TLS connections) AND | 165 | /* Data forwarding was finished (for TLS connections) AND |
162 | * application was closed upgraded connection. | 166 | * application was closed upgraded connection. |
163 | * Insert connection into cleanup list. */ | 167 | * Insert connection into cleanup list. */ |
164 | if ( (NULL != response) && | 168 | if ( (NULL != response) && |
165 | (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) && | 169 | (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) && |
166 | (NULL != response->termination_cb) ) | 170 | (NULL != response->termination_cb) ) |
167 | response->termination_cb (response->termination_cb_cls, | 171 | response->termination_cb (response->termination_cb_cls, |
168 | MHD_REQUEST_TERMINATED_COMPLETED_OK, | 172 | MHD_REQUEST_TERMINATED_COMPLETED_OK, |
169 | &pos->request.client_context); | 173 | &pos->request.client_context); |
170 | DLL_insert (daemon->cleanup_head, | 174 | DLL_insert (daemon->cleanup_head, |
171 | daemon->cleanup_tail, | 175 | daemon->cleanup_tail, |
172 | pos); | 176 | pos); |
173 | 177 | ||
174 | } | ||
175 | #endif /* UPGRADE_SUPPORT */ | ||
176 | pos->resuming = false; | ||
177 | } | 178 | } |
179 | #endif /* UPGRADE_SUPPORT */ | ||
180 | pos->resuming = false; | ||
181 | } | ||
178 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); | 182 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); |
179 | if ( (used_thr_p_c) && | 183 | if ( (used_thr_p_c) && |
180 | (ret) ) | 184 | (ret) ) |
181 | { /* Wake up suspended connections. */ | 185 | { /* Wake up suspended connections. */ |
182 | if (! MHD_itc_activate_(daemon->itc, | 186 | if (! MHD_itc_activate_ (daemon->itc, |
183 | "w")) | 187 | "w")) |
184 | { | 188 | { |
185 | #ifdef HAVE_MESSAGES | 189 | #ifdef HAVE_MESSAGES |
186 | MHD_DLOG (daemon, | 190 | MHD_DLOG (daemon, |
187 | MHD_SC_ITC_USE_FAILED, | 191 | MHD_SC_ITC_USE_FAILED, |
188 | _("Failed to signal resume of connection via inter-thread communication channel.")); | 192 | _ ( |
193 | "Failed to signal resume of connection via inter-thread communication channel.")); | ||
189 | #endif | 194 | #endif |
190 | } | ||
191 | } | 195 | } |
196 | } | ||
192 | return ret; | 197 | return ret; |
193 | } | 198 | } |
194 | 199 | ||
diff --git a/src/lib/request_resume.h b/src/lib/request_resume.h index d23ff9e8..dad43467 100644 --- a/src/lib/request_resume.h +++ b/src/lib/request_resume.h | |||
@@ -38,6 +38,6 @@ | |||
38 | */ | 38 | */ |
39 | bool | 39 | bool |
40 | MHD_resume_suspended_connections_ (struct MHD_Daemon *daemon) | 40 | MHD_resume_suspended_connections_ (struct MHD_Daemon *daemon) |
41 | MHD_NONNULL(1); | 41 | MHD_NONNULL (1); |
42 | 42 | ||
43 | #endif | 43 | #endif |
diff --git a/src/lib/response.c b/src/lib/response.c index ff23c7fd..47dd98d6 100644 --- a/src/lib/response.c +++ b/src/lib/response.c | |||
@@ -38,9 +38,9 @@ | |||
38 | */ | 38 | */ |
39 | static bool | 39 | static bool |
40 | add_response_entry (struct MHD_Response *response, | 40 | add_response_entry (struct MHD_Response *response, |
41 | enum MHD_ValueKind kind, | 41 | enum MHD_ValueKind kind, |
42 | const char *header, | 42 | const char *header, |
43 | const char *content) | 43 | const char *content) |
44 | { | 44 | { |
45 | struct MHD_HTTP_Header *hdr; | 45 | struct MHD_HTTP_Header *hdr; |
46 | 46 | ||
@@ -58,16 +58,16 @@ add_response_entry (struct MHD_Response *response, | |||
58 | if (NULL == (hdr = malloc (sizeof (struct MHD_HTTP_Header)))) | 58 | if (NULL == (hdr = malloc (sizeof (struct MHD_HTTP_Header)))) |
59 | return false; | 59 | return false; |
60 | if (NULL == (hdr->header = strdup (header))) | 60 | if (NULL == (hdr->header = strdup (header))) |
61 | { | 61 | { |
62 | free (hdr); | 62 | free (hdr); |
63 | return false; | 63 | return false; |
64 | } | 64 | } |
65 | if (NULL == (hdr->value = strdup (content))) | 65 | if (NULL == (hdr->value = strdup (content))) |
66 | { | 66 | { |
67 | free (hdr->header); | 67 | free (hdr->header); |
68 | free (hdr); | 68 | free (hdr); |
69 | return false; | 69 | return false; |
70 | } | 70 | } |
71 | hdr->kind = kind; | 71 | hdr->kind = kind; |
72 | hdr->next = response->first_header; | 72 | hdr->next = response->first_header; |
73 | response->first_header = hdr; | 73 | response->first_header = hdr; |
@@ -91,22 +91,22 @@ MHD_response_queue_for_destroy (struct MHD_Response *response) | |||
91 | 91 | ||
92 | MHD_mutex_lock_chk_ (&response->mutex); | 92 | MHD_mutex_lock_chk_ (&response->mutex); |
93 | if (0 != --(response->reference_count)) | 93 | if (0 != --(response->reference_count)) |
94 | { | 94 | { |
95 | MHD_mutex_unlock_chk_ (&response->mutex); | 95 | MHD_mutex_unlock_chk_ (&response->mutex); |
96 | return; | 96 | return; |
97 | } | 97 | } |
98 | MHD_mutex_unlock_chk_ (&response->mutex); | 98 | MHD_mutex_unlock_chk_ (&response->mutex); |
99 | MHD_mutex_destroy_chk_ (&response->mutex); | 99 | MHD_mutex_destroy_chk_ (&response->mutex); |
100 | if (NULL != response->crfc) | 100 | if (NULL != response->crfc) |
101 | response->crfc (response->crc_cls); | 101 | response->crfc (response->crc_cls); |
102 | while (NULL != response->first_header) | 102 | while (NULL != response->first_header) |
103 | { | 103 | { |
104 | pos = response->first_header; | 104 | pos = response->first_header; |
105 | response->first_header = pos->next; | 105 | response->first_header = pos->next; |
106 | free (pos->header); | 106 | free (pos->header); |
107 | free (pos->value); | 107 | free (pos->value); |
108 | free (pos); | 108 | free (pos); |
109 | } | 109 | } |
110 | free (response); | 110 | free (response); |
111 | } | 111 | } |
112 | 112 | ||
@@ -124,12 +124,12 @@ MHD_response_queue_for_destroy (struct MHD_Response *response) | |||
124 | enum MHD_Bool | 124 | enum MHD_Bool |
125 | MHD_response_add_header (struct MHD_Response *response, | 125 | MHD_response_add_header (struct MHD_Response *response, |
126 | const char *header, | 126 | const char *header, |
127 | const char *content) | 127 | const char *content) |
128 | { | 128 | { |
129 | return add_response_entry (response, | 129 | return add_response_entry (response, |
130 | MHD_HEADER_KIND, | 130 | MHD_HEADER_KIND, |
131 | header, | 131 | header, |
132 | content) ? MHD_YES : MHD_NO; | 132 | content) ? MHD_YES : MHD_NO; |
133 | } | 133 | } |
134 | 134 | ||
135 | 135 | ||
@@ -149,9 +149,9 @@ MHD_response_add_trailer (struct MHD_Response *response, | |||
149 | const char *content) | 149 | const char *content) |
150 | { | 150 | { |
151 | return add_response_entry (response, | 151 | return add_response_entry (response, |
152 | MHD_FOOTER_KIND, | 152 | MHD_FOOTER_KIND, |
153 | footer, | 153 | footer, |
154 | content) ? MHD_YES : MHD_NO; | 154 | content) ? MHD_YES : MHD_NO; |
155 | } | 155 | } |
156 | 156 | ||
157 | 157 | ||
@@ -167,7 +167,7 @@ MHD_response_add_trailer (struct MHD_Response *response, | |||
167 | enum MHD_Bool | 167 | enum MHD_Bool |
168 | MHD_response_del_header (struct MHD_Response *response, | 168 | MHD_response_del_header (struct MHD_Response *response, |
169 | const char *header, | 169 | const char *header, |
170 | const char *content) | 170 | const char *content) |
171 | { | 171 | { |
172 | struct MHD_HTTP_Header *pos; | 172 | struct MHD_HTTP_Header *pos; |
173 | struct MHD_HTTP_Header *prev; | 173 | struct MHD_HTTP_Header *prev; |
@@ -175,24 +175,24 @@ MHD_response_del_header (struct MHD_Response *response, | |||
175 | prev = NULL; | 175 | prev = NULL; |
176 | pos = response->first_header; | 176 | pos = response->first_header; |
177 | while (NULL != pos) | 177 | while (NULL != pos) |
178 | { | ||
179 | if ((0 == strcmp (header, | ||
180 | pos->header)) && | ||
181 | (0 == strcmp (content, | ||
182 | pos->value))) | ||
178 | { | 183 | { |
179 | if ((0 == strcmp (header, | 184 | free (pos->header); |
180 | pos->header)) && | 185 | free (pos->value); |
181 | (0 == strcmp (content, | 186 | if (NULL == prev) |
182 | pos->value))) | 187 | response->first_header = pos->next; |
183 | { | 188 | else |
184 | free (pos->header); | 189 | prev->next = pos->next; |
185 | free (pos->value); | 190 | free (pos); |
186 | if (NULL == prev) | 191 | return MHD_YES; |
187 | response->first_header = pos->next; | ||
188 | else | ||
189 | prev->next = pos->next; | ||
190 | free (pos); | ||
191 | return MHD_YES; | ||
192 | } | ||
193 | prev = pos; | ||
194 | pos = pos->next; | ||
195 | } | 192 | } |
193 | prev = pos; | ||
194 | pos = pos->next; | ||
195 | } | ||
196 | return MHD_NO; | 196 | return MHD_NO; |
197 | } | 197 | } |
198 | 198 | ||
@@ -210,7 +210,7 @@ MHD_response_del_header (struct MHD_Response *response, | |||
210 | unsigned int | 210 | unsigned int |
211 | MHD_response_get_headers (struct MHD_Response *response, | 211 | MHD_response_get_headers (struct MHD_Response *response, |
212 | MHD_KeyValueIterator iterator, | 212 | MHD_KeyValueIterator iterator, |
213 | void *iterator_cls) | 213 | void *iterator_cls) |
214 | { | 214 | { |
215 | unsigned int numHeaders = 0; | 215 | unsigned int numHeaders = 0; |
216 | struct MHD_HTTP_Header *pos; | 216 | struct MHD_HTTP_Header *pos; |
@@ -218,15 +218,15 @@ MHD_response_get_headers (struct MHD_Response *response, | |||
218 | for (pos = response->first_header; | 218 | for (pos = response->first_header; |
219 | NULL != pos; | 219 | NULL != pos; |
220 | pos = pos->next) | 220 | pos = pos->next) |
221 | { | 221 | { |
222 | numHeaders++; | 222 | numHeaders++; |
223 | if ( (NULL != iterator) && | 223 | if ( (NULL != iterator) && |
224 | (MHD_YES != iterator (iterator_cls, | 224 | (MHD_YES != iterator (iterator_cls, |
225 | pos->kind, | 225 | pos->kind, |
226 | pos->header, | 226 | pos->header, |
227 | pos->value)) ) | 227 | pos->value)) ) |
228 | break; | 228 | break; |
229 | } | 229 | } |
230 | return numHeaders; | 230 | return numHeaders; |
231 | } | 231 | } |
232 | 232 | ||
@@ -241,18 +241,18 @@ MHD_response_get_headers (struct MHD_Response *response, | |||
241 | */ | 241 | */ |
242 | const char * | 242 | const char * |
243 | MHD_response_get_header (struct MHD_Response *response, | 243 | MHD_response_get_header (struct MHD_Response *response, |
244 | const char *key) | 244 | const char *key) |
245 | { | 245 | { |
246 | struct MHD_HTTP_Header *pos; | 246 | struct MHD_HTTP_Header *pos; |
247 | 247 | ||
248 | for (pos = response->first_header; | 248 | for (pos = response->first_header; |
249 | NULL != pos; | 249 | NULL != pos; |
250 | pos = pos->next) | 250 | pos = pos->next) |
251 | { | 251 | { |
252 | if (MHD_str_equal_caseless_ (pos->header, | 252 | if (MHD_str_equal_caseless_ (pos->header, |
253 | key)) | 253 | key)) |
254 | return pos->value; | 254 | return pos->value; |
255 | } | 255 | } |
256 | return NULL; | 256 | return NULL; |
257 | } | 257 | } |
258 | 258 | ||
diff --git a/src/lib/response_for_upgrade.c b/src/lib/response_for_upgrade.c index 0d843b8e..ef66b029 100644 --- a/src/lib/response_for_upgrade.c +++ b/src/lib/response_for_upgrade.c | |||
@@ -57,21 +57,21 @@ | |||
57 | */ | 57 | */ |
58 | struct MHD_Response * | 58 | struct MHD_Response * |
59 | MHD_response_for_upgrade (MHD_UpgradeHandler upgrade_handler, | 59 | MHD_response_for_upgrade (MHD_UpgradeHandler upgrade_handler, |
60 | void *upgrade_handler_cls) | 60 | void *upgrade_handler_cls) |
61 | { | 61 | { |
62 | #ifdef UPGRADE_SUPPORT | 62 | #ifdef UPGRADE_SUPPORT |
63 | struct MHD_Response *response; | 63 | struct MHD_Response *response; |
64 | 64 | ||
65 | mhd_assert (NULL != upgrade_handler); | 65 | mhd_assert (NULL != upgrade_handler); |
66 | response = MHD_calloc_ (1, | 66 | response = MHD_calloc_ (1, |
67 | sizeof (struct MHD_Response)); | 67 | sizeof (struct MHD_Response)); |
68 | if (NULL == response) | 68 | if (NULL == response) |
69 | return NULL; | 69 | return NULL; |
70 | if (! MHD_mutex_init_ (&response->mutex)) | 70 | if (! MHD_mutex_init_ (&response->mutex)) |
71 | { | 71 | { |
72 | free (response); | 72 | free (response); |
73 | return NULL; | 73 | return NULL; |
74 | } | 74 | } |
75 | response->upgrade_handler = upgrade_handler; | 75 | response->upgrade_handler = upgrade_handler; |
76 | response->upgrade_handler_cls = upgrade_handler_cls; | 76 | response->upgrade_handler_cls = upgrade_handler_cls; |
77 | response->status_code = MHD_HTTP_SWITCHING_PROTOCOLS; | 77 | response->status_code = MHD_HTTP_SWITCHING_PROTOCOLS; |
@@ -81,10 +81,10 @@ MHD_response_for_upgrade (MHD_UpgradeHandler upgrade_handler, | |||
81 | MHD_response_add_header (response, | 81 | MHD_response_add_header (response, |
82 | MHD_HTTP_HEADER_CONNECTION, | 82 | MHD_HTTP_HEADER_CONNECTION, |
83 | "Upgrade")) | 83 | "Upgrade")) |
84 | { | 84 | { |
85 | MHD_response_queue_for_destroy (response); | 85 | MHD_response_queue_for_destroy (response); |
86 | return NULL; | 86 | return NULL; |
87 | } | 87 | } |
88 | return response; | 88 | return response; |
89 | #else | 89 | #else |
90 | return NULL; | 90 | return NULL; |
diff --git a/src/lib/response_from_buffer.c b/src/lib/response_from_buffer.c index a53537b0..a65a0298 100644 --- a/src/lib/response_from_buffer.c +++ b/src/lib/response_from_buffer.c | |||
@@ -39,44 +39,44 @@ | |||
39 | */ | 39 | */ |
40 | struct MHD_Response * | 40 | struct MHD_Response * |
41 | MHD_response_from_buffer (enum MHD_HTTP_StatusCode sc, | 41 | MHD_response_from_buffer (enum MHD_HTTP_StatusCode sc, |
42 | size_t size, | 42 | size_t size, |
43 | void *buffer, | 43 | void *buffer, |
44 | enum MHD_ResponseMemoryMode mode) | 44 | enum MHD_ResponseMemoryMode mode) |
45 | { | 45 | { |
46 | struct MHD_Response *response; | 46 | struct MHD_Response *response; |
47 | void *tmp; | 47 | void *tmp; |
48 | 48 | ||
49 | mhd_assert ( (NULL != buffer) || | 49 | mhd_assert ( (NULL != buffer) || |
50 | (0 == size) ); | 50 | (0 == size) ); |
51 | if (NULL == | 51 | if (NULL == |
52 | (response = MHD_calloc_ (1, | 52 | (response = MHD_calloc_ (1, |
53 | sizeof (struct MHD_Response)))) | 53 | sizeof (struct MHD_Response)))) |
54 | return NULL; | 54 | return NULL; |
55 | response->fd = -1; | 55 | response->fd = -1; |
56 | if (! MHD_mutex_init_ (&response->mutex)) | 56 | if (! MHD_mutex_init_ (&response->mutex)) |
57 | { | 57 | { |
58 | free (response); | 58 | free (response); |
59 | return NULL; | 59 | return NULL; |
60 | } | 60 | } |
61 | if ( (MHD_RESPMEM_MUST_COPY == mode) && | 61 | if ( (MHD_RESPMEM_MUST_COPY == mode) && |
62 | (size > 0) ) | 62 | (size > 0) ) |
63 | { | ||
64 | if (NULL == (tmp = malloc (size))) | ||
63 | { | 65 | { |
64 | if (NULL == (tmp = malloc (size))) | 66 | MHD_mutex_destroy_chk_ (&response->mutex); |
65 | { | 67 | free (response); |
66 | MHD_mutex_destroy_chk_ (&response->mutex); | 68 | return NULL; |
67 | free (response); | ||
68 | return NULL; | ||
69 | } | ||
70 | memcpy (tmp, | ||
71 | buffer, | ||
72 | size); | ||
73 | buffer = tmp; | ||
74 | } | 69 | } |
70 | memcpy (tmp, | ||
71 | buffer, | ||
72 | size); | ||
73 | buffer = tmp; | ||
74 | } | ||
75 | if (MHD_RESPMEM_PERSISTENT != mode) | 75 | if (MHD_RESPMEM_PERSISTENT != mode) |
76 | { | 76 | { |
77 | response->crfc = &free; | 77 | response->crfc = &free; |
78 | response->crc_cls = buffer; | 78 | response->crc_cls = buffer; |
79 | } | 79 | } |
80 | response->status_code = sc; | 80 | response->status_code = sc; |
81 | response->reference_count = 1; | 81 | response->reference_count = 1; |
82 | response->total_size = size; | 82 | response->total_size = size; |
diff --git a/src/lib/response_from_callback.c b/src/lib/response_from_callback.c index 1fd65bf0..e00033ce 100644 --- a/src/lib/response_from_callback.c +++ b/src/lib/response_from_callback.c | |||
@@ -44,11 +44,11 @@ | |||
44 | */ | 44 | */ |
45 | struct MHD_Response * | 45 | struct MHD_Response * |
46 | MHD_response_from_callback (enum MHD_HTTP_StatusCode sc, | 46 | MHD_response_from_callback (enum MHD_HTTP_StatusCode sc, |
47 | uint64_t size, | 47 | uint64_t size, |
48 | size_t block_size, | 48 | size_t block_size, |
49 | MHD_ContentReaderCallback crc, | 49 | MHD_ContentReaderCallback crc, |
50 | void *crc_cls, | 50 | void *crc_cls, |
51 | MHD_ContentReaderFreeCallback crfc) | 51 | MHD_ContentReaderFreeCallback crfc) |
52 | { | 52 | { |
53 | struct MHD_Response *response; | 53 | struct MHD_Response *response; |
54 | 54 | ||
@@ -56,8 +56,8 @@ MHD_response_from_callback (enum MHD_HTTP_StatusCode sc, | |||
56 | mhd_assert (0 != block_size); | 56 | mhd_assert (0 != block_size); |
57 | if (NULL == | 57 | if (NULL == |
58 | (response = MHD_calloc_ (1, | 58 | (response = MHD_calloc_ (1, |
59 | sizeof (struct MHD_Response) + | 59 | sizeof (struct MHD_Response) |
60 | block_size))) | 60 | + block_size))) |
61 | return NULL; | 61 | return NULL; |
62 | response->fd = -1; | 62 | response->fd = -1; |
63 | response->status_code = sc; | 63 | response->status_code = sc; |
diff --git a/src/lib/response_from_fd.c b/src/lib/response_from_fd.c index ac0a54d1..ffeb2b91 100644 --- a/src/lib/response_from_fd.c +++ b/src/lib/response_from_fd.c | |||
@@ -57,34 +57,34 @@ file_reader (void *cls, | |||
57 | size_t max) | 57 | size_t max) |
58 | { | 58 | { |
59 | struct MHD_Response *response = cls; | 59 | struct MHD_Response *response = cls; |
60 | #if !defined(_WIN32) || defined(__CYGWIN__) | 60 | #if ! defined(_WIN32) || defined(__CYGWIN__) |
61 | ssize_t n; | 61 | ssize_t n; |
62 | #else /* _WIN32 && !__CYGWIN__ */ | 62 | #else /* _WIN32 && !__CYGWIN__ */ |
63 | const HANDLE fh = (HANDLE) _get_osfhandle (response->fd); | 63 | const HANDLE fh = (HANDLE) _get_osfhandle (response->fd); |
64 | #endif /* _WIN32 && !__CYGWIN__ */ | 64 | #endif /* _WIN32 && !__CYGWIN__ */ |
65 | const int64_t offset64 = (int64_t)(pos + response->fd_off); | 65 | const int64_t offset64 = (int64_t) (pos + response->fd_off); |
66 | 66 | ||
67 | if (offset64 < 0) | 67 | if (offset64 < 0) |
68 | return MHD_CONTENT_READER_END_WITH_ERROR; /* seek to required position is not possible */ | 68 | return MHD_CONTENT_READER_END_WITH_ERROR; /* seek to required position is not possible */ |
69 | 69 | ||
70 | #if !defined(_WIN32) || defined(__CYGWIN__) | 70 | #if ! defined(_WIN32) || defined(__CYGWIN__) |
71 | if (max > SSIZE_MAX) | 71 | if (max > SSIZE_MAX) |
72 | max = SSIZE_MAX; /* Clamp to maximum return value. */ | 72 | max = SSIZE_MAX; /* Clamp to maximum return value. */ |
73 | 73 | ||
74 | #if defined(HAVE_PREAD64) | 74 | #if defined(HAVE_PREAD64) |
75 | n = pread64 (response->fd, | 75 | n = pread64 (response->fd, |
76 | buf, | 76 | buf, |
77 | max, | 77 | max, |
78 | offset64); | 78 | offset64); |
79 | #elif defined(HAVE_PREAD) | 79 | #elif defined(HAVE_PREAD) |
80 | if ( (sizeof(off_t) < sizeof (uint64_t)) && | 80 | if ( (sizeof(off_t) < sizeof (uint64_t)) && |
81 | (offset64 > (uint64_t)INT32_MAX) ) | 81 | (offset64 > (uint64_t) INT32_MAX) ) |
82 | return MHD_CONTENT_READER_END_WITH_ERROR; /* Read at required position is not possible. */ | 82 | return MHD_CONTENT_READER_END_WITH_ERROR; /* Read at required position is not possible. */ |
83 | 83 | ||
84 | n = pread (response->fd, | 84 | n = pread (response->fd, |
85 | buf, | 85 | buf, |
86 | max, | 86 | max, |
87 | (off_t) offset64); | 87 | (off_t) offset64); |
88 | #else /* ! HAVE_PREAD */ | 88 | #else /* ! HAVE_PREAD */ |
89 | #if defined(HAVE_LSEEK64) | 89 | #if defined(HAVE_LSEEK64) |
90 | if (lseek64 (response->fd, | 90 | if (lseek64 (response->fd, |
@@ -93,7 +93,7 @@ file_reader (void *cls, | |||
93 | return MHD_CONTENT_READER_END_WITH_ERROR; /* can't seek to required position */ | 93 | return MHD_CONTENT_READER_END_WITH_ERROR; /* can't seek to required position */ |
94 | #else /* ! HAVE_LSEEK64 */ | 94 | #else /* ! HAVE_LSEEK64 */ |
95 | if ( (sizeof(off_t) < sizeof (uint64_t)) && | 95 | if ( (sizeof(off_t) < sizeof (uint64_t)) && |
96 | (offset64 > (uint64_t)INT32_MAX) ) | 96 | (offset64 > (uint64_t) INT32_MAX) ) |
97 | return MHD_CONTENT_READER_END_WITH_ERROR; /* seek to required position is not possible */ | 97 | return MHD_CONTENT_READER_END_WITH_ERROR; /* seek to required position is not possible */ |
98 | 98 | ||
99 | if (lseek (response->fd, | 99 | if (lseek (response->fd, |
@@ -115,25 +115,25 @@ file_reader (void *cls, | |||
115 | if (INVALID_HANDLE_VALUE == fh) | 115 | if (INVALID_HANDLE_VALUE == fh) |
116 | return MHD_CONTENT_READER_END_WITH_ERROR; /* Value of 'response->fd' is not valid. */ | 116 | return MHD_CONTENT_READER_END_WITH_ERROR; /* Value of 'response->fd' is not valid. */ |
117 | else | 117 | else |
118 | { | 118 | { |
119 | OVERLAPPED f_ol = {0, 0, {{0, 0}}, 0}; /* Initialize to zero. */ | 119 | OVERLAPPED f_ol = {0, 0, {{0, 0}}, 0}; /* Initialize to zero. */ |
120 | ULARGE_INTEGER pos_uli; | 120 | ULARGE_INTEGER pos_uli; |
121 | DWORD toRead = (max > INT32_MAX) ? INT32_MAX : (DWORD) max; | 121 | DWORD toRead = (max > INT32_MAX) ? INT32_MAX : (DWORD) max; |
122 | DWORD resRead; | 122 | DWORD resRead; |
123 | 123 | ||
124 | pos_uli.QuadPart = (uint64_t) offset64; /* Simple transformation 64bit -> 2x32bit. */ | 124 | pos_uli.QuadPart = (uint64_t) offset64; /* Simple transformation 64bit -> 2x32bit. */ |
125 | f_ol.Offset = pos_uli.LowPart; | 125 | f_ol.Offset = pos_uli.LowPart; |
126 | f_ol.OffsetHigh = pos_uli.HighPart; | 126 | f_ol.OffsetHigh = pos_uli.HighPart; |
127 | if (! ReadFile (fh, | 127 | if (! ReadFile (fh, |
128 | (void*)buf, | 128 | (void*) buf, |
129 | toRead, | 129 | toRead, |
130 | &resRead, | 130 | &resRead, |
131 | &f_ol)) | 131 | &f_ol)) |
132 | return MHD_CONTENT_READER_END_WITH_ERROR; /* Read error. */ | 132 | return MHD_CONTENT_READER_END_WITH_ERROR; /* Read error. */ |
133 | if (0 == resRead) | 133 | if (0 == resRead) |
134 | return MHD_CONTENT_READER_END_OF_STREAM; | 134 | return MHD_CONTENT_READER_END_OF_STREAM; |
135 | return (ssize_t) resRead; | 135 | return (ssize_t) resRead; |
136 | } | 136 | } |
137 | #endif /* _WIN32 && !__CYGWIN__ */ | 137 | #endif /* _WIN32 && !__CYGWIN__ */ |
138 | } | 138 | } |
139 | 139 | ||
@@ -174,18 +174,18 @@ free_callback (void *cls) | |||
174 | */ | 174 | */ |
175 | struct MHD_Response * | 175 | struct MHD_Response * |
176 | MHD_response_from_fd (enum MHD_HTTP_StatusCode sc, | 176 | MHD_response_from_fd (enum MHD_HTTP_StatusCode sc, |
177 | int fd, | 177 | int fd, |
178 | uint64_t offset, | 178 | uint64_t offset, |
179 | uint64_t size) | 179 | uint64_t size) |
180 | { | 180 | { |
181 | struct MHD_Response *response; | 181 | struct MHD_Response *response; |
182 | 182 | ||
183 | mhd_assert (-1 != fd); | 183 | mhd_assert (-1 != fd); |
184 | #if !defined(HAVE___LSEEKI64) && !defined(HAVE_LSEEK64) | 184 | #if ! defined(HAVE___LSEEKI64) && ! defined(HAVE_LSEEK64) |
185 | if ( (sizeof (uint64_t) > sizeof (off_t)) && | 185 | if ( (sizeof (uint64_t) > sizeof (off_t)) && |
186 | ( (size > (uint64_t)INT32_MAX) || | 186 | ( (size > (uint64_t) INT32_MAX) || |
187 | (offset > (uint64_t)INT32_MAX) || | 187 | (offset > (uint64_t) INT32_MAX) || |
188 | ((size + offset) >= (uint64_t)INT32_MAX) ) ) | 188 | ((size + offset) >= (uint64_t) INT32_MAX) ) ) |
189 | return NULL; | 189 | return NULL; |
190 | #endif | 190 | #endif |
191 | if ( ((int64_t) size < 0) || | 191 | if ( ((int64_t) size < 0) || |
@@ -194,11 +194,11 @@ MHD_response_from_fd (enum MHD_HTTP_StatusCode sc, | |||
194 | return NULL; | 194 | return NULL; |
195 | 195 | ||
196 | response = MHD_response_from_callback (sc, | 196 | response = MHD_response_from_callback (sc, |
197 | size, | 197 | size, |
198 | MHD_FILE_READ_BLOCK_SIZE, | 198 | MHD_FILE_READ_BLOCK_SIZE, |
199 | &file_reader, | 199 | &file_reader, |
200 | NULL, | 200 | NULL, |
201 | &free_callback); | 201 | &free_callback); |
202 | if (NULL == response) | 202 | if (NULL == response) |
203 | return NULL; | 203 | return NULL; |
204 | response->fd = fd; | 204 | response->fd = fd; |
@@ -208,4 +208,3 @@ MHD_response_from_fd (enum MHD_HTTP_StatusCode sc, | |||
208 | } | 208 | } |
209 | 209 | ||
210 | /* end of response_from_fd.c */ | 210 | /* end of response_from_fd.c */ |
211 | |||
diff --git a/src/lib/response_options.c b/src/lib/response_options.c index 406d1d32..e349627a 100644 --- a/src/lib/response_options.c +++ b/src/lib/response_options.c | |||
@@ -49,8 +49,9 @@ MHD_response_option_v10_only (struct MHD_Response *response) | |||
49 | */ | 49 | */ |
50 | void | 50 | void |
51 | MHD_response_option_termination_callback (struct MHD_Response *response, | 51 | MHD_response_option_termination_callback (struct MHD_Response *response, |
52 | MHD_RequestTerminationCallback termination_cb, | 52 | MHD_RequestTerminationCallback |
53 | void *termination_cb_cls) | 53 | termination_cb, |
54 | void *termination_cb_cls) | ||
54 | { | 55 | { |
55 | /* Q: should we assert termination_cb non-NULL? */ | 56 | /* Q: should we assert termination_cb non-NULL? */ |
56 | response->termination_cb = termination_cb; | 57 | response->termination_cb = termination_cb; |
diff --git a/src/lib/sysfdsetsize.c b/src/lib/sysfdsetsize.c index fe7fba75..4929b3d2 100644 --- a/src/lib/sysfdsetsize.c +++ b/src/lib/sysfdsetsize.c | |||
@@ -56,7 +56,7 @@ | |||
56 | #include <sys/socket.h> | 56 | #include <sys/socket.h> |
57 | #endif /* HAVE_SYS_SOCKET_H */ | 57 | #endif /* HAVE_SYS_SOCKET_H */ |
58 | 58 | ||
59 | #if defined(_WIN32) && !defined(__CYGWIN__) | 59 | #if defined(_WIN32) && ! defined(__CYGWIN__) |
60 | #ifndef WIN32_LEAN_AND_MEAN | 60 | #ifndef WIN32_LEAN_AND_MEAN |
61 | #define WIN32_LEAN_AND_MEAN 1 | 61 | #define WIN32_LEAN_AND_MEAN 1 |
62 | #endif /* !WIN32_LEAN_AND_MEAN */ | 62 | #endif /* !WIN32_LEAN_AND_MEAN */ |
diff --git a/src/lib/tsearch.c b/src/lib/tsearch.c index fe5fcd5b..e43d758f 100644 --- a/src/lib/tsearch.c +++ b/src/lib/tsearch.c | |||
@@ -13,7 +13,7 @@ | |||
13 | #include <stdlib.h> | 13 | #include <stdlib.h> |
14 | 14 | ||
15 | 15 | ||
16 | typedef struct node | 16 | typedef struct node |
17 | { | 17 | { |
18 | const void *key; | 18 | const void *key; |
19 | struct node *llink; | 19 | struct node *llink; |
@@ -24,35 +24,35 @@ typedef struct node | |||
24 | /* $NetBSD: tsearch.c,v 1.5 2005/11/29 03:12:00 christos Exp $ */ | 24 | /* $NetBSD: tsearch.c,v 1.5 2005/11/29 03:12:00 christos Exp $ */ |
25 | /* find or insert datum into search tree */ | 25 | /* find or insert datum into search tree */ |
26 | void * | 26 | void * |
27 | tsearch (const void *vkey, /* key to be located */ | 27 | tsearch (const void *vkey, /* key to be located */ |
28 | void **vrootp, /* address of tree root */ | 28 | void **vrootp, /* address of tree root */ |
29 | int (*compar)(const void *, const void *)) | 29 | int (*compar)(const void *, const void *)) |
30 | { | 30 | { |
31 | node_t *q; | 31 | node_t *q; |
32 | node_t **rootp = (node_t **)vrootp; | 32 | node_t **rootp = (node_t **) vrootp; |
33 | 33 | ||
34 | if (NULL == rootp) | 34 | if (NULL == rootp) |
35 | return NULL; | 35 | return NULL; |
36 | 36 | ||
37 | while (*rootp != NULL) | 37 | while (*rootp != NULL) |
38 | { /* Knuth's T1: */ | 38 | { /* Knuth's T1: */ |
39 | int r; | 39 | int r; |
40 | 40 | ||
41 | if ((r = (*compar)(vkey, (*rootp)->key)) == 0) /* T2: */ | 41 | if ((r = (*compar)(vkey, (*rootp)->key)) == 0) /* T2: */ |
42 | return *rootp; /* we found it! */ | 42 | return *rootp; /* we found it! */ |
43 | 43 | ||
44 | rootp = (r < 0) ? | 44 | rootp = (r < 0) ? |
45 | &(*rootp)->llink : /* T3: follow left branch */ | 45 | &(*rootp)->llink : /* T3: follow left branch */ |
46 | &(*rootp)->rlink; /* T4: follow right branch */ | 46 | &(*rootp)->rlink; /* T4: follow right branch */ |
47 | } | 47 | } |
48 | 48 | ||
49 | q = malloc (sizeof(node_t)); /* T5: key not found */ | 49 | q = malloc (sizeof(node_t)); /* T5: key not found */ |
50 | if (q) | 50 | if (q) |
51 | { /* make new node */ | 51 | { /* make new node */ |
52 | *rootp = q; /* link new node to old */ | 52 | *rootp = q; /* link new node to old */ |
53 | q->key = vkey; /* initialize new node */ | 53 | q->key = vkey; /* initialize new node */ |
54 | q->llink = q->rlink = NULL; | 54 | q->llink = q->rlink = NULL; |
55 | } | 55 | } |
56 | return q; | 56 | return q; |
57 | } | 57 | } |
58 | 58 | ||
@@ -61,24 +61,24 @@ tsearch (const void *vkey, /* key to be located */ | |||
61 | /* find a node, or return NULL */ | 61 | /* find a node, or return NULL */ |
62 | void * | 62 | void * |
63 | tfind (const void *vkey, /* key to be found */ | 63 | tfind (const void *vkey, /* key to be found */ |
64 | void * const *vrootp, /* address of the tree root */ | 64 | void *const *vrootp, /* address of the tree root */ |
65 | int (*compar)(const void *, const void *)) | 65 | int (*compar)(const void *, const void *)) |
66 | { | 66 | { |
67 | node_t * const *rootp = (node_t * const*)vrootp; | 67 | node_t *const *rootp = (node_t *const*) vrootp; |
68 | 68 | ||
69 | if (NULL == rootp) | 69 | if (NULL == rootp) |
70 | return NULL; | 70 | return NULL; |
71 | 71 | ||
72 | while (*rootp != NULL) | 72 | while (*rootp != NULL) |
73 | { /* T1: */ | 73 | { /* T1: */ |
74 | int r; | 74 | int r; |
75 | 75 | ||
76 | if ((r = (*compar)(vkey, (*rootp)->key)) == 0) /* T2: */ | 76 | if ((r = (*compar)(vkey, (*rootp)->key)) == 0) /* T2: */ |
77 | return *rootp; /* key found */ | 77 | return *rootp; /* key found */ |
78 | rootp = (r < 0) ? | 78 | rootp = (r < 0) ? |
79 | &(*rootp)->llink : /* T3: follow left branch */ | 79 | &(*rootp)->llink : /* T3: follow left branch */ |
80 | &(*rootp)->rlink; /* T4: follow right branch */ | 80 | &(*rootp)->rlink; /* T4: follow right branch */ |
81 | } | 81 | } |
82 | return NULL; | 82 | return NULL; |
83 | } | 83 | } |
84 | 84 | ||
@@ -92,51 +92,51 @@ tfind (const void *vkey, /* key to be found */ | |||
92 | * compar: function to carry out node comparisons | 92 | * compar: function to carry out node comparisons |
93 | */ | 93 | */ |
94 | void * | 94 | void * |
95 | tdelete (const void * __restrict vkey, | 95 | tdelete (const void *__restrict vkey, |
96 | void ** __restrict vrootp, | 96 | void **__restrict vrootp, |
97 | int (*compar)(const void *, const void *)) | 97 | int (*compar)(const void *, const void *)) |
98 | { | 98 | { |
99 | node_t **rootp = (node_t **)vrootp; | 99 | node_t **rootp = (node_t **) vrootp; |
100 | node_t *p; | 100 | node_t *p; |
101 | node_t *q; | 101 | node_t *q; |
102 | node_t *r; | 102 | node_t *r; |
103 | int cmp; | 103 | int cmp; |
104 | 104 | ||
105 | if (rootp == NULL || (p = *rootp) == NULL) | 105 | if ((rootp == NULL)||((p = *rootp) == NULL)) |
106 | return NULL; | 106 | return NULL; |
107 | 107 | ||
108 | while ((cmp = (*compar)(vkey, (*rootp)->key)) != 0) | 108 | while ((cmp = (*compar)(vkey, (*rootp)->key)) != 0) |
109 | { | 109 | { |
110 | p = *rootp; | 110 | p = *rootp; |
111 | rootp = (cmp < 0) ? | 111 | rootp = (cmp < 0) ? |
112 | &(*rootp)->llink : /* follow llink branch */ | 112 | &(*rootp)->llink : /* follow llink branch */ |
113 | &(*rootp)->rlink; /* follow rlink branch */ | 113 | &(*rootp)->rlink; /* follow rlink branch */ |
114 | if (*rootp == NULL) | 114 | if (*rootp == NULL) |
115 | return NULL; /* key not found */ | 115 | return NULL; /* key not found */ |
116 | } | 116 | } |
117 | r = (*rootp)->rlink; /* D1: */ | 117 | r = (*rootp)->rlink; /* D1: */ |
118 | if ((q = (*rootp)->llink) == NULL) /* Left NULL? */ | 118 | if ((q = (*rootp)->llink) == NULL) /* Left NULL? */ |
119 | { | 119 | { |
120 | q = r; | ||
121 | } | ||
122 | else if (r != NULL) | ||
123 | { /* Right link is NULL? */ | ||
124 | if (r->llink == NULL) | ||
125 | { /* D2: Find successor */ | ||
126 | r->llink = q; | ||
120 | q = r; | 127 | q = r; |
121 | } | 128 | } |
122 | else if (r != NULL) | 129 | else |
123 | { /* Right link is NULL? */ | 130 | { /* D3: Find NULL link */ |
124 | if (r->llink == NULL) | 131 | for (q = r->llink; q->llink != NULL; q = r->llink) |
125 | { /* D2: Find successor */ | 132 | r = q; |
126 | r->llink = q; | 133 | r->llink = q->rlink; |
127 | q = r; | 134 | q->llink = (*rootp)->llink; |
128 | } | 135 | q->rlink = (*rootp)->rlink; |
129 | else | ||
130 | { /* D3: Find NULL link */ | ||
131 | for (q = r->llink; q->llink != NULL; q = r->llink) | ||
132 | r = q; | ||
133 | r->llink = q->rlink; | ||
134 | q->llink = (*rootp)->llink; | ||
135 | q->rlink = (*rootp)->rlink; | ||
136 | } | ||
137 | } | 136 | } |
138 | free(*rootp); /* D4: Free node */ | 137 | } |
139 | *rootp = q; /* link parent to new node */ | 138 | free (*rootp); /* D4: Free node */ |
139 | *rootp = q; /* link parent to new node */ | ||
140 | return p; | 140 | return p; |
141 | } | 141 | } |
142 | 142 | ||
diff --git a/src/lib/tsearch.h b/src/lib/tsearch.h index aa186495..0cfe16a7 100644 --- a/src/lib/tsearch.h +++ b/src/lib/tsearch.h | |||
@@ -14,22 +14,22 @@ extern "C" { | |||
14 | #endif /* __cplusplus */ | 14 | #endif /* __cplusplus */ |
15 | 15 | ||
16 | 16 | ||
17 | void * | 17 | void * |
18 | tdelete (const void * __restrict, | 18 | tdelete (const void *__restrict, |
19 | void ** __restrict, | 19 | void **__restrict, |
20 | int (*)(const void *, const void *)); | 20 | int (*)(const void *, const void *)); |
21 | 21 | ||
22 | 22 | ||
23 | void * | 23 | void * |
24 | tfind (const void *, | 24 | tfind (const void *, |
25 | void * const *, | 25 | void *const *, |
26 | int (*)(const void *, const void *)); | 26 | int (*)(const void *, const void *)); |
27 | 27 | ||
28 | 28 | ||
29 | void * | 29 | void * |
30 | tsearch (const void *, | 30 | tsearch (const void *, |
31 | void **, | 31 | void **, |
32 | int (*)(const void *, const void *)); | 32 | int (*)(const void *, const void *)); |
33 | 33 | ||
34 | #if defined(__cplusplus) | 34 | #if defined(__cplusplus) |
35 | }; | 35 | }; |
diff --git a/src/lib/upgrade_process.c b/src/lib/upgrade_process.c index 75924eee..353f2753 100644 --- a/src/lib/upgrade_process.c +++ b/src/lib/upgrade_process.c | |||
@@ -41,59 +41,62 @@ MHD_upgrade_response_handle_process_ (struct MHD_UpgradeResponseHandle *urh) | |||
41 | * pointers to 'connection' and 'daemon' are not changed | 41 | * pointers to 'connection' and 'daemon' are not changed |
42 | * during this processing, so no need to chain dereference | 42 | * during this processing, so no need to chain dereference |
43 | * each time. */ | 43 | * each time. */ |
44 | struct MHD_Connection * const connection = urh->connection; | 44 | struct MHD_Connection *const connection = urh->connection; |
45 | struct MHD_Daemon * const daemon = connection->daemon; | 45 | struct MHD_Daemon *const daemon = connection->daemon; |
46 | /* Prevent data races: use same value of 'was_closed' throughout | 46 | /* Prevent data races: use same value of 'was_closed' throughout |
47 | * this function. If 'was_closed' changed externally in the middle | 47 | * this function. If 'was_closed' changed externally in the middle |
48 | * of processing - it will be processed on next iteration. */ | 48 | * of processing - it will be processed on next iteration. */ |
49 | bool was_closed; | 49 | bool was_closed; |
50 | struct MHD_TLS_Plugin *tls = daemon->tls_api; | 50 | struct MHD_TLS_Plugin *tls = daemon->tls_api; |
51 | 51 | ||
52 | if (daemon->shutdown) | 52 | if (daemon->shutdown) |
53 | { | 53 | { |
54 | /* Daemon shutting down, application will not receive any more data. */ | 54 | /* Daemon shutting down, application will not receive any more data. */ |
55 | #ifdef HAVE_MESSAGES | 55 | #ifdef HAVE_MESSAGES |
56 | if (! urh->was_closed) | 56 | if (! urh->was_closed) |
57 | { | 57 | { |
58 | MHD_DLOG (daemon, | 58 | MHD_DLOG (daemon, |
59 | MHD_SC_DAEMON_ALREADY_SHUTDOWN, | 59 | MHD_SC_DAEMON_ALREADY_SHUTDOWN, |
60 | _("Initiated daemon shutdown while \"upgraded\" connection was not closed.\n")); | 60 | _ ( |
61 | } | 61 | "Initiated daemon shutdown while \"upgraded\" connection was not closed.\n")); |
62 | #endif | ||
63 | urh->was_closed = true; | ||
64 | } | 62 | } |
63 | #endif | ||
64 | urh->was_closed = true; | ||
65 | } | ||
65 | was_closed = urh->was_closed; | 66 | was_closed = urh->was_closed; |
66 | if (was_closed) | 67 | if (was_closed) |
68 | { | ||
69 | /* Application was closed connections: no more data | ||
70 | * can be forwarded to application socket. */ | ||
71 | if (0 < urh->in_buffer_used) | ||
67 | { | 72 | { |
68 | /* Application was closed connections: no more data | ||
69 | * can be forwarded to application socket. */ | ||
70 | if (0 < urh->in_buffer_used) | ||
71 | { | ||
72 | #ifdef HAVE_MESSAGES | 73 | #ifdef HAVE_MESSAGES |
73 | MHD_DLOG (daemon, | 74 | MHD_DLOG (daemon, |
74 | MHD_SC_UPGRADE_FORWARD_INCOMPLETE, | 75 | MHD_SC_UPGRADE_FORWARD_INCOMPLETE, |
75 | _("Failed to forward to application " MHD_UNSIGNED_LONG_LONG_PRINTF \ | 76 | _ ( |
76 | " bytes of data received from remote side: application shut down socket\n"), | 77 | "Failed to forward to application " |
77 | (MHD_UNSIGNED_LONG_LONG) urh->in_buffer_used); | 78 | MHD_UNSIGNED_LONG_LONG_PRINTF \ |
79 | " bytes of data received from remote side: application shut down socket\n"), | ||
80 | (MHD_UNSIGNED_LONG_LONG) urh->in_buffer_used); | ||
78 | #endif | 81 | #endif |
79 | 82 | ||
80 | } | ||
81 | /* If application signaled MHD about socket closure then | ||
82 | * check for any pending data even if socket is not marked | ||
83 | * as 'ready' (signal may arrive after poll()/select()). | ||
84 | * Socketpair for forwarding is always in non-blocking mode | ||
85 | * so no risk that recv() will block the thread. */ | ||
86 | if (0 != urh->out_buffer_size) | ||
87 | urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY; | ||
88 | /* Discard any data received form remote. */ | ||
89 | urh->in_buffer_used = 0; | ||
90 | /* Do not try to push data to application. */ | ||
91 | urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | ||
92 | /* Reading from remote client is not required anymore. */ | ||
93 | urh->in_buffer_size = 0; | ||
94 | urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY; | ||
95 | connection->tls_read_ready = false; | ||
96 | } | 83 | } |
84 | /* If application signaled MHD about socket closure then | ||
85 | * check for any pending data even if socket is not marked | ||
86 | * as 'ready' (signal may arrive after poll()/select()). | ||
87 | * Socketpair for forwarding is always in non-blocking mode | ||
88 | * so no risk that recv() will block the thread. */ | ||
89 | if (0 != urh->out_buffer_size) | ||
90 | urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY; | ||
91 | /* Discard any data received form remote. */ | ||
92 | urh->in_buffer_used = 0; | ||
93 | /* Do not try to push data to application. */ | ||
94 | urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | ||
95 | /* Reading from remote client is not required anymore. */ | ||
96 | urh->in_buffer_size = 0; | ||
97 | urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY; | ||
98 | connection->tls_read_ready = false; | ||
99 | } | ||
97 | 100 | ||
98 | /* On some platforms (W32, possibly Darwin) failed send() (send() will always | 101 | /* On some platforms (W32, possibly Darwin) failed send() (send() will always |
99 | * fail after remote disconnect was detected) may discard data in system | 102 | * fail after remote disconnect was detected) may discard data in system |
@@ -114,245 +117,249 @@ MHD_upgrade_response_handle_process_ (struct MHD_UpgradeResponseHandle *urh) | |||
114 | if ( ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->app.celi)) || | 117 | if ( ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->app.celi)) || |
115 | (connection->tls_read_ready) ) && | 118 | (connection->tls_read_ready) ) && |
116 | (urh->in_buffer_used < urh->in_buffer_size) ) | 119 | (urh->in_buffer_used < urh->in_buffer_size) ) |
117 | { | 120 | { |
118 | ssize_t res; | 121 | ssize_t res; |
119 | size_t buf_size; | 122 | size_t buf_size; |
120 | 123 | ||
121 | buf_size = urh->in_buffer_size - urh->in_buffer_used; | 124 | buf_size = urh->in_buffer_size - urh->in_buffer_used; |
122 | if (buf_size > SSIZE_MAX) | 125 | if (buf_size > SSIZE_MAX) |
123 | buf_size = SSIZE_MAX; | 126 | buf_size = SSIZE_MAX; |
124 | 127 | ||
125 | connection->tls_read_ready = false; | 128 | connection->tls_read_ready = false; |
126 | res = tls->recv (tls->cls, | 129 | res = tls->recv (tls->cls, |
127 | connection->tls_cs, | 130 | connection->tls_cs, |
128 | &urh->in_buffer[urh->in_buffer_used], | 131 | &urh->in_buffer[urh->in_buffer_used], |
129 | buf_size); | 132 | buf_size); |
130 | if (0 >= res) | 133 | if (0 >= res) |
131 | { | 134 | { |
132 | // FIXME: define GNUTLS-independent error codes! | 135 | // FIXME: define GNUTLS-independent error codes! |
133 | if (GNUTLS_E_INTERRUPTED != res) | 136 | if (GNUTLS_E_INTERRUPTED != res) |
134 | { | 137 | { |
135 | urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY; | 138 | urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY; |
136 | if (GNUTLS_E_AGAIN != res) | 139 | if (GNUTLS_E_AGAIN != res) |
137 | { | ||
138 | /* Unrecoverable error on socket was detected or | ||
139 | * socket was disconnected/shut down. */ | ||
140 | /* Stop trying to read from this TLS socket. */ | ||
141 | urh->in_buffer_size = 0; | ||
142 | } | ||
143 | } | ||
144 | } | ||
145 | else /* 0 < res */ | ||
146 | { | ||
147 | urh->in_buffer_used += res; | ||
148 | if (buf_size > (size_t)res) | ||
149 | urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY; | ||
150 | else if (0 < tls->check_record_pending (tls->cls, | ||
151 | connection->tls_cs)) | ||
152 | connection->tls_read_ready = true; | ||
153 | } | ||
154 | if (MHD_EPOLL_STATE_ERROR == | ||
155 | ((MHD_EPOLL_STATE_ERROR | MHD_EPOLL_STATE_READ_READY) & urh->app.celi)) | ||
156 | { | 140 | { |
157 | /* Unrecoverable error on socket was detected and all | 141 | /* Unrecoverable error on socket was detected or |
158 | * pending data was read from system buffers. */ | 142 | * socket was disconnected/shut down. */ |
159 | /* Stop trying to read from this TLS socket. */ | 143 | /* Stop trying to read from this TLS socket. */ |
160 | urh->in_buffer_size = 0; | 144 | urh->in_buffer_size = 0; |
161 | } | 145 | } |
146 | } | ||
162 | } | 147 | } |
148 | else /* 0 < res */ | ||
149 | { | ||
150 | urh->in_buffer_used += res; | ||
151 | if (buf_size > (size_t) res) | ||
152 | urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY; | ||
153 | else if (0 < tls->check_record_pending (tls->cls, | ||
154 | connection->tls_cs)) | ||
155 | connection->tls_read_ready = true; | ||
156 | } | ||
157 | if (MHD_EPOLL_STATE_ERROR == | ||
158 | ((MHD_EPOLL_STATE_ERROR | MHD_EPOLL_STATE_READ_READY) & urh->app.celi)) | ||
159 | { | ||
160 | /* Unrecoverable error on socket was detected and all | ||
161 | * pending data was read from system buffers. */ | ||
162 | /* Stop trying to read from this TLS socket. */ | ||
163 | urh->in_buffer_size = 0; | ||
164 | } | ||
165 | } | ||
163 | 166 | ||
164 | /* | 167 | /* |
165 | * handle reading from application | 168 | * handle reading from application |
166 | */ | 169 | */ |
167 | if ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi)) && | 170 | if ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi)) && |
168 | (urh->out_buffer_used < urh->out_buffer_size) ) | 171 | (urh->out_buffer_used < urh->out_buffer_size) ) |
169 | { | 172 | { |
170 | ssize_t res; | 173 | ssize_t res; |
171 | size_t buf_size; | 174 | size_t buf_size; |
172 | 175 | ||
173 | buf_size = urh->out_buffer_size - urh->out_buffer_used; | 176 | buf_size = urh->out_buffer_size - urh->out_buffer_used; |
174 | if (buf_size > MHD_SCKT_SEND_MAX_SIZE_) | 177 | if (buf_size > MHD_SCKT_SEND_MAX_SIZE_) |
175 | buf_size = MHD_SCKT_SEND_MAX_SIZE_; | 178 | buf_size = MHD_SCKT_SEND_MAX_SIZE_; |
176 | 179 | ||
177 | res = MHD_recv_ (urh->mhd.socket, | 180 | res = MHD_recv_ (urh->mhd.socket, |
178 | &urh->out_buffer[urh->out_buffer_used], | 181 | &urh->out_buffer[urh->out_buffer_used], |
179 | buf_size); | 182 | buf_size); |
180 | if (0 >= res) | 183 | if (0 >= res) |
181 | { | 184 | { |
182 | const int err = MHD_socket_get_error_ (); | 185 | const int err = MHD_socket_get_error_ (); |
183 | if ((0 == res) || | 186 | if ((0 == res) || |
184 | ((! MHD_SCKT_ERR_IS_EINTR_ (err)) && | 187 | ((! MHD_SCKT_ERR_IS_EINTR_ (err)) && |
185 | (! MHD_SCKT_ERR_IS_LOW_RESOURCES_(err)))) | 188 | (! MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err)))) |
186 | { | 189 | { |
187 | urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY; | 190 | urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY; |
188 | if ((0 == res) || | 191 | if ((0 == res) || |
189 | (was_closed) || | 192 | (was_closed) || |
190 | (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) || | 193 | (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) || |
191 | (! MHD_SCKT_ERR_IS_EAGAIN_ (err))) | 194 | (! MHD_SCKT_ERR_IS_EAGAIN_ (err))) |
192 | { | ||
193 | /* Socket disconnect/shutdown was detected; | ||
194 | * Application signaled about closure of 'upgraded' socket; | ||
195 | * or persistent / unrecoverable error. */ | ||
196 | /* Do not try to pull more data from application. */ | ||
197 | urh->out_buffer_size = 0; | ||
198 | } | ||
199 | } | ||
200 | } | ||
201 | else /* 0 < res */ | ||
202 | { | ||
203 | urh->out_buffer_used += res; | ||
204 | if (buf_size > (size_t)res) | ||
205 | urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY; | ||
206 | } | ||
207 | if ( (0 == (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi)) && | ||
208 | ( (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) || | ||
209 | (was_closed) ) ) | ||
210 | { | 195 | { |
211 | /* Unrecoverable error on socket was detected and all | 196 | /* Socket disconnect/shutdown was detected; |
212 | * pending data was read from system buffers. */ | 197 | * Application signaled about closure of 'upgraded' socket; |
198 | * or persistent / unrecoverable error. */ | ||
213 | /* Do not try to pull more data from application. */ | 199 | /* Do not try to pull more data from application. */ |
214 | urh->out_buffer_size = 0; | 200 | urh->out_buffer_size = 0; |
215 | } | 201 | } |
202 | } | ||
203 | } | ||
204 | else /* 0 < res */ | ||
205 | { | ||
206 | urh->out_buffer_used += res; | ||
207 | if (buf_size > (size_t) res) | ||
208 | urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY; | ||
216 | } | 209 | } |
210 | if ( (0 == (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi)) && | ||
211 | ( (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) || | ||
212 | (was_closed) ) ) | ||
213 | { | ||
214 | /* Unrecoverable error on socket was detected and all | ||
215 | * pending data was read from system buffers. */ | ||
216 | /* Do not try to pull more data from application. */ | ||
217 | urh->out_buffer_size = 0; | ||
218 | } | ||
219 | } | ||
217 | 220 | ||
218 | /* | 221 | /* |
219 | * handle writing to remote HTTPS client | 222 | * handle writing to remote HTTPS client |
220 | */ | 223 | */ |
221 | if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->app.celi)) && | 224 | if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->app.celi)) && |
222 | (urh->out_buffer_used > 0) ) | 225 | (urh->out_buffer_used > 0) ) |
223 | { | 226 | { |
224 | ssize_t res; | 227 | ssize_t res; |
225 | size_t data_size; | 228 | size_t data_size; |
226 | 229 | ||
227 | data_size = urh->out_buffer_used; | 230 | data_size = urh->out_buffer_used; |
228 | if (data_size > SSIZE_MAX) | 231 | if (data_size > SSIZE_MAX) |
229 | data_size = SSIZE_MAX; | 232 | data_size = SSIZE_MAX; |
230 | 233 | ||
231 | res = tls->send (tls->cls, | 234 | res = tls->send (tls->cls, |
232 | connection->tls_cs, | 235 | connection->tls_cs, |
233 | urh->out_buffer, | 236 | urh->out_buffer, |
234 | data_size); | 237 | data_size); |
235 | if (0 >= res) | 238 | if (0 >= res) |
239 | { | ||
240 | // FIXME: define GNUTLS-independent error codes! | ||
241 | if (GNUTLS_E_INTERRUPTED != res) | ||
242 | { | ||
243 | urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | ||
244 | if (GNUTLS_E_INTERRUPTED != res) | ||
236 | { | 245 | { |
237 | // FIXME: define GNUTLS-independent error codes! | 246 | /* TLS connection shut down or |
238 | if (GNUTLS_E_INTERRUPTED != res) | 247 | * persistent / unrecoverable error. */ |
239 | { | ||
240 | urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | ||
241 | if (GNUTLS_E_INTERRUPTED != res) | ||
242 | { | ||
243 | /* TLS connection shut down or | ||
244 | * persistent / unrecoverable error. */ | ||
245 | #ifdef HAVE_MESSAGES | 248 | #ifdef HAVE_MESSAGES |
246 | MHD_DLOG (daemon, | 249 | MHD_DLOG (daemon, |
247 | MHD_SC_UPGRADE_FORWARD_INCOMPLETE, | 250 | MHD_SC_UPGRADE_FORWARD_INCOMPLETE, |
248 | _("Failed to forward to remote client " MHD_UNSIGNED_LONG_LONG_PRINTF \ | 251 | _ ( |
249 | " bytes of data received from application: %s\n"), | 252 | "Failed to forward to remote client " |
250 | (MHD_UNSIGNED_LONG_LONG) urh->out_buffer_used, | 253 | MHD_UNSIGNED_LONG_LONG_PRINTF \ |
251 | tls->strerror (tls->cls, | 254 | " bytes of data received from application: %s\n"), |
252 | res)); | 255 | (MHD_UNSIGNED_LONG_LONG) urh->out_buffer_used, |
256 | tls->strerror (tls->cls, | ||
257 | res)); | ||
253 | #endif | 258 | #endif |
254 | /* Discard any data unsent to remote. */ | 259 | /* Discard any data unsent to remote. */ |
255 | urh->out_buffer_used = 0; | 260 | urh->out_buffer_used = 0; |
256 | /* Do not try to pull more data from application. */ | ||
257 | urh->out_buffer_size = 0; | ||
258 | urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY; | ||
259 | } | ||
260 | } | ||
261 | } | ||
262 | else /* 0 < res */ | ||
263 | { | ||
264 | const size_t next_out_buffer_used = urh->out_buffer_used - res; | ||
265 | if (0 != next_out_buffer_used) | ||
266 | { | ||
267 | memmove (urh->out_buffer, | ||
268 | &urh->out_buffer[res], | ||
269 | next_out_buffer_used); | ||
270 | if (data_size > (size_t)res) | ||
271 | urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | ||
272 | } | ||
273 | urh->out_buffer_used = next_out_buffer_used; | ||
274 | } | ||
275 | if ( (0 == urh->out_buffer_used) && | ||
276 | (0 != (MHD_EPOLL_STATE_ERROR & urh->app.celi)) ) | ||
277 | { | ||
278 | /* Unrecoverable error on socket was detected and all | ||
279 | * pending data was sent to remote. */ | ||
280 | /* Do not try to send to remote anymore. */ | ||
281 | urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | ||
282 | /* Do not try to pull more data from application. */ | 261 | /* Do not try to pull more data from application. */ |
283 | urh->out_buffer_size = 0; | 262 | urh->out_buffer_size = 0; |
284 | urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY; | 263 | urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY; |
285 | } | 264 | } |
265 | } | ||
286 | } | 266 | } |
267 | else /* 0 < res */ | ||
268 | { | ||
269 | const size_t next_out_buffer_used = urh->out_buffer_used - res; | ||
270 | if (0 != next_out_buffer_used) | ||
271 | { | ||
272 | memmove (urh->out_buffer, | ||
273 | &urh->out_buffer[res], | ||
274 | next_out_buffer_used); | ||
275 | if (data_size > (size_t) res) | ||
276 | urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | ||
277 | } | ||
278 | urh->out_buffer_used = next_out_buffer_used; | ||
279 | } | ||
280 | if ( (0 == urh->out_buffer_used) && | ||
281 | (0 != (MHD_EPOLL_STATE_ERROR & urh->app.celi)) ) | ||
282 | { | ||
283 | /* Unrecoverable error on socket was detected and all | ||
284 | * pending data was sent to remote. */ | ||
285 | /* Do not try to send to remote anymore. */ | ||
286 | urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | ||
287 | /* Do not try to pull more data from application. */ | ||
288 | urh->out_buffer_size = 0; | ||
289 | urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY; | ||
290 | } | ||
291 | } | ||
287 | 292 | ||
288 | /* | 293 | /* |
289 | * handle writing to application | 294 | * handle writing to application |
290 | */ | 295 | */ |
291 | if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->mhd.celi)) && | 296 | if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->mhd.celi)) && |
292 | (urh->in_buffer_used > 0) ) | 297 | (urh->in_buffer_used > 0) ) |
293 | { | 298 | { |
294 | ssize_t res; | 299 | ssize_t res; |
295 | size_t data_size; | 300 | size_t data_size; |
296 | 301 | ||
297 | data_size = urh->in_buffer_used; | 302 | data_size = urh->in_buffer_used; |
298 | if (data_size > MHD_SCKT_SEND_MAX_SIZE_) | 303 | if (data_size > MHD_SCKT_SEND_MAX_SIZE_) |
299 | data_size = MHD_SCKT_SEND_MAX_SIZE_; | 304 | data_size = MHD_SCKT_SEND_MAX_SIZE_; |
300 | 305 | ||
301 | res = MHD_send_ (urh->mhd.socket, | 306 | res = MHD_send_ (urh->mhd.socket, |
302 | urh->in_buffer, | 307 | urh->in_buffer, |
303 | data_size); | 308 | data_size); |
304 | if (0 >= res) | 309 | if (0 >= res) |
310 | { | ||
311 | const int err = MHD_socket_get_error_ (); | ||
312 | if ( (! MHD_SCKT_ERR_IS_EINTR_ (err)) && | ||
313 | (! MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err)) ) | ||
314 | { | ||
315 | urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | ||
316 | if (! MHD_SCKT_ERR_IS_EAGAIN_ (err)) | ||
305 | { | 317 | { |
306 | const int err = MHD_socket_get_error_ (); | 318 | /* Socketpair connection shut down or |
307 | if ( (! MHD_SCKT_ERR_IS_EINTR_ (err)) && | 319 | * persistent / unrecoverable error. */ |
308 | (! MHD_SCKT_ERR_IS_LOW_RESOURCES_(err)) ) | ||
309 | { | ||
310 | urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | ||
311 | if (! MHD_SCKT_ERR_IS_EAGAIN_ (err)) | ||
312 | { | ||
313 | /* Socketpair connection shut down or | ||
314 | * persistent / unrecoverable error. */ | ||
315 | #ifdef HAVE_MESSAGES | 320 | #ifdef HAVE_MESSAGES |
316 | MHD_DLOG (daemon, | 321 | MHD_DLOG (daemon, |
317 | MHD_SC_UPGRADE_FORWARD_INCOMPLETE, | 322 | MHD_SC_UPGRADE_FORWARD_INCOMPLETE, |
318 | _("Failed to forward to application " MHD_UNSIGNED_LONG_LONG_PRINTF \ | 323 | _ ( |
319 | " bytes of data received from remote side: %s\n"), | 324 | "Failed to forward to application " |
320 | (MHD_UNSIGNED_LONG_LONG) urh->in_buffer_used, | 325 | MHD_UNSIGNED_LONG_LONG_PRINTF \ |
321 | MHD_socket_strerr_ (err)); | 326 | " bytes of data received from remote side: %s\n"), |
327 | (MHD_UNSIGNED_LONG_LONG) urh->in_buffer_used, | ||
328 | MHD_socket_strerr_ (err)); | ||
322 | #endif | 329 | #endif |
323 | /* Discard any data received form remote. */ | 330 | /* Discard any data received form remote. */ |
324 | urh->in_buffer_used = 0; | 331 | urh->in_buffer_used = 0; |
325 | /* Reading from remote client is not required anymore. */ | ||
326 | urh->in_buffer_size = 0; | ||
327 | urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY; | ||
328 | connection->tls_read_ready = false; | ||
329 | } | ||
330 | } | ||
331 | } | ||
332 | else /* 0 < res */ | ||
333 | { | ||
334 | const size_t next_in_buffer_used = urh->in_buffer_used - res; | ||
335 | if (0 != next_in_buffer_used) | ||
336 | { | ||
337 | memmove (urh->in_buffer, | ||
338 | &urh->in_buffer[res], | ||
339 | next_in_buffer_used); | ||
340 | if (data_size > (size_t)res) | ||
341 | urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | ||
342 | } | ||
343 | urh->in_buffer_used = next_in_buffer_used; | ||
344 | } | ||
345 | if ( (0 == urh->in_buffer_used) && | ||
346 | (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) ) | ||
347 | { | ||
348 | /* Do not try to push data to application. */ | ||
349 | urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | ||
350 | /* Reading from remote client is not required anymore. */ | 332 | /* Reading from remote client is not required anymore. */ |
351 | urh->in_buffer_size = 0; | 333 | urh->in_buffer_size = 0; |
352 | urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY; | 334 | urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY; |
353 | connection->tls_read_ready = false; | 335 | connection->tls_read_ready = false; |
354 | } | 336 | } |
337 | } | ||
338 | } | ||
339 | else /* 0 < res */ | ||
340 | { | ||
341 | const size_t next_in_buffer_used = urh->in_buffer_used - res; | ||
342 | if (0 != next_in_buffer_used) | ||
343 | { | ||
344 | memmove (urh->in_buffer, | ||
345 | &urh->in_buffer[res], | ||
346 | next_in_buffer_used); | ||
347 | if (data_size > (size_t) res) | ||
348 | urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | ||
349 | } | ||
350 | urh->in_buffer_used = next_in_buffer_used; | ||
351 | } | ||
352 | if ( (0 == urh->in_buffer_used) && | ||
353 | (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) ) | ||
354 | { | ||
355 | /* Do not try to push data to application. */ | ||
356 | urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | ||
357 | /* Reading from remote client is not required anymore. */ | ||
358 | urh->in_buffer_size = 0; | ||
359 | urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY; | ||
360 | connection->tls_read_ready = false; | ||
355 | } | 361 | } |
362 | } | ||
356 | 363 | ||
357 | /* Check whether data is present in TLS buffers | 364 | /* Check whether data is present in TLS buffers |
358 | * and incoming forward buffer have some space. */ | 365 | * and incoming forward buffer have some space. */ |
@@ -364,24 +371,26 @@ MHD_upgrade_response_handle_process_ (struct MHD_UpgradeResponseHandle *urh) | |||
364 | if ( (daemon->shutdown) && | 371 | if ( (daemon->shutdown) && |
365 | ( (0 != urh->out_buffer_size) || | 372 | ( (0 != urh->out_buffer_size) || |
366 | (0 != urh->out_buffer_used) ) ) | 373 | (0 != urh->out_buffer_used) ) ) |
367 | { | 374 | { |
368 | /* Daemon shutting down, discard any remaining forward data. */ | 375 | /* Daemon shutting down, discard any remaining forward data. */ |
369 | #ifdef HAVE_MESSAGES | 376 | #ifdef HAVE_MESSAGES |
370 | if (0 < urh->out_buffer_used) | 377 | if (0 < urh->out_buffer_used) |
371 | MHD_DLOG (daemon, | 378 | MHD_DLOG (daemon, |
372 | MHD_SC_UPGRADE_FORWARD_INCOMPLETE, | 379 | MHD_SC_UPGRADE_FORWARD_INCOMPLETE, |
373 | _("Failed to forward to remote client " MHD_UNSIGNED_LONG_LONG_PRINTF \ | 380 | _ ( |
374 | " bytes of data received from application: daemon shut down\n"), | 381 | "Failed to forward to remote client " |
375 | (MHD_UNSIGNED_LONG_LONG) urh->out_buffer_used); | 382 | MHD_UNSIGNED_LONG_LONG_PRINTF \ |
383 | " bytes of data received from application: daemon shut down\n"), | ||
384 | (MHD_UNSIGNED_LONG_LONG) urh->out_buffer_used); | ||
376 | #endif | 385 | #endif |
377 | /* Discard any data unsent to remote. */ | 386 | /* Discard any data unsent to remote. */ |
378 | urh->out_buffer_used = 0; | 387 | urh->out_buffer_used = 0; |
379 | /* Do not try to sent to remote anymore. */ | 388 | /* Do not try to sent to remote anymore. */ |
380 | urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | 389 | urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY; |
381 | /* Do not try to pull more data from application. */ | 390 | /* Do not try to pull more data from application. */ |
382 | urh->out_buffer_size = 0; | 391 | urh->out_buffer_size = 0; |
383 | urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY; | 392 | urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY; |
384 | } | 393 | } |
385 | } | 394 | } |
386 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ | 395 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ |
387 | 396 | ||
diff --git a/src/lib/upgrade_process.h b/src/lib/upgrade_process.h index 36a7ddff..8b0d4119 100644 --- a/src/lib/upgrade_process.h +++ b/src/lib/upgrade_process.h | |||
@@ -36,7 +36,7 @@ | |||
36 | */ | 36 | */ |
37 | void | 37 | void |
38 | MHD_upgrade_response_handle_process_ (struct MHD_UpgradeResponseHandle *urh) | 38 | MHD_upgrade_response_handle_process_ (struct MHD_UpgradeResponseHandle *urh) |
39 | MHD_NONNULL(1); | 39 | MHD_NONNULL (1); |
40 | 40 | ||
41 | 41 | ||
42 | #endif | 42 | #endif |
diff --git a/src/lib/version.c b/src/lib/version.c index 472a8c04..5bf4ab01 100644 --- a/src/lib/version.c +++ b/src/lib/version.c | |||
@@ -40,13 +40,13 @@ MHD_get_version (void) | |||
40 | static char ver[12] = "\0\0\0\0\0\0\0\0\0\0\0"; | 40 | static char ver[12] = "\0\0\0\0\0\0\0\0\0\0\0"; |
41 | if (0 == ver[0]) | 41 | if (0 == ver[0]) |
42 | { | 42 | { |
43 | int res = MHD_snprintf_(ver, | 43 | int res = MHD_snprintf_ (ver, |
44 | sizeof(ver), | 44 | sizeof(ver), |
45 | "%x.%x.%x", | 45 | "%x.%x.%x", |
46 | (((int)MHD_VERSION >> 24) & 0xFF), | 46 | (((int) MHD_VERSION >> 24) & 0xFF), |
47 | (((int)MHD_VERSION >> 16) & 0xFF), | 47 | (((int) MHD_VERSION >> 16) & 0xFF), |
48 | (((int)MHD_VERSION >> 8) & 0xFF)); | 48 | (((int) MHD_VERSION >> 8) & 0xFF)); |
49 | if (0 >= res || sizeof(ver) <= res) | 49 | if ((0 >= res)||(sizeof(ver) <= res)) |
50 | return "0.0.0"; /* Can't return real version*/ | 50 | return "0.0.0"; /* Can't return real version*/ |
51 | } | 51 | } |
52 | return ver; | 52 | return ver; |
@@ -66,141 +66,142 @@ MHD_get_version (void) | |||
66 | * @ingroup specialized | 66 | * @ingroup specialized |
67 | */ | 67 | */ |
68 | _MHD_EXTERN enum MHD_Bool | 68 | _MHD_EXTERN enum MHD_Bool |
69 | MHD_is_feature_supported(enum MHD_Feature feature) | 69 | MHD_is_feature_supported (enum MHD_Feature feature) |
70 | { | 70 | { |
71 | switch(feature) | 71 | switch (feature) |
72 | { | 72 | { |
73 | case MHD_FEATURE_MESSAGES: | 73 | case MHD_FEATURE_MESSAGES: |
74 | #ifdef HAVE_MESSAGES | 74 | #ifdef HAVE_MESSAGES |
75 | return MHD_YES; | 75 | return MHD_YES; |
76 | #else | 76 | #else |
77 | return MHD_NO; | 77 | return MHD_NO; |
78 | #endif | 78 | #endif |
79 | case MHD_FEATURE_TLS: | 79 | case MHD_FEATURE_TLS: |
80 | #ifdef HTTPS_SUPPORT | 80 | #ifdef HTTPS_SUPPORT |
81 | return MHD_YES; | 81 | return MHD_YES; |
82 | #else /* ! HTTPS_SUPPORT */ | 82 | #else /* ! HTTPS_SUPPORT */ |
83 | return MHD_NO; | 83 | return MHD_NO; |
84 | #endif /* ! HTTPS_SUPPORT */ | 84 | #endif /* ! HTTPS_SUPPORT */ |
85 | case MHD_FEATURE_HTTPS_CERT_CALLBACK: | 85 | case MHD_FEATURE_HTTPS_CERT_CALLBACK: |
86 | #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_MAJOR >= 3 | 86 | #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_MAJOR >= 3 |
87 | return MHD_YES; | 87 | return MHD_YES; |
88 | #else /* !HTTPS_SUPPORT || GNUTLS_VERSION_MAJOR < 3 */ | 88 | #else /* !HTTPS_SUPPORT || GNUTLS_VERSION_MAJOR < 3 */ |
89 | return MHD_NO; | 89 | return MHD_NO; |
90 | #endif /* !HTTPS_SUPPORT || GNUTLS_VERSION_MAJOR < 3 */ | 90 | #endif /* !HTTPS_SUPPORT || GNUTLS_VERSION_MAJOR < 3 */ |
91 | case MHD_FEATURE_IPv6: | 91 | case MHD_FEATURE_IPv6: |
92 | #ifdef HAVE_INET6 | 92 | #ifdef HAVE_INET6 |
93 | return MHD_YES; | 93 | return MHD_YES; |
94 | #else | 94 | #else |
95 | return MHD_NO; | 95 | return MHD_NO; |
96 | #endif | 96 | #endif |
97 | case MHD_FEATURE_IPv6_ONLY: | 97 | case MHD_FEATURE_IPv6_ONLY: |
98 | #if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY) | 98 | #if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY) |
99 | return MHD_YES; | 99 | return MHD_YES; |
100 | #else | 100 | #else |
101 | return MHD_NO; | 101 | return MHD_NO; |
102 | #endif | 102 | #endif |
103 | case MHD_FEATURE_POLL: | 103 | case MHD_FEATURE_POLL: |
104 | #ifdef HAVE_POLL | 104 | #ifdef HAVE_POLL |
105 | return MHD_YES; | 105 | return MHD_YES; |
106 | #else | 106 | #else |
107 | return MHD_NO; | 107 | return MHD_NO; |
108 | #endif | 108 | #endif |
109 | case MHD_FEATURE_EPOLL: | 109 | case MHD_FEATURE_EPOLL: |
110 | #ifdef EPOLL_SUPPORT | 110 | #ifdef EPOLL_SUPPORT |
111 | return MHD_YES; | 111 | return MHD_YES; |
112 | #else | 112 | #else |
113 | return MHD_NO; | 113 | return MHD_NO; |
114 | #endif | 114 | #endif |
115 | case MHD_FEATURE_SHUTDOWN_LISTEN_SOCKET: | 115 | case MHD_FEATURE_SHUTDOWN_LISTEN_SOCKET: |
116 | #ifdef HAVE_LISTEN_SHUTDOWN | 116 | #ifdef HAVE_LISTEN_SHUTDOWN |
117 | return MHD_YES; | 117 | return MHD_YES; |
118 | #else | 118 | #else |
119 | return MHD_NO; | 119 | return MHD_NO; |
120 | #endif | 120 | #endif |
121 | case MHD_FEATURE_SOCKETPAIR: | 121 | case MHD_FEATURE_SOCKETPAIR: |
122 | #ifdef _MHD_ITC_SOCKETPAIR | 122 | #ifdef _MHD_ITC_SOCKETPAIR |
123 | return MHD_YES; | 123 | return MHD_YES; |
124 | #else | 124 | #else |
125 | return MHD_NO; | 125 | return MHD_NO; |
126 | #endif | 126 | #endif |
127 | case MHD_FEATURE_TCP_FASTOPEN: | 127 | case MHD_FEATURE_TCP_FASTOPEN: |
128 | #ifdef TCP_FASTOPEN | 128 | #ifdef TCP_FASTOPEN |
129 | return MHD_YES; | 129 | return MHD_YES; |
130 | #else | 130 | #else |
131 | return MHD_NO; | 131 | return MHD_NO; |
132 | #endif | 132 | #endif |
133 | case MHD_FEATURE_BASIC_AUTH: | 133 | case MHD_FEATURE_BASIC_AUTH: |
134 | #ifdef BAUTH_SUPPORT | 134 | #ifdef BAUTH_SUPPORT |
135 | return MHD_YES; | 135 | return MHD_YES; |
136 | #else | 136 | #else |
137 | return MHD_NO; | 137 | return MHD_NO; |
138 | #endif | 138 | #endif |
139 | case MHD_FEATURE_DIGEST_AUTH: | 139 | case MHD_FEATURE_DIGEST_AUTH: |
140 | #ifdef DAUTH_SUPPORT | 140 | #ifdef DAUTH_SUPPORT |
141 | return MHD_YES; | 141 | return MHD_YES; |
142 | #else | 142 | #else |
143 | return MHD_NO; | 143 | return MHD_NO; |
144 | #endif | 144 | #endif |
145 | case MHD_FEATURE_POSTPROCESSOR: | 145 | case MHD_FEATURE_POSTPROCESSOR: |
146 | #ifdef HAVE_POSTPROCESSOR | 146 | #ifdef HAVE_POSTPROCESSOR |
147 | return MHD_YES; | 147 | return MHD_YES; |
148 | #else | 148 | #else |
149 | return MHD_NO; | 149 | return MHD_NO; |
150 | #endif | 150 | #endif |
151 | case MHD_FEATURE_HTTPS_KEY_PASSWORD: | 151 | case MHD_FEATURE_HTTPS_KEY_PASSWORD: |
152 | #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_NUMBER >= 0x030111 | 152 | #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_NUMBER >= 0x030111 |
153 | return MHD_YES; | 153 | return MHD_YES; |
154 | #else /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030111 */ | 154 | #else /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030111 */ |
155 | return MHD_NO; | 155 | return MHD_NO; |
156 | #endif /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030111 */ | 156 | #endif /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030111 */ |
157 | case MHD_FEATURE_LARGE_FILE: | 157 | case MHD_FEATURE_LARGE_FILE: |
158 | #if defined(HAVE_PREAD64) || defined(_WIN32) | 158 | #if defined(HAVE_PREAD64) || defined(_WIN32) |
159 | return MHD_YES; | 159 | return MHD_YES; |
160 | #elif defined(HAVE_PREAD) | 160 | #elif defined(HAVE_PREAD) |
161 | return (sizeof(uint64_t) > sizeof(off_t)) ? MHD_NO : MHD_YES; | 161 | return (sizeof(uint64_t) > sizeof(off_t)) ? MHD_NO : MHD_YES; |
162 | #elif defined(HAVE_LSEEK64) | 162 | #elif defined(HAVE_LSEEK64) |
163 | return MHD_YES; | 163 | return MHD_YES; |
164 | #else | 164 | #else |
165 | return (sizeof(uint64_t) > sizeof(off_t)) ? MHD_NO : MHD_YES; | 165 | return (sizeof(uint64_t) > sizeof(off_t)) ? MHD_NO : MHD_YES; |
166 | #endif | 166 | #endif |
167 | case MHD_FEATURE_THREAD_NAMES: | 167 | case MHD_FEATURE_THREAD_NAMES: |
168 | #if defined(MHD_USE_THREAD_NAME_) | 168 | #if defined(MHD_USE_THREAD_NAME_) |
169 | return MHD_YES; | 169 | return MHD_YES; |
170 | #else | 170 | #else |
171 | return MHD_NO; | 171 | return MHD_NO; |
172 | #endif | 172 | #endif |
173 | case MHD_FEATURE_UPGRADE: | 173 | case MHD_FEATURE_UPGRADE: |
174 | #if defined(UPGRADE_SUPPORT) | 174 | #if defined(UPGRADE_SUPPORT) |
175 | return MHD_YES; | 175 | return MHD_YES; |
176 | #else | 176 | #else |
177 | return MHD_NO; | 177 | return MHD_NO; |
178 | #endif | 178 | #endif |
179 | case MHD_FEATURE_RESPONSES_SHARED_FD: | 179 | case MHD_FEATURE_RESPONSES_SHARED_FD: |
180 | #if defined(HAVE_PREAD64) || defined(HAVE_PREAD) || defined(_WIN32) | 180 | #if defined(HAVE_PREAD64) || defined(HAVE_PREAD) || defined(_WIN32) |
181 | return MHD_YES; | 181 | return MHD_YES; |
182 | #else | 182 | #else |
183 | return MHD_NO; | 183 | return MHD_NO; |
184 | #endif | 184 | #endif |
185 | case MHD_FEATURE_AUTODETECT_BIND_PORT: | 185 | case MHD_FEATURE_AUTODETECT_BIND_PORT: |
186 | #ifdef MHD_USE_GETSOCKNAME | 186 | #ifdef MHD_USE_GETSOCKNAME |
187 | return MHD_YES; | 187 | return MHD_YES; |
188 | #else | 188 | #else |
189 | return MHD_NO; | 189 | return MHD_NO; |
190 | #endif | 190 | #endif |
191 | case MHD_FEATURE_AUTOSUPPRESS_SIGPIPE: | 191 | case MHD_FEATURE_AUTOSUPPRESS_SIGPIPE: |
192 | #if defined(MHD_WINSOCK_SOCKETS) || defined(MHD_socket_nosignal_) || defined (MSG_NOSIGNAL) | 192 | #if defined(MHD_WINSOCK_SOCKETS) || defined(MHD_socket_nosignal_) || \ |
193 | return MHD_YES; | 193 | defined (MSG_NOSIGNAL) |
194 | return MHD_YES; | ||
194 | #else | 195 | #else |
195 | return MHD_NO; | 196 | return MHD_NO; |
196 | #endif | 197 | #endif |
197 | case MHD_FEATURE_SENDFILE: | 198 | case MHD_FEATURE_SENDFILE: |
198 | #ifdef _MHD_HAVE_SENDFILE | 199 | #ifdef _MHD_HAVE_SENDFILE |
199 | return MHD_YES; | 200 | return MHD_YES; |
200 | #else | 201 | #else |
201 | return MHD_NO; | 202 | return MHD_NO; |
202 | #endif | 203 | #endif |
203 | 204 | ||
204 | } | 205 | } |
205 | return MHD_NO; | 206 | return MHD_NO; |
206 | } | 207 | } |