GNU libmicrohttpd  0.9.29
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
32 
35 const char *
36 MHD_state_to_string (enum MHD_CONNECTION_STATE state)
37 {
38  switch (state)
39  {
41  return "connection init";
43  return "connection url received";
45  return "header partially received";
47  return "headers received";
49  return "headers processed";
51  return "continue sending";
53  return "continue sent";
55  return "body received";
57  return "footer partially received";
59  return "footers received";
61  return "headers sending";
63  return "headers sent";
65  return "normal body ready";
67  return "normal body unready";
69  return "chunked body ready";
71  return "chunked body unready";
73  return "body sent";
75  return "footers sending";
77  return "footers sent";
79  return "closed";
81  return "secure connection init";
82  default:
83  return "unrecognized connection state";
84  }
85 }
86 #endif
87 #endif
88 
89 
90 #ifdef HAVE_MESSAGES
91 
95 void
96 MHD_DLOG (const struct MHD_Daemon *daemon,
97  const char *format,
98  ...)
99 {
100  va_list va;
101 
102  if (0 == (daemon->options & MHD_USE_ERROR_LOG))
103  return;
104  va_start (va, format);
105  daemon->custom_error_log (daemon->custom_error_log_cls,
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 int
187  enum MHD_ValueKind kind,
188  char *args,
190  unsigned int *num_headers)
191 {
192  struct MHD_Daemon *daemon = connection->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_callback (daemon->unescape_callback_cls,
210  connection,
211  args);
212  if (MHD_YES != cb (connection,
213  args,
214  NULL,
215  kind))
216  return MHD_NO;
217  (*num_headers)++;
218  break;
219  }
220  /* got 'foo=bar' */
221  equals[0] = '\0';
222  equals++;
223  MHD_unescape_plus (args);
224  daemon->unescape_callback (daemon->unescape_callback_cls,
225  connection,
226  args);
227  MHD_unescape_plus (equals);
228  daemon->unescape_callback (daemon->unescape_callback_cls,
229  connection,
230  equals);
231  if (MHD_YES != cb (connection,
232  args,
233  equals,
234  kind))
235  return MHD_NO;
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_callback (daemon->unescape_callback_cls,
248  connection,
249  args);
250  if (MHD_YES != cb (connection,
251  args,
252  NULL,
253  kind))
254  return MHD_NO;
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_callback (daemon->unescape_callback_cls,
266  connection,
267  args);
268  MHD_unescape_plus (equals);
269  daemon->unescape_callback (daemon->unescape_callback_cls,
270  connection,
271  equals);
272  if (MHD_YES != cb (connection,
273  args,
274  equals,
275  kind))
276  return MHD_NO;
277  (*num_headers)++;
278  args = amper;
279  }
280  return MHD_YES;
281 }
282 
283 /* end of internal.c */
void * unescape_callback_cls
Definition: internal.h:1401
void MHD_unescape_plus(char *arg)
Definition: internal.c:119
#define NULL
Definition: reason_phrase.c:31
#define MHD_YES
Definition: microhttpd.h:134
int MHD_parse_arguments_(struct MHD_Connection *connection, enum MHD_ValueKind kind, char *args, MHD_ArgumentIterator_ cb, unsigned int *num_headers)
Definition: internal.c:186
MHD_CONNECTION_STATE
Definition: internal.h:401
struct MHD_Daemon * daemon
Definition: internal.h:641
size_t MHD_strx_to_uint32_n_(const char *str, size_t maxlen, uint32_t *out_val)
Definition: mhd_str.c:571
enum MHD_FLAG options
Definition: internal.h:1578
MHD_ValueKind
Definition: microhttpd.h:1524
internal shared structures
UnescapeCallback unescape_callback
Definition: internal.h:1396
int(* MHD_ArgumentIterator_)(struct MHD_Connection *connection, const char *key, const char *value, enum MHD_ValueKind kind)
Definition: internal.h:1868
Header for string manipulating helpers.
#define MHD_NO
Definition: microhttpd.h:139
size_t MHD_http_unescape(char *val)
Definition: internal.c:138