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 
29 #if 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";
80  return "secure connection init";
81  default:
82  return "unrecognized connection state";
83  }
84 }
85 #endif
86 #endif
87 
88 #if HAVE_MESSAGES
89 
93 void
94 MHD_DLOG (const struct MHD_Daemon *daemon, const char *format, ...)
95 {
96  va_list va;
97 
98  if (0 == (daemon->options & MHD_USE_DEBUG))
99  return;
100  va_start (va, format);
101  daemon->custom_error_log (daemon->custom_error_log_cls, format, va);
102  va_end (va);
103 }
104 #endif
105 
106 
112 void
113 MHD_unescape_plus (char *arg)
114 {
115  char *p;
116 
117  for (p=strchr (arg, '+'); NULL != p; p = strchr (p + 1, '+'))
118  *p = ' ';
119 }
120 
121 
131 size_t
132 MHD_http_unescape (char *val)
133 {
134  char *rpos = val;
135  char *wpos = val;
136  char *end;
137  unsigned int num;
138  char buf3[3];
139 
140  while ('\0' != *rpos)
141  {
142  switch (*rpos)
143  {
144  case '%':
145  if ( ('\0' == rpos[1]) ||
146  ('\0' == rpos[2]) )
147  {
148  *wpos = '\0';
149  return wpos - val;
150  }
151  buf3[0] = rpos[1];
152  buf3[1] = rpos[2];
153  buf3[2] = '\0';
154  num = strtoul (buf3, &end, 16);
155  if ('\0' == *end)
156  {
157  *wpos = (char)((unsigned char) num);
158  wpos++;
159  rpos += 3;
160  break;
161  }
162  /* intentional fall through! */
163  default:
164  *wpos = *rpos;
165  wpos++;
166  rpos++;
167  }
168  }
169  *wpos = '\0'; /* add 0-terminator */
170  return wpos - val; /* = strlen(val) */
171 }
172 
173 
188 int
190  enum MHD_ValueKind kind,
191  char *args,
193  unsigned int *num_headers)
194 {
195  struct MHD_Daemon *daemon = connection->daemon;
196  char *equals;
197  char *amper;
198 
199  *num_headers = 0;
200  while ( (NULL != args) &&
201  ('\0' != args[0]) )
202  {
203  equals = strchr (args, '=');
204  amper = strchr (args, '&');
205  if (NULL == amper)
206  {
207  /* last argument */
208  if (NULL == equals)
209  {
210  /* last argument, without '=' */
211  MHD_unescape_plus (args);
212  daemon->unescape_callback (daemon->unescape_callback_cls,
213  connection,
214  args);
215  if (MHD_YES != cb (connection,
216  args,
217  NULL,
218  kind))
219  return MHD_NO;
220  (*num_headers)++;
221  break;
222  }
223  /* got 'foo=bar' */
224  equals[0] = '\0';
225  equals++;
226  MHD_unescape_plus (args);
227  daemon->unescape_callback (daemon->unescape_callback_cls,
228  connection,
229  args);
230  MHD_unescape_plus (equals);
231  daemon->unescape_callback (daemon->unescape_callback_cls,
232  connection,
233  equals);
234  if (MHD_YES != cb (connection,
235  args,
236  equals,
237  kind))
238  return MHD_NO;
239  (*num_headers)++;
240  break;
241  }
242  /* amper is non-NULL here */
243  amper[0] = '\0';
244  amper++;
245  if ( (NULL == equals) ||
246  (equals >= amper) )
247  {
248  /* got 'foo&bar' or 'foo&bar=val', add key 'foo' with NULL for value */
249  MHD_unescape_plus (args);
250  daemon->unescape_callback (daemon->unescape_callback_cls,
251  connection,
252  args);
253  if (MHD_YES != cb (connection,
254  args,
255  NULL,
256  kind))
257  return MHD_NO;
258  /* continue with 'bar' */
259  (*num_headers)++;
260  args = amper;
261  continue;
262  }
263  /* equals and amper are non-NULL here, and equals < amper,
264  so we got regular 'foo=value&bar...'-kind of argument */
265  equals[0] = '\0';
266  equals++;
267  MHD_unescape_plus (args);
268  daemon->unescape_callback (daemon->unescape_callback_cls,
269  connection,
270  args);
271  MHD_unescape_plus (equals);
272  daemon->unescape_callback (daemon->unescape_callback_cls,
273  connection,
274  equals);
275  if (MHD_YES != cb (connection,
276  args,
277  equals,
278  kind))
279  return MHD_NO;
280  (*num_headers)++;
281  args = amper;
282  }
283  return MHD_YES;
284 }
285 
286 /* end of internal.c */
void * unescape_callback_cls
Definition: internal.h:1056
void MHD_unescape_plus(char *arg)
Definition: internal.c:113
#define NULL
Definition: reason_phrase.c:30
MHD_CONNECTION_STATE
Definition: internal.h:347
#define MHD_YES
Definition: microhttpd.h:138
enum MHD_ValueKind kind
Definition: internal.h:238
struct MHD_Daemon * daemon
Definition: internal.h:558
int(* MHD_ArgumentIterator_)(struct MHD_Connection *connection, const char *key, const char *value, enum MHD_ValueKind kind)
Definition: internal.h:1464
int MHD_parse_arguments_(struct MHD_Connection *connection, enum MHD_ValueKind kind, char *args, MHD_ArgumentIterator_ cb, unsigned int *num_headers)
Definition: internal.c:189
internal shared structures
enum MHD_FLAG options
Definition: internal.h:1192
MHD_ValueKind
Definition: microhttpd.h:997
size_t MHD_http_unescape(char *val)
Definition: internal.c:132
UnescapeCallback unescape_callback
Definition: internal.h:1051
#define MHD_NO
Definition: microhttpd.h:143