isomorfeus-iodine 0.7.49 → 0.7.50

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +1 -1
  3. data/CHANGELOG.md +17 -3
  4. data/Rakefile +1 -9
  5. data/examples/etag.ru +16 -0
  6. data/ext/{iodine → iodine_ext}/extconf.rb +1 -1
  7. data/ext/{iodine → iodine_ext}/fio.c +0 -0
  8. data/ext/{iodine → iodine_ext}/fio.h +0 -0
  9. data/ext/{iodine → iodine_ext}/fio_cli.c +0 -0
  10. data/ext/{iodine → iodine_ext}/fio_cli.h +189 -189
  11. data/ext/{iodine → iodine_ext}/fio_json_parser.h +687 -687
  12. data/ext/{iodine → iodine_ext}/fio_siphash.c +157 -157
  13. data/ext/{iodine → iodine_ext}/fio_siphash.h +37 -37
  14. data/ext/{iodine → iodine_ext}/fio_tls.h +129 -129
  15. data/ext/{iodine → iodine_ext}/fio_tls_missing.c +0 -0
  16. data/ext/{iodine → iodine_ext}/fio_tls_openssl.c +0 -0
  17. data/ext/{iodine → iodine_ext}/fio_tmpfile.h +0 -0
  18. data/ext/{iodine → iodine_ext}/fiobj.h +44 -44
  19. data/ext/{iodine → iodine_ext}/fiobj4fio.h +21 -21
  20. data/ext/{iodine → iodine_ext}/fiobj_ary.c +333 -333
  21. data/ext/{iodine → iodine_ext}/fiobj_ary.h +139 -139
  22. data/ext/{iodine → iodine_ext}/fiobj_data.c +0 -0
  23. data/ext/{iodine → iodine_ext}/fiobj_data.h +0 -0
  24. data/ext/{iodine → iodine_ext}/fiobj_hash.c +0 -0
  25. data/ext/{iodine → iodine_ext}/fiobj_hash.h +176 -176
  26. data/ext/{iodine → iodine_ext}/fiobj_json.c +622 -622
  27. data/ext/{iodine → iodine_ext}/fiobj_json.h +68 -68
  28. data/ext/{iodine → iodine_ext}/fiobj_mem.h +71 -71
  29. data/ext/{iodine → iodine_ext}/fiobj_mustache.c +0 -0
  30. data/ext/{iodine → iodine_ext}/fiobj_mustache.h +62 -62
  31. data/ext/{iodine → iodine_ext}/fiobj_numbers.c +0 -0
  32. data/ext/{iodine → iodine_ext}/fiobj_numbers.h +127 -127
  33. data/ext/{iodine → iodine_ext}/fiobj_str.c +0 -0
  34. data/ext/{iodine → iodine_ext}/fiobj_str.h +172 -172
  35. data/ext/{iodine → iodine_ext}/fiobject.c +0 -0
  36. data/ext/{iodine → iodine_ext}/fiobject.h +0 -0
  37. data/ext/{iodine → iodine_ext}/hpack.h +1923 -1923
  38. data/ext/{iodine → iodine_ext}/http.c +14 -27
  39. data/ext/{iodine → iodine_ext}/http.h +1002 -1002
  40. data/ext/{iodine → iodine_ext}/http1.c +0 -0
  41. data/ext/{iodine → iodine_ext}/http1.h +29 -29
  42. data/ext/{iodine → iodine_ext}/http1_parser.h +0 -0
  43. data/ext/{iodine → iodine_ext}/http_internal.c +0 -0
  44. data/ext/{iodine → iodine_ext}/http_internal.h +0 -0
  45. data/ext/{iodine → iodine_ext}/http_mime_parser.h +350 -350
  46. data/ext/{iodine → iodine_ext}/iodine.c +1 -1
  47. data/ext/{iodine → iodine_ext}/iodine.h +0 -0
  48. data/ext/{iodine → iodine_ext}/iodine_caller.c +0 -0
  49. data/ext/{iodine → iodine_ext}/iodine_caller.h +0 -0
  50. data/ext/{iodine → iodine_ext}/iodine_connection.c +0 -0
  51. data/ext/{iodine → iodine_ext}/iodine_connection.h +55 -55
  52. data/ext/{iodine → iodine_ext}/iodine_defer.c +0 -0
  53. data/ext/{iodine → iodine_ext}/iodine_defer.h +6 -6
  54. data/ext/{iodine → iodine_ext}/iodine_fiobj2rb.h +120 -120
  55. data/ext/{iodine → iodine_ext}/iodine_helpers.c +0 -0
  56. data/ext/{iodine → iodine_ext}/iodine_helpers.h +12 -12
  57. data/ext/{iodine → iodine_ext}/iodine_http.c +0 -2
  58. data/ext/{iodine → iodine_ext}/iodine_http.h +23 -23
  59. data/ext/{iodine → iodine_ext}/iodine_json.c +302 -302
  60. data/ext/{iodine → iodine_ext}/iodine_json.h +6 -6
  61. data/ext/{iodine → iodine_ext}/iodine_mustache.c +0 -0
  62. data/ext/{iodine → iodine_ext}/iodine_mustache.h +6 -6
  63. data/ext/{iodine → iodine_ext}/iodine_pubsub.c +0 -0
  64. data/ext/{iodine → iodine_ext}/iodine_pubsub.h +26 -26
  65. data/ext/{iodine → iodine_ext}/iodine_rack_io.c +0 -0
  66. data/ext/{iodine → iodine_ext}/iodine_rack_io.h +20 -20
  67. data/ext/{iodine → iodine_ext}/iodine_store.c +0 -0
  68. data/ext/{iodine → iodine_ext}/iodine_store.h +20 -20
  69. data/ext/{iodine → iodine_ext}/iodine_tcp.c +0 -0
  70. data/ext/{iodine → iodine_ext}/iodine_tcp.h +0 -0
  71. data/ext/{iodine → iodine_ext}/iodine_tls.c +0 -0
  72. data/ext/{iodine → iodine_ext}/iodine_tls.h +13 -13
  73. data/ext/{iodine → iodine_ext}/mustache_parser.h +0 -0
  74. data/ext/{iodine → iodine_ext}/redis_engine.c +0 -0
  75. data/ext/{iodine → iodine_ext}/redis_engine.h +0 -0
  76. data/ext/{iodine → iodine_ext}/resp_parser.h +0 -0
  77. data/ext/{iodine → iodine_ext}/websocket_parser.h +505 -505
  78. data/ext/{iodine → iodine_ext}/websockets.c +0 -0
  79. data/ext/{iodine → iodine_ext}/websockets.h +185 -185
  80. data/isomorfeus-iodine.gemspec +1 -2
  81. data/lib/iodine/version.rb +1 -1
  82. data/lib/iodine.rb +1 -1
  83. metadata +79 -78
@@ -1,1002 +1,1002 @@
1
- #ifndef H_HTTP_H
2
- /*
3
- Copyright: Boaz Segev, 2016-2019
4
- License: MIT
5
-
6
- Feel free to copy, use and enjoy according to the license provided.
7
- */
8
- #define H_HTTP_H
9
-
10
- #include <fio.h>
11
-
12
- #include <fiobj.h>
13
-
14
- #include <time.h>
15
-
16
- /* support C++ */
17
- #ifdef __cplusplus
18
- extern "C" {
19
- #endif
20
-
21
- /* *****************************************************************************
22
- Compile Time Settings
23
- ***************************************************************************** */
24
-
25
- /** When a new connection is accepted, it will be immediately declined with a
26
- * 503 service unavailable (server busy) response unless the following number of
27
- * file descriptors is available.*/
28
- #ifndef HTTP_BUSY_UNLESS_HAS_FDS
29
- #define HTTP_BUSY_UNLESS_HAS_FDS 64
30
- #endif
31
-
32
- #ifndef HTTP_DEFAULT_BODY_LIMIT
33
- #define HTTP_DEFAULT_BODY_LIMIT (1024 * 1024 * 50)
34
- #endif
35
-
36
- #ifndef HTTP_MAX_HEADER_COUNT
37
- #define HTTP_MAX_HEADER_COUNT 128
38
- #endif
39
-
40
- #ifndef HTTP_MAX_HEADER_LENGTH
41
- /** the default maximum length for a single header line */
42
- #define HTTP_MAX_HEADER_LENGTH 8192
43
- #endif
44
-
45
- #ifndef FIO_HTTP_EXACT_LOGGING
46
- /**
47
- * By default, facil.io logs the HTTP request cycle using a fuzzy starting point
48
- * (a close enough timestamp).
49
- *
50
- * The fuzzy timestamp includes delays that aren't related to the HTTP request,
51
- * sometimes including time that was spent waiting on the client. On the other
52
- * hand, `FIO_HTTP_EXACT_LOGGING` excludes time that the client might have been
53
- * waiting for facil.io to read data from the network.
54
- *
55
- * Due to the preference to err on the side of causion, fuzzy time-stamping is
56
- * the default.
57
- */
58
- #define FIO_HTTP_EXACT_LOGGING 0
59
- #endif
60
-
61
- /** the `http_listen settings, see details in the struct definition. */
62
- typedef struct http_settings_s http_settings_s;
63
-
64
- /* *****************************************************************************
65
- The Request / Response type and functions
66
- ***************************************************************************** */
67
-
68
- /**
69
- * A generic HTTP handle used for HTTP request/response data.
70
- *
71
- * The `http_s` data can only be accessed safely from within the `on_request`
72
- * HTTP callback OR an `http_defer` callback.
73
- */
74
- typedef struct {
75
- /** the HTTP request's "head" starts with a private data used by facil.io */
76
- struct {
77
- /** the function touting table - used by facil.io, don't use directly! */
78
- void *vtbl;
79
- /** the connection's owner / uuid - used by facil.io, don't use directly! */
80
- uintptr_t flag;
81
- /** The response headers, if they weren't sent. Don't access directly. */
82
- FIOBJ out_headers;
83
- } private_data;
84
- /** a time merker indicating when the request was received. */
85
- struct timespec received_at;
86
- /** a String containing the method data (supports non-standard methods. */
87
- FIOBJ method;
88
- /** The status string, for response objects (client mode response). */
89
- FIOBJ status_str;
90
- /** The HTTP version string, if any. */
91
- FIOBJ version;
92
- /** The status used for the response (or if the object is a response).
93
- *
94
- * When sending a request, the status should be set to 0.
95
- */
96
- uintptr_t status;
97
- /** The request path, if any. */
98
- FIOBJ path;
99
- /** The request query, if any. */
100
- FIOBJ query;
101
- /** a hash of general header data. When a header is set multiple times (such
102
- * as cookie headers), an Array will be used instead of a String. */
103
- FIOBJ headers;
104
- /**
105
- * a placeholder for a hash of cookie data.
106
- * the hash will be initialized when parsing the request.
107
- */
108
- FIOBJ cookies;
109
- /**
110
- * a placeholder for a hash of request data.
111
- * the hash will be initialized when parsing the request.
112
- */
113
- FIOBJ params;
114
- /**
115
- * a reader for body data (might be a temporary file or a string or NULL).
116
- * see fiobj_data.h for details.
117
- */
118
- FIOBJ body;
119
- /** an opaque user data pointer, to be used BEFORE calling `http_defer`. */
120
- void *udata;
121
- } http_s;
122
-
123
- /**
124
- * This is a helper for setting cookie data.
125
-
126
- This struct is used together with the `http_response_set_cookie`. i.e.:
127
-
128
- http_response_set_cookie(response,
129
- .name = "my_cookie",
130
- .value = "data" );
131
-
132
- */
133
- typedef struct {
134
- /** The cookie's name (Symbol). */
135
- const char *name;
136
- /** The cookie's value (leave blank to delete cookie). */
137
- const char *value;
138
- /** The cookie's domain (optional). */
139
- const char *domain;
140
- /** The cookie's path (optional). */
141
- const char *path;
142
- /** The cookie name's size in bytes or a terminating NUL will be assumed.*/
143
- size_t name_len;
144
- /** The cookie value's size in bytes or a terminating NUL will be assumed.*/
145
- size_t value_len;
146
- /** The cookie domain's size in bytes or a terminating NUL will be assumed.*/
147
- size_t domain_len;
148
- /** The cookie path's size in bytes or a terminating NULL will be assumed.*/
149
- size_t path_len;
150
- /** Max Age (how long should the cookie persist), in seconds (0 == session).*/
151
- int max_age;
152
- /** Limit cookie to secure connections.*/
153
- unsigned secure : 1;
154
- /** Limit cookie to HTTP (intended to prevent javascript access/hijacking).*/
155
- unsigned http_only : 1;
156
- } http_cookie_args_s;
157
-
158
- /**
159
- * Sets a response header, taking ownership of the value object, but NOT the
160
- * name object (so name objects could be reused in future responses).
161
- *
162
- * Returns -1 on error and 0 on success.
163
- */
164
- int http_set_header(http_s *h, FIOBJ name, FIOBJ value);
165
-
166
- /**
167
- * Sets a response header.
168
- *
169
- * Returns -1 on error and 0 on success.
170
- */
171
- int http_set_header2(http_s *h, fio_str_info_s name, fio_str_info_s value);
172
-
173
- /**
174
- * Sets a response cookie.
175
- *
176
- * Returns -1 on error and 0 on success.
177
- *
178
- * Note: Long cookie names and long cookie values will be considered a security
179
- * violation and an error will be returned. It should be noted that most
180
- * proxies and servers will refuse long cookie names or values and many impose
181
- * total header lengths (including cookies) of ~8Kib.
182
- */
183
- int http_set_cookie(http_s *h, http_cookie_args_s);
184
- #define http_set_cookie(http___handle, ...) \
185
- http_set_cookie((http___handle), (http_cookie_args_s){__VA_ARGS__})
186
-
187
- /**
188
- * Sends the response headers and body.
189
- *
190
- * **Note**: The body is *copied* to the HTTP stream and it's memory should be
191
- * freed by the calling function.
192
- *
193
- * Returns -1 on error and 0 on success.
194
- *
195
- * AFTER THIS FUNCTION IS CALLED, THE `http_s` OBJECT IS NO LONGER VALID.
196
- */
197
- int http_send_body(http_s *h, void *data, uintptr_t length);
198
-
199
- /**
200
- * Sends the response headers and the specified file (the response's body).
201
- *
202
- * The file is closed automatically.
203
- *
204
- * Returns -1 on error and 0 on success.
205
- *
206
- * AFTER THIS FUNCTION IS CALLED, THE `http_s` OBJECT IS NO LONGER VALID.
207
- */
208
- int http_sendfile(http_s *h, int fd, uintptr_t length, uintptr_t offset);
209
-
210
- /**
211
- * Sends the response headers and the specified file (the response's body).
212
- *
213
- * The `local` and `encoded` strings will be joined into a single string that
214
- * represent the file name. Either or both of these strings can be empty.
215
- *
216
- * The `encoded` string will be URL decoded while the `local` string will used
217
- * as is.
218
- *
219
- * Returns 0 on success. A success value WILL CONSUME the `http_s` handle (it
220
- * will become invalid).
221
- *
222
- * Returns -1 on error (The `http_s` handle should still be used).
223
- */
224
- int http_sendfile2(http_s *h, const char *prefix, size_t prefix_len,
225
- const char *encoded, size_t encoded_len);
226
-
227
- /**
228
- * Sends an HTTP error response.
229
- *
230
- * Returns -1 on error and 0 on success.
231
- *
232
- * AFTER THIS FUNCTION IS CALLED, THE `http_s` OBJECT IS NO LONGER VALID.
233
- *
234
- * The `uuid` and `settings` arguments are only required if the `http_s` handle
235
- * is NULL.
236
- */
237
- int http_send_error(http_s *h, size_t error_code);
238
-
239
- /**
240
- * Sends the response headers for a header only response.
241
- *
242
- * AFTER THIS FUNCTION IS CALLED, THE `http_s` OBJECT IS NO LONGER VALID.
243
- */
244
- void http_finish(http_s *h);
245
-
246
- /**
247
- * Pushes a data response when supported (HTTP/2 only).
248
- *
249
- * Returns -1 on error and 0 on success.
250
- */
251
- int http_push_data(http_s *h, void *data, uintptr_t length, FIOBJ mime_type);
252
-
253
- /**
254
- * Pushes a file response when supported (HTTP/2 only).
255
- *
256
- * If `mime_type` is NULL, an attempt at automatic detection using `filename`
257
- * will be made.
258
- *
259
- * Returns -1 on error and 0 on success.
260
- */
261
- int http_push_file(http_s *h, FIOBJ filename, FIOBJ mime_type);
262
-
263
- /* *****************************************************************************
264
- HTTP evented API (pause / resume HTTp handling)
265
- ***************************************************************************** */
266
-
267
- typedef struct http_pause_handle_s http_pause_handle_s;
268
- /**
269
- * Pauses the request / response handling and INVALIDATES the current `http_s`
270
- * handle (no `http` functions can be called).
271
- *
272
- * The `http_resume` function MUST be called (at some point) using the opaque
273
- * `http` pointer given to the callback `task`.
274
- *
275
- * The opaque `http` pointer is only valid for a single call to `http_resume`
276
- * and can't be used by any other `http` function (it's a different data type).
277
- *
278
- * Note: the current `http_s` handle will become invalid once this function is
279
- * called and it's data might be deallocated, invalid or used by a different
280
- * thread.
281
- */
282
- void http_pause(http_s *h, void (*task)(http_pause_handle_s *http));
283
-
284
- /**
285
- * Resumes a request / response handling within a task and INVALIDATES the
286
- * current `http_s` handle.
287
- *
288
- * The `task` MUST call one of the `http_send_*`, `http_finish`, or
289
- * `http_pause`functions.
290
- *
291
- * The (optional) `fallback` will receive the opaque `udata` that was stored in
292
- * the HTTP handle and can be used for cleanup.
293
- *
294
- * Note: `http_resume` can only be called after calling `http_pause` and
295
- * entering it's task.
296
- *
297
- * Note: the current `http_s` handle will become invalid once this function is
298
- * called and it's data might be deallocated, invalidated or used by a
299
- * different thread.
300
- */
301
- void http_resume(http_pause_handle_s *http, void (*task)(http_s *h),
302
- void (*fallback)(void *udata));
303
-
304
- /** Returns the `udata` associated with the paused opaque handle */
305
- void *http_paused_udata_get(http_pause_handle_s *http);
306
-
307
- /**
308
- * Sets the `udata` associated with the paused opaque handle, returning the
309
- * old value.
310
- */
311
- void *http_paused_udata_set(http_pause_handle_s *http, void *udata);
312
-
313
- /* *****************************************************************************
314
- HTTP Connections - Listening / Connecting / Hijacking
315
- ***************************************************************************** */
316
-
317
- /** The HTTP settings. */
318
- struct http_settings_s {
319
- /** Callback for normal HTTP requests. */
320
- void (*on_request)(http_s *request);
321
- /**
322
- * Callback for Upgrade and EventSource (SSE) requests.
323
- *
324
- * SSE/EventSource requests set the `requested_protocol` string to `"sse"`.
325
- */
326
- void (*on_upgrade)(http_s *request, char *requested_protocol, size_t len);
327
- /** CLIENT REQUIRED: a callback for the HTTP response. */
328
- void (*on_response)(http_s *response);
329
- /** (optional) the callback to be performed when the HTTP service closes. */
330
- void (*on_finish)(struct http_settings_s *settings);
331
- /** Opaque user data. Facil.io will ignore this field, but you can use it. */
332
- void *udata;
333
- /**
334
- * A public folder for file transfers - allows to circumvent any application
335
- * layer logic and simply serve static files.
336
- *
337
- * Supports automatic `gz` pre-compressed alternatives.
338
- */
339
- const char *public_folder;
340
- /**
341
- * The length of the public_folder string.
342
- */
343
- size_t public_folder_length;
344
- /**
345
- * The maximum number of bytes allowed for the request string (method, path,
346
- * query), header names and fields.
347
- *
348
- * Defaults to 32Kib (which is about 4 times more than I would recommend).
349
- *
350
- * This reflects the total overall size. On HTTP/1.1, each header line (name +
351
- * value pair) is also limitied to a hardcoded HTTP_MAX_HEADER_LENGTH bytes.
352
- */
353
- size_t max_header_size;
354
- /**
355
- * The maximum size of an HTTP request's body (posting / downloading).
356
- *
357
- * Defaults to ~ 50Mb.
358
- */
359
- size_t max_body_size;
360
- /**
361
- * The maximum number of clients that are allowed to connect concurrently.
362
- *
363
- * This value's default setting is usually for the best.
364
- *
365
- * The default value is computed according to the server's capacity, leaving
366
- * some breathing room for other network and disk operations.
367
- *
368
- * Note: clients, by the nature of socket programming, are counted according
369
- * to their internal file descriptor (`fd`) value. Open files and other
370
- * sockets count towards a server's limit.
371
- */
372
- intptr_t max_clients;
373
- /** SSL/TLS support. */
374
- void *tls;
375
- /** reserved for future use. */
376
- intptr_t reserved1;
377
- /** reserved for future use. */
378
- intptr_t reserved2;
379
- /** reserved for future use. */
380
- intptr_t reserved3;
381
- /**
382
- * The maximum websocket message size/buffer (in bytes) for Websocket
383
- * connections. Defaults to ~250KB.
384
- */
385
- size_t ws_max_msg_size;
386
- /**
387
- * An HTTP/1.x connection timeout.
388
- *
389
- * `http_listen` defaults to ~40s and `http_connect` defaults to ~30s.
390
- *
391
- * Note: the connection might be closed (by other side) before timeout occurs.
392
- */
393
- uint8_t timeout;
394
- /**
395
- * Timeout for the websocket connections, a ping will be sent whenever the
396
- * timeout is reached. Defaults to 40 seconds.
397
- *
398
- * Connections are only closed when a ping cannot be sent (the network layer
399
- * fails). Pongs are ignored.
400
- */
401
- uint8_t ws_timeout;
402
- /** Logging flag - set to TRUE to log HTTP requests. */
403
- uint8_t log;
404
- /** a read only flag set automatically to indicate the protocol's mode. */
405
- uint8_t is_client;
406
- };
407
-
408
- /**
409
- * Listens to HTTP connections at the specified `port`.
410
- *
411
- * Leave as NULL to ignore IP binding.
412
- *
413
- * Returns -1 on error and the socket's uuid on success.
414
- *
415
- * the `on_finish` callback is always called.
416
- */
417
- intptr_t http_listen(const char *port, const char *binding,
418
- struct http_settings_s);
419
- /** Listens to HTTP connections at the specified `port` and `binding`. */
420
- #define http_listen(port, binding, ...) \
421
- http_listen((port), (binding), (struct http_settings_s){__VA_ARGS__})
422
-
423
- /**
424
- * Connects to an HTTP server as a client.
425
- *
426
- * Upon a successful connection, the `on_response` callback is called with an
427
- * empty `http_s*` handler (status == 0). Use the same API to set it's content
428
- * and send the request to the server. The next`on_response` will contain the
429
- * response.
430
- *
431
- * `address` should contain a full URL style address for the server. i.e.:
432
- *
433
- * "http:/www.example.com:8080/"
434
- *
435
- * If an `address` includes a path or query data, they will be automatically
436
- * attached (both of them) to the HTTP handl'es `path` property. i.e.
437
- *
438
- * "http:/www.example.com:8080/my_path?foo=bar"
439
- * // will result in:
440
- * fiobj_obj2cstr(h->path).data; //=> "/my_path?foo=bar"
441
- *
442
- * To open a Websocket connection, it's possible to use the `ws` protocol
443
- * signature. However, it would be better to use the `websocket_connect`
444
- * function instead.
445
- *
446
- * Returns -1 on error and the socket's uuid on success.
447
- *
448
- * The `on_finish` callback is always called.
449
- */
450
- intptr_t http_connect(const char *url, const char *unix_address,
451
- struct http_settings_s);
452
- #define http_connect(url, unix_address, ...) \
453
- http_connect((url), (unix_address), (struct http_settings_s){__VA_ARGS__})
454
-
455
- /**
456
- * Returns the settings used to setup the connection or NULL on error.
457
- */
458
- struct http_settings_s *http_settings(http_s *h);
459
-
460
- /**
461
- * Returns the direct address of the connected peer (likely an intermediary).
462
- */
463
- fio_str_info_s http_peer_addr(http_s *h);
464
-
465
- /**
466
- * Hijacks the socket away from the HTTP protocol and away from facil.io.
467
- *
468
- * It's possible to hijack the socket and than reconnect it to a new protocol
469
- * object.
470
- *
471
- * It's possible to call `http_finish` immediately after calling `http_hijack`
472
- * in order to send the outgoing headers.
473
- *
474
- * If any additional HTTP functions are called after the hijacking, the protocol
475
- * object might attempt to continue reading data from the buffer.
476
- *
477
- * Returns the underlining socket connection's uuid. If `leftover` isn't NULL,
478
- * it will be populated with any remaining data in the HTTP buffer (the data
479
- * will be automatically deallocated, so copy the data when in need).
480
- *
481
- * WARNING: this isn't a good way to handle HTTP connections, especially as
482
- * HTTP/2 enters the picture.
483
- */
484
- intptr_t http_hijack(http_s *h, fio_str_info_s *leftover);
485
-
486
- /* *****************************************************************************
487
- Websocket Upgrade (Server and Client connection establishment)
488
- ***************************************************************************** */
489
-
490
- /**
491
- * The type for a Websocket handle, used to identify a Websocket connection.
492
- *
493
- * Similar to an `http_s` handle, it is only valid within the scope of the
494
- * specific connection (the callbacks / tasks) and shouldn't be stored or
495
- * accessed otherwise.
496
- */
497
- typedef struct ws_s ws_s;
498
-
499
- /**
500
- * This struct is used for the named arguments in the `http_upgrade2ws`
501
- * function and macro.
502
- */
503
- typedef struct {
504
- /**
505
- * The (optional) on_message callback will be called whenever a websocket
506
- * message is received for this connection.
507
- *
508
- * The data received points to the websocket's message buffer and it will be
509
- * overwritten once the function exits (it cannot be saved for later, but it
510
- * can be copied).
511
- */
512
- void (*on_message)(ws_s *ws, fio_str_info_s msg, uint8_t is_text);
513
- /**
514
- * The (optional) on_open callback will be called once the websocket
515
- * connection is established and before is is registered with `facil`, so no
516
- * `on_message` events are raised before `on_open` returns.
517
- */
518
- void (*on_open)(ws_s *ws);
519
- /**
520
- * The (optional) on_ready callback will be after a the underlying socket's
521
- * buffer changes it's state from full to empty.
522
- *
523
- * If the socket's buffer is never used, the callback is never called.
524
- */
525
- void (*on_ready)(ws_s *ws);
526
- /**
527
- * The (optional) on_shutdown callback will be called if a websocket
528
- * connection is still open while the server is shutting down (called before
529
- * `on_close`).
530
- */
531
- void (*on_shutdown)(ws_s *ws);
532
- /**
533
- * The (optional) on_close callback will be called once a websocket connection
534
- * is terminated or failed to be established.
535
- *
536
- * The `uuid` is the connection's unique ID that can identify the Websocket. A
537
- * value of `uuid == 0` indicates the Websocket connection wasn't established
538
- * (an error occurred).
539
- *
540
- * The `udata` is the user data as set during the upgrade or using the
541
- * `websocket_udata_set` function.
542
- */
543
- void (*on_close)(intptr_t uuid, void *udata);
544
- /** Opaque user data. */
545
- void *udata;
546
- } websocket_settings_s;
547
-
548
- /**
549
- * Upgrades an HTTP/1.1 connection to a Websocket connection.
550
- *
551
- * This function will end the HTTP stage of the connection and attempt to
552
- * "upgrade" to a Websockets connection.
553
- *
554
- * Thie `http_s` handle will be invalid after this call and the `udata` will be
555
- * set to the new Websocket `udata`.
556
- *
557
- * A client connection's `on_finish` callback will be called (since the HTTP
558
- * stage has finished).
559
- */
560
- int http_upgrade2ws(http_s *http, websocket_settings_s);
561
-
562
- /** This macro allows easy access to the `http_upgrade2ws` function. The macro
563
- * allows the use of named arguments, using the `websocket_settings_s` struct
564
- * members. i.e.:
565
- *
566
- * on_message(ws_s * ws, char * data, size_t size, int is_text) {
567
- * ; // ... this is the websocket on_message callback
568
- * websocket_write(ws, data, size, is_text); // a simple echo example
569
- * }
570
- *
571
- * on_upgrade(http_s* h) {
572
- * http_upgrade2ws( .http = h, .on_message = on_message);
573
- * }
574
- */
575
- #define http_upgrade2ws(http, ...) \
576
- http_upgrade2ws((http), (websocket_settings_s){__VA_ARGS__})
577
-
578
- /**
579
- * Connects to a Websocket service according to the provided address.
580
- *
581
- * This is a somewhat naive connector object, it doesn't perform any
582
- * authentication or other logical handling. However, it's quire easy to author
583
- * a complext authentication logic using a combination of `http_connect` and
584
- * `http_upgrade2ws`.
585
- *
586
- * Returns the uuid for the future websocket on success.
587
- *
588
- * Returns -1 on error;
589
- */
590
- int websocket_connect(const char *url, websocket_settings_s settings);
591
- #define websocket_connect(url, ...) \
592
- websocket_connect((url), (websocket_settings_s){__VA_ARGS__})
593
-
594
- #include <websockets.h>
595
-
596
- /* *****************************************************************************
597
- EventSource Support (SSE)
598
- ***************************************************************************** */
599
-
600
- /**
601
- * The type for the EventSource (SSE) handle, used to identify an SSE
602
- * connection.
603
- */
604
- typedef struct http_sse_s http_sse_s;
605
-
606
- /**
607
- * This struct is used for the named arguments in the `http_upgrade2sse`
608
- * function and macro.
609
- */
610
- struct http_sse_s {
611
- /**
612
- * The (optional) on_open callback will be called once the EventSource
613
- * connection is established.
614
- */
615
- void (*on_open)(http_sse_s *sse);
616
- /**
617
- * The (optional) on_ready callback will be after a the underlying socket's
618
- * buffer changes it's state to empty.
619
- *
620
- * If the socket's buffer is never used, the callback is never called.
621
- */
622
- void (*on_ready)(http_sse_s *sse);
623
- /**
624
- * The (optional) on_shutdown callback will be called if a connection is still
625
- * open while the server is shutting down (called before `on_close`).
626
- */
627
- void (*on_shutdown)(http_sse_s *sse);
628
- /**
629
- * The (optional) on_close callback will be called once a connection is
630
- * terminated or failed to be established.
631
- *
632
- * The `udata` passed to the `http_upgrade2sse` function is available
633
- * through the `http_sse_s` pointer (`sse->udata`).
634
- */
635
- void (*on_close)(http_sse_s *sse);
636
- /** Opaque user data. */
637
- void *udata;
638
- };
639
-
640
- /**
641
- * Upgrades an HTTP connection to an EventSource (SSE) connection.
642
- *
643
- * The `http_s` handle will be invalid after this call.
644
- *
645
- * On HTTP/1.1 connections, this will preclude future requests using the same
646
- * connection.
647
- */
648
- int http_upgrade2sse(http_s *h, http_sse_s);
649
-
650
- /** This macro allows easy access to the `http_upgrade2sse` function. The macro
651
- * allows the use of named arguments, using the `websocket_settings_s` struct
652
- * members. i.e.:
653
- *
654
- * on_open_sse(sse_s * sse) {
655
- * http_sse_subscribe(sse, .channel = CHANNEL_NAME);
656
- * }
657
- *
658
- * on_upgrade(http_s* h) {
659
- * http_upgrade2sse(h, .on_open = on_open_sse);
660
- * }
661
- */
662
- #define http_upgrade2sse(h, ...) \
663
- http_upgrade2sse((h), (http_sse_s){__VA_ARGS__})
664
-
665
- /**
666
- * Sets the ping interval for SSE connections.
667
- */
668
- void http_sse_set_timout(http_sse_s *sse, uint8_t timeout);
669
-
670
- struct http_sse_subscribe_args {
671
- /** The channel name used for the subscription. */
672
- fio_str_info_s channel;
673
- /** The optional on message callback. If missing, Data is directly writen. */
674
- void (*on_message)(http_sse_s *sse, fio_str_info_s channel,
675
- fio_str_info_s msg, void *udata);
676
- /** An optional callback for when a subscription is fully canceled. */
677
- void (*on_unsubscribe)(void *udata);
678
- /** Opaque user */
679
- void *udata;
680
- /** A callback for pattern matching. */
681
- fio_match_fn match;
682
- };
683
-
684
- /**
685
- * Subscribes to a channel for direct message deliverance. See {struct
686
- * http_sse_subscribe_args} for possible arguments.
687
- *
688
- * Returns a subscription ID on success and 0 on failure.
689
- *
690
- * To unsubscripbe from the channel, use `http_sse_unsubscribe` (NOT
691
- * `fio_unsubscribe`).
692
- *
693
- * All subscriptions are automatically cleared once the connection is closed.
694
- */
695
- uintptr_t http_sse_subscribe(http_sse_s *sse,
696
- struct http_sse_subscribe_args args);
697
-
698
- /** This macro allows easy access to the `http_sse_subscribe` function. */
699
- #define http_sse_subscribe(sse, ...) \
700
- http_sse_subscribe((sse), (struct http_sse_subscribe_args){__VA_ARGS__})
701
-
702
- /**
703
- * Cancels a subscription and invalidates the subscription object.
704
- */
705
- void http_sse_unsubscribe(http_sse_s *sse, uintptr_t subscription);
706
-
707
- /**
708
- * Named arguments for the {http_sse_write} function.
709
- *
710
- * These arguments list the possible fields for the SSE event.
711
- *
712
- * Event fields listed here:
713
- * https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events
714
- */
715
- struct http_sse_write_args {
716
- fio_str_info_s id; /* (optional) sets the `id` event property. */
717
- fio_str_info_s event; /* (optional) sets the `event` event property. */
718
- fio_str_info_s data; /* (optional) sets the `data` event property. */
719
- intptr_t retry; /* (optional) sets the `retry` event property. */
720
- };
721
-
722
- /**
723
- * Writes data to an EventSource (SSE) connection.
724
- *
725
- * See the {struct http_sse_write_args} for possible named arguments.
726
- */
727
- int http_sse_write(http_sse_s *sse, struct http_sse_write_args);
728
- #define http_sse_write(sse, ...) \
729
- http_sse_write((sse), (struct http_sse_write_args){__VA_ARGS__})
730
-
731
- /**
732
- * Get the connection's UUID (for `fio_defer_io_task`, pub/sub, etc').
733
- */
734
- intptr_t http_sse2uuid(http_sse_s *sse);
735
-
736
- /**
737
- * Closes an EventSource (SSE) connection.
738
- */
739
- int http_sse_close(http_sse_s *sse);
740
-
741
- /**
742
- * Duplicates an SSE handle by reference, remember to http_sse_free.
743
- *
744
- * Returns the same object (increases a reference count, no allocation is made).
745
- */
746
- http_sse_s *http_sse_dup(http_sse_s *sse);
747
-
748
- /**
749
- * Frees an SSE handle by reference (decreases the reference count).
750
- */
751
- void http_sse_free(http_sse_s *sse);
752
-
753
- /* *****************************************************************************
754
- HTTP GET and POST parsing helpers
755
- ***************************************************************************** */
756
-
757
- /**
758
- * Attempts to decode the request's body.
759
- *
760
- * Supported Types include:
761
- * * application/x-www-form-urlencoded
762
- * * application/json
763
- * * multipart/form-data
764
- *
765
- * This should be called before `http_parse_query`, in order to support JSON
766
- * data.
767
- *
768
- * If the JSON data isn't an object, it will be saved under the key "JSON" in
769
- * the `params` hash.
770
- *
771
- * If the `multipart/form-data` type contains JSON files, they will NOT be
772
- * parsed (they will behave like any other file, with `data`, `type` and
773
- * `filename` keys assigned). This allows non-object JSON data (such as array)
774
- * to be handled by the app.
775
- */
776
- int http_parse_body(http_s *h);
777
-
778
- /**
779
- * Parses the query part of an HTTP request/response. Uses `http_add2hash`.
780
- *
781
- * This should be called after the `http_parse_body` function, just in case the
782
- * body is JSON that doesn't have an object at it's root.
783
- */
784
- void http_parse_query(http_s *h);
785
-
786
- /** Parses any Cookie / Set-Cookie headers, using the `http_add2hash` scheme. */
787
- void http_parse_cookies(http_s *h, uint8_t is_url_encoded);
788
-
789
- /**
790
- * Adds a named parameter to the hash, converting a string to an object and
791
- * resolving nesting references and URL decoding if required.
792
- *
793
- * i.e.:
794
- *
795
- * * "name[]" references a nested Array (nested in the Hash).
796
- * * "name[key]" references a nested Hash.
797
- * * "name[][key]" references a nested Hash within an array. Hash keys will be
798
- * unique (repeating a key advances the hash).
799
- * * These rules can be nested (i.e. "name[][key1][][key2]...")
800
- * * "name[][]" is an error (there's no way for the parser to analyze
801
- * dimensions)
802
- *
803
- * Note: names can't begin with "[" or end with "]" as these are reserved
804
- * characters.
805
- */
806
- int http_add2hash(FIOBJ dest, char *name, size_t name_len, char *value,
807
- size_t value_len, uint8_t encoded);
808
-
809
- /**
810
- * Adds a named parameter to the hash, using an existing object and resolving
811
- * nesting references.
812
- *
813
- * i.e.:
814
- *
815
- * * "name[]" references a nested Array (nested in the Hash).
816
- * * "name[key]" references a nested Hash.
817
- * * "name[][key]" references a nested Hash within an array. Hash keys will be
818
- * unique (repeating a key advances the array).
819
- * * These rules can be nested (i.e. "name[][key1][][key2]...")
820
- * * "name[][]" is an error (there's no way for the parser to analyze
821
- * dimensions)
822
- *
823
- * Note: names can't begin with "[" or end with "]" as these are reserved
824
- * characters.
825
- */
826
- int http_add2hash2(FIOBJ dest, char *name, size_t name_len, FIOBJ value,
827
- uint8_t encoded);
828
-
829
- /* *****************************************************************************
830
- HTTP Status Strings and Mime-Type helpers
831
- ***************************************************************************** */
832
-
833
- /** Returns a human readable string related to the HTTP status number. */
834
- fio_str_info_s http_status2str(uintptr_t status);
835
-
836
- /** Registers a Mime-Type to be associated with the file extension. */
837
- void http_mimetype_register(char *file_ext, size_t file_ext_len,
838
- FIOBJ mime_type_str);
839
-
840
- /**
841
- * Finds the mime-type associated with the file extension, returning a String on
842
- * success and FIOBJ_INVALID on failure.
843
- *
844
- * Remember to call `fiobj_free`.
845
- */
846
- FIOBJ http_mimetype_find(char *file_ext, size_t file_ext_len);
847
-
848
- /**
849
- * Returns the mime-type associated with the URL or the default mime-type for
850
- * HTTP.
851
- *
852
- * Remember to call `fiobj_free`.
853
- */
854
- FIOBJ http_mimetype_find2(FIOBJ url);
855
-
856
- /** Clears the Mime-Type registry (it will be empty after this call). */
857
- void http_mimetype_clear(void);
858
-
859
- /* *****************************************************************************
860
- Commonly used headers (fiobj Symbol objects)
861
- ***************************************************************************** */
862
-
863
- extern FIOBJ HTTP_HEADER_ACCEPT;
864
- extern FIOBJ HTTP_HEADER_CACHE_CONTROL;
865
- extern FIOBJ HTTP_HEADER_CONNECTION;
866
- extern FIOBJ HTTP_HEADER_CONTENT_ENCODING;
867
- extern FIOBJ HTTP_HEADER_CONTENT_LENGTH;
868
- extern FIOBJ HTTP_HEADER_CONTENT_RANGE;
869
- extern FIOBJ HTTP_HEADER_CONTENT_TYPE;
870
- extern FIOBJ HTTP_HEADER_COOKIE;
871
- extern FIOBJ HTTP_HEADER_DATE;
872
- extern FIOBJ HTTP_HEADER_ETAG;
873
- extern FIOBJ HTTP_HEADER_HOST;
874
- extern FIOBJ HTTP_HEADER_LAST_MODIFIED;
875
- extern FIOBJ HTTP_HEADER_ORIGIN;
876
- extern FIOBJ HTTP_HEADER_SET_COOKIE;
877
- extern FIOBJ HTTP_HEADER_UPGRADE;
878
-
879
- /* *****************************************************************************
880
- HTTP General Helper functions that could be used globally
881
- ***************************************************************************** */
882
-
883
- /**
884
- * Returns a String object representing the unparsed HTTP request (HTTP version
885
- * is capped at HTTP/1.1). Mostly usable for proxy usage and debugging.
886
- */
887
- FIOBJ http_req2str(http_s *h);
888
-
889
- /**
890
- * Writes a log line to `stderr` about the request / response object.
891
- *
892
- * This function is called automatically if the `.log` setting is enabled.
893
- */
894
- void http_write_log(http_s *h);
895
- /* *****************************************************************************
896
- HTTP Time related helper functions that could be used globally
897
- ***************************************************************************** */
898
-
899
- /**
900
- A faster (yet less localized) alternative to `gmtime_r`.
901
-
902
- See the libc `gmtime_r` documentation for details.
903
-
904
- Falls back to `gmtime_r` for dates before epoch.
905
- */
906
- struct tm *http_gmtime(time_t timer, struct tm *tmbuf);
907
-
908
- /** Writes an RFC 7231 date representation (HTTP date format) to target. */
909
- size_t http_date2rfc7231(char *target, struct tm *tmbuf);
910
- /** Writes an RFC 2109 date representation to target. */
911
- size_t http_date2rfc2109(char *target, struct tm *tmbuf);
912
- /** Writes an RFC 2822 date representation to target. */
913
- size_t http_date2rfc2822(char *target, struct tm *tmbuf);
914
- /**
915
- Writes an HTTP date string to the `target` buffer.
916
-
917
- This requires ~32 bytes of space to be available at the target buffer (unless
918
- it's a super funky year, 32 bytes is about 3 more than you need).
919
-
920
- Returns the number of bytes actually written.
921
- */
922
- static inline size_t http_date2str(char *target, struct tm *tmbuf) {
923
- return http_date2rfc7231(target, tmbuf);
924
- }
925
-
926
- /**
927
- * Prints Unix time to a HTTP time formatted string.
928
- *
929
- * This variation implements cached results for faster processing, at the
930
- * price of a less accurate string.
931
- */
932
- size_t http_time2str(char *target, const time_t t);
933
-
934
- /* *****************************************************************************
935
- HTTP URL decoding helper functions that might be used globally
936
- ***************************************************************************** */
937
-
938
- /** Decodes a URL encoded string, no buffer overflow protection. */
939
- ssize_t http_decode_url_unsafe(char *dest, const char *url_data);
940
-
941
- /** Decodes a URL encoded string (query / form data). */
942
- ssize_t http_decode_url(char *dest, const char *url_data, size_t length);
943
-
944
- /** Decodes the "path" part of a request, no buffer overflow protection. */
945
- ssize_t http_decode_path_unsafe(char *dest, const char *url_data);
946
-
947
- /**
948
- * Decodes the "path" part of an HTTP request, no buffer overflow protection.
949
- */
950
- ssize_t http_decode_path(char *dest, const char *url_data, size_t length);
951
-
952
- /* *****************************************************************************
953
- HTTP URL parsing
954
- ***************************************************************************** */
955
-
956
- /** the result returned by `http_url_parse` */
957
- typedef fio_url_s http_url_s
958
- __attribute__((deprecated("use fio_url_s instead")));
959
-
960
- /**
961
- * Parses the URI returning it's components and their lengths (no decoding
962
- * performed, doesn't accept decoded URIs).
963
- *
964
- * The returned string are NOT NUL terminated, they are merely locations within
965
- * the original string.
966
- *
967
- * This function expects any of the following formats:
968
- *
969
- * * `/complete_path?query#target`
970
- *
971
- * i.e.: /index.html?page=1#list
972
- *
973
- * * `host:port/complete_path?query#target`
974
- *
975
- * i.e.:
976
- * example.com
977
- * example.com/index.html
978
- * example.com:8080/index.html
979
- * example.com:8080/index.html?key=val#target
980
- *
981
- * * `user:password@host:port/path?query#target`
982
- *
983
- * i.e.: user:1234@example.com:8080/index.html
984
- *
985
- * * `schema://user:password@host:port/path?query#target`
986
- *
987
- * i.e.: http://example.com/index.html?page=1#list
988
- *
989
- * Invalid formats might produce unexpected results. No error testing performed.
990
- */
991
- #define http_url_parse(url, len) fio_url_parse((url), (len))
992
-
993
- #if DEBUG
994
- void http_tests(void);
995
- #endif
996
-
997
- /* support C++ */
998
- #ifdef __cplusplus
999
- }
1000
- #endif
1001
-
1002
- #endif /* H_HTTP_H */
1
+ #ifndef H_HTTP_H
2
+ /*
3
+ Copyright: Boaz Segev, 2016-2019
4
+ License: MIT
5
+
6
+ Feel free to copy, use and enjoy according to the license provided.
7
+ */
8
+ #define H_HTTP_H
9
+
10
+ #include <fio.h>
11
+
12
+ #include <fiobj.h>
13
+
14
+ #include <time.h>
15
+
16
+ /* support C++ */
17
+ #ifdef __cplusplus
18
+ extern "C" {
19
+ #endif
20
+
21
+ /* *****************************************************************************
22
+ Compile Time Settings
23
+ ***************************************************************************** */
24
+
25
+ /** When a new connection is accepted, it will be immediately declined with a
26
+ * 503 service unavailable (server busy) response unless the following number of
27
+ * file descriptors is available.*/
28
+ #ifndef HTTP_BUSY_UNLESS_HAS_FDS
29
+ #define HTTP_BUSY_UNLESS_HAS_FDS 64
30
+ #endif
31
+
32
+ #ifndef HTTP_DEFAULT_BODY_LIMIT
33
+ #define HTTP_DEFAULT_BODY_LIMIT (1024 * 1024 * 50)
34
+ #endif
35
+
36
+ #ifndef HTTP_MAX_HEADER_COUNT
37
+ #define HTTP_MAX_HEADER_COUNT 128
38
+ #endif
39
+
40
+ #ifndef HTTP_MAX_HEADER_LENGTH
41
+ /** the default maximum length for a single header line */
42
+ #define HTTP_MAX_HEADER_LENGTH 8192
43
+ #endif
44
+
45
+ #ifndef FIO_HTTP_EXACT_LOGGING
46
+ /**
47
+ * By default, facil.io logs the HTTP request cycle using a fuzzy starting point
48
+ * (a close enough timestamp).
49
+ *
50
+ * The fuzzy timestamp includes delays that aren't related to the HTTP request,
51
+ * sometimes including time that was spent waiting on the client. On the other
52
+ * hand, `FIO_HTTP_EXACT_LOGGING` excludes time that the client might have been
53
+ * waiting for facil.io to read data from the network.
54
+ *
55
+ * Due to the preference to err on the side of causion, fuzzy time-stamping is
56
+ * the default.
57
+ */
58
+ #define FIO_HTTP_EXACT_LOGGING 0
59
+ #endif
60
+
61
+ /** the `http_listen settings, see details in the struct definition. */
62
+ typedef struct http_settings_s http_settings_s;
63
+
64
+ /* *****************************************************************************
65
+ The Request / Response type and functions
66
+ ***************************************************************************** */
67
+
68
+ /**
69
+ * A generic HTTP handle used for HTTP request/response data.
70
+ *
71
+ * The `http_s` data can only be accessed safely from within the `on_request`
72
+ * HTTP callback OR an `http_defer` callback.
73
+ */
74
+ typedef struct {
75
+ /** the HTTP request's "head" starts with a private data used by facil.io */
76
+ struct {
77
+ /** the function touting table - used by facil.io, don't use directly! */
78
+ void *vtbl;
79
+ /** the connection's owner / uuid - used by facil.io, don't use directly! */
80
+ uintptr_t flag;
81
+ /** The response headers, if they weren't sent. Don't access directly. */
82
+ FIOBJ out_headers;
83
+ } private_data;
84
+ /** a time merker indicating when the request was received. */
85
+ struct timespec received_at;
86
+ /** a String containing the method data (supports non-standard methods. */
87
+ FIOBJ method;
88
+ /** The status string, for response objects (client mode response). */
89
+ FIOBJ status_str;
90
+ /** The HTTP version string, if any. */
91
+ FIOBJ version;
92
+ /** The status used for the response (or if the object is a response).
93
+ *
94
+ * When sending a request, the status should be set to 0.
95
+ */
96
+ uintptr_t status;
97
+ /** The request path, if any. */
98
+ FIOBJ path;
99
+ /** The request query, if any. */
100
+ FIOBJ query;
101
+ /** a hash of general header data. When a header is set multiple times (such
102
+ * as cookie headers), an Array will be used instead of a String. */
103
+ FIOBJ headers;
104
+ /**
105
+ * a placeholder for a hash of cookie data.
106
+ * the hash will be initialized when parsing the request.
107
+ */
108
+ FIOBJ cookies;
109
+ /**
110
+ * a placeholder for a hash of request data.
111
+ * the hash will be initialized when parsing the request.
112
+ */
113
+ FIOBJ params;
114
+ /**
115
+ * a reader for body data (might be a temporary file or a string or NULL).
116
+ * see fiobj_data.h for details.
117
+ */
118
+ FIOBJ body;
119
+ /** an opaque user data pointer, to be used BEFORE calling `http_defer`. */
120
+ void *udata;
121
+ } http_s;
122
+
123
+ /**
124
+ * This is a helper for setting cookie data.
125
+
126
+ This struct is used together with the `http_response_set_cookie`. i.e.:
127
+
128
+ http_response_set_cookie(response,
129
+ .name = "my_cookie",
130
+ .value = "data" );
131
+
132
+ */
133
+ typedef struct {
134
+ /** The cookie's name (Symbol). */
135
+ const char *name;
136
+ /** The cookie's value (leave blank to delete cookie). */
137
+ const char *value;
138
+ /** The cookie's domain (optional). */
139
+ const char *domain;
140
+ /** The cookie's path (optional). */
141
+ const char *path;
142
+ /** The cookie name's size in bytes or a terminating NUL will be assumed.*/
143
+ size_t name_len;
144
+ /** The cookie value's size in bytes or a terminating NUL will be assumed.*/
145
+ size_t value_len;
146
+ /** The cookie domain's size in bytes or a terminating NUL will be assumed.*/
147
+ size_t domain_len;
148
+ /** The cookie path's size in bytes or a terminating NULL will be assumed.*/
149
+ size_t path_len;
150
+ /** Max Age (how long should the cookie persist), in seconds (0 == session).*/
151
+ int max_age;
152
+ /** Limit cookie to secure connections.*/
153
+ unsigned secure : 1;
154
+ /** Limit cookie to HTTP (intended to prevent javascript access/hijacking).*/
155
+ unsigned http_only : 1;
156
+ } http_cookie_args_s;
157
+
158
+ /**
159
+ * Sets a response header, taking ownership of the value object, but NOT the
160
+ * name object (so name objects could be reused in future responses).
161
+ *
162
+ * Returns -1 on error and 0 on success.
163
+ */
164
+ int http_set_header(http_s *h, FIOBJ name, FIOBJ value);
165
+
166
+ /**
167
+ * Sets a response header.
168
+ *
169
+ * Returns -1 on error and 0 on success.
170
+ */
171
+ int http_set_header2(http_s *h, fio_str_info_s name, fio_str_info_s value);
172
+
173
+ /**
174
+ * Sets a response cookie.
175
+ *
176
+ * Returns -1 on error and 0 on success.
177
+ *
178
+ * Note: Long cookie names and long cookie values will be considered a security
179
+ * violation and an error will be returned. It should be noted that most
180
+ * proxies and servers will refuse long cookie names or values and many impose
181
+ * total header lengths (including cookies) of ~8Kib.
182
+ */
183
+ int http_set_cookie(http_s *h, http_cookie_args_s);
184
+ #define http_set_cookie(http___handle, ...) \
185
+ http_set_cookie((http___handle), (http_cookie_args_s){__VA_ARGS__})
186
+
187
+ /**
188
+ * Sends the response headers and body.
189
+ *
190
+ * **Note**: The body is *copied* to the HTTP stream and it's memory should be
191
+ * freed by the calling function.
192
+ *
193
+ * Returns -1 on error and 0 on success.
194
+ *
195
+ * AFTER THIS FUNCTION IS CALLED, THE `http_s` OBJECT IS NO LONGER VALID.
196
+ */
197
+ int http_send_body(http_s *h, void *data, uintptr_t length);
198
+
199
+ /**
200
+ * Sends the response headers and the specified file (the response's body).
201
+ *
202
+ * The file is closed automatically.
203
+ *
204
+ * Returns -1 on error and 0 on success.
205
+ *
206
+ * AFTER THIS FUNCTION IS CALLED, THE `http_s` OBJECT IS NO LONGER VALID.
207
+ */
208
+ int http_sendfile(http_s *h, int fd, uintptr_t length, uintptr_t offset);
209
+
210
+ /**
211
+ * Sends the response headers and the specified file (the response's body).
212
+ *
213
+ * The `local` and `encoded` strings will be joined into a single string that
214
+ * represent the file name. Either or both of these strings can be empty.
215
+ *
216
+ * The `encoded` string will be URL decoded while the `local` string will used
217
+ * as is.
218
+ *
219
+ * Returns 0 on success. A success value WILL CONSUME the `http_s` handle (it
220
+ * will become invalid).
221
+ *
222
+ * Returns -1 on error (The `http_s` handle should still be used).
223
+ */
224
+ int http_sendfile2(http_s *h, const char *prefix, size_t prefix_len,
225
+ const char *encoded, size_t encoded_len);
226
+
227
+ /**
228
+ * Sends an HTTP error response.
229
+ *
230
+ * Returns -1 on error and 0 on success.
231
+ *
232
+ * AFTER THIS FUNCTION IS CALLED, THE `http_s` OBJECT IS NO LONGER VALID.
233
+ *
234
+ * The `uuid` and `settings` arguments are only required if the `http_s` handle
235
+ * is NULL.
236
+ */
237
+ int http_send_error(http_s *h, size_t error_code);
238
+
239
+ /**
240
+ * Sends the response headers for a header only response.
241
+ *
242
+ * AFTER THIS FUNCTION IS CALLED, THE `http_s` OBJECT IS NO LONGER VALID.
243
+ */
244
+ void http_finish(http_s *h);
245
+
246
+ /**
247
+ * Pushes a data response when supported (HTTP/2 only).
248
+ *
249
+ * Returns -1 on error and 0 on success.
250
+ */
251
+ int http_push_data(http_s *h, void *data, uintptr_t length, FIOBJ mime_type);
252
+
253
+ /**
254
+ * Pushes a file response when supported (HTTP/2 only).
255
+ *
256
+ * If `mime_type` is NULL, an attempt at automatic detection using `filename`
257
+ * will be made.
258
+ *
259
+ * Returns -1 on error and 0 on success.
260
+ */
261
+ int http_push_file(http_s *h, FIOBJ filename, FIOBJ mime_type);
262
+
263
+ /* *****************************************************************************
264
+ HTTP evented API (pause / resume HTTp handling)
265
+ ***************************************************************************** */
266
+
267
+ typedef struct http_pause_handle_s http_pause_handle_s;
268
+ /**
269
+ * Pauses the request / response handling and INVALIDATES the current `http_s`
270
+ * handle (no `http` functions can be called).
271
+ *
272
+ * The `http_resume` function MUST be called (at some point) using the opaque
273
+ * `http` pointer given to the callback `task`.
274
+ *
275
+ * The opaque `http` pointer is only valid for a single call to `http_resume`
276
+ * and can't be used by any other `http` function (it's a different data type).
277
+ *
278
+ * Note: the current `http_s` handle will become invalid once this function is
279
+ * called and it's data might be deallocated, invalid or used by a different
280
+ * thread.
281
+ */
282
+ void http_pause(http_s *h, void (*task)(http_pause_handle_s *http));
283
+
284
+ /**
285
+ * Resumes a request / response handling within a task and INVALIDATES the
286
+ * current `http_s` handle.
287
+ *
288
+ * The `task` MUST call one of the `http_send_*`, `http_finish`, or
289
+ * `http_pause`functions.
290
+ *
291
+ * The (optional) `fallback` will receive the opaque `udata` that was stored in
292
+ * the HTTP handle and can be used for cleanup.
293
+ *
294
+ * Note: `http_resume` can only be called after calling `http_pause` and
295
+ * entering it's task.
296
+ *
297
+ * Note: the current `http_s` handle will become invalid once this function is
298
+ * called and it's data might be deallocated, invalidated or used by a
299
+ * different thread.
300
+ */
301
+ void http_resume(http_pause_handle_s *http, void (*task)(http_s *h),
302
+ void (*fallback)(void *udata));
303
+
304
+ /** Returns the `udata` associated with the paused opaque handle */
305
+ void *http_paused_udata_get(http_pause_handle_s *http);
306
+
307
+ /**
308
+ * Sets the `udata` associated with the paused opaque handle, returning the
309
+ * old value.
310
+ */
311
+ void *http_paused_udata_set(http_pause_handle_s *http, void *udata);
312
+
313
+ /* *****************************************************************************
314
+ HTTP Connections - Listening / Connecting / Hijacking
315
+ ***************************************************************************** */
316
+
317
+ /** The HTTP settings. */
318
+ struct http_settings_s {
319
+ /** Callback for normal HTTP requests. */
320
+ void (*on_request)(http_s *request);
321
+ /**
322
+ * Callback for Upgrade and EventSource (SSE) requests.
323
+ *
324
+ * SSE/EventSource requests set the `requested_protocol` string to `"sse"`.
325
+ */
326
+ void (*on_upgrade)(http_s *request, char *requested_protocol, size_t len);
327
+ /** CLIENT REQUIRED: a callback for the HTTP response. */
328
+ void (*on_response)(http_s *response);
329
+ /** (optional) the callback to be performed when the HTTP service closes. */
330
+ void (*on_finish)(struct http_settings_s *settings);
331
+ /** Opaque user data. Facil.io will ignore this field, but you can use it. */
332
+ void *udata;
333
+ /**
334
+ * A public folder for file transfers - allows to circumvent any application
335
+ * layer logic and simply serve static files.
336
+ *
337
+ * Supports automatic `gz` pre-compressed alternatives.
338
+ */
339
+ const char *public_folder;
340
+ /**
341
+ * The length of the public_folder string.
342
+ */
343
+ size_t public_folder_length;
344
+ /**
345
+ * The maximum number of bytes allowed for the request string (method, path,
346
+ * query), header names and fields.
347
+ *
348
+ * Defaults to 32Kib (which is about 4 times more than I would recommend).
349
+ *
350
+ * This reflects the total overall size. On HTTP/1.1, each header line (name +
351
+ * value pair) is also limitied to a hardcoded HTTP_MAX_HEADER_LENGTH bytes.
352
+ */
353
+ size_t max_header_size;
354
+ /**
355
+ * The maximum size of an HTTP request's body (posting / downloading).
356
+ *
357
+ * Defaults to ~ 50Mb.
358
+ */
359
+ size_t max_body_size;
360
+ /**
361
+ * The maximum number of clients that are allowed to connect concurrently.
362
+ *
363
+ * This value's default setting is usually for the best.
364
+ *
365
+ * The default value is computed according to the server's capacity, leaving
366
+ * some breathing room for other network and disk operations.
367
+ *
368
+ * Note: clients, by the nature of socket programming, are counted according
369
+ * to their internal file descriptor (`fd`) value. Open files and other
370
+ * sockets count towards a server's limit.
371
+ */
372
+ intptr_t max_clients;
373
+ /** SSL/TLS support. */
374
+ void *tls;
375
+ /** reserved for future use. */
376
+ intptr_t reserved1;
377
+ /** reserved for future use. */
378
+ intptr_t reserved2;
379
+ /** reserved for future use. */
380
+ intptr_t reserved3;
381
+ /**
382
+ * The maximum websocket message size/buffer (in bytes) for Websocket
383
+ * connections. Defaults to ~250KB.
384
+ */
385
+ size_t ws_max_msg_size;
386
+ /**
387
+ * An HTTP/1.x connection timeout.
388
+ *
389
+ * `http_listen` defaults to ~40s and `http_connect` defaults to ~30s.
390
+ *
391
+ * Note: the connection might be closed (by other side) before timeout occurs.
392
+ */
393
+ uint8_t timeout;
394
+ /**
395
+ * Timeout for the websocket connections, a ping will be sent whenever the
396
+ * timeout is reached. Defaults to 40 seconds.
397
+ *
398
+ * Connections are only closed when a ping cannot be sent (the network layer
399
+ * fails). Pongs are ignored.
400
+ */
401
+ uint8_t ws_timeout;
402
+ /** Logging flag - set to TRUE to log HTTP requests. */
403
+ uint8_t log;
404
+ /** a read only flag set automatically to indicate the protocol's mode. */
405
+ uint8_t is_client;
406
+ };
407
+
408
+ /**
409
+ * Listens to HTTP connections at the specified `port`.
410
+ *
411
+ * Leave as NULL to ignore IP binding.
412
+ *
413
+ * Returns -1 on error and the socket's uuid on success.
414
+ *
415
+ * the `on_finish` callback is always called.
416
+ */
417
+ intptr_t http_listen(const char *port, const char *binding,
418
+ struct http_settings_s);
419
+ /** Listens to HTTP connections at the specified `port` and `binding`. */
420
+ #define http_listen(port, binding, ...) \
421
+ http_listen((port), (binding), (struct http_settings_s){__VA_ARGS__})
422
+
423
+ /**
424
+ * Connects to an HTTP server as a client.
425
+ *
426
+ * Upon a successful connection, the `on_response` callback is called with an
427
+ * empty `http_s*` handler (status == 0). Use the same API to set it's content
428
+ * and send the request to the server. The next`on_response` will contain the
429
+ * response.
430
+ *
431
+ * `address` should contain a full URL style address for the server. i.e.:
432
+ *
433
+ * "http:/www.example.com:8080/"
434
+ *
435
+ * If an `address` includes a path or query data, they will be automatically
436
+ * attached (both of them) to the HTTP handl'es `path` property. i.e.
437
+ *
438
+ * "http:/www.example.com:8080/my_path?foo=bar"
439
+ * // will result in:
440
+ * fiobj_obj2cstr(h->path).data; //=> "/my_path?foo=bar"
441
+ *
442
+ * To open a Websocket connection, it's possible to use the `ws` protocol
443
+ * signature. However, it would be better to use the `websocket_connect`
444
+ * function instead.
445
+ *
446
+ * Returns -1 on error and the socket's uuid on success.
447
+ *
448
+ * The `on_finish` callback is always called.
449
+ */
450
+ intptr_t http_connect(const char *url, const char *unix_address,
451
+ struct http_settings_s);
452
+ #define http_connect(url, unix_address, ...) \
453
+ http_connect((url), (unix_address), (struct http_settings_s){__VA_ARGS__})
454
+
455
+ /**
456
+ * Returns the settings used to setup the connection or NULL on error.
457
+ */
458
+ struct http_settings_s *http_settings(http_s *h);
459
+
460
+ /**
461
+ * Returns the direct address of the connected peer (likely an intermediary).
462
+ */
463
+ fio_str_info_s http_peer_addr(http_s *h);
464
+
465
+ /**
466
+ * Hijacks the socket away from the HTTP protocol and away from facil.io.
467
+ *
468
+ * It's possible to hijack the socket and than reconnect it to a new protocol
469
+ * object.
470
+ *
471
+ * It's possible to call `http_finish` immediately after calling `http_hijack`
472
+ * in order to send the outgoing headers.
473
+ *
474
+ * If any additional HTTP functions are called after the hijacking, the protocol
475
+ * object might attempt to continue reading data from the buffer.
476
+ *
477
+ * Returns the underlining socket connection's uuid. If `leftover` isn't NULL,
478
+ * it will be populated with any remaining data in the HTTP buffer (the data
479
+ * will be automatically deallocated, so copy the data when in need).
480
+ *
481
+ * WARNING: this isn't a good way to handle HTTP connections, especially as
482
+ * HTTP/2 enters the picture.
483
+ */
484
+ intptr_t http_hijack(http_s *h, fio_str_info_s *leftover);
485
+
486
+ /* *****************************************************************************
487
+ Websocket Upgrade (Server and Client connection establishment)
488
+ ***************************************************************************** */
489
+
490
+ /**
491
+ * The type for a Websocket handle, used to identify a Websocket connection.
492
+ *
493
+ * Similar to an `http_s` handle, it is only valid within the scope of the
494
+ * specific connection (the callbacks / tasks) and shouldn't be stored or
495
+ * accessed otherwise.
496
+ */
497
+ typedef struct ws_s ws_s;
498
+
499
+ /**
500
+ * This struct is used for the named arguments in the `http_upgrade2ws`
501
+ * function and macro.
502
+ */
503
+ typedef struct {
504
+ /**
505
+ * The (optional) on_message callback will be called whenever a websocket
506
+ * message is received for this connection.
507
+ *
508
+ * The data received points to the websocket's message buffer and it will be
509
+ * overwritten once the function exits (it cannot be saved for later, but it
510
+ * can be copied).
511
+ */
512
+ void (*on_message)(ws_s *ws, fio_str_info_s msg, uint8_t is_text);
513
+ /**
514
+ * The (optional) on_open callback will be called once the websocket
515
+ * connection is established and before is is registered with `facil`, so no
516
+ * `on_message` events are raised before `on_open` returns.
517
+ */
518
+ void (*on_open)(ws_s *ws);
519
+ /**
520
+ * The (optional) on_ready callback will be after a the underlying socket's
521
+ * buffer changes it's state from full to empty.
522
+ *
523
+ * If the socket's buffer is never used, the callback is never called.
524
+ */
525
+ void (*on_ready)(ws_s *ws);
526
+ /**
527
+ * The (optional) on_shutdown callback will be called if a websocket
528
+ * connection is still open while the server is shutting down (called before
529
+ * `on_close`).
530
+ */
531
+ void (*on_shutdown)(ws_s *ws);
532
+ /**
533
+ * The (optional) on_close callback will be called once a websocket connection
534
+ * is terminated or failed to be established.
535
+ *
536
+ * The `uuid` is the connection's unique ID that can identify the Websocket. A
537
+ * value of `uuid == 0` indicates the Websocket connection wasn't established
538
+ * (an error occurred).
539
+ *
540
+ * The `udata` is the user data as set during the upgrade or using the
541
+ * `websocket_udata_set` function.
542
+ */
543
+ void (*on_close)(intptr_t uuid, void *udata);
544
+ /** Opaque user data. */
545
+ void *udata;
546
+ } websocket_settings_s;
547
+
548
+ /**
549
+ * Upgrades an HTTP/1.1 connection to a Websocket connection.
550
+ *
551
+ * This function will end the HTTP stage of the connection and attempt to
552
+ * "upgrade" to a Websockets connection.
553
+ *
554
+ * Thie `http_s` handle will be invalid after this call and the `udata` will be
555
+ * set to the new Websocket `udata`.
556
+ *
557
+ * A client connection's `on_finish` callback will be called (since the HTTP
558
+ * stage has finished).
559
+ */
560
+ int http_upgrade2ws(http_s *http, websocket_settings_s);
561
+
562
+ /** This macro allows easy access to the `http_upgrade2ws` function. The macro
563
+ * allows the use of named arguments, using the `websocket_settings_s` struct
564
+ * members. i.e.:
565
+ *
566
+ * on_message(ws_s * ws, char * data, size_t size, int is_text) {
567
+ * ; // ... this is the websocket on_message callback
568
+ * websocket_write(ws, data, size, is_text); // a simple echo example
569
+ * }
570
+ *
571
+ * on_upgrade(http_s* h) {
572
+ * http_upgrade2ws( .http = h, .on_message = on_message);
573
+ * }
574
+ */
575
+ #define http_upgrade2ws(http, ...) \
576
+ http_upgrade2ws((http), (websocket_settings_s){__VA_ARGS__})
577
+
578
+ /**
579
+ * Connects to a Websocket service according to the provided address.
580
+ *
581
+ * This is a somewhat naive connector object, it doesn't perform any
582
+ * authentication or other logical handling. However, it's quire easy to author
583
+ * a complext authentication logic using a combination of `http_connect` and
584
+ * `http_upgrade2ws`.
585
+ *
586
+ * Returns the uuid for the future websocket on success.
587
+ *
588
+ * Returns -1 on error;
589
+ */
590
+ int websocket_connect(const char *url, websocket_settings_s settings);
591
+ #define websocket_connect(url, ...) \
592
+ websocket_connect((url), (websocket_settings_s){__VA_ARGS__})
593
+
594
+ #include <websockets.h>
595
+
596
+ /* *****************************************************************************
597
+ EventSource Support (SSE)
598
+ ***************************************************************************** */
599
+
600
+ /**
601
+ * The type for the EventSource (SSE) handle, used to identify an SSE
602
+ * connection.
603
+ */
604
+ typedef struct http_sse_s http_sse_s;
605
+
606
+ /**
607
+ * This struct is used for the named arguments in the `http_upgrade2sse`
608
+ * function and macro.
609
+ */
610
+ struct http_sse_s {
611
+ /**
612
+ * The (optional) on_open callback will be called once the EventSource
613
+ * connection is established.
614
+ */
615
+ void (*on_open)(http_sse_s *sse);
616
+ /**
617
+ * The (optional) on_ready callback will be after a the underlying socket's
618
+ * buffer changes it's state to empty.
619
+ *
620
+ * If the socket's buffer is never used, the callback is never called.
621
+ */
622
+ void (*on_ready)(http_sse_s *sse);
623
+ /**
624
+ * The (optional) on_shutdown callback will be called if a connection is still
625
+ * open while the server is shutting down (called before `on_close`).
626
+ */
627
+ void (*on_shutdown)(http_sse_s *sse);
628
+ /**
629
+ * The (optional) on_close callback will be called once a connection is
630
+ * terminated or failed to be established.
631
+ *
632
+ * The `udata` passed to the `http_upgrade2sse` function is available
633
+ * through the `http_sse_s` pointer (`sse->udata`).
634
+ */
635
+ void (*on_close)(http_sse_s *sse);
636
+ /** Opaque user data. */
637
+ void *udata;
638
+ };
639
+
640
+ /**
641
+ * Upgrades an HTTP connection to an EventSource (SSE) connection.
642
+ *
643
+ * The `http_s` handle will be invalid after this call.
644
+ *
645
+ * On HTTP/1.1 connections, this will preclude future requests using the same
646
+ * connection.
647
+ */
648
+ int http_upgrade2sse(http_s *h, http_sse_s);
649
+
650
+ /** This macro allows easy access to the `http_upgrade2sse` function. The macro
651
+ * allows the use of named arguments, using the `websocket_settings_s` struct
652
+ * members. i.e.:
653
+ *
654
+ * on_open_sse(sse_s * sse) {
655
+ * http_sse_subscribe(sse, .channel = CHANNEL_NAME);
656
+ * }
657
+ *
658
+ * on_upgrade(http_s* h) {
659
+ * http_upgrade2sse(h, .on_open = on_open_sse);
660
+ * }
661
+ */
662
+ #define http_upgrade2sse(h, ...) \
663
+ http_upgrade2sse((h), (http_sse_s){__VA_ARGS__})
664
+
665
+ /**
666
+ * Sets the ping interval for SSE connections.
667
+ */
668
+ void http_sse_set_timout(http_sse_s *sse, uint8_t timeout);
669
+
670
+ struct http_sse_subscribe_args {
671
+ /** The channel name used for the subscription. */
672
+ fio_str_info_s channel;
673
+ /** The optional on message callback. If missing, Data is directly writen. */
674
+ void (*on_message)(http_sse_s *sse, fio_str_info_s channel,
675
+ fio_str_info_s msg, void *udata);
676
+ /** An optional callback for when a subscription is fully canceled. */
677
+ void (*on_unsubscribe)(void *udata);
678
+ /** Opaque user */
679
+ void *udata;
680
+ /** A callback for pattern matching. */
681
+ fio_match_fn match;
682
+ };
683
+
684
+ /**
685
+ * Subscribes to a channel for direct message deliverance. See {struct
686
+ * http_sse_subscribe_args} for possible arguments.
687
+ *
688
+ * Returns a subscription ID on success and 0 on failure.
689
+ *
690
+ * To unsubscripbe from the channel, use `http_sse_unsubscribe` (NOT
691
+ * `fio_unsubscribe`).
692
+ *
693
+ * All subscriptions are automatically cleared once the connection is closed.
694
+ */
695
+ uintptr_t http_sse_subscribe(http_sse_s *sse,
696
+ struct http_sse_subscribe_args args);
697
+
698
+ /** This macro allows easy access to the `http_sse_subscribe` function. */
699
+ #define http_sse_subscribe(sse, ...) \
700
+ http_sse_subscribe((sse), (struct http_sse_subscribe_args){__VA_ARGS__})
701
+
702
+ /**
703
+ * Cancels a subscription and invalidates the subscription object.
704
+ */
705
+ void http_sse_unsubscribe(http_sse_s *sse, uintptr_t subscription);
706
+
707
+ /**
708
+ * Named arguments for the {http_sse_write} function.
709
+ *
710
+ * These arguments list the possible fields for the SSE event.
711
+ *
712
+ * Event fields listed here:
713
+ * https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events
714
+ */
715
+ struct http_sse_write_args {
716
+ fio_str_info_s id; /* (optional) sets the `id` event property. */
717
+ fio_str_info_s event; /* (optional) sets the `event` event property. */
718
+ fio_str_info_s data; /* (optional) sets the `data` event property. */
719
+ intptr_t retry; /* (optional) sets the `retry` event property. */
720
+ };
721
+
722
+ /**
723
+ * Writes data to an EventSource (SSE) connection.
724
+ *
725
+ * See the {struct http_sse_write_args} for possible named arguments.
726
+ */
727
+ int http_sse_write(http_sse_s *sse, struct http_sse_write_args);
728
+ #define http_sse_write(sse, ...) \
729
+ http_sse_write((sse), (struct http_sse_write_args){__VA_ARGS__})
730
+
731
+ /**
732
+ * Get the connection's UUID (for `fio_defer_io_task`, pub/sub, etc').
733
+ */
734
+ intptr_t http_sse2uuid(http_sse_s *sse);
735
+
736
+ /**
737
+ * Closes an EventSource (SSE) connection.
738
+ */
739
+ int http_sse_close(http_sse_s *sse);
740
+
741
+ /**
742
+ * Duplicates an SSE handle by reference, remember to http_sse_free.
743
+ *
744
+ * Returns the same object (increases a reference count, no allocation is made).
745
+ */
746
+ http_sse_s *http_sse_dup(http_sse_s *sse);
747
+
748
+ /**
749
+ * Frees an SSE handle by reference (decreases the reference count).
750
+ */
751
+ void http_sse_free(http_sse_s *sse);
752
+
753
+ /* *****************************************************************************
754
+ HTTP GET and POST parsing helpers
755
+ ***************************************************************************** */
756
+
757
+ /**
758
+ * Attempts to decode the request's body.
759
+ *
760
+ * Supported Types include:
761
+ * * application/x-www-form-urlencoded
762
+ * * application/json
763
+ * * multipart/form-data
764
+ *
765
+ * This should be called before `http_parse_query`, in order to support JSON
766
+ * data.
767
+ *
768
+ * If the JSON data isn't an object, it will be saved under the key "JSON" in
769
+ * the `params` hash.
770
+ *
771
+ * If the `multipart/form-data` type contains JSON files, they will NOT be
772
+ * parsed (they will behave like any other file, with `data`, `type` and
773
+ * `filename` keys assigned). This allows non-object JSON data (such as array)
774
+ * to be handled by the app.
775
+ */
776
+ int http_parse_body(http_s *h);
777
+
778
+ /**
779
+ * Parses the query part of an HTTP request/response. Uses `http_add2hash`.
780
+ *
781
+ * This should be called after the `http_parse_body` function, just in case the
782
+ * body is JSON that doesn't have an object at it's root.
783
+ */
784
+ void http_parse_query(http_s *h);
785
+
786
+ /** Parses any Cookie / Set-Cookie headers, using the `http_add2hash` scheme. */
787
+ void http_parse_cookies(http_s *h, uint8_t is_url_encoded);
788
+
789
+ /**
790
+ * Adds a named parameter to the hash, converting a string to an object and
791
+ * resolving nesting references and URL decoding if required.
792
+ *
793
+ * i.e.:
794
+ *
795
+ * * "name[]" references a nested Array (nested in the Hash).
796
+ * * "name[key]" references a nested Hash.
797
+ * * "name[][key]" references a nested Hash within an array. Hash keys will be
798
+ * unique (repeating a key advances the hash).
799
+ * * These rules can be nested (i.e. "name[][key1][][key2]...")
800
+ * * "name[][]" is an error (there's no way for the parser to analyze
801
+ * dimensions)
802
+ *
803
+ * Note: names can't begin with "[" or end with "]" as these are reserved
804
+ * characters.
805
+ */
806
+ int http_add2hash(FIOBJ dest, char *name, size_t name_len, char *value,
807
+ size_t value_len, uint8_t encoded);
808
+
809
+ /**
810
+ * Adds a named parameter to the hash, using an existing object and resolving
811
+ * nesting references.
812
+ *
813
+ * i.e.:
814
+ *
815
+ * * "name[]" references a nested Array (nested in the Hash).
816
+ * * "name[key]" references a nested Hash.
817
+ * * "name[][key]" references a nested Hash within an array. Hash keys will be
818
+ * unique (repeating a key advances the array).
819
+ * * These rules can be nested (i.e. "name[][key1][][key2]...")
820
+ * * "name[][]" is an error (there's no way for the parser to analyze
821
+ * dimensions)
822
+ *
823
+ * Note: names can't begin with "[" or end with "]" as these are reserved
824
+ * characters.
825
+ */
826
+ int http_add2hash2(FIOBJ dest, char *name, size_t name_len, FIOBJ value,
827
+ uint8_t encoded);
828
+
829
+ /* *****************************************************************************
830
+ HTTP Status Strings and Mime-Type helpers
831
+ ***************************************************************************** */
832
+
833
+ /** Returns a human readable string related to the HTTP status number. */
834
+ fio_str_info_s http_status2str(uintptr_t status);
835
+
836
+ /** Registers a Mime-Type to be associated with the file extension. */
837
+ void http_mimetype_register(char *file_ext, size_t file_ext_len,
838
+ FIOBJ mime_type_str);
839
+
840
+ /**
841
+ * Finds the mime-type associated with the file extension, returning a String on
842
+ * success and FIOBJ_INVALID on failure.
843
+ *
844
+ * Remember to call `fiobj_free`.
845
+ */
846
+ FIOBJ http_mimetype_find(char *file_ext, size_t file_ext_len);
847
+
848
+ /**
849
+ * Returns the mime-type associated with the URL or the default mime-type for
850
+ * HTTP.
851
+ *
852
+ * Remember to call `fiobj_free`.
853
+ */
854
+ FIOBJ http_mimetype_find2(FIOBJ url);
855
+
856
+ /** Clears the Mime-Type registry (it will be empty after this call). */
857
+ void http_mimetype_clear(void);
858
+
859
+ /* *****************************************************************************
860
+ Commonly used headers (fiobj Symbol objects)
861
+ ***************************************************************************** */
862
+
863
+ extern FIOBJ HTTP_HEADER_ACCEPT;
864
+ extern FIOBJ HTTP_HEADER_CACHE_CONTROL;
865
+ extern FIOBJ HTTP_HEADER_CONNECTION;
866
+ extern FIOBJ HTTP_HEADER_CONTENT_ENCODING;
867
+ extern FIOBJ HTTP_HEADER_CONTENT_LENGTH;
868
+ extern FIOBJ HTTP_HEADER_CONTENT_RANGE;
869
+ extern FIOBJ HTTP_HEADER_CONTENT_TYPE;
870
+ extern FIOBJ HTTP_HEADER_COOKIE;
871
+ extern FIOBJ HTTP_HEADER_DATE;
872
+ extern FIOBJ HTTP_HEADER_ETAG;
873
+ extern FIOBJ HTTP_HEADER_HOST;
874
+ extern FIOBJ HTTP_HEADER_LAST_MODIFIED;
875
+ extern FIOBJ HTTP_HEADER_ORIGIN;
876
+ extern FIOBJ HTTP_HEADER_SET_COOKIE;
877
+ extern FIOBJ HTTP_HEADER_UPGRADE;
878
+
879
+ /* *****************************************************************************
880
+ HTTP General Helper functions that could be used globally
881
+ ***************************************************************************** */
882
+
883
+ /**
884
+ * Returns a String object representing the unparsed HTTP request (HTTP version
885
+ * is capped at HTTP/1.1). Mostly usable for proxy usage and debugging.
886
+ */
887
+ FIOBJ http_req2str(http_s *h);
888
+
889
+ /**
890
+ * Writes a log line to `stderr` about the request / response object.
891
+ *
892
+ * This function is called automatically if the `.log` setting is enabled.
893
+ */
894
+ void http_write_log(http_s *h);
895
+ /* *****************************************************************************
896
+ HTTP Time related helper functions that could be used globally
897
+ ***************************************************************************** */
898
+
899
+ /**
900
+ A faster (yet less localized) alternative to `gmtime_r`.
901
+
902
+ See the libc `gmtime_r` documentation for details.
903
+
904
+ Falls back to `gmtime_r` for dates before epoch.
905
+ */
906
+ struct tm *http_gmtime(time_t timer, struct tm *tmbuf);
907
+
908
+ /** Writes an RFC 7231 date representation (HTTP date format) to target. */
909
+ size_t http_date2rfc7231(char *target, struct tm *tmbuf);
910
+ /** Writes an RFC 2109 date representation to target. */
911
+ size_t http_date2rfc2109(char *target, struct tm *tmbuf);
912
+ /** Writes an RFC 2822 date representation to target. */
913
+ size_t http_date2rfc2822(char *target, struct tm *tmbuf);
914
+ /**
915
+ Writes an HTTP date string to the `target` buffer.
916
+
917
+ This requires ~32 bytes of space to be available at the target buffer (unless
918
+ it's a super funky year, 32 bytes is about 3 more than you need).
919
+
920
+ Returns the number of bytes actually written.
921
+ */
922
+ static inline size_t http_date2str(char *target, struct tm *tmbuf) {
923
+ return http_date2rfc7231(target, tmbuf);
924
+ }
925
+
926
+ /**
927
+ * Prints Unix time to a HTTP time formatted string.
928
+ *
929
+ * This variation implements cached results for faster processing, at the
930
+ * price of a less accurate string.
931
+ */
932
+ size_t http_time2str(char *target, const time_t t);
933
+
934
+ /* *****************************************************************************
935
+ HTTP URL decoding helper functions that might be used globally
936
+ ***************************************************************************** */
937
+
938
+ /** Decodes a URL encoded string, no buffer overflow protection. */
939
+ ssize_t http_decode_url_unsafe(char *dest, const char *url_data);
940
+
941
+ /** Decodes a URL encoded string (query / form data). */
942
+ ssize_t http_decode_url(char *dest, const char *url_data, size_t length);
943
+
944
+ /** Decodes the "path" part of a request, no buffer overflow protection. */
945
+ ssize_t http_decode_path_unsafe(char *dest, const char *url_data);
946
+
947
+ /**
948
+ * Decodes the "path" part of an HTTP request, no buffer overflow protection.
949
+ */
950
+ ssize_t http_decode_path(char *dest, const char *url_data, size_t length);
951
+
952
+ /* *****************************************************************************
953
+ HTTP URL parsing
954
+ ***************************************************************************** */
955
+
956
+ /** the result returned by `http_url_parse` */
957
+ typedef fio_url_s http_url_s
958
+ __attribute__((deprecated("use fio_url_s instead")));
959
+
960
+ /**
961
+ * Parses the URI returning it's components and their lengths (no decoding
962
+ * performed, doesn't accept decoded URIs).
963
+ *
964
+ * The returned string are NOT NUL terminated, they are merely locations within
965
+ * the original string.
966
+ *
967
+ * This function expects any of the following formats:
968
+ *
969
+ * * `/complete_path?query#target`
970
+ *
971
+ * i.e.: /index.html?page=1#list
972
+ *
973
+ * * `host:port/complete_path?query#target`
974
+ *
975
+ * i.e.:
976
+ * example.com
977
+ * example.com/index.html
978
+ * example.com:8080/index.html
979
+ * example.com:8080/index.html?key=val#target
980
+ *
981
+ * * `user:password@host:port/path?query#target`
982
+ *
983
+ * i.e.: user:1234@example.com:8080/index.html
984
+ *
985
+ * * `schema://user:password@host:port/path?query#target`
986
+ *
987
+ * i.e.: http://example.com/index.html?page=1#list
988
+ *
989
+ * Invalid formats might produce unexpected results. No error testing performed.
990
+ */
991
+ #define http_url_parse(url, len) fio_url_parse((url), (len))
992
+
993
+ #if DEBUG
994
+ void http_tests(void);
995
+ #endif
996
+
997
+ /* support C++ */
998
+ #ifdef __cplusplus
999
+ }
1000
+ #endif
1001
+
1002
+ #endif /* H_HTTP_H */