GNU libmicrohttpd  0.9.59
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";
80  default:
81  return "unrecognized connection state";
82  }
83 }
84 #endif
85 #endif
86 
87 
88 #ifdef HAVE_MESSAGES
89 
93 void
94 MHD_DLOG (const struct MHD_Daemon *daemon,
95  const char *format,
96  ...)
97 {
98  va_list va;
99 
100  if (0 == (daemon->options & MHD_USE_ERROR_LOG))
101  return;
102  va_start (va, format);
103  daemon->custom_error_log (daemon->custom_error_log_cls,
104  format,
105  va);
106  va_end (va);
107 }
108 #endif
109 
110 
116 void
117 MHD_unescape_plus (char *arg)
118 {
119  char *p;
120 
121  for (p=strchr (arg, '+'); NULL != p; p = strchr (p + 1, '+'))
122  *p = ' ';
123 }
124 
125 
135 size_t
136 MHD_http_unescape (char *val)
137 {
138  char *rpos = val;
139  char *wpos = val;
140 
141  while ('\0' != *rpos)
142  {
143  uint32_t num;
144  switch (*rpos)
145  {
146  case '%':
147  if (2 == MHD_strx_to_uint32_n_ (rpos + 1,
148  2,
149  &num))
150  {
151  *wpos = (char)((unsigned char) num);
152  wpos++;
153  rpos += 3;
154  break;
155  }
156  /* TODO: add bad sequence handling */
157  /* intentional fall through! */
158  default:
159  *wpos = *rpos;
160  wpos++;
161  rpos++;
162  }
163  }
164  *wpos = '\0'; /* add 0-terminator */
165  return wpos - val; /* = strlen(val) */
166 }
167 
168 
183 int
185  enum MHD_ValueKind kind,
186  char *args,
188  unsigned int *num_headers)
189 {
190  struct MHD_Daemon *daemon = connection->daemon;
191  char *equals;
192  char *amper;
193 
194  *num_headers = 0;
195  while ( (NULL != args) &&
196  ('\0' != args[0]) )
197  {
198  equals = strchr (args, '=');
199  amper = strchr (args, '&');
200  if (NULL == amper)
201  {
202  /* last argument */
203  if (NULL == equals)
204  {
205  /* last argument, without '=' */
206  MHD_unescape_plus (args);
207  daemon->unescape_callback (daemon->unescape_callback_cls,
208  connection,
209  args);
210  if (MHD_YES != cb (connection,
211  args,
212  NULL,
213  kind))
214  return MHD_NO;
215  (*num_headers)++;
216  break;
217  }
218  /* got 'foo=bar' */
219  equals[0] = '\0';
220  equals++;
221  MHD_unescape_plus (args);
222  daemon->unescape_callback (daemon->unescape_callback_cls,
223  connection,
224  args);
225  MHD_unescape_plus (equals);
226  daemon->unescape_callback (daemon->unescape_callback_cls,
227  connection,
228  equals);
229  if (MHD_YES != cb (connection,
230  args,
231  equals,
232  kind))
233  return MHD_NO;
234  (*num_headers)++;
235  break;
236  }
237  /* amper is non-NULL here */
238  amper[0] = '\0';
239  amper++;
240  if ( (NULL == equals) ||
241  (equals >= amper) )
242  {
243  /* got 'foo&bar' or 'foo&bar=val', add key 'foo' with NULL for value */
244  MHD_unescape_plus (args);
245  daemon->unescape_callback (daemon->unescape_callback_cls,
246  connection,
247  args);
248  if (MHD_YES != cb (connection,
249  args,
250  NULL,
251  kind))
252  return MHD_NO;
253  /* continue with 'bar' */
254  (*num_headers)++;
255  args = amper;
256  continue;
257  }
258  /* equals and amper are non-NULL here, and equals < amper,
259  so we got regular 'foo=value&bar...'-kind of argument */
260  equals[0] = '\0';
261  equals++;
262  MHD_unescape_plus (args);
263  daemon->unescape_callback (daemon->unescape_callback_cls,
264  connection,
265  args);
266  MHD_unescape_plus (equals);
267  daemon->unescape_callback (daemon->unescape_callback_cls,
268  connection,
269  equals);
270  if (MHD_YES != cb (connection,
271  args,
272  equals,
273  kind))
274  return MHD_NO;
275  (*num_headers)++;
276  args = amper;
277  }
278  return MHD_YES;
279 }
280 
281 /* end of internal.c */
void * unescape_callback_cls
Definition: internal.h:1392
void MHD_unescape_plus(char *arg)
Definition: internal.c:117
#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:184
MHD_CONNECTION_STATE
Definition: internal.h:403
struct MHD_Daemon * daemon
Definition: internal.h:650
size_t MHD_strx_to_uint32_n_(const char *str, size_t maxlen, uint32_t *out_val)
Definition: mhd_str.c:581
enum MHD_FLAG options
Definition: internal.h:1569
MHD_ValueKind
Definition: microhttpd.h:1517
internal shared structures
UnescapeCallback unescape_callback
Definition: internal.h:1387
int(* MHD_ArgumentIterator_)(struct MHD_Connection *connection, const char *key, const char *value, enum MHD_ValueKind kind)
Definition: internal.h:1852
Header for string manipulating helpers.
#define MHD_NO
Definition: microhttpd.h:139
size_t MHD_http_unescape(char *val)
Definition: internal.c:136