Jamoma API  0.6.0.a19
civetweb.h
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. */
41 struct mg_request_info {
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 
258 /* Send data to the client.
259  Return:
260  0 when the connection has been closed
261  -1 on error
262  >0 number of bytes written on success */
263 int mg_write(struct mg_connection *, const void *buf, size_t len);
264 
265 
266 /* Send data to a websocket client wrapped in a websocket frame. Uses mg_lock
267  to ensure that the transmission is not interrupted, i.e., when the
268  application is proactively communicating and responding to a request
269  simultaneously.
270 
271  Send data to a websocket client wrapped in a websocket frame.
272  This function is available when civetweb is compiled with -DUSE_WEBSOCKET
273 
274  Return:
275  0 when the connection has been closed
276  -1 on error
277  >0 number of bytes written on success */
278 int mg_websocket_write(struct mg_connection* conn, int opcode,
279  const char *data, size_t data_len);
280 
281 /* Blocks until unique access is obtained to this connection. Intended for use
282  with websockets only.
283  Invoke this before mg_write or mg_printf when communicating with a
284  websocket if your code has server-initiated communication as well as
285  communication in direct response to a message. */
286 void mg_lock(struct mg_connection* conn);
287 void mg_unlock(struct mg_connection* conn);
288 
289 /* Opcodes, from http://tools.ietf.org/html/rfc6455 */
290 enum {
291  WEBSOCKET_OPCODE_CONTINUATION = 0x0,
292  WEBSOCKET_OPCODE_TEXT = 0x1,
293  WEBSOCKET_OPCODE_BINARY = 0x2,
294  WEBSOCKET_OPCODE_CONNECTION_CLOSE = 0x8,
295  WEBSOCKET_OPCODE_PING = 0x9,
296  WEBSOCKET_OPCODE_PONG = 0xa
297 };
298 
299 
300 /* Macros for enabling compiler-specific checks for printf-like arguments. */
301 #undef PRINTF_FORMAT_STRING
302 #if defined(_MSC_VER) && _MSC_VER >= 1400
303 #include <sal.h>
304 #if defined(_MSC_VER) && _MSC_VER > 1400
305 #define PRINTF_FORMAT_STRING(s) _Printf_format_string_ s
306 #else
307 #define PRINTF_FORMAT_STRING(s) __format_string s
308 #endif
309 #else
310 #define PRINTF_FORMAT_STRING(s) s
311 #endif
312 
313 #ifdef __GNUC__
314 #define PRINTF_ARGS(x, y) __attribute__((format(printf, x, y)))
315 #else
316 #define PRINTF_ARGS(x, y)
317 #endif
318 
319 /* Send data to the client using printf() semantics.
320 
321  Works exactly like mg_write(), but allows to do message formatting. */
322 int mg_printf(struct mg_connection *,
323  PRINTF_FORMAT_STRING(const char *fmt), ...) PRINTF_ARGS(2, 3);
324 
325 
326 /* Send contents of the entire file together with HTTP headers. */
327 void mg_send_file(struct mg_connection *conn, const char *path);
328 
329 
330 /* Read data from the remote end, return number of bytes read.
331  Return:
332  0 connection has been closed by peer. No more data could be read.
333  < 0 read error. No more data could be read from the connection.
334  > 0 number of bytes read into the buffer. */
335 int mg_read(struct mg_connection *, void *buf, size_t len);
336 
337 
338 /* Get the value of particular HTTP header.
339 
340  This is a helper function. It traverses request_info->http_headers array,
341  and if the header is present in the array, returns its value. If it is
342  not present, NULL is returned. */
343 const char *mg_get_header(const struct mg_connection *, const char *name);
344 
345 
346 /* Get a value of particular form variable.
347 
348  Parameters:
349  data: pointer to form-uri-encoded buffer. This could be either POST data,
350  or request_info.query_string.
351  data_len: length of the encoded data.
352  var_name: variable name to decode from the buffer
353  dst: destination buffer for the decoded variable
354  dst_len: length of the destination buffer
355 
356  Return:
357  On success, length of the decoded variable.
358  On error:
359  -1 (variable not found).
360  -2 (destination buffer is NULL, zero length or too small to hold the
361  decoded variable).
362 
363  Destination buffer is guaranteed to be '\0' - terminated if it is not
364  NULL or zero length. */
365 int mg_get_var(const char *data, size_t data_len,
366  const char *var_name, char *dst, size_t dst_len);
367 
368 /* Get a value of particular form variable.
369 
370  Parameters:
371  data: pointer to form-uri-encoded buffer. This could be either POST data,
372  or request_info.query_string.
373  data_len: length of the encoded data.
374  var_name: variable name to decode from the buffer
375  dst: destination buffer for the decoded variable
376  dst_len: length of the destination buffer
377  occurrence: which occurrence of the variable, 0 is the first, 1 the
378  second...
379  this makes it possible to parse a query like
380  b=x&a=y&a=z which will have occurrence values b:0, a:0 and a:1
381 
382  Return:
383  On success, length of the decoded variable.
384  On error:
385  -1 (variable not found).
386  -2 (destination buffer is NULL, zero length or too small to hold the
387  decoded variable).
388 
389  Destination buffer is guaranteed to be '\0' - terminated if it is not
390  NULL or zero length. */
391 int mg_get_var2(const char *data, size_t data_len,
392  const char *var_name, char *dst, size_t dst_len, size_t occurrence);
393 
394 /* Fetch value of certain cookie variable into the destination buffer.
395 
396  Destination buffer is guaranteed to be '\0' - terminated. In case of
397  failure, dst[0] == '\0'. Note that RFC allows many occurrences of the same
398  parameter. This function returns only first occurrence.
399 
400  Return:
401  On success, value length.
402  On error:
403  -1 (either "Cookie:" header is not present at all or the requested
404  parameter is not found).
405  -2 (destination buffer is NULL, zero length or too small to hold the
406  value). */
407 int mg_get_cookie(const char *cookie, const char *var_name,
408  char *buf, size_t buf_len);
409 
410 
411 /* Download data from the remote web server.
412  host: host name to connect to, e.g. "foo.com", or "10.12.40.1".
413  port: port number, e.g. 80.
414  use_ssl: wether to use SSL connection.
415  error_buffer, error_buffer_size: error message placeholder.
416  request_fmt,...: HTTP request.
417  Return:
418  On success, valid pointer to the new connection, suitable for mg_read().
419  On error, NULL. error_buffer contains error message.
420  Example:
421  char ebuf[100];
422  struct mg_connection *conn;
423  conn = mg_download("google.com", 80, 0, ebuf, sizeof(ebuf),
424  "%s", "GET / HTTP/1.0\r\nHost: google.com\r\n\r\n");
425  */
426 struct mg_connection *mg_download(const char *host, int port, int use_ssl,
427  char *error_buffer, size_t error_buffer_size,
428  PRINTF_FORMAT_STRING(const char *request_fmt),
429  ...) PRINTF_ARGS(6, 7);
430 
431 
432 /* Close the connection opened by mg_download(). */
433 void mg_close_connection(struct mg_connection *conn);
434 
435 
436 /* File upload functionality. Each uploaded file gets saved into a temporary
437  file and MG_UPLOAD event is sent.
438  Return number of uploaded files. */
439 int mg_upload(struct mg_connection *conn, const char *destination_dir);
440 
441 
442 /* Convenience function -- create detached thread.
443  Return: 0 on success, non-0 on error. */
444 typedef void * (*mg_thread_func_t)(void *);
445 int mg_start_thread(mg_thread_func_t f, void *p);
446 
447 
448 /* Return builtin mime type for the given file name.
449  For unrecognized extensions, "text/plain" is returned. */
450 const char *mg_get_builtin_mime_type(const char *file_name);
451 
452 
453 /* Return Civetweb version. */
454 const char *mg_version(void);
455 
456 /* URL-decode input buffer into destination buffer.
457  0-terminate the destination buffer.
458  form-url-encoded data differs from URI encoding in a way that it
459  uses '+' as character for space, see RFC 1866 section 8.2.1
460  http://ftp.ics.uci.edu/pub/ietf/html/rfc1866.txt
461  Return: length of the decoded data, or -1 if dst buffer is too small. */
462 int mg_url_decode(const char *src, int src_len, char *dst,
463  int dst_len, int is_form_url_encoded);
464 
465 /* URL-encode input buffer into destination buffer.
466  returns the length of the resulting buffer or -1
467  is the buffer is too small. */
468 int mg_url_encode(const char *src, char *dst, size_t dst_len);
469 
470 /* MD5 hash given strings.
471  Buffer 'buf' must be 33 bytes long. Varargs is a NULL terminated list of
472  ASCIIz strings. When function returns, buf will contain human-readable
473  MD5 hash. Example:
474  char buf[33];
475  mg_md5(buf, "aa", "bb", NULL); */
476 char *mg_md5(char buf[33], ...);
477 
478 
479 /* Print error message to the opened error log stream.
480  This utilizes the provided logging configuration.
481  conn: connection
482  fmt: format string without the line return
483  ...: variable argument list
484  Example:
485  mg_cry(conn,"i like %s", "logging"); */
486 void mg_cry(struct mg_connection *conn,
487  PRINTF_FORMAT_STRING(const char *fmt), ...) PRINTF_ARGS(2, 3);
488 
489 /* utility method to compare two buffers, case incensitive. */
490 int mg_strncasecmp(const char *s1, const char *s2, size_t len);
491 
492 #ifdef __cplusplus
493 }
494 #endif /* __cplusplus */
495 
496 #endif /* CIVETWEB_HEADER_INCLUDED */