iodine 0.7.60 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (160) hide show
  1. checksums.yaml +4 -4
  2. data/.clang-format +15 -0
  3. data/.rspec +1 -0
  4. data/.yardopts +1 -3
  5. data/CHANGELOG.md +132 -12
  6. data/Gemfile +5 -7
  7. data/LICENSE.txt +1 -1
  8. data/README.md +147 -671
  9. data/Rakefile +9 -16
  10. data/examples/chatroom.nru +9 -0
  11. data/examples/client +74 -0
  12. data/examples/config-hello.nru +9 -0
  13. data/examples/config-hello.ru +11 -0
  14. data/examples/config-hijack.ru +13 -0
  15. data/examples/config-shootout.ru +43 -0
  16. data/examples/config.nru +120 -0
  17. data/examples/config.rb +37 -0
  18. data/examples/config.ru +42 -53
  19. data/examples/fake +24 -0
  20. data/examples/hello_neorack +137 -0
  21. data/examples/routes.nru +29 -0
  22. data/examples/routes.ru +42 -0
  23. data/exe/iodine +218 -258
  24. data/ext/iodine/extconf.rb +27 -100
  25. data/ext/iodine/fio-stl.h +128336 -0
  26. data/ext/iodine/fio-stl.md +26396 -0
  27. data/ext/iodine/iodine.c +213 -1393
  28. data/ext/iodine/iodine.h +250 -55
  29. data/ext/iodine/iodine_arg_helper.h +329 -0
  30. data/ext/iodine/iodine_caller.h +234 -25
  31. data/ext/iodine/iodine_cli.h +434 -0
  32. data/ext/iodine/iodine_compression.h +312 -0
  33. data/ext/iodine/iodine_connection.h +3484 -34
  34. data/ext/iodine/iodine_core.h +363 -0
  35. data/ext/iodine/iodine_crypto.h +1441 -0
  36. data/ext/iodine/iodine_defer.h +225 -4
  37. data/ext/iodine/iodine_json.h +738 -4
  38. data/ext/iodine/iodine_listener.h +263 -0
  39. data/ext/iodine/iodine_log.h +297 -0
  40. data/ext/iodine/iodine_minimap.h +543 -0
  41. data/ext/iodine/iodine_mustache.h +461 -4
  42. data/ext/iodine/iodine_pubsub_eng.h +729 -0
  43. data/ext/iodine/iodine_pubsub_history.h +547 -0
  44. data/ext/iodine/iodine_pubsub_msg.h +228 -0
  45. data/ext/iodine/iodine_redis.h +322 -0
  46. data/ext/iodine/iodine_store.h +418 -16
  47. data/ext/iodine/iodine_threads.h +279 -0
  48. data/ext/iodine/iodine_tls.h +515 -6
  49. data/ext/iodine/iodine_utils.h +923 -0
  50. data/iodine.gemspec +37 -42
  51. data/lib/iodine/benchmark.rb +1690 -0
  52. data/lib/iodine/documentation.rb +3085 -0
  53. data/lib/iodine/version.rb +17 -1
  54. data/lib/iodine.rb +54 -255
  55. data/logo.svg +36 -0
  56. data/mustache.md +55 -0
  57. data/sig/iodine.rbs +4 -0
  58. metadata +58 -184
  59. data/.github/ISSUE_TEMPLATE/bug_report.md +0 -40
  60. data/.github/workflows/ruby.yml +0 -42
  61. data/.gitignore +0 -21
  62. data/LIMITS.md +0 -41
  63. data/SPEC-PubSub-Draft.md +0 -159
  64. data/SPEC-WebSocket-Draft.md +0 -239
  65. data/bin/console +0 -22
  66. data/bin/info.md +0 -353
  67. data/bin/mustache_bench.rb +0 -100
  68. data/bin/poc/Gemfile.lock +0 -23
  69. data/bin/poc/README.md +0 -37
  70. data/bin/poc/config.ru +0 -66
  71. data/bin/poc/gemfile +0 -1
  72. data/bin/poc/www/index.html +0 -57
  73. data/examples/async_task.ru +0 -92
  74. data/examples/bates/README.md +0 -3
  75. data/examples/bates/config.ru +0 -342
  76. data/examples/bates/david+bold.pdf +0 -0
  77. data/examples/bates/public/drop-pdf.png +0 -0
  78. data/examples/bates/public/index.html +0 -600
  79. data/examples/echo.ru +0 -59
  80. data/examples/etag.ru +0 -16
  81. data/examples/hello.ru +0 -29
  82. data/examples/pubsub_engine.ru +0 -81
  83. data/examples/rack3.ru +0 -12
  84. data/examples/redis.ru +0 -70
  85. data/examples/shootout.ru +0 -73
  86. data/examples/sub-protocols.ru +0 -90
  87. data/examples/tcp_client.rb +0 -66
  88. data/examples/x-sendfile.ru +0 -14
  89. data/ext/iodine/fio.c +0 -11995
  90. data/ext/iodine/fio.h +0 -6371
  91. data/ext/iodine/fio_cli.c +0 -431
  92. data/ext/iodine/fio_cli.h +0 -189
  93. data/ext/iodine/fio_json_parser.h +0 -688
  94. data/ext/iodine/fio_siphash.c +0 -157
  95. data/ext/iodine/fio_siphash.h +0 -37
  96. data/ext/iodine/fio_tls.h +0 -129
  97. data/ext/iodine/fio_tls_missing.c +0 -649
  98. data/ext/iodine/fio_tls_openssl.c +0 -1106
  99. data/ext/iodine/fio_tmpfile.h +0 -50
  100. data/ext/iodine/fiobj.h +0 -44
  101. data/ext/iodine/fiobj4fio.h +0 -21
  102. data/ext/iodine/fiobj_ary.c +0 -333
  103. data/ext/iodine/fiobj_ary.h +0 -139
  104. data/ext/iodine/fiobj_data.c +0 -1187
  105. data/ext/iodine/fiobj_data.h +0 -167
  106. data/ext/iodine/fiobj_hash.c +0 -409
  107. data/ext/iodine/fiobj_hash.h +0 -176
  108. data/ext/iodine/fiobj_json.c +0 -622
  109. data/ext/iodine/fiobj_json.h +0 -68
  110. data/ext/iodine/fiobj_mem.h +0 -71
  111. data/ext/iodine/fiobj_mustache.c +0 -317
  112. data/ext/iodine/fiobj_mustache.h +0 -62
  113. data/ext/iodine/fiobj_numbers.c +0 -344
  114. data/ext/iodine/fiobj_numbers.h +0 -127
  115. data/ext/iodine/fiobj_str.c +0 -433
  116. data/ext/iodine/fiobj_str.h +0 -172
  117. data/ext/iodine/fiobject.c +0 -620
  118. data/ext/iodine/fiobject.h +0 -655
  119. data/ext/iodine/hpack.h +0 -1923
  120. data/ext/iodine/http.c +0 -2743
  121. data/ext/iodine/http.h +0 -1002
  122. data/ext/iodine/http1.c +0 -910
  123. data/ext/iodine/http1.h +0 -29
  124. data/ext/iodine/http1_parser.h +0 -878
  125. data/ext/iodine/http_internal.c +0 -1279
  126. data/ext/iodine/http_internal.h +0 -237
  127. data/ext/iodine/http_mime_parser.h +0 -350
  128. data/ext/iodine/iodine_caller.c +0 -230
  129. data/ext/iodine/iodine_connection.c +0 -941
  130. data/ext/iodine/iodine_defer.c +0 -420
  131. data/ext/iodine/iodine_fiobj2rb.h +0 -120
  132. data/ext/iodine/iodine_helpers.c +0 -282
  133. data/ext/iodine/iodine_helpers.h +0 -12
  134. data/ext/iodine/iodine_http.c +0 -1181
  135. data/ext/iodine/iodine_http.h +0 -23
  136. data/ext/iodine/iodine_json.c +0 -302
  137. data/ext/iodine/iodine_mustache.c +0 -567
  138. data/ext/iodine/iodine_pubsub.c +0 -580
  139. data/ext/iodine/iodine_pubsub.h +0 -26
  140. data/ext/iodine/iodine_rack_io.c +0 -273
  141. data/ext/iodine/iodine_rack_io.h +0 -20
  142. data/ext/iodine/iodine_store.c +0 -148
  143. data/ext/iodine/iodine_tcp.c +0 -346
  144. data/ext/iodine/iodine_tcp.h +0 -13
  145. data/ext/iodine/iodine_tls.c +0 -261
  146. data/ext/iodine/mustache_parser.h +0 -1546
  147. data/ext/iodine/redis_engine.c +0 -957
  148. data/ext/iodine/redis_engine.h +0 -79
  149. data/ext/iodine/resp_parser.h +0 -317
  150. data/ext/iodine/websocket_parser.h +0 -506
  151. data/ext/iodine/websockets.c +0 -743
  152. data/ext/iodine/websockets.h +0 -185
  153. data/lib/iodine/connection.rb +0 -61
  154. data/lib/iodine/json.rb +0 -42
  155. data/lib/iodine/mustache.rb +0 -113
  156. data/lib/iodine/pubsub.rb +0 -55
  157. data/lib/iodine/rack_utils.rb +0 -43
  158. data/lib/iodine/tls.rb +0 -16
  159. data/lib/rack/handler/iodine.rb +0 -33
  160. data/logo.png +0 -0
data/ext/iodine/http.h DELETED
@@ -1,1002 +0,0 @@
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 */