aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2018-02-09 05:44:20 +0100
committerChristian Grothoff <christian@grothoff.org>2018-02-09 05:44:20 +0100
commite77fce2749a06b448e496140e8ad7e51891972de (patch)
tree825e1f67dd432cc99016cdff9a4444645711a79f
parentf6e1ee426f9caebe49476ec88720d87032a433a6 (diff)
downloadlibmicrohttpd-e77fce2749a06b448e496140e8ad7e51891972de.tar.gz
libmicrohttpd-e77fce2749a06b448e496140e8ad7e51891972de.zip
more work on mhd2 api implementation
-rw-r--r--src/include/microhttpd2.h35
-rw-r--r--src/lib/action_continue.c60
-rw-r--r--src/lib/action_from_response.c130
-rw-r--r--src/lib/action_parse_post.c61
-rw-r--r--src/lib/action_process_upload.c92
-rw-r--r--src/lib/action_suspend.c132
-rw-r--r--src/lib/connection_info.c52
-rw-r--r--src/lib/connection_options.c111
-rw-r--r--src/lib/daemon_info.c55
-rw-r--r--src/lib/daemon_start.c (renamed from src/lib/daemon.c)6
-rw-r--r--src/lib/init.c25
-rw-r--r--src/lib/init.h25
-rw-r--r--src/lib/internal.h184
-rw-r--r--src/lib/panic.c25
-rw-r--r--src/lib/request_info.c53
-rw-r--r--src/lib/request_resume.c48
-rw-r--r--src/lib/response.c264
-rw-r--r--src/lib/response_for_upgrade.c90
-rw-r--r--src/lib/response_from_buffer.c88
-rw-r--r--src/lib/response_from_callback.c80
-rw-r--r--src/lib/response_from_fd.c198
-rw-r--r--src/lib/response_options.c61
-rw-r--r--src/lib/version.c25
-rw-r--r--src/microhttpd/response.c3
24 files changed, 1852 insertions, 51 deletions
diff --git a/src/include/microhttpd2.h b/src/include/microhttpd2.h
index 7a67fbd3..c69d8731 100644
--- a/src/include/microhttpd2.h
+++ b/src/include/microhttpd2.h
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of libmicrohttpd 2 This file is part of libmicrohttpd
3 Copyright (C) 2006-2017 Christian Grothoff, Karlson2k (Evgeny Grin) 3 Copyright (C) 2006-2018 Christian Grothoff, Karlson2k (Evgeny Grin)
4 (and other contributing authors) 4 (and other contributing authors)
5 5
6 This library is free software; you can redistribute it and/or 6 This library is free software; you can redistribute it and/or
@@ -23,8 +23,9 @@
23 * Note that we do not indicate which of the OLD APIs 23 * Note that we do not indicate which of the OLD APIs
24 * simply need to be kept vs. deprecated. 24 * simply need to be kept vs. deprecated.
25 * 25 *
26 *
26 * The goal is to provide a basis for discussion! 27 * The goal is to provide a basis for discussion!
27 * None of this is implemented yet. 28 * Little of this is implemented yet.
28 * 29 *
29 * Main goals: 30 * Main goals:
30 * - simplify application callbacks by splitting header/upload/post 31 * - simplify application callbacks by splitting header/upload/post
@@ -64,7 +65,13 @@
64 * supported (include the descriptive string) by using an enum; 65 * supported (include the descriptive string) by using an enum;
65 * - simplify API for common-case of one-shot responses by 66 * - simplify API for common-case of one-shot responses by
66 * eliminating need for destroy response in most cases; 67 * eliminating need for destroy response in most cases;
68 *
69 * TODO:
70 * - varargs in upgrade is still there and ugly (and not even used!)
71 * - migrate event loop apis (get fdset, timeout, MHD_run(), etc.)
67 */ 72 */
73#ifndef MICROHTTPD2_H
74#define MICROHTTPD2_H
68 75
69 76
70/** 77/**
@@ -1018,8 +1025,8 @@ MHD_daemon_tls_key_and_cert_from_memory (struct MHD_Daemon *daemon,
1018 * @return #MHD_SC_OK upon success; TODO: define failure modes 1025 * @return #MHD_SC_OK upon success; TODO: define failure modes
1019 */ 1026 */
1020_MHD_EXTERN enum MHD_StatusCode 1027_MHD_EXTERN enum MHD_StatusCode
1021 MHD_daemon_tls_mem_dhparams (struct MHD_Daemon *daemon, 1028MHD_daemon_tls_mem_dhparams (struct MHD_Daemon *daemon,
1022 const char *dh); 1029 const char *dh);
1023 1030
1024 1031
1025/** 1032/**
@@ -1356,17 +1363,16 @@ MHD_daemon_digest_auth_nc_length (struct MHD_Daemon *daemon,
1356 1363
1357 1364
1358/** 1365/**
1359 * Generate option to set a custom timeout for the given connection. 1366 * Set custom timeout for the given connection.
1360 * Specified as the number of seconds. Use zero for no timeout. If 1367 * Specified as the number of seconds. Use zero for no timeout.
1361 * timeout was set to zero (or unset) before, setting of a new value 1368 * Calling this function will reset timeout timer.
1362 * by MHD_connection_set_option() will reset timeout timer.
1363 * 1369 *
1364 * @param connection connection to configure timeout for 1370 * @param connection connection to configure timeout for
1365 * @param timeout_s new timeout in seconds 1371 * @param timeout_s new timeout in seconds
1366 */ 1372 */
1367_MHD_EXTERN struct MHD_ConnectionOption 1373_MHD_EXTERN void
1368MHD_connection_timeout (struct MHD_Connection *connection, 1374MHD_connection_set_timeout (struct MHD_Connection *connection,
1369 unsigned int timeout_s); 1375 unsigned int timeout_s);
1370 1376
1371 1377
1372/* **************** Request handling functions ***************** */ 1378/* **************** Request handling functions ***************** */
@@ -1792,6 +1798,9 @@ struct MHD_UpgradeResponseHandle;
1792 * It allows applications to perform 'special' actions on 1798 * It allows applications to perform 'special' actions on
1793 * the underlying socket from the upgrade. 1799 * the underlying socket from the upgrade.
1794 * 1800 *
1801 * FIXME: this API still uses the untyped, ugly varargs.
1802 * Should we not modernize this one as well?
1803 *
1795 * @param urh the handle identifying the connection to perform 1804 * @param urh the handle identifying the connection to perform
1796 * the upgrade @a action on. 1805 * the upgrade @a action on.
1797 * @param operation which operation should be performed 1806 * @param operation which operation should be performed
@@ -1987,6 +1996,7 @@ MHD_response_get_header (struct MHD_Response *response,
1987 1996
1988/* ************Upload and PostProcessor functions ********************** */ 1997/* ************Upload and PostProcessor functions ********************** */
1989 1998
1999
1990/** 2000/**
1991 * Action telling MHD to continue processing the upload. 2001 * Action telling MHD to continue processing the upload.
1992 * 2002 *
@@ -2493,3 +2503,6 @@ MHD_daemon_get_information_sz (struct MHD_Daemon *daemon,
2493 info_type, \ 2503 info_type, \
2494 return_value) \ 2504 return_value) \
2495 MHD_daemon_get_information_sz((daemon), (info_type), (return_value), sizeof(union MHD_DaemonInformation)); 2505 MHD_daemon_get_information_sz((daemon), (info_type), (return_value), sizeof(union MHD_DaemonInformation));
2506
2507
2508#endif
diff --git a/src/lib/action_continue.c b/src/lib/action_continue.c
new file mode 100644
index 00000000..0367f536
--- /dev/null
+++ b/src/lib/action_continue.c
@@ -0,0 +1,60 @@
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/**
21 * @file lib/action_continue.c
22 * @brief implementation of MHD_action_continue()
23 * @author Christian Grothoff
24 */
25#include "internal.h"
26
27
28/**
29 * The continue action is being run. Continue
30 * handling the upload.
31 *
32 * @param cls NULL
33 * @param request the request to apply the action to
34 */
35static void
36cont_action (void *cls,
37 struct MHD_Request *request)
38{
39 /* not sure yet, but this function body may
40 just legitimately stay empty... */
41}
42
43
44/**
45 * Action telling MHD to continue processing the upload.
46 *
47 * @return action operation, never NULL
48 */
49struct MHD_Action *
50MHD_action_continue (void)
51{
52 static MHD_Action acont = {
53 .action = &cont_action,
54 .action_cls = NULL
55 };
56
57 return &acont;
58}
59
60/* end of action_continue.c */
diff --git a/src/lib/action_from_response.c b/src/lib/action_from_response.c
new file mode 100644
index 00000000..3c13cf42
--- /dev/null
+++ b/src/lib/action_from_response.c
@@ -0,0 +1,130 @@
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/**
21 * @file lib/action_from_response.c
22 * @brief implementation of #MHD_action_from_response()
23 * @author Christian Grothoff
24 */
25#include "internal.h"
26
27
28/**
29 * A response was given as the desired action for a @a request.
30 * Queue the response for the request.
31 *
32 * @param cls the `struct MHD_Response`
33 * @param request the request we are processing
34 */
35static void
36response_action (void *cls,
37 struct MHD_Request *request)
38{
39 struct MHD_Response *response = cls;
40 struct MHD_Daemon *daemon = response->daemon;
41
42 if (daemon->shutdown)
43 return MHD_YES; /* If daemon was shut down in parallel,
44 * response will be aborted now or on later stage. */
45
46#ifdef UPGRADE_SUPPORT
47 if ( (NULL != response->upgrade_handler) &&
48 (0 == (daemon->options & MHD_ALLOW_UPGRADE)) )
49 {
50#ifdef HAVE_MESSAGES
51 MHD_DLOG (daemon,
52 _("Attempted 'upgrade' connection on daemon without MHD_ALLOW_UPGRADE option!\n"));
53#endif
54 return MHD_NO;
55 }
56#endif /* UPGRADE_SUPPORT */
57 request->response = response;
58#if defined(_MHD_HAVE_SENDFILE)
59 if ( (-1 == response->fd)
60#if HTTPS_SUPPORT
61 || (NULL != daemon->tls_api)
62#endif
63 )
64 request->resp_sender = MHD_resp_sender_std;
65 else
66 request->resp_sender = MHD_resp_sender_sendfile;
67#endif /* _MHD_HAVE_SENDFILE */
68
69 if ( ( (NULL != request->method) &&
70 (MHD_str_equal_caseless_ (request->method,
71 MHD_HTTP_METHOD_HEAD)) ) ||
72 (MHD_HTTP_OK > response->status_code) ||
73 (MHD_HTTP_NO_CONTENT == response->status_code) ||
74 (MHD_HTTP_NOT_MODIFIED == response->status_code) )
75 {
76 /* if this is a "HEAD" request, or a status code for
77 which a body is not allowed, pretend that we
78 have already sent the full message body. */
79 request->response_write_position = response->total_size;
80 }
81 if ( (MHD_REQUEST_HEADERS_PROCESSED == request->state) &&
82 (NULL != connection->method) &&
83 ( (MHD_str_equal_caseless_ (request->method,
84 MHD_HTTP_METHOD_POST)) ||
85 (MHD_str_equal_caseless_ (request->method,
86 MHD_HTTP_METHOD_PUT))) )
87 {
88 /* response was queued "early", refuse to read body / footers or
89 further requests! */
90 connection->read_closed = true;
91 request->state = MHD_CONNECTION_FOOTERS_RECEIVED;
92 }
93 if (! request->in_idle)
94 (void) MHD_connection_handle_idle (connection);
95}
96
97
98/**
99 * Converts a @a response to an action. If @a consume
100 * is set, the reference to the @a response is consumed
101 * by the conversion. If @a consume is #MHD_NO, then
102 * the response can be converted to actions in the future.
103 * However, the @a response is frozen by this step and
104 * must no longer be modified (i.e. by setting headers).
105 *
106 * @param response response to convert, not NULL
107 * @param destroy_after_use should the response object be consumed?
108 * @return corresponding action, never returns NULL
109 *
110 * Implementation note: internally, this is largely just
111 * a cast (and possibly an RC increment operation),
112 * as a response *is* an action. As no memory is
113 * allocated, this operation cannot fail.
114 */
115_MHD_EXTERN struct MHD_Action *
116MHD_action_from_response (struct MHD_Response *response,
117 enum MHD_bool destroy_after_use)
118{
119 response->action.action = &response_action;
120 response->action.action_cls = response;
121 if (! destroy_after_use)
122 {
123 MHD_mutex_lock_chk_ (&response->mutex);
124 response->reference_count++;
125 MHD_mutex_unlock_chk_ (&response->mutex);
126 }
127 return &response->action;
128}
129
130/* end of action_from_response */
diff --git a/src/lib/action_parse_post.c b/src/lib/action_parse_post.c
new file mode 100644
index 00000000..202e52f1
--- /dev/null
+++ b/src/lib/action_parse_post.c
@@ -0,0 +1,61 @@
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/**
21 * @file lib/action_parse_post.c
22 * @brief implementation of MHD_action_parse_post()
23 * @author Christian Grothoff
24 */
25#include "internal.h"
26
27
28
29/**
30 * Create an action that parses a POST request.
31 *
32 * This action can be used to (incrementally) parse the data portion
33 * of a POST request. Note that some buggy browsers fail to set the
34 * encoding type. If you want to support those, you may have to call
35 * #MHD_set_connection_value with the proper encoding type before
36 * returning this action (if no supported encoding type is detected,
37 * returning this action will cause a bad request to be returned to
38 * the client).
39 *
40 * @param buffer_size maximum number of bytes to use for
41 * internal buffering (used only for the parsing,
42 * specifically the parsing of the keys). A
43 * tiny value (256-1024) should be sufficient.
44 * Do NOT use a value smaller than 256. For good
45 * performance, use 32 or 64k (i.e. 65536).
46 * @param iter iterator to be called with the parsed data,
47 * Must NOT be NULL.
48 * @param iter_cls first argument to @a iter
49 * @return NULL on error (out of memory, unsupported encoding),
50 * otherwise a PP handle
51 * @ingroup request
52 */
53struct MHD_Action *
54MHD_action_parse_post (size_t buffer_size,
55 MHD_PostDataIterator iter,
56 void *iter_cls)
57{
58 return NULL; /* not yet implemented */
59}
60
61/* end of action_parse_post.c */
diff --git a/src/lib/action_process_upload.c b/src/lib/action_process_upload.c
new file mode 100644
index 00000000..d67b60a1
--- /dev/null
+++ b/src/lib/action_process_upload.c
@@ -0,0 +1,92 @@
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/**
21 * @file lib/action_process_upload.c
22 * @brief implementation of MHD_action_process_upload()
23 * @author Christian Grothoff
24 */
25#include "internal.h"
26
27
28/**
29 * Internal details about an upload action.
30 */
31struct UploadAction
32{
33 /**
34 * An upload action is an action. This field
35 * must come first!
36 */
37 struct MHD_Action action;
38
39 MHD_UploadCallback uc;
40
41 void *uc_cls;
42
43};
44
45
46/**
47 * The application wants to process uploaded data for
48 * the given request. Do it!
49 *
50 * @param cls the `struct UploadAction` with the
51 * function we are to call for upload data
52 * @param request the request for which we are to process
53 * upload data
54 */
55static void
56upload_action (void *cls,
57 struct MHD_Request *request)
58{
59 struct UploadAction *ua = cls;
60
61 (void) ua;
62 // FIXME: implement!
63}
64
65
66/**
67 * Create an action that handles an upload.
68 *
69 * @param uc function to call with uploaded data
70 * @param uc_cls closure for @a uc
71 * @return NULL on error (out of memory)
72 * @ingroup action
73 */
74struct MHD_Action *
75MHD_action_process_upload (MHD_UploadCallback uc,
76 void *uc_cls)
77{
78 struct UploadAction *ua;
79
80 if (NULL == (ua = malloc (sizeof (struct UploadAction))))
81 return NULL;
82 ua->action = &upload_action;
83 ua->action_cls = ua;
84 ua->uc = uc;
85 ua->uc_cls = uc_cls;
86 return ua;
87}
88
89
90/* end of action_process_upload.c */
91
92
diff --git a/src/lib/action_suspend.c b/src/lib/action_suspend.c
new file mode 100644
index 00000000..8327992d
--- /dev/null
+++ b/src/lib/action_suspend.c
@@ -0,0 +1,132 @@
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/**
21 * @file lib/action_suspend.c
22 * @brief implementation of MHD_action_suspend()
23 * @author Christian Grothoff
24 */
25#include "internal.h"
26
27
28/**
29 * The suspend action is being run. Suspend handling
30 * of the given request.
31 *
32 * @param cls NULL
33 * @param request the request to apply the action to
34 */
35static void
36suspend_action (void *cls,
37 struct MHD_Request *request)
38{
39 struct MHD_Daemon *daemon = connection->daemon;
40
41 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
42 if (connection->resuming)
43 {
44 /* suspending again while we didn't even complete resuming yet */
45 connection->resuming = false;
46 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
47 return;
48 }
49 if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
50 {
51 if (connection->connection_timeout == daemon->connection_timeout)
52 XDLL_remove (daemon->normal_timeout_head,
53 daemon->normal_timeout_tail,
54 connection);
55 else
56 XDLL_remove (daemon->manual_timeout_head,
57 daemon->manual_timeout_tail,
58 connection);
59 }
60 DLL_remove (daemon->connections_head,
61 daemon->connections_tail,
62 connection);
63 mhd_assert (! connection->suspended);
64 DLL_insert (daemon->suspended_connections_head,
65 daemon->suspended_connections_tail,
66 connection);
67 connection->suspended = true;
68#ifdef EPOLL_SUPPORT
69 if (MHD_ELS_EPOLL == daemon->event_loop_syscall)
70 {
71 if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
72 {
73 EDLL_remove (daemon->eready_head,
74 daemon->eready_tail,
75 connection);
76 connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
77 }
78 if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET))
79 {
80 if (0 != epoll_ctl (daemon->epoll_fd,
81 EPOLL_CTL_DEL,
82 connection->socket_fd,
83 NULL))
84 MHD_PANIC (_("Failed to remove FD from epoll set\n"));
85 connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET;
86 }
87 connection->epoll_state |= MHD_EPOLL_STATE_SUSPENDED;
88 }
89#endif
90 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
91}
92
93
94/**
95 * Suspend handling of network data for a given request. This can
96 * be used to dequeue a request from MHD's event loop for a while.
97 *
98 * If you use this API in conjunction with a internal select or a
99 * thread pool, you must set the option #MHD_USE_ITC to
100 * ensure that a resumed request is immediately processed by MHD.
101 *
102 * Suspended requests continue to count against the total number of
103 * requests allowed (per daemon, as well as per IP, if such limits
104 * are set). Suspended requests will NOT time out; timeouts will
105 * restart when the request handling is resumed. While a
106 * request is suspended, MHD will not detect disconnects by the
107 * client.
108 *
109 * The only safe time to suspend a request is from either a
110 * #MHD_RequestHeaderCallback, #MHD_UploadCallback, or a
111 * #MHD_RequestfetchResponseCallback. Suspending a request
112 * at any other time will cause an assertion failure.
113 *
114 * Finally, it is an API violation to call #MHD_daemon_stop() while
115 * having suspended requests (this will at least create memory and
116 * socket leaks or lead to undefined behavior). You must explicitly
117 * resume all requests before stopping the daemon.
118 *
119 * @return action to cause a request to be suspended.
120 */
121struct MHD_Action *
122MHD_action_suspend (void)
123{
124 static MHD_Action suspend = {
125 .action = &suspend_action,
126 .action_cls = NULL
127 };
128
129 return &suspend;
130}
131
132/* end of action_suspend.c */
diff --git a/src/lib/connection_info.c b/src/lib/connection_info.c
new file mode 100644
index 00000000..a4337679
--- /dev/null
+++ b/src/lib/connection_info.c
@@ -0,0 +1,52 @@
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/**
21 * @file lib/connection_info.c
22 * @brief implementation of MHD_connection_get_information_sz()
23 * @author Christian Grothoff
24 */
25#include "internal.h"
26
27
28/**
29 * Obtain information about the given connection.
30 * Use wrapper macro #MHD_connection_get_information() instead of direct use
31 * of this function.
32 *
33 * @param connection what connection to get information about
34 * @param info_type what information is desired?
35 * @param[out] return_value pointer to union where requested information will
36 * be stored
37 * @param return_value_size size of union MHD_ConnectionInformation at compile
38 * time
39 * @return #MHD_YES on success, #MHD_NO on error
40 * (@a info_type is unknown, NULL pointer etc.)
41 * @ingroup specialized
42 */
43enum MHD_Bool
44MHD_connection_get_information_sz (struct MHD_Connection *connection,
45 enum MHD_ConnectionInformationType info_type,
46 union MHD_ConnectionInformation *return_value,
47 size_t return_value_size)
48{
49 return MHD_NO; /* FIXME: not yet implemented */
50}
51
52/* end of connection_info.c */
diff --git a/src/lib/connection_options.c b/src/lib/connection_options.c
index 163c956a..24301ddf 100644
--- a/src/lib/connection_options.c
+++ b/src/lib/connection_options.c
@@ -1,16 +1,113 @@
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/**
21 * @file lib/connection_options.c
22 * @brief functions to set per-connection options
23 * @author Christian Grothoff
24 */
25#include "internal.h"
26
1 27
2/** 28/**
3 * Generate option to set a custom timeout for the given connection. 29 * Set custom timeout for the given connection. Specified as the
4 * Specified as the number of seconds. Use zero for no timeout. If 30 * number of seconds. Use zero for no timeout. Calling this function
5 * timeout was set to zero (or unset) before, setting of a new value 31 * will reset timeout timer.
6 * by MHD_connection_set_option() will reset timeout timer.
7 * 32 *
8 * @param connection connection to configure timeout for 33 * @param connection connection to configure timeout for
9 * @param timeout_s new timeout in seconds 34 * @param timeout_s new timeout in seconds
10 */ 35 */
11struct MHD_ConnectionOption 36void
12MHD_connection_timeout (struct MHD_Connection *connection, 37MHD_connection_set_timeout (struct MHD_Connection *connection,
13 unsigned int timeout_s); 38 unsigned int timeout_s)
39{
40 struct MHD_Daemon *daemon = connection->daemon;
41
42 connection->last_activity = MHD_monotonic_sec_counter();
43 if (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_model)
44 {
45 /* Simple case, no need to lock to update DLLs */
46 connection->connection_timeout = (time_t) timeout_s;
47 return;
48 }
49 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
50 if (! connection->suspended)
51 {
52 if (connection->connection_timeout == daemon->connection_timeout)
53 XDLL_remove (daemon->normal_timeout_head,
54 daemon->normal_timeout_tail,
55 connection);
56 else
57 XDLL_remove (daemon->manual_timeout_head,
58 daemon->manual_timeout_tail,
59 connection);
60 }
61 connection->connection_timeout = (time_t) timeout_s;
62 if (! connection->suspended)
63 {
64 if (connection->connection_timeout == daemon->connection_timeout)
65 XDLL_insert (daemon->normal_timeout_head,
66 daemon->normal_timeout_tail,
67 connection);
68 else
69 XDLL_insert (daemon->manual_timeout_head,
70 daemon->manual_timeout_tail,
71 connection);
72 }
73 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
74}
75
76
77/**
78 * Update the 'last_activity' field of the connection to the current
79 * time and move the connection to the head of the 'normal_timeout'
80 * list if the timeout for the connection uses the default value.
81 *
82 * @param connection the connection that saw some activity
83 */
84void
85MHD_update_last_activity_ (struct MHD_Connection *connection)
86{
87 struct MHD_Daemon *daemon = connection->daemon;
88
89 if (0 == connection->connection_timeout)
90 return; /* Skip update of activity for connections
91 without timeout timer. */
92 if (connection->suspended)
93 return; /* no activity on suspended connections */
94
95 connection->last_activity = MHD_monotonic_sec_counter();
96 if (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_model)
97 return; /* each connection has personal timeout */
14 98
99 if (connection->connection_timeout != daemon->connection_timeout)
100 return; /* custom timeout, no need to move it in "normal" DLL */
15 101
102 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
103 /* move connection to head of timeout list (by remove + add operation) */
104 XDLL_remove (daemon->normal_timeout_head,
105 daemon->normal_timeout_tail,
106 connection);
107 XDLL_insert (daemon->normal_timeout_head,
108 daemon->normal_timeout_tail,
109 connection);
110 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
111}
16 112
113/* end of connection_options.c */
diff --git a/src/lib/daemon_info.c b/src/lib/daemon_info.c
index b724094d..47009687 100644
--- a/src/lib/daemon_info.c
+++ b/src/lib/daemon_info.c
@@ -1,20 +1,52 @@
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*/
1 19
2/** 20/**
3 * Obtain information about the given daemon 21 * @file lib/daemon_info.c
4 * (not fully implemented!). 22 * @brief implementation of MHD_daemon_get_information_sz()
23 * @author Christian Grothoff
24 */
25#include "internal.h"
26
27
28/**
29 * Obtain information about the given daemon.
30 * Use wrapper macro #MHD_daemon_get_information() instead of direct use
31 * of this function.
5 * 32 *
6 * @param daemon what daemon to get information about 33 * @param daemon what daemon to get information about
7 * @param info_type what information is desired? 34 * @param info_type what information is desired?
8 * @param ... depends on @a info_type 35 * @param[out] return_value pointer to union where requested information will
9 * @return NULL if this information is not available 36 * be stored
10 * (or if the @a info_type is unknown) 37 * @param return_value_size size of union MHD_DaemonInformation at compile
38 * time
39 * @return #MHD_YES on success, #MHD_NO on error
40 * (@a info_type is unknown, NULL pointer etc.)
11 * @ingroup specialized 41 * @ingroup specialized
12 */ 42 */
13const union MHD_DaemonInfo * 43enum MHD_Bool
14MHD_get_daemon_info (struct MHD_Daemon *daemon, 44MHD_daemon_get_information_sz (struct MHD_Daemon *daemon,
15 enum MHD_DaemonInfoType info_type, 45 enum MHD_DaemonInformationType info_type,
16 ...) 46 union MHD_DaemonInformation *return_value,
47 size_t return_value_size)
17{ 48{
49#if OLD
18 if (NULL == daemon) 50 if (NULL == daemon)
19 return NULL; 51 return NULL;
20 switch (info_type) 52 switch (info_type)
@@ -55,6 +87,9 @@ MHD_get_daemon_info (struct MHD_Daemon *daemon,
55 default: 87 default:
56 return NULL; 88 return NULL;
57 } 89 }
90#else
91 return MHD_NO;
92#endif
58} 93}
59 94
60 95/* end of daemon_info.c */
diff --git a/src/lib/daemon.c b/src/lib/daemon_start.c
index 2973dd2e..51c48a28 100644
--- a/src/lib/daemon.c
+++ b/src/lib/daemon_start.c
@@ -19,7 +19,7 @@
19 19
20/** 20/**
21 * @file lib/daemon.c 21 * @file lib/daemon.c
22 * @brief main functions to start a daemon 22 * @brief functions to start a daemon
23 * @author Christian Grothoff 23 * @author Christian Grothoff
24 */ 24 */
25#include "internal.h" 25#include "internal.h"
@@ -642,8 +642,8 @@ setup_thread_pool (struct MHD_Daemon *daemon)
642 enum MHD_StatusCode sc; 642 enum MHD_StatusCode sc;
643 643
644 /* Allocate memory for pooled objects */ 644 /* Allocate memory for pooled objects */
645 daemon->worker_pool = calloc (daemon->threading_model, 645 daemon->worker_pool = MHD_calloc_ (daemon->threading_model,
646 sizeof (struct MHD_Daemon)); 646 sizeof (struct MHD_Daemon));
647 if (NULL == daemon->worker_pool) 647 if (NULL == daemon->worker_pool)
648 return MHD_SC_THREAD_POOL_MALLOC_FAILURE; 648 return MHD_SC_THREAD_POOL_MALLOC_FAILURE;
649 649
diff --git a/src/lib/init.c b/src/lib/init.c
index d7a6faa1..d7ba332d 100644
--- a/src/lib/init.c
+++ b/src/lib/init.c
@@ -1,3 +1,28 @@
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/**
21 * @file lib/init.c
22 * @brief initialization routines
23 * @author Christian Grothoff
24 */
25#include "internal.h"
1#include "init.h" 26#include "init.h"
2 27
3 28
diff --git a/src/lib/init.h b/src/lib/init.h
index 25243c17..f64f9b51 100644
--- a/src/lib/init.h
+++ b/src/lib/init.h
@@ -1,3 +1,28 @@
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/**
21 * @file lib/init.h
22 * @brief functions to initialize library
23 * @author Christian Grothoff
24 */
25#include "internal.h"
1 26
2 27
3#ifndef INIT_H 28#ifndef INIT_H
diff --git a/src/lib/internal.h b/src/lib/internal.h
index c14d96eb..f5df8ce2 100644
--- a/src/lib/internal.h
+++ b/src/lib/internal.h
@@ -562,12 +562,6 @@ struct MHD_Request
562 enum MHD_RequestEventLoopInfo event_loop_info; 562 enum MHD_RequestEventLoopInfo event_loop_info;
563 563
564 /** 564 /**
565 * HTTP response code. Only valid if response object
566 * is already set.
567 */
568 unsigned int responseCode;
569
570 /**
571 * Did we ever call the "default_handler" on this request? (this 565 * Did we ever call the "default_handler" on this request? (this
572 * flag will determine if we call the #MHD_OPTION_NOTIFY_COMPLETED 566 * flag will determine if we call the #MHD_OPTION_NOTIFY_COMPLETED
573 * handler when the request closes down). 567 * handler when the request closes down).
@@ -594,16 +588,6 @@ struct MHD_Request
594 * be set to #MHD_NO again (before the final call to the handler). 588 * be set to #MHD_NO again (before the final call to the handler).
595 */ 589 */
596 bool have_chunked_upload; 590 bool have_chunked_upload;
597
598 /**
599 * Is the request suspended?
600 */
601 bool suspended;
602
603 /**
604 * Is the request wanting to resume?
605 */
606 bool resuming;
607}; 591};
608 592
609 593
@@ -660,6 +644,15 @@ struct MHD_Connection
660 */ 644 */
661 struct MHD_Request request; 645 struct MHD_Request request;
662 646
647 /**
648 * Is the connection suspended?
649 */
650 bool suspended;
651
652 /**
653 * Is the connection wanting to resume?
654 */
655 bool resuming;
663 656
664 /** 657 /**
665 * Set to `true` if the thread has been joined. 658 * Set to `true` if the thread has been joined.
@@ -679,8 +672,7 @@ struct MHD_Connection
679 */ 672 */
680 bool read_closed; 673 bool read_closed;
681 674
682 675 /**
683 /**
684 * Length of the foreign address. 676 * Length of the foreign address.
685 */ 677 */
686 socklen_t addr_len; 678 socklen_t addr_len;
@@ -998,12 +990,166 @@ struct MHD_Daemon
998 */ 990 */
999 bool allow_address_reuse; 991 bool allow_address_reuse;
1000 992
1001 993
994};
995
996
997/**
998 * Action function implementing some action to be
999 * performed on a request.
1000 *
1001 * @param cls action-specfic closure
1002 * @param request the request on which the action is to be performed
1003 */
1004typedef void
1005(*ActionCallback) (void *cls,
1006 const struct MHD_Request *request);
1007
1008
1009/**
1010 * Actions are returned by the application to drive the request
1011 * handling of MHD.
1012 */
1013struct MHD_Action
1014{
1015
1016 /**
1017 * Function to call for the action.
1018 */
1019 ActionCallback action;
1020
1021 /**
1022 * Closure for @a action
1023 */
1024 void *action_cls;
1002 1025
1003}; 1026};
1004 1027
1005 1028
1029/**
1030 * Representation of an HTTP response.
1031 */
1032struct MHD_Response
1033{
1034
1035 /**
1036 * A response *is* an action. See also
1037 * #MHD_action_from_response(). Hence this field
1038 * must be the first field in a response!
1039 */
1040 struct MHD_Action action;
1041
1042 /**
1043 * Headers to send for the response. Initially
1044 * the linked list is created in inverse order;
1045 * the order should be inverted before sending!
1046 */
1047 struct MHD_HTTP_Header *first_header;
1048
1049 /**
1050 * Buffer pointing to data that we are supposed
1051 * to send as a response.
1052 */
1053 char *data;
1054
1055 /**
1056 * Closure to give to the content reader @e crc
1057 * and content reader free callback @e crfc.
1058 */
1059 void *crc_cls;
1060
1061 /**
1062 * How do we get more data? NULL if we are
1063 * given all of the data up front.
1064 */
1065 MHD_ContentReaderCallback crc;
1066
1067 /**
1068 * NULL if data must not be freed, otherwise
1069 * either user-specified callback or "&free".
1070 */
1071 MHD_ContentReaderFreeCallback crfc;
1072
1073 /**
1074 * Function to call once MHD is finished with
1075 * the request, may be NULL.
1076 */
1077 MHD_RequestTerminationCallback termination_cb;
1078
1079 /**
1080 * Closure for @e termination_cb.
1081 */
1082 void *termination_cb_cls;
1083
1084#ifdef UPGRADE_SUPPORT
1085 /**
1086 * Application function to call once we are done sending the headers
1087 * of the response; NULL unless this is a response created with
1088 * #MHD_create_response_for_upgrade().
1089 */
1090 MHD_UpgradeHandler upgrade_handler;
1091
1092 /**
1093 * Closure for @e uh.
1094 */
1095 void *upgrade_handler_cls;
1096#endif /* UPGRADE_SUPPORT */
1097
1098 /**
1099 * Mutex to synchronize access to @e data, @e size and
1100 * @e reference_count.
1101 */
1102 MHD_mutex_ mutex;
1103
1104 /**
1105 * Set to #MHD_SIZE_UNKNOWN if size is not known.
1106 */
1107 uint64_t total_size;
1108
1109 /**
1110 * At what offset in the stream is the
1111 * beginning of @e data located?
1112 */
1113 uint64_t data_start;
1114
1115 /**
1116 * Offset to start reading from when using @e fd.
1117 */
1118 uint64_t fd_off;
1119
1120 /**
1121 * Number of bytes ready in @e data (buffer may be larger
1122 * than what is filled with payload).
1123 */
1124 size_t data_size;
1125
1126 /**
1127 * Size of the data buffer @e data.
1128 */
1129 size_t data_buffer_size;
1130
1131 /**
1132 * HTTP status code of the response.
1133 */
1134 enum MHD_HTTP_StatusCode status_code;
1135
1136 /**
1137 * Reference count for this response. Free once the counter hits
1138 * zero.
1139 */
1140 unsigned int reference_count;
1006 1141
1142 /**
1143 * File-descriptor if this response is FD-backed.
1144 */
1145 int fd;
1146
1147 /**
1148 * Only respond in HTTP 1.0 mode.
1149 */
1150 bool v10_only;
1151
1152};
1007 1153
1008 1154
1009 1155
diff --git a/src/lib/panic.c b/src/lib/panic.c
index f3cfe82d..0c2c7940 100644
--- a/src/lib/panic.c
+++ b/src/lib/panic.c
@@ -1,3 +1,28 @@
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/**
21 * @file lib/panic.c
22 * @brief functions to panic (abort)
23 * @author Christian Grothoff
24 */
25#include "internal.h"
1 26
2 27
3/** 28/**
diff --git a/src/lib/request_info.c b/src/lib/request_info.c
new file mode 100644
index 00000000..4a903ef0
--- /dev/null
+++ b/src/lib/request_info.c
@@ -0,0 +1,53 @@
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/**
21 * @file lib/request_info.c
22 * @brief implementation of MHD_request_get_information_sz()
23 * @author Christian Grothoff
24 */
25#include "internal.h"
26
27
28/**
29 * Obtain information about the given request.
30 * Use wrapper macro #MHD_request_get_information() instead of direct use
31 * of this function.
32 *
33 * @param request what request to get information about
34 * @param info_type what information is desired?
35 * @param[out] return_value pointer to union where requested information will
36 * be stored
37 * @param return_value_size size of union MHD_RequestInformation at compile
38 * time
39 * @return #MHD_YES on success, #MHD_NO on error
40 * (@a info_type is unknown, NULL pointer etc.)
41 * @ingroup specialized
42 */
43enum MHD_Bool
44MHD_request_get_information_sz (struct MHD_Request *request,
45 enum MHD_RequestInformationType info_type,
46 union MHD_RequestInformation *return_value,
47 size_t return_value_size)
48{
49 return MHD_NO; /* not implemented */
50}
51
52
53/* end of request_info.c */
diff --git a/src/lib/request_resume.c b/src/lib/request_resume.c
new file mode 100644
index 00000000..cd642580
--- /dev/null
+++ b/src/lib/request_resume.c
@@ -0,0 +1,48 @@
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/**
21 * @file lib/request_resume.c
22 * @brief implementation of MHD_request_resume()
23 * @author Christian Grothoff
24 */
25#include "internal.h"
26
27
28/**
29 * Resume handling of network data for suspended request. It is
30 * safe to resume a suspended request at any time. Calling this
31 * function on a request that was not previously suspended will
32 * result in undefined behavior.
33 *
34 * If you are using this function in ``external'' select mode, you must
35 * make sure to run #MHD_run() afterwards (before again calling
36 * #MHD_get_fdset(), as otherwise the change may not be reflected in
37 * the set returned by #MHD_get_fdset() and you may end up with a
38 * request that is stuck until the next network activity.
39 *
40 * @param request the request to resume
41 */
42void
43MHD_request_resume (struct MHD_Request *request)
44{
45 abort (); // not implemented...
46}
47
48/* end of request_resume.c */
diff --git a/src/lib/response.c b/src/lib/response.c
new file mode 100644
index 00000000..25943883
--- /dev/null
+++ b/src/lib/response.c
@@ -0,0 +1,264 @@
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/**
21 * @file lib/response.c
22 * @brief implementation of general response functions
23 * @author Daniel Pittman
24 * @author Christian Grothoff
25 * @author Karlson2k (Evgeny Grin)
26 */
27#include "internal.h"
28
29
30/**
31 * Add a header or footer line to the response.
32 *
33 * @param response response to add a header to
34 * @param kind header or footer
35 * @param header the header to add
36 * @param content value to add
37 * @return false on error (i.e. invalid header or content format).
38 */
39static bool
40add_response_entry (struct MHD_Response *response,
41 enum MHD_ValueKind kind,
42 const char *header,
43 const char *content)
44{
45 struct MHD_HTTP_Header *hdr;
46
47 if ( (NULL == header) ||
48 (NULL == content) ||
49 (0 == header[0]) ||
50 (0 == content[0]) ||
51 (NULL != strchr (header, '\t')) ||
52 (NULL != strchr (header, '\r')) ||
53 (NULL != strchr (header, '\n')) ||
54 (NULL != strchr (content, '\t')) ||
55 (NULL != strchr (content, '\r')) ||
56 (NULL != strchr (content, '\n')) )
57 return false;
58 if (NULL == (hdr = malloc (sizeof (struct MHD_HTTP_Header))))
59 return false;
60 if (NULL == (hdr->header = strdup (header)))
61 {
62 free (hdr);
63 return false;
64 }
65 if (NULL == (hdr->value = strdup (content)))
66 {
67 free (hdr->header);
68 free (hdr);
69 return false;
70 }
71 hdr->kind = kind;
72 hdr->next = response->first_header;
73 response->first_header = hdr;
74 return true;
75}
76
77
78/**
79 * Explicitly decrease reference counter of a response object. If the
80 * counter hits zero, destroys a response object and associated
81 * resources. Usually, this is implicitly done by converting a
82 * response to an action and returning the action to MHD.
83 *
84 * @param response response to decrement RC of
85 * @ingroup response
86 */
87void
88MHD_response_queue_for_destroy (struct MHD_Response *response)
89{
90 struct MHD_HTTP_Header *pos;
91
92 MHD_mutex_lock_chk_ (&response->mutex);
93 if (0 != --(response->reference_count))
94 {
95 MHD_mutex_unlock_chk_ (&response->mutex);
96 return;
97 }
98 MHD_mutex_unlock_chk_ (&response->mutex);
99 MHD_mutex_destroy_chk_ (&response->mutex);
100 if (NULL != response->crfc)
101 response->crfc (response->crc_cls);
102 while (NULL != response->first_header)
103 {
104 pos = response->first_header;
105 response->first_header = pos->next;
106 free (pos->header);
107 free (pos->value);
108 free (pos);
109 }
110 free (response);
111}
112
113
114/**
115 * Add a header line to the response.
116 *
117 * @param response response to add a header to
118 * @param header the header to add
119 * @param content value to add
120 * @return #MHD_NO on error (i.e. invalid header or content format),
121 * or out of memory
122 * @ingroup response
123 */
124enum MHD_Bool
125MHD_response_add_header (struct MHD_Response *response,
126 const char *header,
127 const char *content)
128{
129 return add_response_entry (response,
130 MHD_HEADER_KIND,
131 header,
132 content) ? MHD_TRUE : MHD_FALSE;
133}
134
135
136/**
137 * Add a tailer line to the response.
138 *
139 * @param response response to add a footer to
140 * @param footer the footer to add
141 * @param content value to add
142 * @return #MHD_NO on error (i.e. invalid footer or content format),
143 * or out of memory
144 * @ingroup response
145 */
146enum MHD_Bool
147MHD_response_add_trailer (struct MHD_Response *response,
148 const char *footer,
149 const char *content)
150{
151 return add_response_entry (response,
152 MHD_FOOTER_KIND,
153 footer,
154 content) ? MHD_TRUE : MHD_FALSE;
155}
156
157
158/**
159 * Delete a header (or footer) line from the response.
160 *
161 * @param response response to remove a header from
162 * @param header the header to delete
163 * @param content value to delete
164 * @return #MHD_NO on error (no such header known)
165 * @ingroup response
166 */
167enum MHD_Bool
168MHD_response_del_header (struct MHD_Response *response,
169 const char *header,
170 const char *content)
171{
172 struct MHD_HTTP_Header *pos;
173 struct MHD_HTTP_Header *prev;
174
175 if ( (NULL == header) ||
176 (NULL == content) )
177 return MHD_NO;
178 prev = NULL;
179 pos = response->first_header;
180 while (NULL != pos)
181 {
182 if ((0 == strcmp (header,
183 pos->header)) &&
184 (0 == strcmp (content,
185 pos->value)))
186 {
187 free (pos->header);
188 free (pos->value);
189 if (NULL == prev)
190 response->first_header = pos->next;
191 else
192 prev->next = pos->next;
193 free (pos);
194 return MHD_YES;
195 }
196 prev = pos;
197 pos = pos->next;
198 }
199 return MHD_NO;
200}
201
202
203/**
204 * Get all of the headers (and footers) added to a response.
205 *
206 * @param response response to query
207 * @param iterator callback to call on each header;
208 * maybe NULL (then just count headers)
209 * @param iterator_cls extra argument to @a iterator
210 * @return number of entries iterated over
211 * @ingroup response
212 */
213unsigned int
214MHD_response_get_headers (struct MHD_Response *response,
215 MHD_KeyValueIterator iterator,
216 void *iterator_cls)
217{
218 unsigned int numHeaders = 0;
219 struct MHD_HTTP_Header *pos;
220
221 for (pos = response->first_header;
222 NULL != pos;
223 pos = pos->next)
224 {
225 numHeaders++;
226 if ( (NULL != iterator) &&
227 (MHD_YES != iterator (iterator_cls,
228 pos->kind,
229 pos->header,
230 pos->value)) )
231 break;
232 }
233 return numHeaders;
234}
235
236
237/**
238 * Get a particular header (or footer) from the response.
239 *
240 * @param response response to query
241 * @param key which header to get
242 * @return NULL if header does not exist
243 * @ingroup response
244 */
245const char *
246MHD_response_get_header (struct MHD_Response *response,
247 const char *key)
248{
249 struct MHD_HTTP_Header *pos;
250
251 if (NULL == key)
252 return NULL;
253 for (pos = response->first_header;
254 NULL != pos;
255 pos = pos->next)
256 {
257 if (MHD_str_equal_caseless_ (pos->header,
258 key))
259 return pos->value;
260 }
261 return NULL;
262}
263
264/* end of response.c */
diff --git a/src/lib/response_for_upgrade.c b/src/lib/response_for_upgrade.c
new file mode 100644
index 00000000..90e361b6
--- /dev/null
+++ b/src/lib/response_for_upgrade.c
@@ -0,0 +1,90 @@
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/**
21 * @file lib/response_for_upgrade.c
22 * @brief implementation of MHD_response_for_upgrade()
23 * @author Christian Grothoff
24 */
25#include "internal.h"
26
27
28/**
29 * Create a response object that can be used for 101 UPGRADE
30 * responses, for example to implement WebSockets. After sending the
31 * response, control over the data stream is given to the callback (which
32 * can then, for example, start some bi-directional communication).
33 * If the response is queued for multiple connections, the callback
34 * will be called for each connection. The callback
35 * will ONLY be called after the response header was successfully passed
36 * to the OS; if there are communication errors before, the usual MHD
37 * connection error handling code will be performed.
38 *
39 * MHD will automatically set the correct HTTP status
40 * code (#MHD_HTTP_SWITCHING_PROTOCOLS).
41 * Setting correct HTTP headers for the upgrade must be done
42 * manually (this way, it is possible to implement most existing
43 * WebSocket versions using this API; in fact, this API might be useful
44 * for any protocol switch, not just WebSockets). Note that
45 * draft-ietf-hybi-thewebsocketprotocol-00 cannot be implemented this
46 * way as the header "HTTP/1.1 101 WebSocket Protocol Handshake"
47 * cannot be generated; instead, MHD will always produce "HTTP/1.1 101
48 * Switching Protocols" (if the response code 101 is used).
49 *
50 * As usual, the response object can be extended with header
51 * information and then be used any number of times (as long as the
52 * header information is not connection-specific).
53 *
54 * @param upgrade_handler function to call with the "upgraded" socket
55 * @param upgrade_handler_cls closure for @a upgrade_handler
56 * @return NULL on error (i.e. invalid arguments, out of memory)
57 */
58struct MHD_Response *
59MHD_response_for_upgrade (MHD_UpgradeHandler upgrade_handler,
60 void *upgrade_handler_cls)
61{
62 struct MHD_Response *response;
63
64 mhd_assert (NULL != upgrade_handler);
65 response = MHD_calloc_ (1,
66 sizeof (struct MHD_Response));
67 if (NULL == response)
68 return NULL;
69 if (! MHD_mutex_init_ (&response->mutex))
70 {
71 free (response);
72 return NULL;
73 }
74 response->upgrade_handler = upgrade_handler;
75 response->upgrade_handler_cls = upgrade_handler_cls;
76 response->status_code = MHD_HTTP_SWITCHING_PROTOCOLS;
77 response->total_size = MHD_SIZE_UNKNOWN;
78 response->reference_count = 1;
79 if (MHD_NO ==
80 MHD_add_response_header (response,
81 MHD_HTTP_HEADER_CONNECTION,
82 "Upgrade"))
83 {
84 MHD_destroy_response (response);
85 return NULL;
86 }
87 return response;
88}
89
90/* end of response_for_upgrade.c */
diff --git a/src/lib/response_from_buffer.c b/src/lib/response_from_buffer.c
new file mode 100644
index 00000000..be6a1e00
--- /dev/null
+++ b/src/lib/response_from_buffer.c
@@ -0,0 +1,88 @@
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/**
21 * @file lib/response_from_buffer.c
22 * @brief implementation of MHD_response_from_buffer()
23 * @author Christian Grothoff
24 */
25#include "internal.h"
26
27
28/**
29 * Create a response object. The response object can be extended with
30 * header information and then be used any number of times.
31 *
32 * @param sc status code to use for the response;
33 * #MHD_HTTP_NO_CONTENT is only valid if @a size is 0;
34 * @param size size of the data portion of the response
35 * @param buffer size bytes containing the response's data portion
36 * @param mode flags for buffer management
37 * @return NULL on error (i.e. invalid arguments, out of memory)
38 * @ingroup response
39 */
40struct MHD_Response *
41MHD_response_from_buffer (enum MHD_HTTP_StatusCode sc,
42 size_t size,
43 void *buffer,
44 enum MHD_ResponseMemoryMode mode)
45{
46 struct MHD_Response *response;
47 void *tmp;
48
49 mhd_assert ( (NULL != data) ||
50 (0 == size) );
51 if (NULL ==
52 (response = MHD_calloc_ (1,
53 sizeof (struct MHD_Response))))
54 return NULL;
55 response->fd = -1;
56 if (! MHD_mutex_init_ (&response->mutex))
57 {
58 free (response);
59 return NULL;
60 }
61 if ( (MHD_RESPMEM_MUST_COPY == mode) &&
62 (size > 0) )
63 {
64 if (NULL == (tmp = malloc (size)))
65 {
66 MHD_mutex_destroy_chk_ (&response->mutex);
67 free (response);
68 return NULL;
69 }
70 memcpy (tmp,
71 data,
72 size);
73 data = tmp;
74 }
75 if (MHD_RESPMEM_PERSISTENT != mode)
76 {
77 response->crfc = &free;
78 response->crc_cls = data;
79 }
80 response->status_code = sc;
81 response->reference_count = 1;
82 response->total_size = size;
83 response->data = data;
84 response->data_size = size;
85 return response;
86}
87
88/* end of response_from_buffer.c */
diff --git a/src/lib/response_from_callback.c b/src/lib/response_from_callback.c
new file mode 100644
index 00000000..1fd65bf0
--- /dev/null
+++ b/src/lib/response_from_callback.c
@@ -0,0 +1,80 @@
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/**
21 * @file lib/response_from_callback.c
22 * @brief implementation of MHD_response_from_callback()
23 * @author Christian Grothoff
24 */
25#include "internal.h"
26
27
28/**
29 * Create a response action. The response object can be extended with
30 * header information and then be used any number of times.
31 *
32 * @param sc status code to return
33 * @param size size of the data portion of the response, #MHD_SIZE_UNKNOWN for unknown
34 * @param block_size preferred block size for querying crc (advisory only,
35 * MHD may still call @a crc using smaller chunks); this
36 * is essentially the buffer size used for IO, clients
37 * should pick a value that is appropriate for IO and
38 * memory performance requirements
39 * @param crc callback to use to obtain response data
40 * @param crc_cls extra argument to @a crc
41 * @param crfc callback to call to free @a crc_cls resources
42 * @return NULL on error (i.e. invalid arguments, out of memory)
43 * @ingroup response
44 */
45struct MHD_Response *
46MHD_response_from_callback (enum MHD_HTTP_StatusCode sc,
47 uint64_t size,
48 size_t block_size,
49 MHD_ContentReaderCallback crc,
50 void *crc_cls,
51 MHD_ContentReaderFreeCallback crfc)
52{
53 struct MHD_Response *response;
54
55 mhd_assert (NULL != crc);
56 mhd_assert (0 != block_size);
57 if (NULL ==
58 (response = MHD_calloc_ (1,
59 sizeof (struct MHD_Response) +
60 block_size)))
61 return NULL;
62 response->fd = -1;
63 response->status_code = sc;
64 response->data = (void *) &response[1];
65 response->data_buffer_size = block_size;
66 if (! MHD_mutex_init_ (&response->mutex))
67 {
68 free (response);
69 return NULL;
70 }
71 response->crc = crc;
72 response->crfc = crfc;
73 response->crc_cls = crc_cls;
74 response->reference_count = 1;
75 response->total_size = size;
76 return response;
77}
78
79
80/* end of response_from_callback.c */
diff --git a/src/lib/response_from_fd.c b/src/lib/response_from_fd.c
new file mode 100644
index 00000000..ea486600
--- /dev/null
+++ b/src/lib/response_from_fd.c
@@ -0,0 +1,198 @@
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/**
21 * @file lib/response_from_fd.c
22 * @brief implementation of MHD_response_from_fd()
23 * @author Daniel Pittman
24 * @author Christian Grothoff
25 * @author Karlson2k (Evgeny Grin)
26 */
27#include "internal.h"
28
29
30/**
31 * Given a file descriptor, read data from the file
32 * to generate the response.
33 *
34 * @param cls pointer to the response
35 * @param pos offset in the file to access
36 * @param buf where to write the data
37 * @param max number of bytes to write at most
38 * @return number of bytes written
39 */
40static ssize_t
41file_reader (void *cls,
42 uint64_t pos,
43 char *buf,
44 size_t max)
45{
46 struct MHD_Response *response = cls;
47#if !defined(_WIN32) || defined(__CYGWIN__)
48 ssize_t n;
49#else /* _WIN32 && !__CYGWIN__ */
50 const HANDLE fh = (HANDLE) _get_osfhandle (response->fd);
51#endif /* _WIN32 && !__CYGWIN__ */
52 const int64_t offset64 = (int64_t)(pos + response->fd_off);
53
54 if (offset64 < 0)
55 return MHD_CONTENT_READER_END_WITH_ERROR; /* seek to required position is not possible */
56
57#if !defined(_WIN32) || defined(__CYGWIN__)
58 if (max > SSIZE_MAX)
59 max = SSIZE_MAX; /* Clamp to maximum return value. */
60
61#if defined(HAVE_PREAD64)
62 n = pread64 (response->fd,
63 buf,
64 max,
65 offset64);
66#elif defined(HAVE_PREAD)
67 if ( (sizeof(off_t) < sizeof (uint64_t)) &&
68 (offset64 > (uint64_t)INT32_MAX) )
69 return MHD_CONTENT_READER_END_WITH_ERROR; /* Read at required position is not possible. */
70
71 n = pread (response->fd,
72 buf,
73 max,
74 (off_t) offset64);
75#else /* ! HAVE_PREAD */
76#if defined(HAVE_LSEEK64)
77 if (lseek64 (response->fd,
78 offset64,
79 SEEK_SET) != offset64)
80 return MHD_CONTENT_READER_END_WITH_ERROR; /* can't seek to required position */
81#else /* ! HAVE_LSEEK64 */
82 if ( (sizeof(off_t) < sizeof (uint64_t)) &&
83 (offset64 > (uint64_t)INT32_MAX) )
84 return MHD_CONTENT_READER_END_WITH_ERROR; /* seek to required position is not possible */
85
86 if (lseek (response->fd,
87 (off_t) offset64,
88 SEEK_SET) != (off_t) offset64)
89 return MHD_CONTENT_READER_END_WITH_ERROR; /* can't seek to required position */
90#endif /* ! HAVE_LSEEK64 */
91 n = read (response->fd,
92 buf,
93 max);
94
95#endif /* ! HAVE_PREAD */
96 if (0 == n)
97 return MHD_CONTENT_READER_END_OF_STREAM;
98 if (n < 0)
99 return MHD_CONTENT_READER_END_WITH_ERROR;
100 return n;
101#else /* _WIN32 && !__CYGWIN__ */
102 if (INVALID_HANDLE_VALUE == fh)
103 return MHD_CONTENT_READER_END_WITH_ERROR; /* Value of 'response->fd' is not valid. */
104 else
105 {
106 OVERLAPPED f_ol = {0, 0, {{0, 0}}, 0}; /* Initialize to zero. */
107 ULARGE_INTEGER pos_uli;
108 DWORD toRead = (max > INT32_MAX) ? INT32_MAX : (DWORD) max;
109 DWORD resRead;
110
111 pos_uli.QuadPart = (uint64_t) offset64; /* Simple transformation 64bit -> 2x32bit. */
112 f_ol.Offset = pos_uli.LowPart;
113 f_ol.OffsetHigh = pos_uli.HighPart;
114 if (! ReadFile (fh,
115 (void*)buf,
116 toRead,
117 &resRead,
118 &f_ol))
119 return MHD_CONTENT_READER_END_WITH_ERROR; /* Read error. */
120 if (0 == resRead)
121 return MHD_CONTENT_READER_END_OF_STREAM;
122 return (ssize_t) resRead;
123 }
124#endif /* _WIN32 && !__CYGWIN__ */
125}
126
127
128/**
129 * Destroy file reader context. Closes the file
130 * descriptor.
131 *
132 * @param cls pointer to file descriptor
133 */
134static void
135free_callback (void *cls)
136{
137 struct MHD_Response *response = cls;
138
139 (void) close (response->fd);
140 response->fd = -1;
141}
142
143
144/**
145 * Create a response object based on an @a fd from which
146 * data is read. The response object can be extended with
147 * header information and then be used any number of times.
148 *
149 * @param sc status code to return
150 * @param fd file descriptor referring to a file on disk with the
151 * data; will be closed when response is destroyed;
152 * fd should be in 'blocking' mode
153 * @param offset offset to start reading from in the file;
154 * reading file beyond 2 GiB may be not supported by OS or
155 * MHD build; see ::MHD_FEATURE_LARGE_FILE
156 * @param size size of the data portion of the response;
157 * sizes larger than 2 GiB may be not supported by OS or
158 * MHD build; see ::MHD_FEATURE_LARGE_FILE
159 * @return NULL on error (i.e. invalid arguments, out of memory)
160 * @ingroup response
161 */
162struct MHD_Response *
163MHD_response_from_fd (enum MHD_HTTP_StatusCode sc,
164 int fd,
165 uint64_t offset,
166 uint64_t size)
167{
168 struct MHD_Response *response;
169
170 mhd_assert (-1 != fd);
171#if !defined(HAVE___LSEEKI64) && !defined(HAVE_LSEEK64)
172 if ( (sizeof (uint64_t) > sizeof (off_t)) &&
173 ( (size > (uint64_t)INT32_MAX) ||
174 (offset > (uint64_t)INT32_MAX) ||
175 ((size + offset) >= (uint64_t)INT32_MAX) ) )
176 return NULL;
177#endif
178 if ( ((int64_t) size < 0) ||
179 ((int64_t) offset < 0) ||
180 ((int64_t) (size + offset) < 0) )
181 return NULL;
182
183 response = MHD_response_from_callback (size,
184 4 * 1024,
185 &file_reader,
186 NULL,
187 &free_callback);
188 if (NULL == response)
189 return NULL;
190 response->fd = fd;
191 response->status_code = sc;
192 response->fd_off = offset;
193 response->crc_cls = response;
194 return response;
195}
196
197/* end of response_from_fd.c */
198
diff --git a/src/lib/response_options.c b/src/lib/response_options.c
new file mode 100644
index 00000000..406d1d32
--- /dev/null
+++ b/src/lib/response_options.c
@@ -0,0 +1,61 @@
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/**
21 * @file lib/response_option.c
22 * @brief implementation of response options
23 * @author Christian Grothoff
24 */
25#include "internal.h"
26
27
28/**
29 * Only respond in conservative HTTP 1.0-mode. In
30 * particular, do not (automatically) sent "Connection" headers and
31 * always close the connection after generating the response.
32 *
33 * @param request the request for which we force HTTP 1.0 to be used
34 */
35void
36MHD_response_option_v10_only (struct MHD_Response *response)
37{
38 response->v10_only = true;
39}
40
41
42/**
43 * Set a function to be called once MHD is finished with the
44 * request.
45 *
46 * @param response which response to set the callback for
47 * @param termination_cb function to call
48 * @param termination_cb_cls closure for @e termination_cb
49 */
50void
51MHD_response_option_termination_callback (struct MHD_Response *response,
52 MHD_RequestTerminationCallback termination_cb,
53 void *termination_cb_cls)
54{
55 /* Q: should we assert termination_cb non-NULL? */
56 response->termination_cb = termination_cb;
57 response->termination_cb_cls = termination_cb_cls;
58}
59
60
61/* end of response_option.c */
diff --git a/src/lib/version.c b/src/lib/version.c
index 84918fb7..9ef03e53 100644
--- a/src/lib/version.c
+++ b/src/lib/version.c
@@ -1,3 +1,28 @@
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/**
21 * @file lib/version.c
22 * @brief versioning and optional feature tests
23 * @author Christian Grothoff
24 */
25#include "internal.h"
1 26
2 27
3/** 28/**
diff --git a/src/microhttpd/response.c b/src/microhttpd/response.c
index d677cf62..9de4843d 100644
--- a/src/microhttpd/response.c
+++ b/src/microhttpd/response.c
@@ -246,12 +246,13 @@ MHD_get_response_header (struct MHD_Response *response,
246 NULL != pos; 246 NULL != pos;
247 pos = pos->next) 247 pos = pos->next)
248 { 248 {
249 if ( MHD_str_equal_caseless_ (pos->header, key) ) 249 if (MHD_str_equal_caseless_ (pos->header, key))
250 return pos->value; 250 return pos->value;
251 } 251 }
252 return NULL; 252 return NULL;
253} 253}
254 254
255
255/** 256/**
256 * Check whether response header contains particular token. 257 * Check whether response header contains particular token.
257 * 258 *