GNU libmicrohttpd  0.9.68
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
31 
34 const char *
35 MHD_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 #endif
84 #endif
85 
86 
87 #ifdef HAVE_MESSAGES
88 
92 void
93 MHD_DLOG (const struct MHD_Daemon *daemon,
94  enum MHD_StatusCode sc,
95  const char *format,
96  ...)
97 {
98  va_list va;
99 
100  if (NULL == daemon->logger)
101  return;
102  va_start (va,
103  format);
104  daemon->logger (daemon->logger_cls,
105  sc,
106  format,
107  va);
108  va_end (va);
109 }
110 #endif
111 
112 
118 void
119 MHD_unescape_plus (char *arg)
120 {
121  char *p;
122 
123  for (p = strchr (arg, '+'); NULL != p; p = strchr (p + 1, '+'))
124  *p = ' ';
125 }
126 
127 
137 size_t
138 MHD_http_unescape (char *val)
139 {
140  char *rpos = val;
141  char *wpos = val;
142 
143  while ('\0' != *rpos)
144  {
145  uint32_t num;
146  switch (*rpos)
147  {
148  case '%':
149  if (2 == MHD_strx_to_uint32_n_ (rpos + 1,
150  2,
151  &num))
152  {
153  *wpos = (char) ((unsigned char) num);
154  wpos++;
155  rpos += 3;
156  break;
157  }
158  /* TODO: add bad sequence handling */
159  /* intentional fall through! */
160  default:
161  *wpos = *rpos;
162  wpos++;
163  rpos++;
164  }
165  }
166  *wpos = '\0'; /* add 0-terminator */
167  return wpos - val; /* = strlen(val) */
168 }
169 
170 
185 bool
187  enum MHD_ValueKind kind,
188  char *args,
190  unsigned int *num_headers)
191 {
192  struct MHD_Daemon *daemon = request->daemon;
193  char *equals;
194  char *amper;
195 
196  *num_headers = 0;
197  while ( (NULL != args) &&
198  ('\0' != args[0]) )
199  {
200  equals = strchr (args, '=');
201  amper = strchr (args, '&');
202  if (NULL == amper)
203  {
204  /* last argument */
205  if (NULL == equals)
206  {
207  /* last argument, without '=' */
208  MHD_unescape_plus (args);
209  daemon->unescape_cb (daemon->unescape_cb_cls,
210  request,
211  args);
212  if (! cb (request,
213  args,
214  NULL,
215  kind))
216  return false;
217  (*num_headers)++;
218  break;
219  }
220  /* got 'foo=bar' */
221  equals[0] = '\0';
222  equals++;
223  MHD_unescape_plus (args);
224  daemon->unescape_cb (daemon->unescape_cb_cls,
225  request,
226  args);
227  MHD_unescape_plus (equals);
228  daemon->unescape_cb (daemon->unescape_cb_cls,
229  request,
230  equals);
231  if (! cb (request,
232  args,
233  equals,
234  kind))
235  return false;
236  (*num_headers)++;
237  break;
238  }
239  /* amper is non-NULL here */
240  amper[0] = '\0';
241  amper++;
242  if ( (NULL == equals) ||
243  (equals >= amper) )
244  {
245  /* got 'foo&bar' or 'foo&bar=val', add key 'foo' with NULL for value */
246  MHD_unescape_plus (args);
247  daemon->unescape_cb (daemon->unescape_cb_cls,
248  request,
249  args);
250  if (! cb (request,
251  args,
252  NULL,
253  kind))
254  return false;
255  /* continue with 'bar' */
256  (*num_headers)++;
257  args = amper;
258  continue;
259  }
260  /* equals and amper are non-NULL here, and equals < amper,
261  so we got regular 'foo=value&bar...'-kind of argument */
262  equals[0] = '\0';
263  equals++;
264  MHD_unescape_plus (args);
265  daemon->unescape_cb (daemon->unescape_cb_cls,
266  request,
267  args);
268  MHD_unescape_plus (equals);
269  daemon->unescape_cb (daemon->unescape_cb_cls,
270  request,
271  equals);
272  if (! cb (request,
273  args,
274  equals,
275  kind))
276  return false;
277  (*num_headers)++;
278  args = amper;
279  }
280  return true;
281 }
282 
283 /* end of internal.c */
void * logger_cls
Definition: internal.h:1020
MHD_CONNECTION_STATE
Definition: internal.h:420
bool MHD_parse_arguments_(struct MHD_Request *request, enum MHD_ValueKind kind, char *args, MHD_ArgumentIterator_ cb, unsigned int *num_headers)
Definition: internal.c:186
internal shared structures
struct MHD_Daemon * daemon
Definition: internal.h:372
void * unescape_cb_cls
Definition: internal.h:1063
MHD_UnescapeCallback unescape_cb
Definition: internal.h:1058
size_t MHD_http_unescape(char *val)
Definition: internal.c:138
#define NULL
Definition: reason_phrase.c:30
MHD_ValueKind
Definition: microhttpd.h:1757
MHD_LoggingCallback logger
Definition: internal.h:1015
bool(* MHD_ArgumentIterator_)(struct MHD_Request *request, const char *key, const char *value, enum MHD_ValueKind kind)
Definition: internal.h:1708
void MHD_unescape_plus(char *arg)
Definition: internal.c:119
size_t MHD_strx_to_uint32_n_(const char *str, size_t maxlen, uint32_t *out_val)
Definition: mhd_str.c:589