GNU libmicrohttpd 0.9.77
Loading...
Searching...
No Matches
internal.c
Go to the documentation of this file.
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
26#include "internal.h"
27#include "mhd_str.h"
28
29#ifdef HAVE_MESSAGES
30#if DEBUG_STATES
34const char *
35MHD_state_to_string (enum MHD_CONNECTION_STATE state)
36{
37 switch (state)
38 {
40 return "connection init";
42 return "connection url received";
44 return "header partially received";
46 return "headers received";
48 return "headers processed";
50 return "continue sending";
52 return "continue sent";
54 return "body received";
56 return "footer partially received";
58 return "footers received";
60 return "headers sending";
62 return "headers sent";
64 return "normal body ready";
66 return "normal body unready";
68 return "chunked body ready";
70 return "chunked body unready";
72 return "body sent";
74 return "footers sending";
76 return "footers sent";
78 return "closed";
79 default:
80 return "unrecognized connection state";
81 }
82}
83
84
85#endif
86#endif
87
88
89#ifdef HAVE_MESSAGES
94void
95MHD_DLOG (const struct MHD_Daemon *daemon,
96 enum MHD_StatusCode sc,
97 const char *format,
98 ...)
99{
100 va_list va;
101
102 if (NULL == daemon->logger)
103 return;
104 va_start (va,
105 format);
106 daemon->logger (daemon->logger_cls,
107 sc,
108 format,
109 va);
110 va_end (va);
111}
112
113
114#endif
115
116
122void
124{
125 char *p;
126
127 for (p = strchr (arg, '+'); NULL != p; p = strchr (p + 1, '+'))
128 *p = ' ';
129}
130
131
141size_t
143{
144 char *rpos = val;
145 char *wpos = val;
146
147 while ('\0' != *rpos)
148 {
149 uint32_t num;
150 switch (*rpos)
151 {
152 case '%':
153 if (2 == MHD_strx_to_uint32_n_ (rpos + 1,
154 2,
155 &num))
156 {
157 *wpos = (char) ((unsigned char) num);
158 wpos++;
159 rpos += 3;
160 break;
161 }
162 /* TODO: add bad sequence handling */
163 /* intentional fall through! */
164 default:
165 *wpos = *rpos;
166 wpos++;
167 rpos++;
168 }
169 }
170 *wpos = '\0'; /* add 0-terminator */
171 return wpos - val; /* = strlen(val) */
172}
173
174
189bool
191 enum MHD_ValueKind kind,
192 char *args,
194 unsigned int *num_headers)
195{
196 struct MHD_Daemon *daemon = request->daemon;
197 char *equals;
198 char *amper;
199
200 *num_headers = 0;
201 while ( (NULL != args) &&
202 ('\0' != args[0]) )
203 {
204 equals = strchr (args, '=');
205 amper = strchr (args, '&');
206 if (NULL == amper)
207 {
208 /* last argument */
209 if (NULL == equals)
210 {
211 /* last argument, without '=' */
212 MHD_unescape_plus (args);
213 daemon->unescape_cb (daemon->unescape_cb_cls,
214 request,
215 args);
216 if (! cb (request,
217 args,
218 NULL,
219 kind))
220 return false;
221 (*num_headers)++;
222 break;
223 }
224 /* got 'foo=bar' */
225 equals[0] = '\0';
226 equals++;
227 MHD_unescape_plus (args);
228 daemon->unescape_cb (daemon->unescape_cb_cls,
229 request,
230 args);
231 MHD_unescape_plus (equals);
232 daemon->unescape_cb (daemon->unescape_cb_cls,
233 request,
234 equals);
235 if (! cb (request,
236 args,
237 equals,
238 kind))
239 return false;
240 (*num_headers)++;
241 break;
242 }
243 /* amper is non-NULL here */
244 amper[0] = '\0';
245 amper++;
246 if ( (NULL == equals) ||
247 (equals >= amper) )
248 {
249 /* got 'foo&bar' or 'foo&bar=val', add key 'foo' with NULL for value */
250 MHD_unescape_plus (args);
251 daemon->unescape_cb (daemon->unescape_cb_cls,
252 request,
253 args);
254 if (! cb (request,
255 args,
256 NULL,
257 kind))
258 return false;
259 /* continue with 'bar' */
260 (*num_headers)++;
261 args = amper;
262 continue;
263 }
264 /* equals and amper are non-NULL here, and equals < amper,
265 so we got regular 'foo=value&bar...'-kind of argument */
266 equals[0] = '\0';
267 equals++;
268 MHD_unescape_plus (args);
269 daemon->unescape_cb (daemon->unescape_cb_cls,
270 request,
271 args);
272 MHD_unescape_plus (equals);
273 daemon->unescape_cb (daemon->unescape_cb_cls,
274 request,
275 equals);
276 if (! cb (request,
277 args,
278 equals,
279 kind))
280 return false;
281 (*num_headers)++;
282 args = amper;
283 }
284 return true;
285}
286
287
288/* end of internal.c */
size_t MHD_http_unescape(char *val)
Definition internal.c:142
void MHD_unescape_plus(char *arg)
Definition internal.c:123
bool MHD_parse_arguments_(struct MHD_Request *request, enum MHD_ValueKind kind, char *args, MHD_ArgumentIterator_ cb, unsigned int *num_headers)
Definition internal.c:190
bool(* MHD_ArgumentIterator_)(struct MHD_Request *request, const char *key, const char *value, enum MHD_ValueKind kind)
Definition internal.h:1707
size_t MHD_strx_to_uint32_n_(const char *str, size_t maxlen, uint32_t *out_val)
Definition mhd_str.c:605
#define NULL
MHD internal shared structures.
MHD_CONNECTION_STATE
Definition internal.h:574
@ MHD_CONNECTION_BODY_RECEIVED
Definition internal.h:620
@ MHD_CONNECTION_HEADER_PART_RECEIVED
Definition internal.h:595
@ MHD_CONNECTION_HEADERS_SENDING
Definition internal.h:650
@ MHD_CONNECTION_FOOTERS_SENDING
Definition internal.h:686
@ MHD_CONNECTION_FOOTERS_RECEIVED
Definition internal.h:631
@ MHD_CONNECTION_HEADERS_SENT
Definition internal.h:655
@ MHD_CONNECTION_HEADERS_PROCESSED
Definition internal.h:605
@ MHD_CONNECTION_INIT
Definition internal.h:579
@ MHD_CONNECTION_CLOSED
Definition internal.h:696
@ MHD_CONNECTION_NORMAL_BODY_UNREADY
Definition internal.h:661
@ MHD_CONNECTION_HEADERS_RECEIVED
Definition internal.h:600
@ MHD_CONNECTION_NORMAL_BODY_READY
Definition internal.h:666
@ MHD_CONNECTION_CHUNKED_BODY_READY
Definition internal.h:676
@ MHD_CONNECTION_FOOTER_PART_RECEIVED
Definition internal.h:626
@ MHD_CONNECTION_CONTINUE_SENT
Definition internal.h:615
@ MHD_CONNECTION_FOOTERS_SENT
Definition internal.h:691
@ MHD_CONNECTION_CHUNKED_BODY_UNREADY
Definition internal.h:671
@ MHD_CONNECTION_BODY_SENT
Definition internal.h:681
@ MHD_CONNECTION_CONTINUE_SENDING
Definition internal.h:610
@ MHD_CONNECTION_URL_RECEIVED
Definition internal.h:590
Header for string manipulating helpers.
MHD_ValueKind
void * unescape_cb_cls
Definition internal.h:1063
MHD_LoggingCallback logger
Definition internal.h:1015
void * logger_cls
Definition internal.h:1020
MHD_UnescapeCallback unescape_cb
Definition internal.h:1058
struct MHD_Daemon * daemon
Definition internal.h:372