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.
- checksums.yaml +4 -4
- data/.clang-format +15 -0
- data/.rspec +1 -0
- data/.yardopts +1 -3
- data/CHANGELOG.md +132 -12
- data/Gemfile +5 -7
- data/LICENSE.txt +1 -1
- data/README.md +147 -671
- data/Rakefile +9 -16
- data/examples/chatroom.nru +9 -0
- data/examples/client +74 -0
- data/examples/config-hello.nru +9 -0
- data/examples/config-hello.ru +11 -0
- data/examples/config-hijack.ru +13 -0
- data/examples/config-shootout.ru +43 -0
- data/examples/config.nru +120 -0
- data/examples/config.rb +37 -0
- data/examples/config.ru +42 -53
- data/examples/fake +24 -0
- data/examples/hello_neorack +137 -0
- data/examples/routes.nru +29 -0
- data/examples/routes.ru +42 -0
- data/exe/iodine +218 -258
- data/ext/iodine/extconf.rb +27 -100
- data/ext/iodine/fio-stl.h +128336 -0
- data/ext/iodine/fio-stl.md +26396 -0
- data/ext/iodine/iodine.c +213 -1393
- data/ext/iodine/iodine.h +250 -55
- data/ext/iodine/iodine_arg_helper.h +329 -0
- data/ext/iodine/iodine_caller.h +234 -25
- data/ext/iodine/iodine_cli.h +434 -0
- data/ext/iodine/iodine_compression.h +312 -0
- data/ext/iodine/iodine_connection.h +3484 -34
- data/ext/iodine/iodine_core.h +363 -0
- data/ext/iodine/iodine_crypto.h +1441 -0
- data/ext/iodine/iodine_defer.h +225 -4
- data/ext/iodine/iodine_json.h +738 -4
- data/ext/iodine/iodine_listener.h +263 -0
- data/ext/iodine/iodine_log.h +297 -0
- data/ext/iodine/iodine_minimap.h +543 -0
- data/ext/iodine/iodine_mustache.h +461 -4
- data/ext/iodine/iodine_pubsub_eng.h +729 -0
- data/ext/iodine/iodine_pubsub_history.h +547 -0
- data/ext/iodine/iodine_pubsub_msg.h +228 -0
- data/ext/iodine/iodine_redis.h +322 -0
- data/ext/iodine/iodine_store.h +418 -16
- data/ext/iodine/iodine_threads.h +279 -0
- data/ext/iodine/iodine_tls.h +515 -6
- data/ext/iodine/iodine_utils.h +923 -0
- data/iodine.gemspec +37 -42
- data/lib/iodine/benchmark.rb +1690 -0
- data/lib/iodine/documentation.rb +3085 -0
- data/lib/iodine/version.rb +17 -1
- data/lib/iodine.rb +54 -255
- data/logo.svg +36 -0
- data/mustache.md +55 -0
- data/sig/iodine.rbs +4 -0
- metadata +58 -184
- data/.github/ISSUE_TEMPLATE/bug_report.md +0 -40
- data/.github/workflows/ruby.yml +0 -42
- data/.gitignore +0 -21
- data/LIMITS.md +0 -41
- data/SPEC-PubSub-Draft.md +0 -159
- data/SPEC-WebSocket-Draft.md +0 -239
- data/bin/console +0 -22
- data/bin/info.md +0 -353
- data/bin/mustache_bench.rb +0 -100
- data/bin/poc/Gemfile.lock +0 -23
- data/bin/poc/README.md +0 -37
- data/bin/poc/config.ru +0 -66
- data/bin/poc/gemfile +0 -1
- data/bin/poc/www/index.html +0 -57
- data/examples/async_task.ru +0 -92
- data/examples/bates/README.md +0 -3
- data/examples/bates/config.ru +0 -342
- data/examples/bates/david+bold.pdf +0 -0
- data/examples/bates/public/drop-pdf.png +0 -0
- data/examples/bates/public/index.html +0 -600
- data/examples/echo.ru +0 -59
- data/examples/etag.ru +0 -16
- data/examples/hello.ru +0 -29
- data/examples/pubsub_engine.ru +0 -81
- data/examples/rack3.ru +0 -12
- data/examples/redis.ru +0 -70
- data/examples/shootout.ru +0 -73
- data/examples/sub-protocols.ru +0 -90
- data/examples/tcp_client.rb +0 -66
- data/examples/x-sendfile.ru +0 -14
- data/ext/iodine/fio.c +0 -11995
- data/ext/iodine/fio.h +0 -6371
- data/ext/iodine/fio_cli.c +0 -431
- data/ext/iodine/fio_cli.h +0 -189
- data/ext/iodine/fio_json_parser.h +0 -688
- data/ext/iodine/fio_siphash.c +0 -157
- data/ext/iodine/fio_siphash.h +0 -37
- data/ext/iodine/fio_tls.h +0 -129
- data/ext/iodine/fio_tls_missing.c +0 -649
- data/ext/iodine/fio_tls_openssl.c +0 -1106
- data/ext/iodine/fio_tmpfile.h +0 -50
- data/ext/iodine/fiobj.h +0 -44
- data/ext/iodine/fiobj4fio.h +0 -21
- data/ext/iodine/fiobj_ary.c +0 -333
- data/ext/iodine/fiobj_ary.h +0 -139
- data/ext/iodine/fiobj_data.c +0 -1187
- data/ext/iodine/fiobj_data.h +0 -167
- data/ext/iodine/fiobj_hash.c +0 -409
- data/ext/iodine/fiobj_hash.h +0 -176
- data/ext/iodine/fiobj_json.c +0 -622
- data/ext/iodine/fiobj_json.h +0 -68
- data/ext/iodine/fiobj_mem.h +0 -71
- data/ext/iodine/fiobj_mustache.c +0 -317
- data/ext/iodine/fiobj_mustache.h +0 -62
- data/ext/iodine/fiobj_numbers.c +0 -344
- data/ext/iodine/fiobj_numbers.h +0 -127
- data/ext/iodine/fiobj_str.c +0 -433
- data/ext/iodine/fiobj_str.h +0 -172
- data/ext/iodine/fiobject.c +0 -620
- data/ext/iodine/fiobject.h +0 -655
- data/ext/iodine/hpack.h +0 -1923
- data/ext/iodine/http.c +0 -2743
- data/ext/iodine/http.h +0 -1002
- data/ext/iodine/http1.c +0 -910
- data/ext/iodine/http1.h +0 -29
- data/ext/iodine/http1_parser.h +0 -878
- data/ext/iodine/http_internal.c +0 -1279
- data/ext/iodine/http_internal.h +0 -237
- data/ext/iodine/http_mime_parser.h +0 -350
- data/ext/iodine/iodine_caller.c +0 -230
- data/ext/iodine/iodine_connection.c +0 -941
- data/ext/iodine/iodine_defer.c +0 -420
- data/ext/iodine/iodine_fiobj2rb.h +0 -120
- data/ext/iodine/iodine_helpers.c +0 -282
- data/ext/iodine/iodine_helpers.h +0 -12
- data/ext/iodine/iodine_http.c +0 -1181
- data/ext/iodine/iodine_http.h +0 -23
- data/ext/iodine/iodine_json.c +0 -302
- data/ext/iodine/iodine_mustache.c +0 -567
- data/ext/iodine/iodine_pubsub.c +0 -580
- data/ext/iodine/iodine_pubsub.h +0 -26
- data/ext/iodine/iodine_rack_io.c +0 -273
- data/ext/iodine/iodine_rack_io.h +0 -20
- data/ext/iodine/iodine_store.c +0 -148
- data/ext/iodine/iodine_tcp.c +0 -346
- data/ext/iodine/iodine_tcp.h +0 -13
- data/ext/iodine/iodine_tls.c +0 -261
- data/ext/iodine/mustache_parser.h +0 -1546
- data/ext/iodine/redis_engine.c +0 -957
- data/ext/iodine/redis_engine.h +0 -79
- data/ext/iodine/resp_parser.h +0 -317
- data/ext/iodine/websocket_parser.h +0 -506
- data/ext/iodine/websockets.c +0 -743
- data/ext/iodine/websockets.h +0 -185
- data/lib/iodine/connection.rb +0 -61
- data/lib/iodine/json.rb +0 -42
- data/lib/iodine/mustache.rb +0 -113
- data/lib/iodine/pubsub.rb +0 -55
- data/lib/iodine/rack_utils.rb +0 -43
- data/lib/iodine/tls.rb +0 -16
- data/lib/rack/handler/iodine.rb +0 -33
- 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 */
|