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 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
27#include "internal.h"
28#include "mhd_str.h"
29
30#ifdef HAVE_MESSAGES
31#if DEBUG_STATES
35const char *
36MHD_state_to_string (enum MHD_CONNECTION_STATE state)
37{
38 switch (state)
39 {
41 return "connection init";
43 return "receiving request line";
45 return "connection url received";
47 return "header partially received";
49 return "headers received";
51 return "headers processed";
53 return "continue sending";
55 return "continue sent";
57 return "body received";
59 return "footer partially received";
61 return "footers received";
63 return "full request received";
65 return "start sending reply";
67 return "headers sending";
69 return "headers sent";
71 return "normal body unready";
73 return "normal body ready";
75 return "chunked body unready";
77 return "chunked body ready";
79 return "body sent";
81 return "footers sending";
83 return "footers sent";
85 return "closed";
86 default:
87 return "unrecognized connection state";
88 }
89}
90
91
92#endif
93#endif
94
95
96#ifdef HAVE_MESSAGES
101void
102MHD_DLOG (const struct MHD_Daemon *daemon,
103 const char *format,
104 ...)
105{
106 va_list va;
107
108 if (0 == (daemon->options & MHD_USE_ERROR_LOG))
109 return;
110 va_start (va, format);
111 daemon->custom_error_log (daemon->custom_error_log_cls,
112 format,
113 va);
114 va_end (va);
115}
116
117
118#endif
119
120
126void
128{
129 char *p;
130
131 for (p = strchr (arg, '+'); NULL != p; p = strchr (p + 1, '+'))
132 *p = ' ';
133}
134
135
145size_t
147{
148 char *rpos = val;
149 char *wpos = val;
150
151 while ('\0' != *rpos)
152 {
153 uint32_t num;
154 switch (*rpos)
155 {
156 case '%':
157 if (2 == MHD_strx_to_uint32_n_ (rpos + 1,
158 2,
159 &num))
160 {
161 *wpos = (char) ((unsigned char) num);
162 wpos++;
163 rpos += 3;
164 break;
165 }
166 /* TODO: add bad sequence handling */
167 /* intentional fall through! */
168 default:
169 *wpos = *rpos;
170 wpos++;
171 rpos++;
172 }
173 }
174 *wpos = '\0'; /* add 0-terminator */
175 return wpos - val;
176}
177
178
193enum MHD_Result
195 enum MHD_ValueKind kind,
196 char *args,
198 unsigned int *num_headers)
199{
200 struct MHD_Daemon *daemon = connection->daemon;
201 char *equals;
202 char *amper;
203
204 *num_headers = 0;
205 while ( (NULL != args) &&
206 ('\0' != args[0]) )
207 {
208 size_t key_len;
209 size_t value_len;
210 equals = strchr (args, '=');
211 amper = strchr (args, '&');
212 if (NULL == amper)
213 {
214 /* last argument */
215 if (NULL == equals)
216 {
217 /* last argument, without '=' */
218 MHD_unescape_plus (args);
219 key_len = daemon->unescape_callback (daemon->unescape_callback_cls,
220 connection,
221 args);
222 if (MHD_NO == cb (connection,
223 args,
224 key_len,
225 NULL,
226 0,
227 kind))
228 return MHD_NO;
229 (*num_headers)++;
230 break;
231 }
232 /* got 'foo=bar' */
233 equals[0] = '\0';
234 equals++;
235 MHD_unescape_plus (args);
236 key_len = daemon->unescape_callback (daemon->unescape_callback_cls,
237 connection,
238 args);
239 MHD_unescape_plus (equals);
240 value_len = daemon->unescape_callback (daemon->unescape_callback_cls,
241 connection,
242 equals);
243 if (MHD_NO == cb (connection,
244 args,
245 key_len,
246 equals,
247 value_len,
248 kind))
249 return MHD_NO;
250 (*num_headers)++;
251 break;
252 }
253 /* amper is non-NULL here */
254 amper[0] = '\0';
255 amper++;
256 if ( (NULL == equals) ||
257 (equals >= amper) )
258 {
259 /* got 'foo&bar' or 'foo&bar=val', add key 'foo' with NULL for value */
260 MHD_unescape_plus (args);
261 key_len = daemon->unescape_callback (daemon->unescape_callback_cls,
262 connection,
263 args);
264 if (MHD_NO == cb (connection,
265 args,
266 key_len,
267 NULL,
268 0,
269 kind))
270 return MHD_NO;
271 /* continue with 'bar' */
272 (*num_headers)++;
273 args = amper;
274 continue;
275 }
276 /* equals and amper are non-NULL here, and equals < amper,
277 so we got regular 'foo=value&bar...'-kind of argument */
278 equals[0] = '\0';
279 equals++;
280 MHD_unescape_plus (args);
281 key_len = daemon->unescape_callback (daemon->unescape_callback_cls,
282 connection,
283 args);
284 MHD_unescape_plus (equals);
285 value_len = daemon->unescape_callback (daemon->unescape_callback_cls,
286 connection,
287 equals);
288 if (MHD_NO == cb (connection,
289 args,
290 key_len,
291 equals,
292 value_len,
293 kind))
294 return MHD_NO;
295 (*num_headers)++;
296 args = amper;
297 }
298 return MHD_YES;
299}
300
301
302/* 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_START_REPLY
Definition internal.h:644
@ 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_FULL_REQ_RECEIVED
Definition internal.h:637
@ 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
@ MHD_CONNECTION_REQ_LINE_RECEIVING
Definition internal.h:585
Header for string manipulating helpers.
MHD_Result
Definition microhttpd.h:158
@ MHD_YES
Definition microhttpd.h:167
@ MHD_NO
Definition microhttpd.h:162
MHD_ValueKind
@ MHD_USE_ERROR_LOG
struct MHD_Daemon * daemon
Definition internal.h:675
void * unescape_callback_cls
Definition internal.h:1811
enum MHD_FLAG options
Definition internal.h:1619
UnescapeCallback unescape_callback
Definition internal.h:1806