1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
/*
This file is part of libmicrohttpd
Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file lib/action_from_response.c
* @brief implementation of #MHD_action_from_response()
* @author Christian Grothoff
*/
#include "internal.h"
#include "connection_call_handlers.h"
/**
* A response was given as the desired action for a @a request.
* Queue the response for the request.
*
* @param cls the `struct MHD_Response`
* @param request the request we are processing
* @return #MHD_SC_OK on success
*/
static enum MHD_StatusCode
response_action (void *cls,
struct MHD_Request *request)
{
struct MHD_Response *response = cls;
struct MHD_Daemon *daemon = request->daemon;
/* If daemon was shut down in parallel,
* response will be aborted now or on later stage. */
if (daemon->shutdown)
return MHD_SC_DAEMON_ALREADY_SHUTDOWN;
#ifdef UPGRADE_SUPPORT
if ( (NULL != response->upgrade_handler) &&
daemon->disallow_upgrade )
{
#ifdef HAVE_MESSAGES
MHD_DLOG (daemon,
MHD_SC_UPGRADE_ON_DAEMON_WITH_UPGRADE_DISALLOWED,
_ (
"Attempted 'upgrade' connection on daemon without MHD_ALLOW_UPGRADE option!\n"));
#endif
return MHD_SC_UPGRADE_ON_DAEMON_WITH_UPGRADE_DISALLOWED;
}
#endif /* UPGRADE_SUPPORT */
request->response = response;
#if defined(_MHD_HAVE_SENDFILE)
if ( (-1 == response->fd)
#if HTTPS_SUPPORT
|| (NULL != daemon->tls_api)
#endif
)
request->resp_sender = MHD_resp_sender_std;
else
request->resp_sender = MHD_resp_sender_sendfile;
#endif /* _MHD_HAVE_SENDFILE */
if ( (MHD_METHOD_HEAD == request->method) ||
(MHD_HTTP_OK > response->status_code) ||
(MHD_HTTP_NO_CONTENT == response->status_code) ||
(MHD_HTTP_NOT_MODIFIED == response->status_code) )
{
/* if this is a "HEAD" request, or a status code for
which a body is not allowed, pretend that we
have already sent the full message body. */
request->response_write_position = response->total_size;
}
if ( (MHD_REQUEST_HEADERS_PROCESSED == request->state) &&
( (MHD_METHOD_POST == request->method) ||
(MHD_METHOD_PUT == request->method) ) )
{
/* response was queued "early", refuse to read body / footers or
further requests! */
request->connection->read_closed = true;
request->state = MHD_REQUEST_FOOTERS_RECEIVED;
}
if (! request->in_idle)
(void) MHD_request_handle_idle_ (request);
return MHD_SC_OK;
}
/**
* Converts a @a response to an action. If @a consume
* is set, the reference to the @a response is consumed
* by the conversion. If @a consume is #MHD_NO, then
* the response can be converted to actions in the future.
* However, the @a response is frozen by this step and
* must no longer be modified (i.e. by setting headers).
*
* @param response response to convert, not NULL
* @param destroy_after_use should the response object be consumed?
* @return corresponding action, never returns NULL
*
* Implementation note: internally, this is largely just
* a cast (and possibly an RC increment operation),
* as a response *is* an action. As no memory is
* allocated, this operation cannot fail.
*/
_MHD_EXTERN const struct MHD_Action *
MHD_action_from_response (struct MHD_Response *response,
enum MHD_Bool destroy_after_use)
{
response->action.action = &response_action;
response->action.action_cls = response;
if (! destroy_after_use)
{
MHD_mutex_lock_chk_ (&response->mutex);
response->reference_count++;
MHD_mutex_unlock_chk_ (&response->mutex);
}
return &response->action;
}
/* end of action_from_response */
|