ROOT  6.06/09
Reference Guide
civetweb.h
Go to the documentation of this file.
1 /* Copyright (c) 2004-2013 Sergey Lyubka
2  *
3  * Permission is hereby granted, free of charge, to any person obtaining a copy
4  * of this software and associated documentation files (the "Software"), to deal
5  * in the Software without restriction, including without limitation the rights
6  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7  * copies of the Software, and to permit persons to whom the Software is
8  * furnished to do so, subject to the following conditions:
9  *
10  * The above copyright notice and this permission notice shall be included in
11  * all copies or substantial portions of the Software.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19  * THE SOFTWARE.
20  */
21 
22 #ifndef CIVETWEB_HEADER_INCLUDED
23 #define CIVETWEB_HEADER_INCLUDED
24 
25 #ifndef CIVETWEB_VERSION
26 #define CIVETWEB_VERSION "1.6"
27 #endif
28 
29 #include <stdio.h>
30 #include <stddef.h>
31 
32 #ifdef __cplusplus
33 extern "C" {
34 #endif /* __cplusplus */
35 
36 struct mg_context; /* Handle for the HTTP service itself */
37 struct mg_connection; /* Handle for the individual connection */
38 
39 
40 /* This structure contains information about the HTTP request. */
42  const char *request_method; /* "GET", "POST", etc */
43  const char *uri; /* URL-decoded URI */
44  const char *http_version; /* E.g. "1.0", "1.1" */
45  const char *query_string; /* URL part after '?', not including '?', or
46  NULL */
47  const char *remote_user; /* Authenticated user, or NULL if no auth
48  used */
49  long remote_ip; /* Client's IP address */
50  int remote_port; /* Client's port */
51  int is_ssl; /* 1 if SSL-ed, 0 if not */
52  void *user_data; /* User data pointer passed to mg_start() */
53  void *conn_data; /* Connection-specific user data */
54 
55  int num_headers; /* Number of HTTP headers */
56  struct mg_header {
57  const char *name; /* HTTP header name */
58  const char *value; /* HTTP header value */
59  } http_headers[64]; /* Maximum 64 headers */
60 };
61 
62 
63 /* This structure needs to be passed to mg_start(), to let civetweb know
64  which callbacks to invoke. For detailed description, see
65  https://github.com/sunsetbrew/civetweb/blob/master/docs/UserManual.md */
66 struct mg_callbacks {
67  /* Called when civetweb has received new HTTP request.
68  If callback returns non-zero,
69  callback must process the request by sending valid HTTP headers and
70  body, and civetweb will not do any further processing.
71  If callback returns 0, civetweb processes the request itself. In this
72  case, callback must not send any data to the client. */
73  int (*begin_request)(struct mg_connection *);
74 
75  /* Called when civetweb has finished processing request. */
76  void (*end_request)(const struct mg_connection *, int reply_status_code);
77 
78  /* Called when civetweb is about to log a message. If callback returns
79  non-zero, civetweb does not log anything. */
80  int (*log_message)(const struct mg_connection *, const char *message);
81 
82  /* Called when civetweb initializes SSL library. */
83  int (*init_ssl)(void *ssl_context, void *user_data);
84 
85  /* Called when websocket request is received, before websocket handshake.
86  If callback returns 0, civetweb proceeds with handshake, otherwise
87  cinnection is closed immediately. */
88  int (*websocket_connect)(const struct mg_connection *);
89 
90  /* Called when websocket handshake is successfully completed, and
91  connection is ready for data exchange. */
92  void (*websocket_ready)(struct mg_connection *);
93 
94  /* Called when data frame has been received from the client.
95  Parameters:
96  bits: first byte of the websocket frame, see websocket RFC at
97  http://tools.ietf.org/html/rfc6455, section 5.2
98  data, data_len: payload, with mask (if any) already applied.
99  Return value:
100  non-0: keep this websocket connection opened.
101  0: close this websocket connection. */
102  int (*websocket_data)(struct mg_connection *, int bits,
103  char *data, size_t data_len);
104 
105  /* Called when civetweb is closing a connection. The per-context mutex is
106  locked when this is invoked. This is primarily useful for noting when
107  a websocket is closing and removing it from any application-maintained
108  list of clients. */
109  void (*connection_close)(struct mg_connection *);
110 
111  /* Called when civetweb tries to open a file. Used to intercept file open
112  calls, and serve file data from memory instead.
113  Parameters:
114  path: Full path to the file to open.
115  data_len: Placeholder for the file size, if file is served from
116  memory.
117  Return value:
118  NULL: do not serve file from memory, proceed with normal file open.
119  non-NULL: pointer to the file contents in memory. data_len must be
120  initilized with the size of the memory block. */
121  const char * (*open_file)(const struct mg_connection *,
122  const char *path, size_t *data_len);
123 
124  /* Called when civetweb is about to serve Lua server page (.lp file), if
125  Lua support is enabled.
126  Parameters:
127  lua_context: "lua_State *" pointer. */
128  void (*init_lua)(struct mg_connection *, void *lua_context);
129 
130  /* Called when civetweb has uploaded a file to a temporary directory as a
131  result of mg_upload() call.
132  Parameters:
133  file_file: full path name to the uploaded file. */
134  void (*upload)(struct mg_connection *, const char *file_name);
135 
136  /* Called when civetweb is about to send HTTP error to the client.
137  Implementing this callback allows to create custom error pages.
138  Parameters:
139  status: HTTP error status code. */
140  int (*http_error)(struct mg_connection *, int status);
141 };
142 
143 /* Start web server.
144 
145  Parameters:
146  callbacks: mg_callbacks structure with user-defined callbacks.
147  options: NULL terminated list of option_name, option_value pairs that
148  specify Civetweb configuration parameters.
149 
150  Side-effects: on UNIX, ignores SIGCHLD and SIGPIPE signals. If custom
151  processing is required for these, signal handlers must be set up
152  after calling mg_start().
153 
154 
155  Example:
156  const char *options[] = {
157  "document_root", "/var/www",
158  "listening_ports", "80,443s",
159  NULL
160  };
161  struct mg_context *ctx = mg_start(&my_func, NULL, options);
162 
163  Refer to https://github.com/sunsetbrew/civetweb/blob/master/docs/UserManual.md
164  for the list of valid option and their possible values.
165 
166  Return:
167  web server context, or NULL on error. */
168 struct mg_context *mg_start(const struct mg_callbacks *callbacks,
169  void *user_data,
170  const char **configuration_options);
171 
172 
173 /* Stop the web server.
174 
175  Must be called last, when an application wants to stop the web server and
176  release all associated resources. This function blocks until all Civetweb
177  threads are stopped. Context pointer becomes invalid. */
178 void mg_stop(struct mg_context *);
179 
180 /* mg_request_handler
181 
182  Called when a new request comes in. This callback is URI based
183  and configured with mg_set_request_handler().
184 
185  Parameters:
186  conn: current connection information.
187  cbdata: the callback data configured with mg_set_request_handler().
188  Returns:
189  0: the handler could not handle the request, so fall through.
190  1: the handler processed the request. */
191 typedef int (* mg_request_handler)(struct mg_connection *conn, void *cbdata);
192 
193 /* mg_set_request_handler
194 
195  Sets or removes a URI mapping for a request handler.
196 
197  URI's are ordered and prefixed URI's are supported. For example,
198  consider two URIs: /a/b and /a
199  /a matches /a
200  /a/b matches /a/b
201  /a/c matches /a
202 
203  Parameters:
204  ctx: server context
205  uri: the URI to configure
206  handler: the callback handler to use when the URI is requested.
207  If NULL, the URI will be removed.
208  cbdata: the callback data to give to the handler when it s requested. */
209 void mg_set_request_handler(struct mg_context *ctx, const char *uri, mg_request_handler handler, void *cbdata);
210 
211 
212 /* Get the value of particular configuration parameter.
213  The value returned is read-only. Civetweb does not allow changing
214  configuration at run time.
215  If given parameter name is not valid, NULL is returned. For valid
216  names, return value is guaranteed to be non-NULL. If parameter is not
217  set, zero-length string is returned. */
218 const char *mg_get_option(const struct mg_context *ctx, const char *name);
219 
220 
221 /* Return array of strings that represent valid configuration options.
222  For each option, option name and default value is returned, i.e. the
223  number of entries in the array equals to number_of_options x 2.
224  Array is NULL terminated. */
225 const char **mg_get_valid_option_names(void);
226 
227 /* Get the list of ports that civetweb is listening on.
228  size is the size of the ports int array and ssl int array to fill.
229  It is the caller's responsibility to make sure ports and ssl each
230  contain at least size int elements worth of memory to write into.
231  Return value is the number of ports and ssl information filled in.
232  The value returned is read-only. Civetweb does not allow changing
233  configuration at run time. */
234 size_t mg_get_ports(const struct mg_context *ctx, size_t size, int* ports, int* ssl);
235 
236 /* Add, edit or delete the entry in the passwords file.
237 
238  This function allows an application to manipulate .htpasswd files on the
239  fly by adding, deleting and changing user records. This is one of the
240  several ways of implementing authentication on the server side. For another,
241  cookie-based way please refer to the examples/chat in the source tree.
242 
243  If password is not NULL, entry is added (or modified if already exists).
244  If password is NULL, entry is deleted.
245 
246  Return:
247  1 on success, 0 on error. */
248 int mg_modify_passwords_file(const char *passwords_file_name,
249  const char *domain,
250  const char *user,
251  const char *password);
252 
253 
254 /* Return information associated with the request. */
255 struct mg_request_info *mg_get_request_info(struct mg_connection *);
256 
257 /* Return context associated with connection. */
258 const struct mg_context *mg_get_context(const struct mg_connection *conn);
259 
260 /* Return user data pointer for context. */
261 void *mg_get_user_data(const struct mg_context *ctx);
262 
263 
264 /* Send data to the client.
265  Return:
266  0 when the connection has been closed
267  -1 on error
268  >0 number of bytes written on success */
269 int mg_write(struct mg_connection *, const void *buf, size_t len);
270 
271 
272 /* Send data to a websocket client wrapped in a websocket frame. Uses mg_lock
273  to ensure that the transmission is not interrupted, i.e., when the
274  application is proactively communicating and responding to a request
275  simultaneously.
276 
277  Send data to a websocket client wrapped in a websocket frame.
278  This function is available when civetweb is compiled with -DUSE_WEBSOCKET
279 
280  Return:
281  0 when the connection has been closed
282  -1 on error
283  >0 number of bytes written on success */
284 int mg_websocket_write(struct mg_connection* conn, int opcode,
285  const char *data, size_t data_len);
286 
287 /* Blocks until unique access is obtained to this connection. Intended for use
288  with websockets only.
289  Invoke this before mg_write or mg_printf when communicating with a
290  websocket if your code has server-initiated communication as well as
291  communication in direct response to a message. */
292 void mg_lock(struct mg_connection* conn);
293 void mg_unlock(struct mg_connection* conn);
294 
295 /* Opcodes, from http://tools.ietf.org/html/rfc6455 */
296 enum {
303 };
304 
305 
306 /* Macros for enabling compiler-specific checks for printf-like arguments. */
307 #undef PRINTF_FORMAT_STRING
308 #if defined(_MSC_VER) && _MSC_VER >= 1400
309 #include <sal.h>
310 #if defined(_MSC_VER) && _MSC_VER > 1400
311 #define PRINTF_FORMAT_STRING(s) _Printf_format_string_ s
312 #else
313 #define PRINTF_FORMAT_STRING(s) __format_string s
314 #endif
315 #else
316 #define PRINTF_FORMAT_STRING(s) s
317 #endif
318 
319 #ifdef __GNUC__
320 #define PRINTF_ARGS(x, y) __attribute__((format(printf, x, y)))
321 #else
322 #define PRINTF_ARGS(x, y)
323 #endif
324 
325 /* Send data to the client using printf() semantics.
326 
327  Works exactly like mg_write(), but allows to do message formatting. */
328 int mg_printf(struct mg_connection *,
329  PRINTF_FORMAT_STRING(const char *fmt), ...) PRINTF_ARGS(2, 3);
330 
331 
332 /* Send contents of the entire file together with HTTP headers. */
333 void mg_send_file(struct mg_connection *conn, const char *path);
334 
335 
336 /* Read data from the remote end, return number of bytes read.
337  Return:
338  0 connection has been closed by peer. No more data could be read.
339  < 0 read error. No more data could be read from the connection.
340  > 0 number of bytes read into the buffer. */
341 int mg_read(struct mg_connection *, void *buf, size_t len);
342 
343 
344 /* Get the value of particular HTTP header.
345 
346  This is a helper function. It traverses request_info->http_headers array,
347  and if the header is present in the array, returns its value. If it is
348  not present, NULL is returned. */
349 const char *mg_get_header(const struct mg_connection *, const char *name);
350 
351 
352 /* Get a value of particular form variable.
353 
354  Parameters:
355  data: pointer to form-uri-encoded buffer. This could be either POST data,
356  or request_info.query_string.
357  data_len: length of the encoded data.
358  var_name: variable name to decode from the buffer
359  dst: destination buffer for the decoded variable
360  dst_len: length of the destination buffer
361 
362  Return:
363  On success, length of the decoded variable.
364  On error:
365  -1 (variable not found).
366  -2 (destination buffer is NULL, zero length or too small to hold the
367  decoded variable).
368 
369  Destination buffer is guaranteed to be '\0' - terminated if it is not
370  NULL or zero length. */
371 int mg_get_var(const char *data, size_t data_len,
372  const char *var_name, char *dst, size_t dst_len);
373 
374 /* Get a value of particular form variable.
375 
376  Parameters:
377  data: pointer to form-uri-encoded buffer. This could be either POST data,
378  or request_info.query_string.
379  data_len: length of the encoded data.
380  var_name: variable name to decode from the buffer
381  dst: destination buffer for the decoded variable
382  dst_len: length of the destination buffer
383  occurrence: which occurrence of the variable, 0 is the first, 1 the
384  second...
385  this makes it possible to parse a query like
386  b=x&a=y&a=z which will have occurrence values b:0, a:0 and a:1
387 
388  Return:
389  On success, length of the decoded variable.
390  On error:
391  -1 (variable not found).
392  -2 (destination buffer is NULL, zero length or too small to hold the
393  decoded variable).
394 
395  Destination buffer is guaranteed to be '\0' - terminated if it is not
396  NULL or zero length. */
397 int mg_get_var2(const char *data, size_t data_len,
398  const char *var_name, char *dst, size_t dst_len, size_t occurrence);
399 
400 /* Fetch value of certain cookie variable into the destination buffer.
401 
402  Destination buffer is guaranteed to be '\0' - terminated. In case of
403  failure, dst[0] == '\0'. Note that RFC allows many occurrences of the same
404  parameter. This function returns only first occurrence.
405 
406  Return:
407  On success, value length.
408  On error:
409  -1 (either "Cookie:" header is not present at all or the requested
410  parameter is not found).
411  -2 (destination buffer is NULL, zero length or too small to hold the
412  value). */
413 int mg_get_cookie(const char *cookie, const char *var_name,
414  char *buf, size_t buf_len);
415 
416 
417 /* Download data from the remote web server.
418  host: host name to connect to, e.g. "foo.com", or "10.12.40.1".
419  port: port number, e.g. 80.
420  use_ssl: wether to use SSL connection.
421  error_buffer, error_buffer_size: error message placeholder.
422  request_fmt,...: HTTP request.
423  Return:
424  On success, valid pointer to the new connection, suitable for mg_read().
425  On error, NULL. error_buffer contains error message.
426  Example:
427  char ebuf[100];
428  struct mg_connection *conn;
429  conn = mg_download("google.com", 80, 0, ebuf, sizeof(ebuf),
430  "%s", "GET / HTTP/1.0\r\nHost: google.com\r\n\r\n");
431  */
432 struct mg_connection *mg_download(const char *host, int port, int use_ssl,
433  char *error_buffer, size_t error_buffer_size,
434  PRINTF_FORMAT_STRING(const char *request_fmt),
435  ...) PRINTF_ARGS(6, 7);
436 
437 
438 /* Close the connection opened by mg_download(). */
439 void mg_close_connection(struct mg_connection *conn);
440 
441 
442 /* File upload functionality. Each uploaded file gets saved into a temporary
443  file and MG_UPLOAD event is sent.
444  Return number of uploaded files. */
445 int mg_upload(struct mg_connection *conn, const char *destination_dir);
446 
447 
448 /* Convenience function -- create detached thread.
449  Return: 0 on success, non-0 on error. */
450 typedef void * (*mg_thread_func_t)(void *);
451 int mg_start_thread(mg_thread_func_t f, void *p);
452 
453 
454 /* Return builtin mime type for the given file name.
455  For unrecognized extensions, "text/plain" is returned. */
456 const char *mg_get_builtin_mime_type(const char *file_name);
457 
458 
459 /* Return Civetweb version. */
460 const char *mg_version(void);
461 
462 /* URL-decode input buffer into destination buffer.
463  0-terminate the destination buffer.
464  form-url-encoded data differs from URI encoding in a way that it
465  uses '+' as character for space, see RFC 1866 section 8.2.1
466  http://ftp.ics.uci.edu/pub/ietf/html/rfc1866.txt
467  Return: length of the decoded data, or -1 if dst buffer is too small. */
468 int mg_url_decode(const char *src, int src_len, char *dst,
469  int dst_len, int is_form_url_encoded);
470 
471 /* URL-encode input buffer into destination buffer.
472  returns the length of the resulting buffer or -1
473  is the buffer is too small. */
474 int mg_url_encode(const char *src, char *dst, size_t dst_len);
475 
476 /* MD5 hash given strings.
477  Buffer 'buf' must be 33 bytes long. Varargs is a NULL terminated list of
478  ASCIIz strings. When function returns, buf will contain human-readable
479  MD5 hash. Example:
480  char buf[33];
481  mg_md5(buf, "aa", "bb", NULL); */
482 char *mg_md5(char buf[33], ...);
483 
484 
485 /* Print error message to the opened error log stream.
486  This utilizes the provided logging configuration.
487  conn: connection
488  fmt: format string without the line return
489  ...: variable argument list
490  Example:
491  mg_cry(conn,"i like %s", "logging"); */
492 void mg_cry(struct mg_connection *conn,
493  PRINTF_FORMAT_STRING(const char *fmt), ...) PRINTF_ARGS(2, 3);
494 
495 /* utility method to compare two buffers, case incensitive. */
496 int mg_strncasecmp(const char *s1, const char *s2, size_t len);
497 
498 #ifdef __cplusplus
499 }
500 #endif /* __cplusplus */
501 
502 #endif /* CIVETWEB_HEADER_INCLUDED */
void(* upload)(struct mg_connection *, const char *file_name)
Definition: civetweb.h:134
int mg_read(struct mg_connection *, void *buf, size_t len)
Definition: civetweb.c:1996
const char * remote_user
Definition: civetweb.h:47
const char * mg_get_header(const struct mg_connection *, const char *name)
Definition: civetweb.c:1033
int mg_websocket_write(struct mg_connection *conn, int opcode, const char *data, size_t data_len)
int mg_get_var(const char *data, size_t data_len, const char *var_name, char *dst, size_t dst_len)
Definition: civetweb.c:2189
int(* mg_request_handler)(struct mg_connection *conn, void *cbdata)
Definition: civetweb.h:191
const char * uri
Definition: civetweb.h:43
void(* end_request)(const struct mg_connection *, int reply_status_code)
Definition: civetweb.h:76
const char ** mg_get_valid_option_names(void)
Definition: civetweb.c:673
int mg_printf(struct mg_connection *, PRINTF_FORMAT_STRING(const char *fmt),...) PRINTF_ARGS(2
#define PRINTF_ARGS(x, y)
Definition: civetweb.h:322
int(* begin_request)(struct mg_connection *)
Definition: civetweb.h:73
void mg_unlock(struct mg_connection *conn)
Definition: civetweb.c:4371
void * mg_get_user_data(const struct mg_context *ctx)
Definition: civetweb.c:701
int(* init_ssl)(void *ssl_context, void *user_data)
Definition: civetweb.h:83
int(* log_message)(const struct mg_connection *, const char *message)
Definition: civetweb.h:80
void mg_cry(struct mg_connection *conn, PRINTF_FORMAT_STRING(const char *fmt),...) PRINTF_ARGS(2
int mg_url_encode(const char *src, char *dst, size_t dst_len)
Definition: civetweb.c:2997
int mg_start_thread(mg_thread_func_t f, void *p)
Definition: civetweb.c:1797
void(* connection_close)(struct mg_connection *)
Definition: civetweb.h:109
TAlienJobStatus * status
Definition: TAlienJob.cxx:51
struct mg_request_info::mg_header http_headers[64]
int mg_modify_passwords_file(const char *passwords_file_name, const char *domain, const char *user, const char *password)
Definition: civetweb.c:2900
int(* websocket_connect)(const struct mg_connection *)
Definition: civetweb.h:88
void int mg_strncasecmp(const char *s1, const char *s2, size_t len)
Definition: civetweb.c:869
struct mg_connection void mg_close_connection(struct mg_connection *conn)
Definition: civetweb.c:5805
#define PRINTF_FORMAT_STRING(s)
Definition: civetweb.h:316
const char * request_method
Definition: civetweb.h:42
const char * mg_version(void)
Definition: civetweb.c:846
void(* init_lua)(struct mg_connection *, void *lua_context)
Definition: civetweb.h:128
struct mg_connection * mg_download(const char *host, int port, int use_ssl, char *error_buffer, size_t error_buffer_size, PRINTF_FORMAT_STRING(const char *request_fmt),...) PRINTF_ARGS(6
int mg_write(struct mg_connection *, const void *buf, size_t len)
Definition: civetweb.c:2037
const char * mg_get_option(const struct mg_context *ctx, const char *name)
Definition: civetweb.c:743
long remote_ip
Definition: civetweb.h:49
void(* websocket_ready)(struct mg_connection *)
Definition: civetweb.h:92
int mg_url_decode(const char *src, int src_len, char *dst, int dst_len, int is_form_url_encoded)
Definition: civetweb.c:2163
const struct mg_context * mg_get_context(const struct mg_connection *conn)
Definition: civetweb.c:696
size_t mg_get_ports(const struct mg_context *ctx, size_t size, int *ports, int *ssl)
Definition: civetweb.c:755
const char * http_version
Definition: civetweb.h:44
struct mg_request_info * mg_get_request_info(struct mg_connection *)
Definition: civetweb.c:851
int(* http_error)(struct mg_connection *, int status)
Definition: civetweb.h:140
void mg_stop(struct mg_context *)
Definition: civetweb.c:6341
int mg_get_var2(const char *data, size_t data_len, const char *var_name, char *dst, size_t dst_len, size_t occurrence)
Definition: civetweb.c:2195
double f(double x)
int mg_get_cookie(const char *cookie, const char *var_name, char *buf, size_t buf_len)
Definition: civetweb.c:2244
void mg_lock(struct mg_connection *conn)
Definition: civetweb.c:4366
void * user_data
Definition: civetweb.h:52
#define name(a, b)
Definition: linkTestLib0.cpp:5
void mg_set_request_handler(struct mg_context *ctx, const char *uri, mg_request_handler handler, void *cbdata)
Definition: civetweb.c:5092
int mg_upload(struct mg_connection *conn, const char *destination_dir)
Definition: civetweb.c:4928
typedef void((*Func_t)())
const char * mg_get_builtin_mime_type(const char *file_name)
Definition: civetweb.c:2556
int void mg_send_file(struct mg_connection *conn, const char *path)
Definition: civetweb.c:3435
void *(* mg_thread_func_t)(void *)
Definition: civetweb.h:450
char * mg_md5(char buf[33],...)
Definition: civetweb.c:2615
const char * query_string
Definition: civetweb.h:45
string message
Definition: ROOT.py:94
int(* websocket_data)(struct mg_connection *, int bits, char *data, size_t data_len)
Definition: civetweb.h:102
void * conn_data
Definition: civetweb.h:53
struct mg_context * mg_start(const struct mg_callbacks *callbacks, void *user_data, const char **configuration_options)
Definition: civetweb.c:6357