diff options
author | Christian Grothoff <christian@grothoff.org> | 2018-02-09 05:44:20 +0100 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2018-02-09 05:44:20 +0100 |
commit | e77fce2749a06b448e496140e8ad7e51891972de (patch) | |
tree | 825e1f67dd432cc99016cdff9a4444645711a79f | |
parent | f6e1ee426f9caebe49476ec88720d87032a433a6 (diff) | |
download | libmicrohttpd-e77fce2749a06b448e496140e8ad7e51891972de.tar.gz libmicrohttpd-e77fce2749a06b448e496140e8ad7e51891972de.zip |
more work on mhd2 api implementation
-rw-r--r-- | src/include/microhttpd2.h | 35 | ||||
-rw-r--r-- | src/lib/action_continue.c | 60 | ||||
-rw-r--r-- | src/lib/action_from_response.c | 130 | ||||
-rw-r--r-- | src/lib/action_parse_post.c | 61 | ||||
-rw-r--r-- | src/lib/action_process_upload.c | 92 | ||||
-rw-r--r-- | src/lib/action_suspend.c | 132 | ||||
-rw-r--r-- | src/lib/connection_info.c | 52 | ||||
-rw-r--r-- | src/lib/connection_options.c | 111 | ||||
-rw-r--r-- | src/lib/daemon_info.c | 55 | ||||
-rw-r--r-- | src/lib/daemon_start.c (renamed from src/lib/daemon.c) | 6 | ||||
-rw-r--r-- | src/lib/init.c | 25 | ||||
-rw-r--r-- | src/lib/init.h | 25 | ||||
-rw-r--r-- | src/lib/internal.h | 184 | ||||
-rw-r--r-- | src/lib/panic.c | 25 | ||||
-rw-r--r-- | src/lib/request_info.c | 53 | ||||
-rw-r--r-- | src/lib/request_resume.c | 48 | ||||
-rw-r--r-- | src/lib/response.c | 264 | ||||
-rw-r--r-- | src/lib/response_for_upgrade.c | 90 | ||||
-rw-r--r-- | src/lib/response_from_buffer.c | 88 | ||||
-rw-r--r-- | src/lib/response_from_callback.c | 80 | ||||
-rw-r--r-- | src/lib/response_from_fd.c | 198 | ||||
-rw-r--r-- | src/lib/response_options.c | 61 | ||||
-rw-r--r-- | src/lib/version.c | 25 | ||||
-rw-r--r-- | src/microhttpd/response.c | 3 |
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, | 1028 | MHD_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 |
1368 | MHD_connection_timeout (struct MHD_Connection *connection, | 1374 | MHD_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 | */ | ||
35 | static void | ||
36 | cont_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 | */ | ||
49 | struct MHD_Action * | ||
50 | MHD_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 | */ | ||
35 | static void | ||
36 | response_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 * | ||
116 | MHD_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 | */ | ||
53 | struct MHD_Action * | ||
54 | MHD_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 | */ | ||
31 | struct 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 | */ | ||
55 | static void | ||
56 | upload_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 | */ | ||
74 | struct MHD_Action * | ||
75 | MHD_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 | */ | ||
35 | static void | ||
36 | suspend_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 | */ | ||
121 | struct MHD_Action * | ||
122 | MHD_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 | */ | ||
43 | enum MHD_Bool | ||
44 | MHD_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 | */ |
11 | struct MHD_ConnectionOption | 36 | void |
12 | MHD_connection_timeout (struct MHD_Connection *connection, | 37 | MHD_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 | */ | ||
84 | void | ||
85 | MHD_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 | */ |
13 | const union MHD_DaemonInfo * | 43 | enum MHD_Bool |
14 | MHD_get_daemon_info (struct MHD_Daemon *daemon, | 44 | MHD_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 | */ | ||
1004 | typedef 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 | */ | ||
1013 | struct 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 | */ | ||
1032 | struct 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 | */ | ||
43 | enum MHD_Bool | ||
44 | MHD_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 | */ | ||
42 | void | ||
43 | MHD_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 | */ | ||
39 | static bool | ||
40 | add_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 | */ | ||
87 | void | ||
88 | MHD_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 | */ | ||
124 | enum MHD_Bool | ||
125 | MHD_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 | */ | ||
146 | enum MHD_Bool | ||
147 | MHD_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 | */ | ||
167 | enum MHD_Bool | ||
168 | MHD_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 | */ | ||
213 | unsigned int | ||
214 | MHD_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 | */ | ||
245 | const char * | ||
246 | MHD_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 | */ | ||
58 | struct MHD_Response * | ||
59 | MHD_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 | */ | ||
40 | struct MHD_Response * | ||
41 | MHD_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 | */ | ||
45 | struct MHD_Response * | ||
46 | MHD_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 | */ | ||
40 | static ssize_t | ||
41 | file_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 | */ | ||
134 | static void | ||
135 | free_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 | */ | ||
162 | struct MHD_Response * | ||
163 | MHD_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 | */ | ||
35 | void | ||
36 | MHD_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 | */ | ||
50 | void | ||
51 | MHD_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 | * |