aboutsummaryrefslogtreecommitdiff
path: root/src/lib/action_from_response.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/action_from_response.c')
-rw-r--r--src/lib/action_from_response.c130
1 files changed, 130 insertions, 0 deletions
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 */