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/http.h
CHANGED
@@ -7,7 +7,9 @@ Feel free to copy, use and enjoy according to the license provided.
|
|
7
7
|
*/
|
8
8
|
#define H_HTTP_H
|
9
9
|
|
10
|
-
#include
|
10
|
+
#include <fio.h>
|
11
|
+
|
12
|
+
#include <fiobj.h>
|
11
13
|
|
12
14
|
#include <time.h>
|
13
15
|
|
@@ -40,7 +42,7 @@ Compile Time Settings
|
|
40
42
|
#define HTTP_MAX_HEADER_LENGTH 8192
|
41
43
|
#endif
|
42
44
|
|
43
|
-
/** the `http_listen settings, see
|
45
|
+
/** the `http_listen settings, see details in the struct definition. */
|
44
46
|
typedef struct http_settings_s http_settings_s;
|
45
47
|
|
46
48
|
/* *****************************************************************************
|
@@ -114,18 +116,18 @@ This struct is used together with the `http_response_set_cookie`. i.e.:
|
|
114
116
|
*/
|
115
117
|
typedef struct {
|
116
118
|
/** The cookie's name (Symbol). */
|
117
|
-
char *name;
|
119
|
+
const char *name;
|
118
120
|
/** The cookie's value (leave blank to delete cookie). */
|
119
|
-
char *value;
|
121
|
+
const char *value;
|
120
122
|
/** The cookie's domain (optional). */
|
121
|
-
char *domain;
|
123
|
+
const char *domain;
|
122
124
|
/** The cookie's path (optional). */
|
123
|
-
char *path;
|
124
|
-
/** The cookie name's size in bytes or a terminating
|
125
|
+
const char *path;
|
126
|
+
/** The cookie name's size in bytes or a terminating NUL will be assumed.*/
|
125
127
|
size_t name_len;
|
126
|
-
/** The cookie value's size in bytes or a terminating
|
128
|
+
/** The cookie value's size in bytes or a terminating NUL will be assumed.*/
|
127
129
|
size_t value_len;
|
128
|
-
/** The cookie domain's size in bytes or a terminating
|
130
|
+
/** The cookie domain's size in bytes or a terminating NUL will be assumed.*/
|
129
131
|
size_t domain_len;
|
130
132
|
/** The cookie path's size in bytes or a terminating NULL will be assumed.*/
|
131
133
|
size_t path_len;
|
@@ -151,16 +153,15 @@ int http_set_header(http_s *h, FIOBJ name, FIOBJ value);
|
|
151
153
|
*
|
152
154
|
* Returns -1 on error and 0 on success.
|
153
155
|
*/
|
154
|
-
int http_set_header2(http_s *h,
|
156
|
+
int http_set_header2(http_s *h, fio_str_info_s name, fio_str_info_s value);
|
155
157
|
|
156
158
|
/**
|
157
|
-
* Sets a response cookie
|
158
|
-
* name object (so name objects could be reused in future responses).
|
159
|
+
* Sets a response cookie.
|
159
160
|
*
|
160
161
|
* Returns -1 on error and 0 on success.
|
161
162
|
*
|
162
163
|
* Note: Long cookie names and long cookie values will be considered a security
|
163
|
-
*
|
164
|
+
* violation and an error will be returned. It should be noted that most
|
164
165
|
* proxies and servers will refuse long cookie names or values and many impose
|
165
166
|
* total header lengths (including cookies) of ~8Kib.
|
166
167
|
*/
|
@@ -248,6 +249,7 @@ int http_push_file(http_s *h, FIOBJ filename, FIOBJ mime_type);
|
|
248
249
|
HTTP evented API (pause / resume HTTp handling)
|
249
250
|
***************************************************************************** */
|
250
251
|
|
252
|
+
typedef struct http_pause_handle_s http_pause_handle_s;
|
251
253
|
/**
|
252
254
|
* Pauses the request / response handling and INVALIDATES the current `http_s`
|
253
255
|
* handle (no `http` functions can be called).
|
@@ -258,11 +260,11 @@ HTTP evented API (pause / resume HTTp handling)
|
|
258
260
|
* The opaque `http` pointer is only valid for a single call to `http_resume`
|
259
261
|
* and can't be used by any other `http` function (it's a different data type).
|
260
262
|
*
|
261
|
-
* Note: the
|
263
|
+
* Note: the current `http_s` handle will become invalid once this function is
|
262
264
|
* called and it's data might be deallocated, invalid or used by a different
|
263
265
|
* thread.
|
264
266
|
*/
|
265
|
-
void http_pause(http_s *h, void (*task)(
|
267
|
+
void http_pause(http_s *h, void (*task)(http_pause_handle_s *http));
|
266
268
|
|
267
269
|
/**
|
268
270
|
* Resumes a request / response handling within a task and INVALIDATES the
|
@@ -281,24 +283,24 @@ void http_pause(http_s *h, void (*task)(void *http));
|
|
281
283
|
* called and it's data might be deallocated, invalidated or used by a
|
282
284
|
* different thread.
|
283
285
|
*/
|
284
|
-
void http_resume(
|
286
|
+
void http_resume(http_pause_handle_s *http, void (*task)(http_s *h),
|
285
287
|
void (*fallback)(void *udata));
|
286
288
|
|
287
289
|
/** Returns the `udata` associated with the paused opaque handle */
|
288
|
-
void *http_paused_udata_get(
|
290
|
+
void *http_paused_udata_get(http_pause_handle_s *http);
|
289
291
|
|
290
292
|
/**
|
291
293
|
* Sets the `udata` associated with the paused opaque handle, returning the
|
292
294
|
* old value.
|
293
295
|
*/
|
294
|
-
void *http_paused_udata_set(
|
296
|
+
void *http_paused_udata_set(http_pause_handle_s *http, void *udata);
|
295
297
|
|
296
298
|
/* *****************************************************************************
|
297
299
|
HTTP Connections - Listening / Connecting / Hijacking
|
298
300
|
***************************************************************************** */
|
299
301
|
|
300
302
|
/** The HTTP settings. */
|
301
|
-
|
303
|
+
struct http_settings_s {
|
302
304
|
/** Callback for normal HTTP requests. */
|
303
305
|
void (*on_request)(http_s *request);
|
304
306
|
/**
|
@@ -386,17 +388,19 @@ typedef struct http_settings_s {
|
|
386
388
|
uint8_t log;
|
387
389
|
/** a read only flag set automatically to indicate the protocol's mode. */
|
388
390
|
uint8_t is_client;
|
389
|
-
}
|
391
|
+
};
|
390
392
|
|
391
393
|
/**
|
392
394
|
* Listens to HTTP connections at the specified `port`.
|
393
395
|
*
|
394
396
|
* Leave as NULL to ignore IP binding.
|
395
397
|
*
|
396
|
-
* Returns -1 on error and
|
397
|
-
*
|
398
|
+
* Returns -1 on error and the socket's uuid on success.
|
399
|
+
*
|
400
|
+
* the `on_finish` callback is always called.
|
398
401
|
*/
|
399
|
-
|
402
|
+
intptr_t http_listen(const char *port, const char *binding,
|
403
|
+
struct http_settings_s);
|
400
404
|
/** Listens to HTTP connections at the specified `port` and `binding`. */
|
401
405
|
#define http_listen(port, binding, ...) \
|
402
406
|
http_listen((port), (binding), (struct http_settings_s){__VA_ARGS__})
|
@@ -424,24 +428,23 @@ int http_listen(const char *port, const char *binding, struct http_settings_s);
|
|
424
428
|
* signature. However, it would be better to use the `websocket_connect`
|
425
429
|
* function instead.
|
426
430
|
*
|
427
|
-
* Returns -1 on error and
|
428
|
-
*
|
431
|
+
* Returns -1 on error and the socket's uuid on success.
|
432
|
+
*
|
433
|
+
* The `on_finish` callback is always called.
|
429
434
|
*/
|
430
|
-
|
435
|
+
intptr_t http_connect(const char *address, struct http_settings_s);
|
431
436
|
#define http_connect(address, ...) \
|
432
437
|
http_connect((address), (struct http_settings_s){__VA_ARGS__})
|
433
438
|
|
434
439
|
/**
|
435
|
-
* Returns the settings used to setup the connection.
|
436
|
-
*
|
437
|
-
* Returns -1 on error and 0 on success.
|
440
|
+
* Returns the settings used to setup the connection or NULL on error.
|
438
441
|
*/
|
439
442
|
struct http_settings_s *http_settings(http_s *h);
|
440
443
|
|
441
444
|
/**
|
442
445
|
* Returns the direct address of the connected peer (likely an intermediary).
|
443
446
|
*/
|
444
|
-
|
447
|
+
fio_str_info_s http_peer_addr(http_s *h);
|
445
448
|
|
446
449
|
/**
|
447
450
|
* Hijacks the socket away from the HTTP protocol and away from facil.io.
|
@@ -452,7 +455,7 @@ sock_peer_addr_s http_peer_addr(http_s *h);
|
|
452
455
|
* It's possible to call `http_finish` immediately after calling `http_hijack`
|
453
456
|
* in order to send the outgoing headers.
|
454
457
|
*
|
455
|
-
* If any
|
458
|
+
* If any additional HTTP functions are called after the hijacking, the protocol
|
456
459
|
* object might attempt to continue reading data from the buffer.
|
457
460
|
*
|
458
461
|
* Returns the underlining socket connection's uuid. If `leftover` isn't NULL,
|
@@ -462,7 +465,7 @@ sock_peer_addr_s http_peer_addr(http_s *h);
|
|
462
465
|
* WARNING: this isn't a good way to handle HTTP connections, especially as
|
463
466
|
* HTTP/2 enters the picture.
|
464
467
|
*/
|
465
|
-
intptr_t http_hijack(http_s *h,
|
468
|
+
intptr_t http_hijack(http_s *h, fio_str_info_s *leftover);
|
466
469
|
|
467
470
|
/* *****************************************************************************
|
468
471
|
Websocket Upgrade (Server and Client connection establishment)
|
@@ -478,12 +481,10 @@ Websocket Upgrade (Server and Client connection establishment)
|
|
478
481
|
typedef struct ws_s ws_s;
|
479
482
|
|
480
483
|
/**
|
481
|
-
* This struct is used for the named
|
484
|
+
* This struct is used for the named arguments in the `http_upgrade2ws`
|
482
485
|
* function and macro.
|
483
486
|
*/
|
484
487
|
typedef struct {
|
485
|
-
/** REQUIRED: The `http_s` to be initiating the websocket connection.*/
|
486
|
-
http_s *http;
|
487
488
|
/**
|
488
489
|
* The (optional) on_message callback will be called whenever a websocket
|
489
490
|
* message is received for this connection.
|
@@ -492,7 +493,7 @@ typedef struct {
|
|
492
493
|
* overwritten once the function exits (it cannot be saved for later, but it
|
493
494
|
* can be copied).
|
494
495
|
*/
|
495
|
-
void (*on_message)(ws_s *ws,
|
496
|
+
void (*on_message)(ws_s *ws, fio_str_info_s msg, uint8_t is_text);
|
496
497
|
/**
|
497
498
|
* The (optional) on_open callback will be called once the websocket
|
498
499
|
* connection is established and before is is registered with `facil`, so no
|
@@ -518,7 +519,7 @@ typedef struct {
|
|
518
519
|
*
|
519
520
|
* The `uuid` is the connection's unique ID that can identify the Websocket. A
|
520
521
|
* value of `uuid == 0` indicates the Websocket connection wasn't established
|
521
|
-
* (an error
|
522
|
+
* (an error occurred).
|
522
523
|
*
|
523
524
|
* The `udata` is the user data as set during the upgrade or using the
|
524
525
|
* `websocket_udata_set` function.
|
@@ -540,7 +541,7 @@ typedef struct {
|
|
540
541
|
* A client connection's `on_finish` callback will be called (since the HTTP
|
541
542
|
* stage has finished).
|
542
543
|
*/
|
543
|
-
int http_upgrade2ws(websocket_settings_s);
|
544
|
+
int http_upgrade2ws(http_s *http, websocket_settings_s);
|
544
545
|
|
545
546
|
/** This macro allows easy access to the `http_upgrade2ws` function. The macro
|
546
547
|
* allows the use of named arguments, using the `websocket_settings_s` struct
|
@@ -555,8 +556,8 @@ int http_upgrade2ws(websocket_settings_s);
|
|
555
556
|
* http_upgrade2ws( .http = h, .on_message = on_message);
|
556
557
|
* }
|
557
558
|
*/
|
558
|
-
#define http_upgrade2ws(...)
|
559
|
-
http_upgrade2ws((websocket_settings_s){__VA_ARGS__})
|
559
|
+
#define http_upgrade2ws(http, ...) \
|
560
|
+
http_upgrade2ws((http), (websocket_settings_s){__VA_ARGS__})
|
560
561
|
|
561
562
|
/**
|
562
563
|
* Connects to a Websocket service according to the provided address.
|
@@ -574,7 +575,7 @@ int websocket_connect(const char *address, websocket_settings_s settings);
|
|
574
575
|
#define websocket_connect(address, ...) \
|
575
576
|
websocket_connect((address), (websocket_settings_s){__VA_ARGS__})
|
576
577
|
|
577
|
-
#include
|
578
|
+
#include <websockets.h>
|
578
579
|
|
579
580
|
/* *****************************************************************************
|
580
581
|
EventSource Support (SSE)
|
@@ -587,7 +588,7 @@ EventSource Support (SSE)
|
|
587
588
|
typedef struct http_sse_s http_sse_s;
|
588
589
|
|
589
590
|
/**
|
590
|
-
* This struct is used for the named
|
591
|
+
* This struct is used for the named arguments in the `http_upgrade2sse`
|
591
592
|
* function and macro.
|
592
593
|
*/
|
593
594
|
struct http_sse_s {
|
@@ -612,12 +613,8 @@ struct http_sse_s {
|
|
612
613
|
* The (optional) on_close callback will be called once a connection is
|
613
614
|
* terminated or failed to be established.
|
614
615
|
*
|
615
|
-
* The `
|
616
|
-
*
|
617
|
-
* (an error occured).
|
618
|
-
*
|
619
|
-
* The `udata` is the user data as set during the upgrade or using the
|
620
|
-
* `websocket_udata_set` function.
|
616
|
+
* The `udata` passed to the `http_upgrade2sse` function is available
|
617
|
+
* through the `http_sse_s` pointer (`sse->udata`).
|
621
618
|
*/
|
622
619
|
void (*on_close)(http_sse_s *sse);
|
623
620
|
/** Opaque user data. */
|
@@ -627,7 +624,7 @@ struct http_sse_s {
|
|
627
624
|
/**
|
628
625
|
* Upgrades an HTTP connection to an EventSource (SSE) connection.
|
629
626
|
*
|
630
|
-
*
|
627
|
+
* The `http_s` handle will be invalid after this call.
|
631
628
|
*
|
632
629
|
* On HTTP/1.1 connections, this will preclude future requests using the same
|
633
630
|
* connection.
|
@@ -639,9 +636,7 @@ int http_upgrade2sse(http_s *h, http_sse_s);
|
|
639
636
|
* members. i.e.:
|
640
637
|
*
|
641
638
|
* on_open_sse(sse_s * sse) {
|
642
|
-
*
|
643
|
-
* FIOBJ ch = (FIOBJ)sse->udata;
|
644
|
-
* http_sse_subscribe(ch, NULL, NULL); // a simple echo example
|
639
|
+
* http_sse_subscribe(sse, .channel = CHANNEL_NAME);
|
645
640
|
* }
|
646
641
|
*
|
647
642
|
* on_upgrade(http_s* h) {
|
@@ -657,30 +652,29 @@ int http_upgrade2sse(http_s *h, http_sse_s);
|
|
657
652
|
void http_sse_set_timout(http_sse_s *sse, uint8_t timeout);
|
658
653
|
|
659
654
|
struct http_sse_subscribe_args {
|
660
|
-
/** The channel
|
661
|
-
|
655
|
+
/** The channel name used for the subscription. */
|
656
|
+
fio_str_info_s channel;
|
662
657
|
/** The optional on message callback. If missing, Data is directly writen. */
|
663
|
-
void (*on_message)(http_sse_s *sse,
|
658
|
+
void (*on_message)(http_sse_s *sse, fio_str_info_s channel,
|
659
|
+
fio_str_info_s msg, void *udata);
|
664
660
|
/** An optional callback for when a subscription is fully canceled. */
|
665
661
|
void (*on_unsubscribe)(void *udata);
|
666
662
|
/** Opaque user */
|
667
663
|
void *udata;
|
668
|
-
/**
|
669
|
-
|
664
|
+
/** A callback for pattern matching. */
|
665
|
+
fio_match_fn match;
|
670
666
|
};
|
671
667
|
|
672
668
|
/**
|
673
|
-
* Subscribes to a channel. See {struct
|
674
|
-
* arguments.
|
669
|
+
* Subscribes to a channel for direct message deliverance. See {struct
|
670
|
+
* http_sse_subscribe_args} for possible arguments.
|
675
671
|
*
|
676
672
|
* Returns a subscription ID on success and 0 on failure.
|
677
673
|
*
|
678
|
-
*
|
674
|
+
* To unsubscripbe from the channel, use `http_sse_unsubscribe` (NOT
|
675
|
+
* `fio_unsubscribe`).
|
679
676
|
*
|
680
|
-
*
|
681
|
-
* will be merged. However, another subscription ID will be assigned, and two
|
682
|
-
* calls to {http_sse_unsubscribe} will be required in order to unregister from
|
683
|
-
* the channel.
|
677
|
+
* All subscriptions are automatically cleared once the connection is closed.
|
684
678
|
*/
|
685
679
|
uintptr_t http_sse_subscribe(http_sse_s *sse,
|
686
680
|
struct http_sse_subscribe_args args);
|
@@ -703,10 +697,10 @@ void http_sse_unsubscribe(http_sse_s *sse, uintptr_t subscription);
|
|
703
697
|
* https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events
|
704
698
|
*/
|
705
699
|
struct http_sse_write_args {
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
intptr_t retry;
|
700
|
+
fio_str_info_s id; /* (optional) sets the `id` event property. */
|
701
|
+
fio_str_info_s event; /* (optional) sets the `event` event property. */
|
702
|
+
fio_str_info_s data; /* (optional) sets the `data` event property. */
|
703
|
+
intptr_t retry; /* (optional) sets the `retry` event property. */
|
710
704
|
};
|
711
705
|
|
712
706
|
/**
|
@@ -719,7 +713,7 @@ int http_sse_write(http_sse_s *sse, struct http_sse_write_args);
|
|
719
713
|
http_sse_write((sse), (struct http_sse_write_args){__VA_ARGS__})
|
720
714
|
|
721
715
|
/**
|
722
|
-
* Get the connection's UUID (for
|
716
|
+
* Get the connection's UUID (for `fio_defer_io_task`, pub/sub, etc').
|
723
717
|
*/
|
724
718
|
intptr_t http_sse2uuid(http_sse_s *sse);
|
725
719
|
|
@@ -787,10 +781,10 @@ void http_parse_cookies(http_s *h, uint8_t is_url_encoded);
|
|
787
781
|
* * "name[][key]" references a nested Hash within an array. Hash keys will be
|
788
782
|
* unique (repeating a key advances the hash).
|
789
783
|
* * These rules can be nested (i.e. "name[][key1][][key2]...")
|
790
|
-
* * "name[][]" is an error (there's no way for the parser to
|
791
|
-
*
|
784
|
+
* * "name[][]" is an error (there's no way for the parser to analyze
|
785
|
+
* dimensions)
|
792
786
|
*
|
793
|
-
* Note: names can't
|
787
|
+
* Note: names can't begin with "[" or end with "]" as these are reserved
|
794
788
|
* characters.
|
795
789
|
*/
|
796
790
|
int http_add2hash(FIOBJ dest, char *name, size_t name_len, char *value,
|
@@ -805,12 +799,12 @@ int http_add2hash(FIOBJ dest, char *name, size_t name_len, char *value,
|
|
805
799
|
* * "name[]" references a nested Array (nested in the Hash).
|
806
800
|
* * "name[key]" references a nested Hash.
|
807
801
|
* * "name[][key]" references a nested Hash within an array. Hash keys will be
|
808
|
-
* unique (repeating a key advances the
|
802
|
+
* unique (repeating a key advances the array).
|
809
803
|
* * These rules can be nested (i.e. "name[][key1][][key2]...")
|
810
|
-
* * "name[][]" is an error (there's no way for the parser to
|
811
|
-
*
|
804
|
+
* * "name[][]" is an error (there's no way for the parser to analyze
|
805
|
+
* dimensions)
|
812
806
|
*
|
813
|
-
* Note: names can't
|
807
|
+
* Note: names can't begin with "[" or end with "]" as these are reserved
|
814
808
|
* characters.
|
815
809
|
*/
|
816
810
|
int http_add2hash2(FIOBJ dest, char *name, size_t name_len, FIOBJ value,
|
@@ -821,7 +815,7 @@ HTTP Status Strings and Mime-Type helpers
|
|
821
815
|
***************************************************************************** */
|
822
816
|
|
823
817
|
/** Returns a human readable string related to the HTTP status number. */
|
824
|
-
|
818
|
+
fio_str_info_s http_status2str(uintptr_t status);
|
825
819
|
|
826
820
|
/** Registers a Mime-Type to be associated with the file extension. */
|
827
821
|
void http_mimetype_register(char *file_ext, size_t file_ext_len,
|
@@ -843,7 +837,7 @@ FIOBJ http_mimetype_find(char *file_ext, size_t file_ext_len);
|
|
843
837
|
*/
|
844
838
|
FIOBJ http_mimetype_find2(FIOBJ url);
|
845
839
|
|
846
|
-
/** Clears the Mime-Type registry (it will be
|
840
|
+
/** Clears the Mime-Type registry (it will be empty after this call). */
|
847
841
|
void http_mimetype_clear(void);
|
848
842
|
|
849
843
|
/* *****************************************************************************
|
@@ -912,7 +906,7 @@ size_t http_date2rfc2822(char *target, struct tm *tmbuf);
|
|
912
906
|
/**
|
913
907
|
* Prints Unix time to a HTTP time formatted string.
|
914
908
|
*
|
915
|
-
* This variation implements
|
909
|
+
* This variation implements cached results for faster processing, at the
|
916
910
|
* price of a less accurate string.
|
917
911
|
*/
|
918
912
|
size_t http_time2str(char *target, const time_t t);
|
@@ -930,10 +924,60 @@ ssize_t http_decode_url(char *dest, const char *url_data, size_t length);
|
|
930
924
|
/** Decodes the "path" part of a request, no buffer overflow protection. */
|
931
925
|
ssize_t http_decode_path_unsafe(char *dest, const char *url_data);
|
932
926
|
|
933
|
-
/**
|
927
|
+
/**
|
928
|
+
* Decodes the "path" part of an HTTP request, no buffer overflow protection.
|
934
929
|
*/
|
935
930
|
ssize_t http_decode_path(char *dest, const char *url_data, size_t length);
|
936
931
|
|
932
|
+
/* *****************************************************************************
|
933
|
+
HTTP URL parsing
|
934
|
+
***************************************************************************** */
|
935
|
+
|
936
|
+
/** the result returned by `http_url_parse` */
|
937
|
+
typedef struct {
|
938
|
+
fio_str_info_s scheme;
|
939
|
+
fio_str_info_s user;
|
940
|
+
fio_str_info_s password;
|
941
|
+
fio_str_info_s host;
|
942
|
+
fio_str_info_s port;
|
943
|
+
fio_str_info_s path;
|
944
|
+
fio_str_info_s query;
|
945
|
+
fio_str_info_s target;
|
946
|
+
} http_url_s;
|
947
|
+
|
948
|
+
/**
|
949
|
+
* Parses the URI returning it's components and their lengths (no decoding
|
950
|
+
* performed, doesn't accept decoded URIs).
|
951
|
+
*
|
952
|
+
* The returned string are NOT NUL terminated, they are merely locations within
|
953
|
+
* the original string.
|
954
|
+
*
|
955
|
+
* This function expects any of the following formats:
|
956
|
+
*
|
957
|
+
* * `/complete_path?query#target`
|
958
|
+
*
|
959
|
+
* i.e.: /index.html?page=1#list
|
960
|
+
*
|
961
|
+
* * `host:port/complete_path?query#target`
|
962
|
+
*
|
963
|
+
* i.e.:
|
964
|
+
* example.com
|
965
|
+
* example.com/index.html
|
966
|
+
* user:1234@example.com:8080
|
967
|
+
* example.com:8080/index.html
|
968
|
+
*
|
969
|
+
* * `schema://user:password@host:port/path?query#target`
|
970
|
+
*
|
971
|
+
* i.e.: http://example.com/index.html?page=1#list
|
972
|
+
*
|
973
|
+
* Invalid formats might produce unexpected results. No error testing performed.
|
974
|
+
*/
|
975
|
+
http_url_s http_url_parse(const char *url, size_t length);
|
976
|
+
|
977
|
+
#if DEBUG
|
978
|
+
void http_tests(void);
|
979
|
+
#endif
|
980
|
+
|
937
981
|
/* support C++ */
|
938
982
|
#ifdef __cplusplus
|
939
983
|
}
|