GNU libmicrohttpd  1.0.1
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  Copyright (C) 2015-2023 Evgeny Grin (Karlson2k)
5 
6  This library is free software; you can redistribute it and/or
7  modify it under the terms of the GNU Lesser General Public
8  License as published by the Free Software Foundation; either
9  version 2.1 of the License, or (at your option) any later version.
10 
11  This library is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  Lesser General Public License for more details.
15 
16  You should have received a copy of the GNU Lesser General Public
17  License along with this library; if not, write to the Free Software
18  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20 
29 #include "internal.h"
30 #include "mhd_str.h"
31 
32 #ifdef HAVE_MESSAGES
33 #if DEBUG_STATES
37 const char *
38 MHD_state_to_string (enum MHD_CONNECTION_STATE state)
39 {
40  switch (state)
41  {
43  return "connection init";
45  return "receiving request line";
47  return "request line received";
49  return "headers receiving";
51  return "headers received";
53  return "headers processed";
55  return "continue sending";
57  return "body receiving";
59  return "body received";
61  return "footers receiving";
63  return "footers received";
65  return "full request received";
67  return "start sending reply";
69  return "headers sending";
71  return "headers sent";
73  return "normal body unready";
75  return "normal body ready";
77  return "chunked body unready";
79  return "chunked body ready";
81  return "chunked body sent";
83  return "footers sending";
85  return "reply sent completely";
87  return "closed";
88  default:
89  return "unrecognized connection state";
90  }
91 }
92 
93 
94 #endif
95 #endif
96 
97 
98 #ifdef HAVE_MESSAGES
103 void
104 MHD_DLOG (const struct MHD_Daemon *daemon,
105  const char *format,
106  ...)
107 {
108  va_list va;
109 
110  if (0 == (daemon->options & MHD_USE_ERROR_LOG))
111  return;
112  va_start (va, format);
113  daemon->custom_error_log (daemon->custom_error_log_cls,
114  format,
115  va);
116  va_end (va);
117 }
118 
119 
120 #endif
121 
122 
128 void
129 MHD_unescape_plus (char *arg)
130 {
131  char *p;
132 
133  for (p = strchr (arg, '+'); NULL != p; p = strchr (p + 1, '+'))
134  *p = ' ';
135 }
136 
137 
147 _MHD_EXTERN size_t
148 MHD_http_unescape (char *val)
149 {
151 }
152 
153 
168 enum MHD_Result
169 MHD_parse_arguments_ (struct MHD_Connection *connection,
170  enum MHD_ValueKind kind,
171  char *args,
173  void *cls)
174 {
175  struct MHD_Daemon *daemon = connection->daemon;
176  char *equals;
177  char *amper;
178 
179  while ( (NULL != args) &&
180  ('\0' != args[0]) )
181  {
182  size_t key_len;
183  size_t value_len;
184  equals = strchr (args, '=');
185  amper = strchr (args, '&');
186  if (NULL == amper)
187  {
188  /* last argument */
189  if (NULL == equals)
190  {
191  /* last argument, without '=' */
192  MHD_unescape_plus (args);
193  key_len = daemon->unescape_callback (daemon->unescape_callback_cls,
194  connection,
195  args);
196  if (MHD_NO == cb (cls,
197  args,
198  key_len,
199  NULL,
200  0,
201  kind))
202  return MHD_NO;
203  break;
204  }
205  /* got 'foo=bar' */
206  equals[0] = '\0';
207  equals++;
208  MHD_unescape_plus (args);
209  key_len = daemon->unescape_callback (daemon->unescape_callback_cls,
210  connection,
211  args);
212  MHD_unescape_plus (equals);
213  value_len = daemon->unescape_callback (daemon->unescape_callback_cls,
214  connection,
215  equals);
216  if (MHD_NO == cb (cls,
217  args,
218  key_len,
219  equals,
220  value_len,
221  kind))
222  return MHD_NO;
223  break;
224  }
225  /* amper is non-NULL here */
226  amper[0] = '\0';
227  amper++;
228  if ( (NULL == equals) ||
229  (equals >= amper) )
230  {
231  /* got 'foo&bar' or 'foo&bar=val', add key 'foo' with NULL for value */
232  MHD_unescape_plus (args);
233  key_len = daemon->unescape_callback (daemon->unescape_callback_cls,
234  connection,
235  args);
236  if (MHD_NO == cb (cls,
237  args,
238  key_len,
239  NULL,
240  0,
241  kind))
242  return MHD_NO;
243  /* continue with 'bar' */
244  args = amper;
245  continue;
246  }
247  /* equals and amper are non-NULL here, and equals < amper,
248  so we got regular 'foo=value&bar...'-kind of argument */
249  equals[0] = '\0';
250  equals++;
251  MHD_unescape_plus (args);
252  key_len = daemon->unescape_callback (daemon->unescape_callback_cls,
253  connection,
254  args);
255  MHD_unescape_plus (equals);
256  value_len = daemon->unescape_callback (daemon->unescape_callback_cls,
257  connection,
258  equals);
259  if (MHD_NO == cb (cls,
260  args,
261  key_len,
262  equals,
263  value_len,
264  kind))
265  return MHD_NO;
266  args = amper;
267  }
268  return MHD_YES;
269 }
270 
271 
272 /* 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
#define NULL
Definition: reason_phrase.c:30
#define _MHD_EXTERN
Definition: mhd_options.h:53
MHD internal shared structures.
MHD_CONNECTION_STATE
Definition: internal.h:613
@ MHD_CONNECTION_BODY_RECEIVED
Definition: internal.h:663
@ MHD_CONNECTION_CHUNKED_BODY_SENT
Definition: internal.h:725
@ MHD_CONNECTION_REQ_HEADERS_RECEIVING
Definition: internal.h:636
@ MHD_CONNECTION_BODY_RECEIVING
Definition: internal.h:656
@ MHD_CONNECTION_HEADERS_SENDING
Definition: internal.h:694
@ MHD_CONNECTION_FOOTERS_SENDING
Definition: internal.h:730
@ MHD_CONNECTION_FOOTERS_RECEIVED
Definition: internal.h:675
@ MHD_CONNECTION_FULL_REPLY_SENT
Definition: internal.h:736
@ MHD_CONNECTION_HEADERS_SENT
Definition: internal.h:699
@ MHD_CONNECTION_HEADERS_PROCESSED
Definition: internal.h:646
@ MHD_CONNECTION_INIT
Definition: internal.h:618
@ MHD_CONNECTION_CLOSED
Definition: internal.h:741
@ MHD_CONNECTION_REQ_LINE_RECEIVED
Definition: internal.h:631
@ MHD_CONNECTION_NORMAL_BODY_UNREADY
Definition: internal.h:705
@ MHD_CONNECTION_HEADERS_RECEIVED
Definition: internal.h:641
@ MHD_CONNECTION_NORMAL_BODY_READY
Definition: internal.h:710
@ MHD_CONNECTION_START_REPLY
Definition: internal.h:688
@ MHD_CONNECTION_FOOTERS_RECEIVING
Definition: internal.h:668
@ MHD_CONNECTION_CHUNKED_BODY_READY
Definition: internal.h:720
@ MHD_CONNECTION_FULL_REQ_RECEIVED
Definition: internal.h:681
@ MHD_CONNECTION_CHUNKED_BODY_UNREADY
Definition: internal.h:715
@ MHD_CONNECTION_CONTINUE_SENDING
Definition: internal.h:651
@ MHD_CONNECTION_REQ_LINE_RECEIVING
Definition: internal.h:624
size_t MHD_str_pct_decode_in_place_lenient_(char *str, bool *broken_encoding)
Definition: mhd_str.c:1984
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
Definition: microhttpd.h:2245
@ MHD_USE_ERROR_LOG
Definition: microhttpd.h:1254
struct MHD_Daemon * daemon
Definition: internal.h:675
void * unescape_callback_cls
Definition: internal.h:2072
enum MHD_FLAG options
Definition: internal.h:1880
UnescapeCallback unescape_callback
Definition: internal.h:2067