iodine 0.6.5 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of iodine might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -0
- data/README.md +4 -4
- data/SPEC-Websocket-Draft.md +3 -6
- data/bin/mustache.rb +128 -0
- data/examples/test_template.mustache +16 -0
- data/ext/iodine/fio.c +9397 -0
- data/ext/iodine/fio.h +4723 -0
- data/ext/iodine/fio_ary.h +353 -54
- data/ext/iodine/fio_cli.c +351 -361
- data/ext/iodine/fio_cli.h +84 -105
- data/ext/iodine/fio_hashmap.h +70 -16
- data/ext/iodine/fio_json_parser.h +35 -24
- data/ext/iodine/fio_siphash.c +104 -4
- data/ext/iodine/fio_siphash.h +18 -2
- data/ext/iodine/fio_str.h +1218 -0
- data/ext/iodine/fio_tmpfile.h +1 -1
- data/ext/iodine/fiobj.h +13 -8
- data/ext/iodine/fiobj4sock.h +6 -8
- data/ext/iodine/fiobj_ary.c +107 -17
- data/ext/iodine/fiobj_ary.h +36 -4
- data/ext/iodine/fiobj_data.c +146 -127
- data/ext/iodine/fiobj_data.h +25 -23
- data/ext/iodine/fiobj_hash.c +7 -7
- data/ext/iodine/fiobj_hash.h +6 -5
- data/ext/iodine/fiobj_json.c +20 -17
- data/ext/iodine/fiobj_json.h +5 -5
- data/ext/iodine/fiobj_mem.h +71 -0
- data/ext/iodine/fiobj_mustache.c +310 -0
- data/ext/iodine/fiobj_mustache.h +40 -0
- data/ext/iodine/fiobj_numbers.c +199 -94
- data/ext/iodine/fiobj_numbers.h +7 -7
- data/ext/iodine/fiobj_str.c +142 -333
- data/ext/iodine/fiobj_str.h +65 -55
- data/ext/iodine/fiobject.c +49 -11
- data/ext/iodine/fiobject.h +40 -39
- data/ext/iodine/http.c +382 -190
- data/ext/iodine/http.h +124 -80
- data/ext/iodine/http1.c +99 -127
- data/ext/iodine/http1.h +5 -5
- data/ext/iodine/http1_parser.c +3 -2
- data/ext/iodine/http1_parser.h +2 -2
- data/ext/iodine/http_internal.c +14 -12
- data/ext/iodine/http_internal.h +25 -19
- data/ext/iodine/iodine.c +37 -18
- data/ext/iodine/iodine.h +4 -0
- data/ext/iodine/iodine_caller.c +9 -2
- data/ext/iodine/iodine_caller.h +2 -0
- data/ext/iodine/iodine_connection.c +82 -117
- data/ext/iodine/iodine_defer.c +57 -50
- data/ext/iodine/iodine_defer.h +0 -1
- data/ext/iodine/iodine_fiobj2rb.h +4 -2
- data/ext/iodine/iodine_helpers.c +4 -4
- data/ext/iodine/iodine_http.c +25 -32
- data/ext/iodine/iodine_json.c +2 -1
- data/ext/iodine/iodine_mustache.c +423 -0
- data/ext/iodine/iodine_mustache.h +6 -0
- data/ext/iodine/iodine_pubsub.c +48 -153
- data/ext/iodine/iodine_pubsub.h +5 -4
- data/ext/iodine/iodine_rack_io.c +7 -5
- data/ext/iodine/iodine_store.c +16 -13
- data/ext/iodine/iodine_tcp.c +26 -34
- data/ext/iodine/mustache_parser.h +1085 -0
- data/ext/iodine/redis_engine.c +740 -646
- data/ext/iodine/redis_engine.h +13 -15
- data/ext/iodine/resp_parser.h +11 -5
- data/ext/iodine/websocket_parser.h +13 -13
- data/ext/iodine/websockets.c +240 -393
- data/ext/iodine/websockets.h +52 -113
- data/lib/iodine.rb +1 -1
- data/lib/iodine/mustache.rb +140 -0
- data/lib/iodine/version.rb +1 -1
- metadata +15 -28
- data/ext/iodine/defer.c +0 -566
- data/ext/iodine/defer.h +0 -148
- data/ext/iodine/evio.c +0 -26
- data/ext/iodine/evio.h +0 -161
- data/ext/iodine/evio_callbacks.c +0 -26
- data/ext/iodine/evio_epoll.c +0 -251
- data/ext/iodine/evio_kqueue.c +0 -194
- data/ext/iodine/facil.c +0 -2325
- data/ext/iodine/facil.h +0 -616
- data/ext/iodine/fio_base64.c +0 -277
- data/ext/iodine/fio_base64.h +0 -71
- data/ext/iodine/fio_llist.h +0 -257
- data/ext/iodine/fio_mem.c +0 -675
- data/ext/iodine/fio_mem.h +0 -143
- data/ext/iodine/fio_random.c +0 -248
- data/ext/iodine/fio_random.h +0 -45
- data/ext/iodine/fio_sha1.c +0 -362
- data/ext/iodine/fio_sha1.h +0 -107
- data/ext/iodine/fio_sha2.c +0 -842
- data/ext/iodine/fio_sha2.h +0 -169
- data/ext/iodine/pubsub.c +0 -867
- data/ext/iodine/pubsub.h +0 -221
- data/ext/iodine/sock.c +0 -1366
- data/ext/iodine/sock.h +0 -566
- data/ext/iodine/spnlock.inc +0 -111
data/ext/iodine/http1.c
CHANGED
@@ -2,33 +2,24 @@
|
|
2
2
|
Copyright: Boaz Segev, 2017
|
3
3
|
License: MIT
|
4
4
|
*/
|
5
|
-
#include
|
5
|
+
#include <fio.h>
|
6
6
|
|
7
|
-
#include
|
8
|
-
#include
|
9
|
-
#include
|
10
|
-
#include
|
7
|
+
#include <http1.h>
|
8
|
+
#include <http1_parser.h>
|
9
|
+
#include <http_internal.h>
|
10
|
+
#include <websockets.h>
|
11
11
|
|
12
|
-
|
13
|
-
#include "fio_base64.h"
|
14
|
-
#include "fio_sha1.h"
|
15
|
-
#include "fiobj.h"
|
12
|
+
#include <fiobj.h>
|
16
13
|
|
17
14
|
#include <assert.h>
|
18
15
|
#include <stddef.h>
|
19
16
|
|
20
|
-
/* Don't use `#define FIO_OVERRIDE_MALLOC 1`
|
21
|
-
* because protocol objects can have long life spans and fio_malloc is optimized
|
22
|
-
* for short life spans.
|
23
|
-
*/
|
24
|
-
#include "fio_mem.h"
|
25
|
-
|
26
17
|
/* *****************************************************************************
|
27
18
|
The HTTP/1.1 Protocol Object
|
28
19
|
***************************************************************************** */
|
29
20
|
|
30
21
|
typedef struct http1pr_s {
|
31
|
-
|
22
|
+
http_fio_protocol_s p;
|
32
23
|
http1_parser_s parser;
|
33
24
|
http_s request;
|
34
25
|
uintptr_t buf_len;
|
@@ -54,7 +45,7 @@ inline static void h1_reset(http1pr_s *p) { p->header_size = 0; }
|
|
54
45
|
#define http1_pr2handle(pr) (((http1pr_s *)(pr))->request)
|
55
46
|
#define handle2pr(h) ((http1pr_s *)h->private_data.flag)
|
56
47
|
|
57
|
-
static
|
48
|
+
static fio_str_info_s http1pr_status2str(uintptr_t status);
|
58
49
|
|
59
50
|
/* cleanup an HTTP/1.1 handler object */
|
60
51
|
static inline void http1_after_finish(http_s *h) {
|
@@ -67,7 +58,7 @@ static inline void http1_after_finish(http_s *h) {
|
|
67
58
|
http_s_clear(h, p->p.settings->log);
|
68
59
|
}
|
69
60
|
if (p->close)
|
70
|
-
|
61
|
+
fio_close(p->p.uuid);
|
71
62
|
}
|
72
63
|
|
73
64
|
/* *****************************************************************************
|
@@ -90,8 +81,8 @@ static int write_header(FIOBJ o, void *w_) {
|
|
90
81
|
fiobj_each1(o, 0, write_header, w);
|
91
82
|
return 0;
|
92
83
|
}
|
93
|
-
|
94
|
-
|
84
|
+
fio_str_info_s name = fiobj_obj2cstr(w->name);
|
85
|
+
fio_str_info_s str = fiobj_obj2cstr(o);
|
95
86
|
if (!str.data)
|
96
87
|
return 0;
|
97
88
|
fiobj_str_capa_assert(w->dest,
|
@@ -120,8 +111,8 @@ static FIOBJ headers2str(http_s *h, uintptr_t padding) {
|
|
120
111
|
http1pr_s *p = handle2pr(h);
|
121
112
|
|
122
113
|
if (p->is_client == 0) {
|
123
|
-
|
124
|
-
fiobj_str_write(w.dest, t.data, t.
|
114
|
+
fio_str_info_s t = http1pr_status2str(h->status);
|
115
|
+
fiobj_str_write(w.dest, t.data, t.len);
|
125
116
|
FIOBJ tmp = fiobj_hash_get2(h->private_data.out_headers, connection_hash);
|
126
117
|
if (tmp) {
|
127
118
|
t = fiobj_obj2cstr(tmp);
|
@@ -205,14 +196,14 @@ static int http1_sendfile(http_s *h, int fd, uintptr_t length,
|
|
205
196
|
}
|
206
197
|
if (length < HTTP_MAX_HEADER_LENGTH) {
|
207
198
|
/* optimize away small files */
|
208
|
-
|
199
|
+
fio_str_info_s s = fiobj_obj2cstr(packet);
|
209
200
|
fiobj_str_capa_assert(packet, s.len + length);
|
210
201
|
s = fiobj_obj2cstr(packet);
|
211
202
|
intptr_t i = pread(fd, s.data + s.len, length, offset);
|
212
203
|
if (i < 0) {
|
213
204
|
close(fd);
|
214
205
|
fiobj_send_free((handle2pr(h)->p.uuid), packet);
|
215
|
-
|
206
|
+
fio_close((handle2pr(h)->p.uuid));
|
216
207
|
return -1;
|
217
208
|
}
|
218
209
|
close(fd);
|
@@ -222,7 +213,7 @@ static int http1_sendfile(http_s *h, int fd, uintptr_t length,
|
|
222
213
|
return 0;
|
223
214
|
}
|
224
215
|
fiobj_send_free((handle2pr(h)->p.uuid), packet);
|
225
|
-
|
216
|
+
fio_sendfile((handle2pr(h)->p.uuid), fd, offset, length);
|
226
217
|
http1_after_finish(h);
|
227
218
|
return 0;
|
228
219
|
}
|
@@ -257,38 +248,38 @@ static int http1_push_file(http_s *h, FIOBJ filename, FIOBJ mime_type) {
|
|
257
248
|
/**
|
258
249
|
* Called befor a pause task,
|
259
250
|
*/
|
260
|
-
void http1_on_pause(http_s *h,
|
251
|
+
void http1_on_pause(http_s *h, http_fio_protocol_s *pr) {
|
261
252
|
((http1pr_s *)pr)->stop = 1;
|
262
|
-
|
253
|
+
fio_suspend(pr->uuid);
|
263
254
|
(void)h;
|
264
255
|
}
|
265
256
|
|
266
257
|
/**
|
267
258
|
* called after the resume task had completed.
|
268
259
|
*/
|
269
|
-
void http1_on_resume(http_s *h,
|
260
|
+
void http1_on_resume(http_s *h, http_fio_protocol_s *pr) {
|
270
261
|
if (!((http1pr_s *)pr)->stop) {
|
271
|
-
|
262
|
+
fio_force_event(pr->uuid, FIO_EVENT_ON_DATA);
|
272
263
|
}
|
273
264
|
(void)h;
|
274
265
|
}
|
275
266
|
|
276
|
-
intptr_t http1_hijack(http_s *h,
|
267
|
+
intptr_t http1_hijack(http_s *h, fio_str_info_s *leftover) {
|
277
268
|
if (leftover) {
|
278
269
|
intptr_t len =
|
279
270
|
handle2pr(h)->buf_len -
|
280
271
|
(intptr_t)(handle2pr(h)->parser.state.next - handle2pr(h)->buf);
|
281
272
|
if (len) {
|
282
|
-
*leftover =
|
283
|
-
|
273
|
+
*leftover = (fio_str_info_s){
|
274
|
+
.len = len, .data = (char *)handle2pr(h)->parser.state.next};
|
284
275
|
} else {
|
285
|
-
*leftover = (
|
276
|
+
*leftover = (fio_str_info_s){.len = 0, .data = NULL};
|
286
277
|
}
|
287
278
|
}
|
288
279
|
|
289
280
|
handle2pr(h)->stop = 3;
|
290
281
|
intptr_t uuid = handle2pr(h)->p.uuid;
|
291
|
-
|
282
|
+
fio_attach(uuid, NULL);
|
292
283
|
return uuid;
|
293
284
|
}
|
294
285
|
|
@@ -300,11 +291,10 @@ static void http1_websocket_client_on_upgrade(http_s *h, char *proto,
|
|
300
291
|
size_t len) {
|
301
292
|
http1pr_s *p = handle2pr(h);
|
302
293
|
websocket_settings_s *args = h->udata;
|
303
|
-
|
304
|
-
|
305
|
-
http_settings_s *set = handle2pr(args->http)->p.settings;
|
294
|
+
const intptr_t uuid = handle2pr(h)->p.uuid;
|
295
|
+
http_settings_s *set = handle2pr(h)->p.settings;
|
306
296
|
set->udata = NULL;
|
307
|
-
http_finish(
|
297
|
+
http_finish(h);
|
308
298
|
p->stop = 1;
|
309
299
|
websocket_attach(uuid, set, args, p->parser.state.next,
|
310
300
|
p->buf_len - (intptr_t)(p->parser.state.next - p->buf));
|
@@ -329,7 +319,7 @@ static void http1_websocket_client_on_hangup(http_settings_s *settings) {
|
|
329
319
|
}
|
330
320
|
}
|
331
321
|
|
332
|
-
static int http1_http2websocket_server(websocket_settings_s *args) {
|
322
|
+
static int http1_http2websocket_server(http_s *h, websocket_settings_s *args) {
|
333
323
|
// A static data used for all websocket connections.
|
334
324
|
static char ws_key_accpt_str[] = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
|
335
325
|
static uintptr_t sec_version = 0;
|
@@ -339,48 +329,46 @@ static int http1_http2websocket_server(websocket_settings_s *args) {
|
|
339
329
|
if (!sec_key)
|
340
330
|
sec_key = fio_siphash("sec-websocket-key", 17);
|
341
331
|
|
342
|
-
FIOBJ tmp = fiobj_hash_get2(
|
332
|
+
FIOBJ tmp = fiobj_hash_get2(h->headers, sec_version);
|
343
333
|
if (!tmp)
|
344
334
|
goto bad_request;
|
345
|
-
|
346
|
-
if (stmp.
|
335
|
+
fio_str_info_s stmp = fiobj_obj2cstr(tmp);
|
336
|
+
if (stmp.len != 2 || stmp.data[0] != '1' || stmp.data[1] != '3')
|
347
337
|
goto bad_request;
|
348
338
|
|
349
|
-
tmp = fiobj_hash_get2(
|
339
|
+
tmp = fiobj_hash_get2(h->headers, sec_key);
|
350
340
|
if (!tmp)
|
351
341
|
goto bad_request;
|
352
342
|
stmp = fiobj_obj2cstr(tmp);
|
353
343
|
|
354
|
-
|
344
|
+
fio_sha1_s sha1 = fio_sha1_init();
|
355
345
|
fio_sha1_write(&sha1, stmp.data, stmp.len);
|
356
346
|
fio_sha1_write(&sha1, ws_key_accpt_str, sizeof(ws_key_accpt_str) - 1);
|
357
347
|
tmp = fiobj_str_buf(32);
|
358
348
|
stmp = fiobj_obj2cstr(tmp);
|
359
349
|
fiobj_str_resize(tmp,
|
360
350
|
fio_base64_encode(stmp.data, fio_sha1_result(&sha1), 20));
|
361
|
-
http_set_header(
|
362
|
-
|
363
|
-
http_set_header(
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
http_settings_s *set = handle2pr(args->http)->p.settings;
|
370
|
-
http_finish(args->http);
|
351
|
+
http_set_header(h, HTTP_HEADER_CONNECTION, fiobj_dup(HTTP_HVALUE_WS_UPGRADE));
|
352
|
+
http_set_header(h, HTTP_HEADER_UPGRADE, fiobj_dup(HTTP_HVALUE_WEBSOCKET));
|
353
|
+
http_set_header(h, HTTP_HEADER_WS_SEC_KEY, tmp);
|
354
|
+
h->status = 101;
|
355
|
+
http1pr_s *pr = handle2pr(h);
|
356
|
+
const intptr_t uuid = handle2pr(h)->p.uuid;
|
357
|
+
http_settings_s *set = handle2pr(h)->p.settings;
|
358
|
+
http_finish(h);
|
371
359
|
pr->stop = 1;
|
372
360
|
websocket_attach(uuid, set, args, pr->parser.state.next,
|
373
361
|
pr->buf_len - (intptr_t)(pr->parser.state.next - pr->buf));
|
374
362
|
return 0;
|
375
363
|
bad_request:
|
376
|
-
http_send_error(
|
364
|
+
http_send_error(h, 400);
|
377
365
|
if (args->on_close)
|
378
366
|
args->on_close(0, args->udata);
|
379
367
|
return -1;
|
380
368
|
}
|
381
369
|
|
382
|
-
static int http1_http2websocket_client(websocket_settings_s *args) {
|
383
|
-
http1pr_s *p = handle2pr(
|
370
|
+
static int http1_http2websocket_client(http_s *h, websocket_settings_s *args) {
|
371
|
+
http1pr_s *p = handle2pr(h);
|
384
372
|
/* We're done with the HTTP stage, so we call the `on_finish` */
|
385
373
|
if (p->p.settings->on_finish)
|
386
374
|
p->p.settings->on_finish(p->p.settings);
|
@@ -393,40 +381,38 @@ static int http1_http2websocket_client(websocket_settings_s *args) {
|
|
393
381
|
p->p.settings->on_response = http1_websocket_client_on_failed; /* failed */
|
394
382
|
p->p.settings->on_request = http1_websocket_client_on_failed; /* failed */
|
395
383
|
/* Set headers */
|
396
|
-
http_set_header(
|
397
|
-
|
398
|
-
http_set_header(
|
399
|
-
fiobj_dup(HTTP_HVALUE_WEBSOCKET));
|
400
|
-
http_set_header(args->http, HTTP_HVALUE_WS_SEC_VERSION,
|
384
|
+
http_set_header(h, HTTP_HEADER_CONNECTION, fiobj_dup(HTTP_HVALUE_WS_UPGRADE));
|
385
|
+
http_set_header(h, HTTP_HEADER_UPGRADE, fiobj_dup(HTTP_HVALUE_WEBSOCKET));
|
386
|
+
http_set_header(h, HTTP_HVALUE_WS_SEC_VERSION,
|
401
387
|
fiobj_dup(HTTP_HVALUE_WS_VERSION));
|
402
388
|
|
403
389
|
/* we don't set the Origin header since we're not a browser... should we? */
|
404
390
|
// http_set_header(
|
405
|
-
//
|
406
|
-
// fiobj_dup(fiobj_hash_get2(
|
391
|
+
// h, HTTP_HEADER_ORIGIN,
|
392
|
+
// fiobj_dup(fiobj_hash_get2(h->private_data.out_headers,
|
407
393
|
// fiobj_obj2hash(HTTP_HEADER_HOST))));
|
408
394
|
|
409
395
|
/* create nonce */
|
410
396
|
uint64_t key[2]; /* 16 bytes */
|
411
|
-
key[0] = (uintptr_t)
|
412
|
-
key[1] = (uintptr_t)args->udata ^ (uint64_t)
|
397
|
+
key[0] = (uintptr_t)h ^ (uint64_t)fio_last_tick().tv_sec;
|
398
|
+
key[1] = (uintptr_t)args->udata ^ (uint64_t)fio_last_tick().tv_nsec;
|
413
399
|
FIOBJ encoded = fiobj_str_buf(26); /* we need 24 really. */
|
414
|
-
|
400
|
+
fio_str_info_s tmp = fiobj_obj2cstr(encoded);
|
415
401
|
tmp.len = fio_base64_encode(tmp.data, (char *)key, 16);
|
416
402
|
fiobj_str_resize(encoded, tmp.len);
|
417
|
-
http_set_header(
|
418
|
-
http_finish(
|
403
|
+
http_set_header(h, HTTP_HEADER_WS_SEC_CLIENT_KEY, encoded);
|
404
|
+
http_finish(h);
|
419
405
|
return 0;
|
420
406
|
}
|
421
407
|
|
422
|
-
static int http1_http2websocket(websocket_settings_s *args) {
|
423
|
-
assert(
|
424
|
-
http1pr_s *p = handle2pr(
|
408
|
+
static int http1_http2websocket(http_s *h, websocket_settings_s *args) {
|
409
|
+
assert(h);
|
410
|
+
http1pr_s *p = handle2pr(h);
|
425
411
|
|
426
412
|
if (p->is_client == 0) {
|
427
|
-
return http1_http2websocket_server(args);
|
413
|
+
return http1_http2websocket_server(h, args);
|
428
414
|
}
|
429
|
-
return http1_http2websocket_client(args);
|
415
|
+
return http1_http2websocket_client(h, args);
|
430
416
|
}
|
431
417
|
|
432
418
|
/* *****************************************************************************
|
@@ -436,33 +422,32 @@ EventSource Support (SSE)
|
|
436
422
|
#undef http_upgrade2sse
|
437
423
|
|
438
424
|
typedef struct {
|
439
|
-
|
425
|
+
fio_protocol_s p;
|
440
426
|
http_sse_internal_s *sse;
|
441
|
-
}
|
427
|
+
} http1_sse_fio_protocol_s;
|
442
428
|
|
443
|
-
static void http1_sse_on_ready(intptr_t uuid,
|
444
|
-
|
429
|
+
static void http1_sse_on_ready(intptr_t uuid, fio_protocol_s *p_) {
|
430
|
+
http1_sse_fio_protocol_s *p = (http1_sse_fio_protocol_s *)p_;
|
445
431
|
if (p->sse->sse.on_ready)
|
446
432
|
p->sse->sse.on_ready(&p->sse->sse);
|
447
433
|
(void)uuid;
|
448
434
|
}
|
449
|
-
static
|
450
|
-
|
435
|
+
static uint8_t http1_sse_on_shutdown(intptr_t uuid, fio_protocol_s *p_) {
|
436
|
+
http1_sse_fio_protocol_s *p = (http1_sse_fio_protocol_s *)p_;
|
451
437
|
if (p->sse->sse.on_shutdown)
|
452
438
|
p->sse->sse.on_shutdown(&p->sse->sse);
|
439
|
+
return 0;
|
453
440
|
(void)uuid;
|
454
441
|
}
|
455
|
-
static void http1_sse_on_close(intptr_t uuid,
|
456
|
-
|
457
|
-
if (p->sse->sse.on_close)
|
458
|
-
p->sse->sse.on_close(&p->sse->sse);
|
442
|
+
static void http1_sse_on_close(intptr_t uuid, fio_protocol_s *p_) {
|
443
|
+
http1_sse_fio_protocol_s *p = (http1_sse_fio_protocol_s *)p_;
|
459
444
|
http_sse_destroy(p->sse);
|
460
445
|
free(p);
|
461
446
|
(void)uuid;
|
462
447
|
}
|
463
|
-
static void http1_sse_ping(intptr_t uuid,
|
464
|
-
|
465
|
-
|
448
|
+
static void http1_sse_ping(intptr_t uuid, fio_protocol_s *p_) {
|
449
|
+
fio_write2(uuid, .data.buffer = ": ping\n\n", .length = 8,
|
450
|
+
.after.dealloc = FIO_DEALLOC_NOOP);
|
466
451
|
(void)p_;
|
467
452
|
}
|
468
453
|
|
@@ -487,13 +472,12 @@ static int http1_upgrade2sse(http_s *h, http_sse_s *sse) {
|
|
487
472
|
htt1p_finish(h); /* avoid the enforced content length in http_finish */
|
488
473
|
|
489
474
|
/* switch protocol to SSE */
|
490
|
-
|
475
|
+
http1_sse_fio_protocol_s *sse_pr = malloc(sizeof(*sse_pr));
|
491
476
|
if (!sse_pr)
|
492
477
|
goto failed;
|
493
|
-
*sse_pr = (
|
478
|
+
*sse_pr = (http1_sse_fio_protocol_s){
|
494
479
|
.p =
|
495
480
|
{
|
496
|
-
.service = "http/1.1 internal SSE",
|
497
481
|
.on_ready = http1_sse_on_ready,
|
498
482
|
.on_shutdown = http1_sse_on_shutdown,
|
499
483
|
.on_close = http1_sse_on_close,
|
@@ -506,17 +490,14 @@ static int http1_upgrade2sse(http_s *h, http_sse_s *sse) {
|
|
506
490
|
goto failed;
|
507
491
|
|
508
492
|
http_sse_init(sse_pr->sse, uuid, &HTTP1_VTABLE, sse);
|
509
|
-
|
510
|
-
if (facil_attach(uuid, &sse_pr->p))
|
511
|
-
return -1;
|
512
|
-
facil_set_timeout(uuid, handle2pr(h)->p.settings->ws_timeout);
|
493
|
+
fio_timeout_set(uuid, handle2pr(h)->p.settings->ws_timeout);
|
513
494
|
if (sse->on_open)
|
514
495
|
sse->on_open(&sse_pr->sse->sse);
|
515
|
-
|
496
|
+
fio_attach(uuid, &sse_pr->p);
|
516
497
|
return 0;
|
517
498
|
|
518
499
|
failed:
|
519
|
-
|
500
|
+
fio_close(handle2pr(h)->p.uuid);
|
520
501
|
if (sse->on_close)
|
521
502
|
sse->on_close(sse);
|
522
503
|
return -1;
|
@@ -537,7 +518,7 @@ static int http1_sse_write(http_sse_s *sse, FIOBJ str) {
|
|
537
518
|
* Closes an EventSource (SSE) connection.
|
538
519
|
*/
|
539
520
|
static int http1_sse_close(http_sse_s *sse) {
|
540
|
-
|
521
|
+
fio_close(((http_sse_internal_s *)sse)->uuid);
|
541
522
|
return 0;
|
542
523
|
}
|
543
524
|
/* *****************************************************************************
|
@@ -677,9 +658,9 @@ static int http1_on_body_chunk(http1_parser_s *parser, char *data,
|
|
677
658
|
return 0;
|
678
659
|
}
|
679
660
|
|
680
|
-
/** called when a protocol error
|
661
|
+
/** called when a protocol error occurred. */
|
681
662
|
static int http1_on_error(http1_parser_s *parser) {
|
682
|
-
|
663
|
+
fio_close(parser2http(parser)->p.uuid);
|
683
664
|
return -1;
|
684
665
|
}
|
685
666
|
|
@@ -688,14 +669,6 @@ Connection Callbacks
|
|
688
669
|
*****************************************************************************
|
689
670
|
*/
|
690
671
|
|
691
|
-
/**
|
692
|
-
* A string to identify the protocol's service (i.e. "http").
|
693
|
-
*
|
694
|
-
* The string should be a global constant, only a pointer comparison will be
|
695
|
-
* used (not `strcmp`).
|
696
|
-
*/
|
697
|
-
static const char *HTTP1_SERVICE_STR = "http1_protocol_facil_io";
|
698
|
-
|
699
672
|
static inline void http1_consume_data(intptr_t uuid, http1pr_s *p) {
|
700
673
|
ssize_t i = 0;
|
701
674
|
size_t org_len = p->buf_len;
|
@@ -731,21 +704,21 @@ static inline void http1_consume_data(intptr_t uuid, http1pr_s *p) {
|
|
731
704
|
}
|
732
705
|
|
733
706
|
if (!pipeline_limit) {
|
734
|
-
|
707
|
+
fio_force_event(uuid, FIO_EVENT_ON_DATA);
|
735
708
|
}
|
736
709
|
}
|
737
710
|
|
738
711
|
/** called when a data is available, but will not run concurrently */
|
739
|
-
static void http1_on_data(intptr_t uuid,
|
712
|
+
static void http1_on_data(intptr_t uuid, fio_protocol_s *protocol) {
|
740
713
|
http1pr_s *p = (http1pr_s *)protocol;
|
741
714
|
if (p->stop) {
|
742
|
-
|
715
|
+
fio_suspend(uuid);
|
743
716
|
return;
|
744
717
|
}
|
745
718
|
ssize_t i = 0;
|
746
719
|
if (HTTP_MAX_HEADER_LENGTH - p->buf_len)
|
747
|
-
i =
|
748
|
-
|
720
|
+
i = fio_read(uuid, p->buf + p->buf_len,
|
721
|
+
HTTP_MAX_HEADER_LENGTH - p->buf_len);
|
749
722
|
if (i > 0) {
|
750
723
|
p->buf_len += i;
|
751
724
|
}
|
@@ -753,17 +726,17 @@ static void http1_on_data(intptr_t uuid, protocol_s *protocol) {
|
|
753
726
|
}
|
754
727
|
|
755
728
|
/** called when the connection was closed, but will not run concurrently */
|
756
|
-
static void http1_on_close(intptr_t uuid,
|
729
|
+
static void http1_on_close(intptr_t uuid, fio_protocol_s *protocol) {
|
757
730
|
http1_destroy(protocol);
|
758
731
|
(void)uuid;
|
759
732
|
}
|
760
733
|
|
761
734
|
/** called when a data is available for the first time */
|
762
|
-
static void http1_on_data_first_time(intptr_t uuid,
|
735
|
+
static void http1_on_data_first_time(intptr_t uuid, fio_protocol_s *protocol) {
|
763
736
|
http1pr_s *p = (http1pr_s *)protocol;
|
764
737
|
ssize_t i;
|
765
738
|
|
766
|
-
i =
|
739
|
+
i = fio_read(uuid, p->buf + p->buf_len, HTTP_MAX_HEADER_LENGTH - p->buf_len);
|
767
740
|
|
768
741
|
if (i <= 0)
|
769
742
|
return;
|
@@ -774,7 +747,7 @@ static void http1_on_data_first_time(intptr_t uuid, protocol_s *protocol) {
|
|
774
747
|
if (i >= 24 && !memcmp(p->buf, "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n", 24)) {
|
775
748
|
fprintf(stderr,
|
776
749
|
"ERROR: unsupported HTTP/2 attempeted using prior knowledge.\n");
|
777
|
-
|
750
|
+
fio_close(uuid);
|
778
751
|
return;
|
779
752
|
}
|
780
753
|
|
@@ -789,8 +762,8 @@ Public API
|
|
789
762
|
|
790
763
|
/** Creates an HTTP1 protocol object and handles any unread data in the buffer
|
791
764
|
* (if any). */
|
792
|
-
|
793
|
-
|
765
|
+
fio_protocol_s *http1_new(uintptr_t uuid, http_settings_s *settings,
|
766
|
+
void *unread_data, size_t unread_length) {
|
794
767
|
if (unread_data && unread_length > HTTP_MAX_HEADER_LENGTH)
|
795
768
|
return NULL;
|
796
769
|
http1pr_s *p = malloc(sizeof(*p) + HTTP_MAX_HEADER_LENGTH);
|
@@ -798,7 +771,6 @@ protocol_s *http1_new(uintptr_t uuid, http_settings_s *settings,
|
|
798
771
|
*p = (http1pr_s){
|
799
772
|
.p.protocol =
|
800
773
|
{
|
801
|
-
.service = HTTP1_SERVICE_STR,
|
802
774
|
.on_data = http1_on_data_first_time,
|
803
775
|
.on_close = http1_on_close,
|
804
776
|
},
|
@@ -808,17 +780,17 @@ protocol_s *http1_new(uintptr_t uuid, http_settings_s *settings,
|
|
808
780
|
.is_client = settings->is_client,
|
809
781
|
};
|
810
782
|
http_s_new(&p->request, &p->p, &HTTP1_VTABLE);
|
811
|
-
|
783
|
+
fio_attach(uuid, &p->p.protocol);
|
812
784
|
if (unread_data && unread_length <= HTTP_MAX_HEADER_LENGTH) {
|
813
785
|
memcpy(p->buf, unread_data, unread_length);
|
814
786
|
p->buf_len = unread_length;
|
815
|
-
|
787
|
+
fio_force_event(uuid, FIO_EVENT_ON_DATA);
|
816
788
|
}
|
817
789
|
return &p->p.protocol;
|
818
790
|
}
|
819
791
|
|
820
792
|
/** Manually destroys the HTTP1 protocol object. */
|
821
|
-
void http1_destroy(
|
793
|
+
void http1_destroy(fio_protocol_s *pr) {
|
822
794
|
http1pr_s *p = (http1pr_s *)pr;
|
823
795
|
http1_pr2handle(p).status = 0;
|
824
796
|
http_s_destroy(&http1_pr2handle(p), 0);
|
@@ -830,12 +802,12 @@ Protocol Data
|
|
830
802
|
***************************************************************************** */
|
831
803
|
|
832
804
|
// clang-format off
|
833
|
-
#define HTTP_SET_STATUS_STR(status, str) [((status)-100)] = { .
|
805
|
+
#define HTTP_SET_STATUS_STR(status, str) [((status)-100)] = { .data = ("HTTP/1.1 " #status " " str "\r\n"), .len = (sizeof("HTTP/1.1 " #status " " str "\r\n") - 1) }
|
834
806
|
// #undef HTTP_SET_STATUS_STR
|
835
807
|
// clang-format on
|
836
808
|
|
837
|
-
static
|
838
|
-
static
|
809
|
+
static fio_str_info_s http1pr_status2str(uintptr_t status) {
|
810
|
+
static fio_str_info_s status2str[] = {
|
839
811
|
HTTP_SET_STATUS_STR(100, "Continue"),
|
840
812
|
HTTP_SET_STATUS_STR(101, "Switching Protocols"),
|
841
813
|
HTTP_SET_STATUS_STR(102, "Processing"),
|
@@ -901,11 +873,11 @@ static fio_cstr_s http1pr_status2str(uintptr_t status) {
|
|
901
873
|
HTTP_SET_STATUS_STR(510, "Not Extended"),
|
902
874
|
HTTP_SET_STATUS_STR(511, "Network Authentication Required"),
|
903
875
|
};
|
904
|
-
|
876
|
+
fio_str_info_s ret = (fio_str_info_s){.len = 0, .data = NULL};
|
905
877
|
if (status >= 100 &&
|
906
878
|
(status - 100) < sizeof(status2str) / sizeof(status2str[0]))
|
907
879
|
ret = status2str[status - 100];
|
908
|
-
if (!ret.
|
880
|
+
if (!ret.data) {
|
909
881
|
ret = status2str[400];
|
910
882
|
}
|
911
883
|
return ret;
|