aboutsummaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2018-02-16 06:30:29 +0100
committerChristian Grothoff <christian@grothoff.org>2018-02-16 06:30:29 +0100
commit6450f55f0c18d7a4b2fac829d9eff5d567348d19 (patch)
tree63a062752ac68f9339d31f455e01a36059cc5943 /src/lib
parent552f3aa7b23b958c8ad275fbf28682f229dbc4f7 (diff)
downloadlibmicrohttpd-6450f55f0c18d7a4b2fac829d9eff5d567348d19.tar.gz
libmicrohttpd-6450f55f0c18d7a4b2fac829d9eff5d567348d19.zip
add upgrade_process.c
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/Makefile.am1
-rw-r--r--src/lib/connection_add.c3
-rw-r--r--src/lib/daemon_epoll.c4
-rw-r--r--src/lib/daemon_ip_limit.c6
-rw-r--r--src/lib/daemon_poll.c5
-rw-r--r--src/lib/daemon_run.c19
-rw-r--r--src/lib/daemon_select.c5
-rw-r--r--src/lib/upgrade_process.c388
-rw-r--r--src/lib/upgrade_process.h44
9 files changed, 460 insertions, 15 deletions
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index b53e00b4..1667978a 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -100,6 +100,7 @@ libmicrohttpd_la_SOURCES = \
100 request_info.c \ 100 request_info.c \
101 request_resume.c \ 101 request_resume.c \
102 sysfdsetsize.c sysfdsetsize.h \ 102 sysfdsetsize.c sysfdsetsize.h \
103 upgrade_process.c upgrade_process.h \
103 panic.c \ 104 panic.c \
104 version.c 105 version.c
105 106
diff --git a/src/lib/connection_add.c b/src/lib/connection_add.c
index eb5984e3..0aebe501 100644
--- a/src/lib/connection_add.c
+++ b/src/lib/connection_add.c
@@ -23,6 +23,8 @@
23 */ 23 */
24#include "internal.h" 24#include "internal.h"
25#include "connection_add.h" 25#include "connection_add.h"
26#include "connection_close.h"
27#include "connection_finish_forward.h"
26#include "connection_update_last_activity.h" 28#include "connection_update_last_activity.h"
27#include "daemon_ip_limit.h" 29#include "daemon_ip_limit.h"
28#include "daemon_select.h" 30#include "daemon_select.h"
@@ -42,7 +44,6 @@ static void
42thread_main_connection_upgrade (struct MHD_Connection *con) 44thread_main_connection_upgrade (struct MHD_Connection *con)
43{ 45{
44#ifdef HTTPS_SUPPORT 46#ifdef HTTPS_SUPPORT
45 struct MHD_UpgradeResponseHandle *urh = con->request.urh;
46 struct MHD_Daemon *daemon = con->daemon; 47 struct MHD_Daemon *daemon = con->daemon;
47 48
48 /* Here, we need to bi-directionally forward 49 /* Here, we need to bi-directionally forward
diff --git a/src/lib/daemon_epoll.c b/src/lib/daemon_epoll.c
index d85d54e7..115bb9d0 100644
--- a/src/lib/daemon_epoll.c
+++ b/src/lib/daemon_epoll.c
@@ -24,7 +24,9 @@
24 */ 24 */
25#include "internal.h" 25#include "internal.h"
26#include "daemon_epoll.h" 26#include "daemon_epoll.h"
27#include "upgrade_process.h"
27#include "request_resume.h" 28#include "request_resume.h"
29#include "connection_add.h"
28#include "connection_finish_forward.h" 30#include "connection_finish_forward.h"
29 31
30#ifdef EPOLL_SUPPORT 32#ifdef EPOLL_SUPPORT
@@ -170,7 +172,7 @@ run_epoll_for_upgrade (struct MHD_Daemon *daemon)
170 while (NULL != (pos = prev)) 172 while (NULL != (pos = prev))
171 { 173 {
172 prev = pos->prevE; 174 prev = pos->prevE;
173 process_urh (pos); 175 MHD_upgrade_response_handle_process_ (pos);
174 if (! is_urh_ready(pos)) 176 if (! is_urh_ready(pos))
175 { 177 {
176 EDLL_remove (daemon->eready_urh_head, 178 EDLL_remove (daemon->eready_urh_head,
diff --git a/src/lib/daemon_ip_limit.c b/src/lib/daemon_ip_limit.c
index d368893b..4a131c92 100644
--- a/src/lib/daemon_ip_limit.c
+++ b/src/lib/daemon_ip_limit.c
@@ -24,6 +24,12 @@
24 */ 24 */
25#include "internal.h" 25#include "internal.h"
26#include "daemon_ip_limit.h" 26#include "daemon_ip_limit.h"
27#if HAVE_SEARCH_H
28#include <search.h>
29#else
30#include "tsearch.h"
31#endif
32
27 33
28/** 34/**
29 * Maintain connection count for single address. 35 * Maintain connection count for single address.
diff --git a/src/lib/daemon_poll.c b/src/lib/daemon_poll.c
index 63747bd0..39d22ccf 100644
--- a/src/lib/daemon_poll.c
+++ b/src/lib/daemon_poll.c
@@ -23,6 +23,7 @@
23 */ 23 */
24#include "internal.h" 24#include "internal.h"
25#include "daemon_poll.h" 25#include "daemon_poll.h"
26#include "upgrade_process.h"
26#include "request_resume.h" 27#include "request_resume.h"
27#include "connection_add.h" 28#include "connection_add.h"
28#include "connection_finish_forward.h" 29#include "connection_finish_forward.h"
@@ -315,7 +316,7 @@ MHD_daemon_poll_all_ (struct MHD_Daemon *daemon,
315 urh_from_pollfd (urh, 316 urh_from_pollfd (urh,
316 &(p[poll_server+i])); 317 &(p[poll_server+i]));
317 i += 2; 318 i += 2;
318 process_urh (urh); 319 MHD_upgrade_response_handle_process_ (urh);
319 /* Finished forwarding? */ 320 /* Finished forwarding? */
320 if ( (0 == urh->in_buffer_size) && 321 if ( (0 == urh->in_buffer_size) &&
321 (0 == urh->out_buffer_size) && 322 (0 == urh->out_buffer_size) &&
@@ -508,7 +509,7 @@ MHD_daemon_upgrade_connection_with_poll_ (struct MHD_Connection *con)
508 } 509 }
509 urh_from_pollfd (urh, 510 urh_from_pollfd (urh,
510 p); 511 p);
511 process_urh (urh); 512 MHD_upgrade_response_handle_process_ (urh);
512 } 513 }
513} 514}
514#endif 515#endif
diff --git a/src/lib/daemon_run.c b/src/lib/daemon_run.c
index c93a5f83..d95cff12 100644
--- a/src/lib/daemon_run.c
+++ b/src/lib/daemon_run.c
@@ -49,6 +49,8 @@
49enum MHD_StatusCode 49enum MHD_StatusCode
50MHD_daemon_run (struct MHD_Daemon *daemon) 50MHD_daemon_run (struct MHD_Daemon *daemon)
51{ 51{
52 enum MHD_StatusCode sc;
53
52 if (daemon->shutdown) 54 if (daemon->shutdown)
53 return MHD_SC_DAEMON_ALREADY_SHUTDOWN; 55 return MHD_SC_DAEMON_ALREADY_SHUTDOWN;
54 if (MHD_TM_EXTERNAL_EVENT_LOOP != daemon->threading_model) 56 if (MHD_TM_EXTERNAL_EVENT_LOOP != daemon->threading_model)
@@ -56,22 +58,21 @@ MHD_daemon_run (struct MHD_Daemon *daemon)
56 switch (daemon->event_loop_syscall) 58 switch (daemon->event_loop_syscall)
57 { 59 {
58 case MHD_ELS_POLL: 60 case MHD_ELS_POLL:
59 MHD_daemon_poll_ (daemon, 61 sc = MHD_daemon_poll_ (daemon,
60 MHD_NO); 62 MHD_NO);
61 MHD_cleanup_connections (daemon); 63 MHD_cleanup_connections (daemon);
62 break; 64 return sc;
63#ifdef EPOLL_SUPPORT 65#ifdef EPOLL_SUPPORT
64 case MHD_ELS_EPOLL: 66 case MHD_ELS_EPOLL:
65 MHD_daemon_epoll_ (daemon, 67 sc = MHD_daemon_epoll_ (daemon,
66 MHD_NO); 68 MHD_NO);
67 MHD_cleanup_connections (daemon); 69 MHD_cleanup_connections (daemon);
68 break; 70 return sc;
69#endif 71#endif
70 case MHD_ELS_SELECT: 72 case MHD_ELS_SELECT:
71 MHD_daemon_select_ (daemon, 73 return MHD_daemon_select_ (daemon,
72 MHD_NO); 74 MHD_NO);
73 /* MHD_select does MHD_cleanup_connections already */ 75 /* MHD_select does MHD_cleanup_connections already */
74 break;
75 default: 76 default:
76 return MHD_SC_CONFIGURATION_UNEXPECTED_ELS; 77 return MHD_SC_CONFIGURATION_UNEXPECTED_ELS;
77 } 78 }
diff --git a/src/lib/daemon_select.c b/src/lib/daemon_select.c
index 9c80812c..ec4da399 100644
--- a/src/lib/daemon_select.c
+++ b/src/lib/daemon_select.c
@@ -25,6 +25,7 @@
25#include "internal.h" 25#include "internal.h"
26#include "daemon_select.h" 26#include "daemon_select.h"
27#include "request_resume.h" 27#include "request_resume.h"
28#include "upgrade_process.h"
28#include "connection_finish_forward.h" 29#include "connection_finish_forward.h"
29 30
30 31
@@ -461,7 +462,7 @@ internal_run_from_select (struct MHD_Daemon *daemon,
461 write_fd_set, 462 write_fd_set,
462 except_fd_set); 463 except_fd_set);
463 /* call generic forwarding function for passing data */ 464 /* call generic forwarding function for passing data */
464 process_urh (urh); 465 MHD_upgrade_response_handle_process_ (urh);
465 /* Finished forwarding? */ 466 /* Finished forwarding? */
466 if ( (0 == urh->in_buffer_size) && 467 if ( (0 == urh->in_buffer_size) &&
467 (0 == urh->out_buffer_size) && 468 (0 == urh->out_buffer_size) &&
@@ -566,7 +567,7 @@ MHD_daemon_upgrade_connection_with_select_ (struct MHD_Connection *con)
566 &rs, 567 &rs,
567 &ws, 568 &ws,
568 &es); 569 &es);
569 process_urh (urh); 570 MHD_upgrade_response_handle_process_ (urh);
570 } 571 }
571} 572}
572#endif 573#endif
diff --git a/src/lib/upgrade_process.c b/src/lib/upgrade_process.c
new file mode 100644
index 00000000..318881ab
--- /dev/null
+++ b/src/lib/upgrade_process.c
@@ -0,0 +1,388 @@
1/*
2 This file is part of libmicrohttpd
3 Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18*/
19/**
20 * @file lib/upgrade_process.c
21 * @brief function to process upgrade activity (over TLS)
22 * @author Christian Grothoff
23 */
24#include "internal.h"
25#include "upgrade_process.h"
26
27
28#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
29/**
30 * Performs bi-directional forwarding on upgraded HTTPS connections
31 * based on the readyness state stored in the @a urh handle.
32 * @remark To be called only from thread that process
33 * connection's recv(), send() and response.
34 *
35 * @param urh handle to process
36 */
37void
38MHD_upgrade_response_handle_process_ (struct MHD_UpgradeResponseHandle *urh)
39{
40 /* Help compiler to optimize:
41 * pointers to 'connection' and 'daemon' are not changed
42 * during this processing, so no need to chain dereference
43 * each time. */
44 struct MHD_Connection * const connection = urh->connection;
45 struct MHD_Daemon * const daemon = connection->daemon;
46 /* Prevent data races: use same value of 'was_closed' throughout
47 * this function. If 'was_closed' changed externally in the middle
48 * of processing - it will be processed on next iteration. */
49 bool was_closed;
50 struct MHD_TLS_Plugin *tls = daemon->tls_api;
51
52 if (daemon->shutdown)
53 {
54 /* Daemon shutting down, application will not receive any more data. */
55#ifdef HAVE_MESSAGES
56 if (! urh->was_closed)
57 {
58 MHD_DLOG (daemon,
59 MHD_SC_DAEMON_ALREADY_SHUTDOWN,
60 _("Initiated daemon shutdown while \"upgraded\" connection was not closed.\n"));
61 }
62#endif
63 urh->was_closed = true;
64 }
65 was_closed = urh->was_closed;
66 if (was_closed)
67 {
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 MHD_DLOG (daemon,
74 MHD_SC_UPGRADE_FORWARD_INCOMPLETE,
75 _("Failed to forward to application " MHD_UNSIGNED_LONG_LONG_PRINTF \
76 " bytes of data received from remote side: application shut down socket\n"),
77 (MHD_UNSIGNED_LONG_LONG) urh->in_buffer_used);
78#endif
79
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 }
97
98 /* On some platforms (W32, possibly Darwin) failed send() (send() will always
99 * fail after remote disconnect was detected) may discard data in system
100 * buffers received by system but not yet read by recv().
101 * So, before trying send() on any socket, recv() must be performed at first
102 * otherwise last part of incoming data may be lost. */
103
104 /* If disconnect or error was detected - try to read from socket
105 * to dry data possibly pending is system buffers. */
106 if (0 != (MHD_EPOLL_STATE_ERROR & urh->app.celi))
107 urh->app.celi |= MHD_EPOLL_STATE_READ_READY;
108 if (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi))
109 urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
110
111 /*
112 * handle reading from remote TLS client
113 */
114 if ( ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->app.celi)) ||
115 (connection->tls_read_ready) ) &&
116 (urh->in_buffer_used < urh->in_buffer_size) )
117 {
118 ssize_t res;
119 size_t buf_size;
120
121 buf_size = urh->in_buffer_size - urh->in_buffer_used;
122 if (buf_size > SSIZE_MAX)
123 buf_size = SSIZE_MAX;
124
125 connection->tls_read_ready = false;
126 res = tls->recv (tls->cls,
127 connection->tls_cs,
128 &urh->in_buffer[urh->in_buffer_used],
129 buf_size);
130 if (0 >= res)
131 {
132 // FIXME: define GNUTLS-independent error codes!
133 if (GNUTLS_E_INTERRUPTED != res)
134 {
135 urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
136 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 {
157 /* Unrecoverable error on socket was detected and all
158 * pending data was read from system buffers. */
159 /* Stop trying to read from this TLS socket. */
160 urh->in_buffer_size = 0;
161 }
162 }
163
164 /*
165 * handle reading from application
166 */
167 if ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi)) &&
168 (urh->out_buffer_used < urh->out_buffer_size) )
169 {
170 ssize_t res;
171 size_t buf_size;
172
173 buf_size = urh->out_buffer_size - urh->out_buffer_used;
174 if (buf_size > MHD_SCKT_SEND_MAX_SIZE_)
175 buf_size = MHD_SCKT_SEND_MAX_SIZE_;
176
177 res = MHD_recv_ (urh->mhd.socket,
178 &urh->out_buffer[urh->out_buffer_used],
179 buf_size);
180 if (0 >= res)
181 {
182 const int err = MHD_socket_get_error_ ();
183 if ((0 == res) ||
184 ((! MHD_SCKT_ERR_IS_EINTR_ (err)) &&
185 (! MHD_SCKT_ERR_IS_LOW_RESOURCES_(err))))
186 {
187 urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
188 if ((0 == res) ||
189 (was_closed) ||
190 (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) ||
191 (! 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 {
211 /* Unrecoverable error on socket was detected and all
212 * pending data was read from system buffers. */
213 /* Do not try to pull more data from application. */
214 urh->out_buffer_size = 0;
215 }
216 }
217
218 /*
219 * handle writing to remote HTTPS client
220 */
221 if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->app.celi)) &&
222 (urh->out_buffer_used > 0) )
223 {
224 ssize_t res;
225 size_t data_size;
226
227 data_size = urh->out_buffer_used;
228 if (data_size > SSIZE_MAX)
229 data_size = SSIZE_MAX;
230
231 res = tls->send (tls->cls,
232 connection->tls_cs,
233 urh->out_buffer,
234 data_size);
235 if (0 >= res)
236 {
237 // FIXME: define GNUTLS-independent error codes!
238 if (GNUTLS_E_INTERRUPTED != res)
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
246 MHD_DLOG (daemon,
247 MHD_SC_UPGRADE_FORWARD_INCOMPLETE,
248 _("Failed to forward to remote client " MHD_UNSIGNED_LONG_LONG_PRINTF \
249 " bytes of data received from application: %s\n"),
250 (MHD_UNSIGNED_LONG_LONG) urh->out_buffer_used,
251 tls->strerror (tls->cls,
252 res));
253#endif
254 /* Discard any data unsent to remote. */
255 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. */
283 urh->out_buffer_size = 0;
284 urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
285 }
286 }
287
288 /*
289 * handle writing to application
290 */
291 if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->mhd.celi)) &&
292 (urh->in_buffer_used > 0) )
293 {
294 ssize_t res;
295 size_t data_size;
296
297 data_size = urh->in_buffer_used;
298 if (data_size > MHD_SCKT_SEND_MAX_SIZE_)
299 data_size = MHD_SCKT_SEND_MAX_SIZE_;
300
301 res = MHD_send_ (urh->mhd.socket,
302 urh->in_buffer,
303 data_size);
304 if (0 >= res)
305 {
306 const int err = MHD_socket_get_error_ ();
307 if ( (! MHD_SCKT_ERR_IS_EINTR_ (err)) &&
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
316 MHD_DLOG (daemon,
317 MHD_SC_UPGRADE_FORWARD_INCOMPLETE,
318 _("Failed to forward to application " MHD_UNSIGNED_LONG_LONG_PRINTF \
319 " bytes of data received from remote side: %s\n"),
320 (MHD_UNSIGNED_LONG_LONG) urh->in_buffer_used,
321 MHD_socket_strerr_ (err));
322#endif
323 /* Discard any data received form remote. */
324 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. */
351 urh->in_buffer_size = 0;
352 urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
353 connection->tls_read_ready = false;
354 }
355 }
356
357 /* Check whether data is present in TLS buffers
358 * and incoming forward buffer have some space. */
359 if ( (connection->tls_read_ready) &&
360 (urh->in_buffer_used < urh->in_buffer_size) &&
361 (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_model) )
362 daemon->data_already_pending = true;
363
364 if ( (daemon->shutdown) &&
365 ( (0 != urh->out_buffer_size) ||
366 (0 != urh->out_buffer_used) ) )
367 {
368 /* Daemon shutting down, discard any remaining forward data. */
369#ifdef HAVE_MESSAGES
370 if (0 < urh->out_buffer_used)
371 MHD_DLOG (daemon,
372 MHD_SC_UPGRADE_FORWARD_INCOMPLETE,
373 _("Failed to forward to remote client " MHD_UNSIGNED_LONG_LONG_PRINTF \
374 " bytes of data received from application: daemon shut down\n"),
375 (MHD_UNSIGNED_LONG_LONG) urh->out_buffer_used);
376#endif
377 /* Discard any data unsent to remote. */
378 urh->out_buffer_used = 0;
379 /* Do not try to sent to remote anymore. */
380 urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
381 /* Do not try to pull more data from application. */
382 urh->out_buffer_size = 0;
383 urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
384 }
385}
386#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
387
388/* end of upgrade_process.c */
diff --git a/src/lib/upgrade_process.h b/src/lib/upgrade_process.h
new file mode 100644
index 00000000..36a7ddff
--- /dev/null
+++ b/src/lib/upgrade_process.h
@@ -0,0 +1,44 @@
1/*
2 This file is part of libmicrohttpd
3 Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18*/
19/**
20 * @file lib/upgrade_process.h
21 * @brief function to process upgrade activity (over TLS)
22 * @author Christian Grothoff
23 */
24#ifndef UPGRADE_PROCESS_H
25#define UPGRADE_PROCESS_H
26
27
28#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
29/**
30 * Performs bi-directional forwarding on upgraded HTTPS connections
31 * based on the readyness state stored in the @a urh handle.
32 * @remark To be called only from thread that process
33 * connection's recv(), send() and response.
34 *
35 * @param urh handle to process
36 */
37void
38MHD_upgrade_response_handle_process_ (struct MHD_UpgradeResponseHandle *urh)
39 MHD_NONNULL(1);
40
41
42#endif
43
44#endif