iodine 0.7.58 → 0.7.59
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/README.md +8 -8
- data/SECURITY.md +32 -0
- data/ext/iodine/fio.c +1 -1
- data/ext/iodine/fio.h +12 -14
- data/ext/iodine/fio_json_parser.h +5 -4
- data/ext/iodine/fiobj_data.c +13 -11
- data/ext/iodine/fiobj_str.h +1 -1
- data/ext/iodine/fiobject.h +5 -4
- data/ext/iodine/http1.c +92 -7
- data/ext/iodine/http1_parser.h +164 -1121
- data/ext/iodine/iodine_store.c +23 -19
- data/ext/iodine/websockets.c +7 -16
- data/lib/iodine/version.rb +1 -1
- data/lib/iodine.rb +4 -0
- metadata +5 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b701f0b79a433993d53684b5ce564356f1317e0a23060a0a9c7f729d8857d3bb
|
|
4
|
+
data.tar.gz: 1abd95637405ccc2990d00d771e61c25cc075e8d819da47205879e151099d546
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4d35fb80524542d8dbaf5a9d0b8c36fbe2b8a82801d3957559573d6141bd109537ea64f4d1bee905b16b37b6b80bc998403e5da8476aaeee2c19cb009f23b9cd
|
|
7
|
+
data.tar.gz: d7ddbe875e12102ab71557391c8be4eedd9d0735d9734bfddfcbf600af0a3867ab1f0ea159f1a2ad61f823772d300732a0907e20cc1f30941e5ec211d3268068
|
data/README.md
CHANGED
|
@@ -33,7 +33,7 @@ Iodine includes native support for:
|
|
|
33
33
|
|
|
34
34
|
Since iodine wraps much of the [C facil.io framework](https://github.com/boazsegev/facil.io) for Ruby:
|
|
35
35
|
|
|
36
|
-
* Iodine can handle **thousands of concurrent connections** (tested with more
|
|
36
|
+
* Iodine can handle **thousands of concurrent connections** (tested with more than 20K connections on Linux)!
|
|
37
37
|
|
|
38
38
|
* Iodine is ideal for **Linux/Unix** based systems (i.e. macOS, Ubuntu, FreeBSD etc'), which are ideal for evented IO (while Windows and Solaris are better at IO *completion* events, which are very different).
|
|
39
39
|
|
|
@@ -45,7 +45,7 @@ Iodine is a C extension for Ruby, developed and optimized for Ruby MRI 2.3 and u
|
|
|
45
45
|
|
|
46
46
|
Iodine includes a light and fast HTTP and Websocket server written in C that was written according to the [Rack interface specifications](http://www.rubydoc.info/github/rack/rack/master/file/SPEC) and the [Websocket draft extension](./SPEC-Websocket-Draft.md).
|
|
47
47
|
|
|
48
|
-
With `Iodine.listen service: :http` it's possible to run multiple HTTP applications (but please remember not to set more than a single application on a single TCP/IP port).
|
|
48
|
+
With `Iodine.listen service: :http` it's possible to run multiple HTTP applications (but please remember not to set more than a single application on a single TCP/IP port).
|
|
49
49
|
|
|
50
50
|
Iodine also supports native process cluster Pub/Sub and a native RedisEngine to easily scale iodine's Pub/Sub horizontally.
|
|
51
51
|
|
|
@@ -278,11 +278,11 @@ module WebsocketChat
|
|
|
278
278
|
extend self
|
|
279
279
|
end
|
|
280
280
|
APP = Proc.new do |env|
|
|
281
|
-
if env['rack.upgrade?'.freeze] == :websocket
|
|
282
|
-
env['rack.upgrade'.freeze] = WebsocketChat
|
|
281
|
+
if env['rack.upgrade?'.freeze] == :websocket
|
|
282
|
+
env['rack.upgrade'.freeze] = WebsocketChat
|
|
283
283
|
[0,{}, []] # It's possible to set cookies for the response.
|
|
284
284
|
elsif env['rack.upgrade?'.freeze] == :sse
|
|
285
|
-
puts "SSE connections can only receive data from the server, the can't write."
|
|
285
|
+
puts "SSE connections can only receive data from the server, the can't write."
|
|
286
286
|
env['rack.upgrade'.freeze] = WebsocketChat
|
|
287
287
|
[0,{}, []] # It's possible to set cookies for the response.
|
|
288
288
|
else
|
|
@@ -556,7 +556,7 @@ Iodine is written in C and allows some compile-time customizations, such as:
|
|
|
556
556
|
* `FIO_MAX_SOCK_CAPACITY` - limits iodine's maximum client capacity. Defaults to 131,072 clients.
|
|
557
557
|
|
|
558
558
|
* `FIO_USE_RISKY_HASH` - replaces SipHash with RiskyHash for iodine's internal hash maps.
|
|
559
|
-
|
|
559
|
+
|
|
560
560
|
Since iodine hash maps have internal protection against collisions and hash flooding attacks, it's possible for iodine to leverage RiskyHash, which is faster than SipHash.
|
|
561
561
|
|
|
562
562
|
By default, SipHash will be used. This is a community related choice, since the community seems to believe a hash function should protect the hash map rather than it being enough for a hash map implementation to be attack resistance.
|
|
@@ -611,7 +611,7 @@ end
|
|
|
611
611
|
|
|
612
612
|
In pure Ruby (without using C extensions or Java), it's possible to do the same by using `select`... and although `select` has some issues, it could work well for lighter loads.
|
|
613
613
|
|
|
614
|
-
The server events are fairly fast and fragmented (longer code is fragmented across multiple events), so one thread is enough to run the server including it's static file service and everything...
|
|
614
|
+
The server events are fairly fast and fragmented (longer code is fragmented across multiple events), so one thread is enough to run the server including it's static file service and everything...
|
|
615
615
|
|
|
616
616
|
...but single threaded mode should probably be avoided.
|
|
617
617
|
|
|
@@ -642,7 +642,7 @@ If you have the development headers but still can't compile the iodine extension
|
|
|
642
642
|
|
|
643
643
|
## Mr. Sandman, write me a server
|
|
644
644
|
|
|
645
|
-
Iodine allows custom TCP/IP server authoring, for those cases where we need raw TCP/IP (UDP isn't supported just yet).
|
|
645
|
+
Iodine allows custom TCP/IP server authoring, for those cases where we need raw TCP/IP (UDP isn't supported just yet).
|
|
646
646
|
|
|
647
647
|
Here's a short and sweet echo server - No HTTP, just use `telnet`:
|
|
648
648
|
|
data/SECURITY.md
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
Please report any security issues you discover on GitHub using the [`Security and quality`](https://github.com/boazsegev/iodine/security) reporting form.
|
|
4
|
+
|
|
5
|
+
Please remember that this is an open source project that I work on in my free time. Take it as is, I don't promise anything.
|
|
6
|
+
|
|
7
|
+
## Supported Versions
|
|
8
|
+
|
|
9
|
+
I support what I have time to support, with my main focus being:
|
|
10
|
+
|
|
11
|
+
| Version | Support |
|
|
12
|
+
| ------- | ------------------ |
|
|
13
|
+
| 0.8.x | :green_circle: |
|
|
14
|
+
| 0.7.x | :orange_circle: |
|
|
15
|
+
| < 0.7.0 | :red_circle: |
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
### [facil.io](https://facil.io) Security Issues
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
| Version | facil.io link |
|
|
23
|
+
| ------- | ------------------ |
|
|
24
|
+
| 0.8.x | https://github.com/facil-io/cstl/security |
|
|
25
|
+
| 0.7.x | https://github.com/boazsegev/facil.io/security |
|
|
26
|
+
| < 0.7.0 | :red_circle: |
|
|
27
|
+
|
|
28
|
+
## Reporting a Vulnerability
|
|
29
|
+
|
|
30
|
+
Please report any security issues you discover on GitHub using the [`Security and quality`](https://github.com/boazsegev/iodine/security) reporting form or privately using email.
|
|
31
|
+
|
|
32
|
+
Usually I implement a security patch for the version reported before porting to the current developer version. Please note that it's usually possible to port the patch manually if you don't want to upgrade an older version.
|
data/ext/iodine/fio.c
CHANGED
|
@@ -3385,7 +3385,7 @@ read_error:
|
|
|
3385
3385
|
static int fio_sock_sendfile_from_fd(int fd, fio_packet_s *packet) {
|
|
3386
3386
|
ssize_t sent;
|
|
3387
3387
|
sent =
|
|
3388
|
-
|
|
3388
|
+
sendfile(fd, packet->data.fd, (off_t *)&packet->offset, packet->length);
|
|
3389
3389
|
if (sent < 0)
|
|
3390
3390
|
return -1;
|
|
3391
3391
|
packet->length -= sent;
|
data/ext/iodine/fio.h
CHANGED
|
@@ -109,7 +109,7 @@ Version and helper macros
|
|
|
109
109
|
|
|
110
110
|
#define FIO_VERSION_MAJOR 0
|
|
111
111
|
#define FIO_VERSION_MINOR 7
|
|
112
|
-
#define FIO_VERSION_PATCH
|
|
112
|
+
#define FIO_VERSION_PATCH 7
|
|
113
113
|
#define FIO_VERSION_BETA 0
|
|
114
114
|
|
|
115
115
|
/* Automatically convert version data to a string constant - ignore these two */
|
|
@@ -221,6 +221,7 @@ Version and helper macros
|
|
|
221
221
|
#include <unistd.h>
|
|
222
222
|
#ifdef __MINGW32__
|
|
223
223
|
#include <winsock2.h>
|
|
224
|
+
|
|
224
225
|
#include <winsock.h>
|
|
225
226
|
#include <ws2tcpip.h>
|
|
226
227
|
#endif
|
|
@@ -251,10 +252,10 @@ Version and helper macros
|
|
|
251
252
|
#endif
|
|
252
253
|
|
|
253
254
|
#ifdef __MINGW32__
|
|
254
|
-
#define
|
|
255
|
-
#define __S_IFLNK
|
|
256
|
-
#define
|
|
257
|
-
#define S_ISLNK(mode)
|
|
255
|
+
#define __S_IFMT 0170000
|
|
256
|
+
#define __S_IFLNK 0120000
|
|
257
|
+
#define __S_ISTYPE(mode, mask) (((mode)&__S_IFMT) == (mask))
|
|
258
|
+
#define S_ISLNK(mode) __S_ISTYPE((mode), __S_IFLNK)
|
|
258
259
|
|
|
259
260
|
#define SIGKILL 9
|
|
260
261
|
#define SIGTERM 15
|
|
@@ -4743,14 +4744,11 @@ static FIO_ARY_TYPE const FIO_NAME(s___const_invalid_object);
|
|
|
4743
4744
|
/* minimizes allocation "dead space" by alligning allocated length to 16bytes */
|
|
4744
4745
|
#undef FIO_ARY_SIZE2WORDS
|
|
4745
4746
|
#define FIO_ARY_SIZE2WORDS(size) \
|
|
4746
|
-
((sizeof(FIO_ARY_TYPE) & 1)
|
|
4747
|
-
|
|
4748
|
-
|
|
4749
|
-
|
|
4750
|
-
|
|
4751
|
-
? (((size) & (~3)) + 4) \
|
|
4752
|
-
: (sizeof(FIO_ARY_TYPE) & 8) ? (((size) & (~1)) + 2) \
|
|
4753
|
-
: (size))
|
|
4747
|
+
((sizeof(FIO_ARY_TYPE) & 1) ? (((size) & (~15)) + 16) \
|
|
4748
|
+
: (sizeof(FIO_ARY_TYPE) & 2) ? (((size) & (~7)) + 8) \
|
|
4749
|
+
: (sizeof(FIO_ARY_TYPE) & 4) ? (((size) & (~3)) + 4) \
|
|
4750
|
+
: (sizeof(FIO_ARY_TYPE) & 8) ? (((size) & (~1)) + 2) \
|
|
4751
|
+
: (size))
|
|
4754
4752
|
|
|
4755
4753
|
/* *****************************************************************************
|
|
4756
4754
|
Array API
|
|
@@ -6048,7 +6046,7 @@ FIO_NAME(_insert_or_overwrite_)(FIO_NAME(s) * set, FIO_SET_HASH_TYPE hash_value,
|
|
|
6048
6046
|
pos->hash = hash_value;
|
|
6049
6047
|
pos->pos->hash = hash_value;
|
|
6050
6048
|
FIO_SET_COPY(pos->pos->obj, obj);
|
|
6051
|
-
|
|
6049
|
+
|
|
6052
6050
|
return pos->pos->obj;
|
|
6053
6051
|
}
|
|
6054
6052
|
|
|
@@ -393,7 +393,7 @@ fio_json_parse(json_parser_s *parser, const char *buffer, size_t length) {
|
|
|
393
393
|
goto error;
|
|
394
394
|
break;
|
|
395
395
|
case ']':
|
|
396
|
-
if ((parser->dict & 1))
|
|
396
|
+
if ((parser->dict & 1) || !parser->depth)
|
|
397
397
|
goto error;
|
|
398
398
|
--parser->depth;
|
|
399
399
|
++pos;
|
|
@@ -453,12 +453,12 @@ fio_json_parse(json_parser_s *parser, const char *buffer, size_t length) {
|
|
|
453
453
|
long long i = fio_atol((char **)&tmp);
|
|
454
454
|
if (tmp > limit)
|
|
455
455
|
goto stop;
|
|
456
|
-
if (!tmp || JSON_NUMERAL[*tmp]) {
|
|
456
|
+
if (!tmp || tmp == pos || JSON_NUMERAL[*tmp]) {
|
|
457
457
|
tmp = pos;
|
|
458
458
|
double f = fio_atof((char **)&tmp);
|
|
459
459
|
if (tmp > limit)
|
|
460
460
|
goto stop;
|
|
461
|
-
if (!tmp || JSON_NUMERAL[*tmp])
|
|
461
|
+
if (!tmp || tmp == pos || JSON_NUMERAL[*tmp])
|
|
462
462
|
goto error;
|
|
463
463
|
fio_json_on_float(parser, f);
|
|
464
464
|
pos = tmp;
|
|
@@ -481,8 +481,9 @@ fio_json_parse(json_parser_s *parser, const char *buffer, size_t length) {
|
|
|
481
481
|
if (pos[1] == '*') {
|
|
482
482
|
if (pos + 4 > limit)
|
|
483
483
|
goto stop;
|
|
484
|
-
uint8_t *tmp = pos +
|
|
484
|
+
uint8_t *tmp = pos + 2; /* avoid this: /*/
|
|
485
485
|
do {
|
|
486
|
+
++tmp;
|
|
486
487
|
tmp = memchr(tmp, '/', (uintptr_t)(limit - tmp));
|
|
487
488
|
} while (tmp && tmp[-1] != '*');
|
|
488
489
|
if (!tmp)
|
data/ext/iodine/fiobj_data.c
CHANGED
|
@@ -63,6 +63,17 @@ Object required VTable and functions
|
|
|
63
63
|
} \
|
|
64
64
|
} while (0)
|
|
65
65
|
|
|
66
|
+
static inline int64_t fiobj_data_get_fd_size(const FIOBJ o) {
|
|
67
|
+
struct stat stat;
|
|
68
|
+
retry:
|
|
69
|
+
if (fstat(obj2io(o)->fd, &stat)) {
|
|
70
|
+
if (errno == EINTR)
|
|
71
|
+
goto retry;
|
|
72
|
+
return -1;
|
|
73
|
+
}
|
|
74
|
+
return stat.st_size;
|
|
75
|
+
}
|
|
76
|
+
|
|
66
77
|
static void fiobj_data_copy_buffer(FIOBJ o) {
|
|
67
78
|
obj2io(o)->capa = (((obj2io(o)->len) >> 12) + 1) << 12;
|
|
68
79
|
void *tmp = fio_malloc(obj2io(o)->capa);
|
|
@@ -145,17 +156,6 @@ static inline void fiobj_data_pre_write(FIOBJ o, uintptr_t length) {
|
|
|
145
156
|
REQUIRE_MEM(obj2io(o)->buffer);
|
|
146
157
|
}
|
|
147
158
|
|
|
148
|
-
static inline int64_t fiobj_data_get_fd_size(const FIOBJ o) {
|
|
149
|
-
struct stat stat;
|
|
150
|
-
retry:
|
|
151
|
-
if (fstat(obj2io(o)->fd, &stat)) {
|
|
152
|
-
if (errno == EINTR)
|
|
153
|
-
goto retry;
|
|
154
|
-
return -1;
|
|
155
|
-
}
|
|
156
|
-
return stat.st_size;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
159
|
static FIOBJ fiobj_data_alloc(void *buffer, int fd) {
|
|
160
160
|
fiobj_data_s *io = fio_malloc(sizeof(*io));
|
|
161
161
|
REQUIRE_MEM(io);
|
|
@@ -963,6 +963,7 @@ intptr_t fiobj_data_write(FIOBJ io, void *buffer, uintptr_t length) {
|
|
|
963
963
|
/* Unslice slices */
|
|
964
964
|
if (obj2io(io)->fd == -2)
|
|
965
965
|
fiobj_data_assert_dynamic(io);
|
|
966
|
+
|
|
966
967
|
if (obj2io(io)->fd == -1) {
|
|
967
968
|
/* String Code */
|
|
968
969
|
fiobj_data_pre_write(io, length + 1);
|
|
@@ -971,6 +972,7 @@ intptr_t fiobj_data_write(FIOBJ io, void *buffer, uintptr_t length) {
|
|
|
971
972
|
obj2io(io)->buffer[obj2io(io)->len] = 0;
|
|
972
973
|
return length;
|
|
973
974
|
}
|
|
975
|
+
|
|
974
976
|
/* File Code */
|
|
975
977
|
return pwrite(obj2io(io)->fd, buffer, length, fiobj_data_get_fd_size(io));
|
|
976
978
|
}
|
data/ext/iodine/fiobj_str.h
CHANGED
|
@@ -38,7 +38,7 @@ static inline __attribute__((unused)) FIOBJ fiobj_str_copy(FIOBJ src) {
|
|
|
38
38
|
/**
|
|
39
39
|
* Creates a String object. Remember to use `fiobj_free`.
|
|
40
40
|
*
|
|
41
|
-
* It's possible to wrap a
|
|
41
|
+
* It's possible to wrap a previously allocated memory block in a FIOBJ String
|
|
42
42
|
* object, as long as it was allocated using `fio_malloc`.
|
|
43
43
|
*
|
|
44
44
|
* The ownership of the memory indicated by `str` will "move" to the object and
|
data/ext/iodine/fiobject.h
CHANGED
|
@@ -147,10 +147,10 @@ FIO_INLINE double fiobj_obj2float(const FIOBJ obj);
|
|
|
147
147
|
/**
|
|
148
148
|
* Returns a C String (NUL terminated) using the `fio_str_info_s` data type.
|
|
149
149
|
*
|
|
150
|
-
* The
|
|
151
|
-
* a terminating NUL.
|
|
150
|
+
* The String is binary safe and might contain NUL bytes in the middle as well
|
|
151
|
+
* as a terminating NUL.
|
|
152
152
|
*
|
|
153
|
-
* If a
|
|
153
|
+
* If a Number or a Float are passed to the function, they
|
|
154
154
|
* will be parsed as a *temporary*, thread-safe, String.
|
|
155
155
|
*
|
|
156
156
|
* Numbers will be represented in base 10 numerical data.
|
|
@@ -270,7 +270,8 @@ FIO_INLINE size_t fiobj_type_is(FIOBJ o, fiobj_type_enum type) {
|
|
|
270
270
|
switch (type) {
|
|
271
271
|
case FIOBJ_T_NUMBER:
|
|
272
272
|
return (o & FIOBJECT_NUMBER_FLAG) ||
|
|
273
|
-
((
|
|
273
|
+
(o && !(o & FIOBJECT_PRIMITIVE_FLAG) &&
|
|
274
|
+
((fiobj_type_enum *)o)[0] == FIOBJ_T_NUMBER);
|
|
274
275
|
case FIOBJ_T_NULL:
|
|
275
276
|
return !o || o == fiobj_null();
|
|
276
277
|
case FIOBJ_T_TRUE:
|
data/ext/iodine/http1.c
CHANGED
|
@@ -45,6 +45,8 @@ inline static void h1_reset(http1pr_s *p) { p->header_size = 0; }
|
|
|
45
45
|
#define http1_pr2handle(pr) (((http1pr_s *)(pr))->request)
|
|
46
46
|
#define handle2pr(h) ((http1pr_s *)h->private_data.flag)
|
|
47
47
|
|
|
48
|
+
static fio_str_info_s http1pr_status2str(uintptr_t status);
|
|
49
|
+
|
|
48
50
|
/* cleanup an HTTP/1.1 handler object */
|
|
49
51
|
static inline void http1_after_finish(http_s *h) {
|
|
50
52
|
http1pr_s *p = handle2pr(h);
|
|
@@ -110,10 +112,8 @@ static FIOBJ headers2str(http_s *h, uintptr_t padding) {
|
|
|
110
112
|
http1pr_s *p = handle2pr(h);
|
|
111
113
|
|
|
112
114
|
if (p->is_client == 0) {
|
|
113
|
-
fio_str_info_s t =
|
|
114
|
-
fiobj_str_write(w.dest, "HTTP/1.1 ", 9);
|
|
115
|
+
fio_str_info_s t = http1pr_status2str(h->status);
|
|
115
116
|
fiobj_str_write(w.dest, t.data, t.len);
|
|
116
|
-
fiobj_str_write(w.dest, "\r\n", 2);
|
|
117
117
|
FIOBJ tmp = fiobj_hash_get2(h->private_data.out_headers, connection_hash);
|
|
118
118
|
if (tmp) {
|
|
119
119
|
t = fiobj_obj2cstr(tmp);
|
|
@@ -787,8 +787,7 @@ fio_protocol_s *http1_new(uintptr_t uuid, http_settings_s *settings,
|
|
|
787
787
|
if (unread_data && unread_length > HTTP_MAX_HEADER_LENGTH)
|
|
788
788
|
return NULL;
|
|
789
789
|
http1pr_s *p = fio_malloc(sizeof(*p) + HTTP_MAX_HEADER_LENGTH);
|
|
790
|
-
// FIO_LOG_DEBUG("Allocated HTTP/1.1 protocol %p
|
|
791
|
-
// (int)fio_uuid2fd(uuid), (void *)p);
|
|
790
|
+
// FIO_LOG_DEBUG("Allocated HTTP/1.1 protocol at. %p", (void *)p);
|
|
792
791
|
FIO_ASSERT_ALLOC(p);
|
|
793
792
|
*p = (http1pr_s){
|
|
794
793
|
.p.protocol =
|
|
@@ -819,7 +818,93 @@ void http1_destroy(fio_protocol_s *pr) {
|
|
|
819
818
|
http1pr_s *p = (http1pr_s *)pr;
|
|
820
819
|
http1_pr2handle(p).status = 0;
|
|
821
820
|
http_s_destroy(&http1_pr2handle(p), 0);
|
|
822
|
-
// FIO_LOG_DEBUG("Deallocating HTTP/1.1 protocol %p(%d)=>%p", (void
|
|
823
|
-
// *)p->p.uuid, (int)fio_uuid2fd(p->p.uuid), (void *)p);
|
|
824
821
|
fio_free(p); // occasional Windows crash bug
|
|
822
|
+
// FIO_LOG_DEBUG("Deallocated HTTP/1.1 protocol at. %p", (void *)p);
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
/* *****************************************************************************
|
|
826
|
+
Protocol Data
|
|
827
|
+
***************************************************************************** */
|
|
828
|
+
|
|
829
|
+
// clang-format off
|
|
830
|
+
#define HTTP_SET_STATUS_STR(status, str) [((status)-100)] = { .data = (char*)("HTTP/1.1 " #status " " str "\r\n"), .len = (sizeof("HTTP/1.1 " #status " " str "\r\n") - 1) }
|
|
831
|
+
// #undef HTTP_SET_STATUS_STR
|
|
832
|
+
// clang-format on
|
|
833
|
+
|
|
834
|
+
static fio_str_info_s http1pr_status2str(uintptr_t status) {
|
|
835
|
+
static fio_str_info_s status2str[] = {
|
|
836
|
+
HTTP_SET_STATUS_STR(100, "Continue"),
|
|
837
|
+
HTTP_SET_STATUS_STR(101, "Switching Protocols"),
|
|
838
|
+
HTTP_SET_STATUS_STR(102, "Processing"),
|
|
839
|
+
HTTP_SET_STATUS_STR(103, "Early Hints"),
|
|
840
|
+
HTTP_SET_STATUS_STR(200, "OK"),
|
|
841
|
+
HTTP_SET_STATUS_STR(201, "Created"),
|
|
842
|
+
HTTP_SET_STATUS_STR(202, "Accepted"),
|
|
843
|
+
HTTP_SET_STATUS_STR(203, "Non-Authoritative Information"),
|
|
844
|
+
HTTP_SET_STATUS_STR(204, "No Content"),
|
|
845
|
+
HTTP_SET_STATUS_STR(205, "Reset Content"),
|
|
846
|
+
HTTP_SET_STATUS_STR(206, "Partial Content"),
|
|
847
|
+
HTTP_SET_STATUS_STR(207, "Multi-Status"),
|
|
848
|
+
HTTP_SET_STATUS_STR(208, "Already Reported"),
|
|
849
|
+
HTTP_SET_STATUS_STR(226, "IM Used"),
|
|
850
|
+
HTTP_SET_STATUS_STR(300, "Multiple Choices"),
|
|
851
|
+
HTTP_SET_STATUS_STR(301, "Moved Permanently"),
|
|
852
|
+
HTTP_SET_STATUS_STR(302, "Found"),
|
|
853
|
+
HTTP_SET_STATUS_STR(303, "See Other"),
|
|
854
|
+
HTTP_SET_STATUS_STR(304, "Not Modified"),
|
|
855
|
+
HTTP_SET_STATUS_STR(305, "Use Proxy"),
|
|
856
|
+
HTTP_SET_STATUS_STR(306, "(Unused), "),
|
|
857
|
+
HTTP_SET_STATUS_STR(307, "Temporary Redirect"),
|
|
858
|
+
HTTP_SET_STATUS_STR(308, "Permanent Redirect"),
|
|
859
|
+
HTTP_SET_STATUS_STR(400, "Bad Request"),
|
|
860
|
+
HTTP_SET_STATUS_STR(403, "Forbidden"),
|
|
861
|
+
HTTP_SET_STATUS_STR(404, "Not Found"),
|
|
862
|
+
HTTP_SET_STATUS_STR(401, "Unauthorized"),
|
|
863
|
+
HTTP_SET_STATUS_STR(402, "Payment Required"),
|
|
864
|
+
HTTP_SET_STATUS_STR(405, "Method Not Allowed"),
|
|
865
|
+
HTTP_SET_STATUS_STR(406, "Not Acceptable"),
|
|
866
|
+
HTTP_SET_STATUS_STR(407, "Proxy Authentication Required"),
|
|
867
|
+
HTTP_SET_STATUS_STR(408, "Request Timeout"),
|
|
868
|
+
HTTP_SET_STATUS_STR(409, "Conflict"),
|
|
869
|
+
HTTP_SET_STATUS_STR(410, "Gone"),
|
|
870
|
+
HTTP_SET_STATUS_STR(411, "Length Required"),
|
|
871
|
+
HTTP_SET_STATUS_STR(412, "Precondition Failed"),
|
|
872
|
+
HTTP_SET_STATUS_STR(413, "Payload Too Large"),
|
|
873
|
+
HTTP_SET_STATUS_STR(414, "URI Too Long"),
|
|
874
|
+
HTTP_SET_STATUS_STR(415, "Unsupported Media Type"),
|
|
875
|
+
HTTP_SET_STATUS_STR(416, "Range Not Satisfiable"),
|
|
876
|
+
HTTP_SET_STATUS_STR(417, "Expectation Failed"),
|
|
877
|
+
HTTP_SET_STATUS_STR(421, "Misdirected Request"),
|
|
878
|
+
HTTP_SET_STATUS_STR(422, "Unprocessable Entity"),
|
|
879
|
+
HTTP_SET_STATUS_STR(423, "Locked"),
|
|
880
|
+
HTTP_SET_STATUS_STR(424, "Failed Dependency"),
|
|
881
|
+
HTTP_SET_STATUS_STR(425, "Unassigned"),
|
|
882
|
+
HTTP_SET_STATUS_STR(426, "Upgrade Required"),
|
|
883
|
+
HTTP_SET_STATUS_STR(427, "Unassigned"),
|
|
884
|
+
HTTP_SET_STATUS_STR(428, "Precondition Required"),
|
|
885
|
+
HTTP_SET_STATUS_STR(429, "Too Many Requests"),
|
|
886
|
+
HTTP_SET_STATUS_STR(430, "Unassigned"),
|
|
887
|
+
HTTP_SET_STATUS_STR(431, "Request Header Fields Too Large"),
|
|
888
|
+
HTTP_SET_STATUS_STR(500, "Internal Server Error"),
|
|
889
|
+
HTTP_SET_STATUS_STR(501, "Not Implemented"),
|
|
890
|
+
HTTP_SET_STATUS_STR(502, "Bad Gateway"),
|
|
891
|
+
HTTP_SET_STATUS_STR(503, "Service Unavailable"),
|
|
892
|
+
HTTP_SET_STATUS_STR(504, "Gateway Timeout"),
|
|
893
|
+
HTTP_SET_STATUS_STR(505, "HTTP Version Not Supported"),
|
|
894
|
+
HTTP_SET_STATUS_STR(506, "Variant Also Negotiates"),
|
|
895
|
+
HTTP_SET_STATUS_STR(507, "Insufficient Storage"),
|
|
896
|
+
HTTP_SET_STATUS_STR(508, "Loop Detected"),
|
|
897
|
+
HTTP_SET_STATUS_STR(509, "Unassigned"),
|
|
898
|
+
HTTP_SET_STATUS_STR(510, "Not Extended"),
|
|
899
|
+
HTTP_SET_STATUS_STR(511, "Network Authentication Required"),
|
|
900
|
+
};
|
|
901
|
+
fio_str_info_s ret = (fio_str_info_s){.len = 0, .data = NULL};
|
|
902
|
+
if (status >= 100 &&
|
|
903
|
+
(status - 100) < sizeof(status2str) / sizeof(status2str[0]))
|
|
904
|
+
ret = status2str[status - 100];
|
|
905
|
+
if (!ret.data) {
|
|
906
|
+
ret = status2str[400];
|
|
907
|
+
}
|
|
908
|
+
return ret;
|
|
825
909
|
}
|
|
910
|
+
#undef HTTP_SET_STATUS_STR
|