iodine 0.2.7 → 0.2.8
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 +9 -1
- data/README.md +5 -1
- data/ext/iodine/base64.c +3 -3
- data/ext/iodine/base64.h +3 -3
- data/ext/iodine/bscrypt-common.h +5 -5
- data/ext/iodine/bscrypt.h +4 -4
- data/ext/iodine/hex.c +11 -10
- data/ext/iodine/hex.h +3 -3
- data/ext/iodine/http.c +34 -27
- data/ext/iodine/http.h +15 -8
- data/ext/iodine/http1.c +63 -60
- data/ext/iodine/http1.h +10 -5
- data/ext/iodine/http1_simple_parser.c +6 -0
- data/ext/iodine/http1_simple_parser.h +10 -6
- data/ext/iodine/http_request.h +28 -22
- data/ext/iodine/http_response.c +22 -7
- data/ext/iodine/http_response.h +6 -0
- data/ext/iodine/http_response_http1.h +9 -1
- data/ext/iodine/iodine_core.c +6 -1
- data/ext/iodine/iodine_core.h +13 -6
- data/ext/iodine/iodine_http.c +6 -0
- data/ext/iodine/iodine_http.h +6 -0
- data/ext/iodine/iodine_websocket.c +23 -4
- data/ext/iodine/iodine_websocket.h +2 -2
- data/ext/iodine/libasync.c +5 -3
- data/ext/iodine/libasync.h +8 -8
- data/ext/iodine/libreact.c +8 -8
- data/ext/iodine/libreact.h +5 -5
- data/ext/iodine/libserver.c +2 -2
- data/ext/iodine/libserver.h +2 -2
- data/ext/iodine/libsock.c +2 -2
- data/ext/iodine/libsock.h +3 -3
- data/ext/iodine/mempool.h +826 -0
- data/ext/iodine/misc.c +14 -14
- data/ext/iodine/misc.h +3 -3
- data/ext/iodine/random.c +6 -6
- data/ext/iodine/random.h +3 -3
- data/ext/iodine/rb-call.c +6 -0
- data/ext/iodine/rb-call.h +2 -2
- data/ext/iodine/rb-libasync.h +5 -3
- data/ext/iodine/rb-rack-io.c +15 -3
- data/ext/iodine/rb-rack-io.h +5 -2
- data/ext/iodine/rb-registry.c +6 -0
- data/ext/iodine/rb-registry.h +2 -2
- data/ext/iodine/sha1.c +13 -11
- data/ext/iodine/sha1.h +3 -3
- data/ext/iodine/sha2.c +8 -6
- data/ext/iodine/sha2.h +3 -3
- data/ext/iodine/siphash.c +9 -2
- data/ext/iodine/siphash.h +8 -1
- data/ext/iodine/spnlock.h +9 -3
- data/ext/iodine/websockets.c +62 -38
- data/ext/iodine/websockets.h +6 -0
- data/ext/iodine/xor-crypt.c +3 -3
- data/ext/iodine/xor-crypt.h +3 -3
- data/lib/iodine/version.rb +1 -1
- metadata +3 -4
- data/ext/iodine/rb-call.c_old +0 -127
- data/ext/iodine/rb-registry_old.c_old +0 -213
data/ext/iodine/http1.h
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
/*
|
2
|
+
copyright: Boaz segev, 2016-2017
|
3
|
+
license: MIT
|
4
|
+
|
5
|
+
Feel free to copy, use and enjoy according to the license provided.
|
6
|
+
*/
|
1
7
|
#ifndef HTTP1_H
|
2
8
|
#define HTTP1_H
|
3
9
|
|
@@ -26,7 +32,7 @@ Any concurrent HTTP1 connections over this amount will be dynamically allocated.
|
|
26
32
|
#define HTTP1_POOL_SIZE (64) /* should be ~0.5Mb with default values*/
|
27
33
|
#endif
|
28
34
|
|
29
|
-
extern char*
|
35
|
+
extern char *HTTP1;
|
30
36
|
|
31
37
|
/**
|
32
38
|
Allocates memory for an HTTP/1.1 protocol.
|
@@ -35,17 +41,16 @@ The protocol self destructs when the `on_close` callback is called.
|
|
35
41
|
|
36
42
|
To free the protocol manually, it's possible to call it's `on_close` callback.
|
37
43
|
*/
|
38
|
-
protocol_s*
|
44
|
+
protocol_s *http1_alloc(intptr_t fd, http_settings_s *settings);
|
39
45
|
|
40
46
|
/**
|
41
47
|
Listens for incoming HTTP/1.1 connections on the specified posrt and address,
|
42
48
|
implementing the requested settings.
|
43
49
|
*/
|
44
|
-
int http1_listen(const char*
|
45
|
-
const char* address,
|
50
|
+
int http1_listen(const char *port, const char *address,
|
46
51
|
http_settings_s settings);
|
47
52
|
|
48
|
-
#define http1_listen(port, address, ...)
|
53
|
+
#define http1_listen(port, address, ...) \
|
49
54
|
http1_listen((port), (address), (http_settings_s){__VA_ARGS__})
|
50
55
|
|
51
56
|
#endif
|
@@ -1,3 +1,9 @@
|
|
1
|
+
/*
|
2
|
+
copyright: Boaz segev, 2016-2017
|
3
|
+
license: MIT
|
4
|
+
|
5
|
+
Feel free to copy, use and enjoy according to the license provided.
|
6
|
+
*/
|
1
7
|
#ifndef HTTP1_SIMPLE_PARSER_H
|
2
8
|
#define HTTP1_SIMPLE_PARSER_H
|
3
9
|
#include "http_request.h"
|
@@ -30,9 +36,8 @@ attempt, only the `len` argument is expected to grow.
|
|
30
36
|
The buffer should be kept intact for the life of the request object, as the
|
31
37
|
HTTP/1.1 parser does NOT copy any data.
|
32
38
|
*/
|
33
|
-
ssize_t http1_parse_request_headers(void*
|
34
|
-
|
35
|
-
http_request_s* request);
|
39
|
+
ssize_t http1_parse_request_headers(void *buffer, size_t len,
|
40
|
+
http_request_s *request);
|
36
41
|
|
37
42
|
/**
|
38
43
|
Parses HTTP request body content (if any).
|
@@ -48,9 +53,8 @@ recycled).
|
|
48
53
|
It is expected that the next attempt will contain fresh data in the `buffer`
|
49
54
|
argument.
|
50
55
|
*/
|
51
|
-
ssize_t http1_parse_request_body(void*
|
52
|
-
|
53
|
-
http_request_s* request);
|
56
|
+
ssize_t http1_parse_request_body(void *buffer, size_t len,
|
57
|
+
http_request_s *request);
|
54
58
|
|
55
59
|
#if defined(DEBUG) && DEBUG == 1
|
56
60
|
void http_parser_test(void);
|
data/ext/iodine/http_request.h
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
/*
|
2
|
+
Copyright: Boaz segev, 2016-2017
|
3
|
+
License: MIT
|
4
|
+
|
5
|
+
Feel free to copy, use and enjoy according to the license provided.
|
6
|
+
*/
|
1
7
|
#ifndef HTTP_REQUEST_H
|
2
8
|
#define HTTP_REQUEST_H
|
3
9
|
|
@@ -5,41 +11,42 @@
|
|
5
11
|
#define _GNU_SOURCE
|
6
12
|
#endif
|
7
13
|
|
8
|
-
#include <stdlib.h>
|
9
|
-
#include <stdio.h>
|
10
14
|
#include <stdint.h>
|
11
|
-
#include <
|
15
|
+
#include <stdio.h>
|
16
|
+
#include <stdlib.h>
|
12
17
|
#include <string.h>
|
18
|
+
#include <strings.h>
|
19
|
+
#include <unistd.h>
|
13
20
|
|
14
21
|
#ifndef __unused
|
15
22
|
#define __unused __attribute__((unused))
|
16
23
|
#endif
|
17
24
|
|
18
25
|
typedef struct {
|
19
|
-
const char*
|
20
|
-
const char*
|
26
|
+
const char *name;
|
27
|
+
const char *value;
|
21
28
|
uint16_t name_length;
|
22
29
|
uint16_t value_length;
|
23
30
|
} http_headers_s;
|
24
31
|
|
25
32
|
typedef struct {
|
26
33
|
/** points to the HTTP method name. */
|
27
|
-
const char*
|
34
|
+
const char *method;
|
28
35
|
/** The portion of the request URL that comes before the '?', if any. */
|
29
|
-
const char*
|
36
|
+
const char *path;
|
30
37
|
/** The string length of the path (editing the path requires update). */
|
31
38
|
/** The portion of the request URL that follows the ?, if any. */
|
32
|
-
const char*
|
39
|
+
const char *query;
|
33
40
|
/** Points to a version string. */
|
34
|
-
const char*
|
41
|
+
const char *version;
|
35
42
|
/** Points to the body's host header value (a required header). */
|
36
|
-
const char*
|
43
|
+
const char *host;
|
37
44
|
/** points to the body's content type header, if any. */
|
38
|
-
const char*
|
45
|
+
const char *content_type;
|
39
46
|
/** points to the Upgrade header, if any. */
|
40
|
-
const char*
|
47
|
+
const char *upgrade;
|
41
48
|
/** points to the Connection header, if any. */
|
42
|
-
const char*
|
49
|
+
const char *connection;
|
43
50
|
|
44
51
|
/** the body's content's length, in bytes (can be 0). */
|
45
52
|
size_t content_length;
|
@@ -59,7 +66,7 @@ typedef struct {
|
|
59
66
|
/**
|
60
67
|
Points the body of the request, if the body exists and is stored in memory.
|
61
68
|
Otherwise, NULL. */
|
62
|
-
const char*
|
69
|
+
const char *body_str;
|
63
70
|
/** points a tmpfile file descriptor containing the body of the request. */
|
64
71
|
int body_file;
|
65
72
|
/** semi-private information. */
|
@@ -69,11 +76,11 @@ typedef struct {
|
|
69
76
|
In other times it may contain arbitrary data that can be used by the parser
|
70
77
|
or implementation.
|
71
78
|
*/
|
72
|
-
void*
|
79
|
+
void *next;
|
73
80
|
/**
|
74
81
|
Implementation specific. This, conceptually, holds information about the
|
75
82
|
"owner" of this request. */
|
76
|
-
void*
|
83
|
+
void *owner;
|
77
84
|
/**
|
78
85
|
Implementation specific. This, conceptually, holds the connection that
|
79
86
|
"owns" this request, or an implementation identifier. */
|
@@ -90,7 +97,7 @@ typedef struct {
|
|
90
97
|
http_headers_s headers[];
|
91
98
|
} http_request_s;
|
92
99
|
|
93
|
-
__unused static inline void http_request_clear(http_request_s*
|
100
|
+
__unused static inline void http_request_clear(http_request_s *request) {
|
94
101
|
if (request->body_file > 0) /* assumes no tempfile with fd 0 */
|
95
102
|
close(request->body_file);
|
96
103
|
*request = (http_request_s){
|
@@ -102,10 +109,9 @@ __unused static inline void http_request_clear(http_request_s* request) {
|
|
102
109
|
|
103
110
|
/** searches for a header in the header array, both reaturnning it's value and
|
104
111
|
* setting it's position in the `request->metadata.header_pos` variable.*/
|
105
|
-
__unused static inline const char*
|
106
|
-
|
107
|
-
|
108
|
-
size_t header_len) {
|
112
|
+
__unused static inline const char *
|
113
|
+
http_request_find_header(http_request_s *request, const char *header,
|
114
|
+
size_t header_len) {
|
109
115
|
if (header == NULL || request == NULL)
|
110
116
|
return NULL;
|
111
117
|
if (header_len == 0)
|
@@ -122,7 +128,7 @@ __unused static inline const char* http_request_find_header(
|
|
122
128
|
return NULL;
|
123
129
|
}
|
124
130
|
|
125
|
-
#define HTTP_REQUEST_SIZE(header_count)
|
131
|
+
#define HTTP_REQUEST_SIZE(header_count) \
|
126
132
|
(sizeof(http_request_s) + ((header_count) * sizeof(http_headers_s)))
|
127
133
|
|
128
134
|
#endif
|
data/ext/iodine/http_response.c
CHANGED
@@ -1,16 +1,29 @@
|
|
1
|
+
/*
|
2
|
+
Copyright: Boaz segev, 2016-2017
|
3
|
+
License: MIT
|
4
|
+
|
5
|
+
Feel free to copy, use and enjoy according to the license provided.
|
6
|
+
*/
|
7
|
+
#ifndef _GNU_SOURCE
|
8
|
+
#define _GNU_SOURCE
|
9
|
+
#endif
|
10
|
+
|
11
|
+
// clang-format off
|
12
|
+
#include "http_response_http1.h"
|
13
|
+
// clang-format on
|
14
|
+
|
15
|
+
#include "base64.h"
|
1
16
|
#include "http.h"
|
2
17
|
#include "siphash.h"
|
3
|
-
#include "base64.h"
|
4
|
-
#include "http_response_http1.h"
|
5
|
-
#include <netinet/in.h>
|
6
|
-
#include <netinet/ip.h>
|
7
18
|
#include <arpa/inet.h>
|
8
19
|
#include <fcntl.h>
|
20
|
+
#include <netinet/in.h>
|
21
|
+
#include <netinet/ip.h>
|
22
|
+
#include <sys/resource.h>
|
23
|
+
#include <sys/socket.h>
|
9
24
|
#include <sys/stat.h>
|
10
25
|
#include <sys/types.h>
|
11
|
-
#include <sys/socket.h>
|
12
26
|
#include <time.h>
|
13
|
-
#include <sys/resource.h>
|
14
27
|
|
15
28
|
/* *****************************************************************************
|
16
29
|
Helpers
|
@@ -418,7 +431,6 @@ void http_response_log_start(http_response_s *response) {
|
|
418
431
|
prints out the log to stderr.
|
419
432
|
*/
|
420
433
|
void http_response_log_finish(http_response_s *response) {
|
421
|
-
// TODO optimize using fwrite
|
422
434
|
http_request_s *request = response->metadata.request;
|
423
435
|
uintptr_t bytes_sent = (uintptr_t)response->metadata.headers_pos;
|
424
436
|
|
@@ -431,6 +443,9 @@ void http_response_log_finish(http_response_s *response) {
|
|
431
443
|
socklen_t addrlen = sizeof(addrinfo);
|
432
444
|
time_t last_tick = server_last_tick();
|
433
445
|
http_gmtime(&last_tick, &tm);
|
446
|
+
|
447
|
+
// TODO Guess IP address from headers (forwarded) where possible
|
448
|
+
|
434
449
|
int got_add = getpeername(sock_uuid2fd(request->metadata.fd),
|
435
450
|
(struct sockaddr *)&addrinfo, &addrlen);
|
436
451
|
#define HTTP_REQUEST_LOG_LIMIT 128
|
data/ext/iodine/http_response.h
CHANGED
@@ -1,8 +1,16 @@
|
|
1
|
+
/*
|
2
|
+
Copyright: Boaz segev, 2016-2017
|
3
|
+
License: MIT
|
4
|
+
|
5
|
+
Feel free to copy, use and enjoy according to the license provided.
|
6
|
+
*/
|
1
7
|
#ifndef HTTP1_RESPONSE_FORMATTER
|
2
8
|
#define HTTP1_RESPONSE_FORMATTER
|
3
9
|
|
4
|
-
|
10
|
+
// clang-format off
|
5
11
|
#include "libsock.h"
|
12
|
+
#include "http_response.h"
|
13
|
+
// clang-format on
|
6
14
|
|
7
15
|
#ifndef __unused
|
8
16
|
#define __unused __attribute__((unused))
|
data/ext/iodine/iodine_core.c
CHANGED
@@ -1,6 +1,11 @@
|
|
1
|
+
/*
|
2
|
+
Copyright: Boaz segev, 2016-2017
|
3
|
+
License: MIT
|
4
|
+
|
5
|
+
Feel free to copy, use and enjoy according to the license provided.
|
6
|
+
*/
|
1
7
|
#include "iodine_core.h"
|
2
8
|
#include "iodine_http.h"
|
3
|
-
#include <ruby/io.h>
|
4
9
|
|
5
10
|
/* *****************************************************************************
|
6
11
|
Core data
|
data/ext/iodine/iodine_core.h
CHANGED
@@ -1,18 +1,25 @@
|
|
1
1
|
/*
|
2
|
-
|
3
|
-
|
2
|
+
Copyright: Boaz segev, 2016-2017
|
3
|
+
License: MIT
|
4
4
|
|
5
5
|
Feel free to copy, use and enjoy according to the license provided.
|
6
6
|
*/
|
7
7
|
#ifndef IODINE_CORE_H
|
8
8
|
#define IODINE_CORE_H
|
9
|
-
|
10
|
-
#include "rb-call.h"
|
11
|
-
#include "libserver.h"
|
9
|
+
// clang-format off
|
12
10
|
#include <ruby.h>
|
13
|
-
#
|
11
|
+
#ifndef _GNU_SOURCE
|
12
|
+
#define _GNU_SOURCE
|
13
|
+
#endif
|
14
14
|
#include <ruby/encoding.h>
|
15
|
+
#include <ruby/thread.h>
|
15
16
|
#include <ruby/version.h>
|
17
|
+
#include <ruby/io.h>
|
18
|
+
// clang-format on
|
19
|
+
|
20
|
+
#include "libserver.h"
|
21
|
+
#include "rb-call.h"
|
22
|
+
#include "rb-registry.h"
|
16
23
|
#include <stdio.h>
|
17
24
|
#include <stdlib.h>
|
18
25
|
#include <string.h>
|
data/ext/iodine/iodine_http.c
CHANGED
data/ext/iodine/iodine_http.h
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
/*
|
2
|
+
Copyright: Boaz segev, 2016-2017
|
3
|
+
License: MIT
|
4
|
+
|
5
|
+
Feel free to copy, use and enjoy according to the license provided.
|
6
|
+
*/
|
1
7
|
#include "iodine_websocket.h"
|
2
8
|
#include "iodine_core.h"
|
3
9
|
#include "iodine_http.h"
|
@@ -56,8 +62,8 @@ struct buffer_s resize_ws_buffer(ws_s *owner, struct buffer_s);
|
|
56
62
|
/** releases an existing buffer. */
|
57
63
|
void free_ws_buffer(ws_s *owner, struct buffer_s);
|
58
64
|
|
59
|
-
/** Sets the initial buffer size. (
|
60
|
-
#define WS_INITIAL_BUFFER_SIZE
|
65
|
+
/** Sets the initial buffer size. (4Kb)*/
|
66
|
+
#define WS_INITIAL_BUFFER_SIZE 4096
|
61
67
|
|
62
68
|
// buffer increments by 4,096 Bytes (4Kb)
|
63
69
|
#define round_up_buffer_size(size) ((((size) >> 12) + 1) << 12)
|
@@ -100,7 +106,10 @@ struct buffer_s resize_ws_buffer(ws_s *owner, struct buffer_s buffer) {
|
|
100
106
|
RubyCaller.call_c(ruby_land_buffer, &args);
|
101
107
|
return args.buffer;
|
102
108
|
}
|
103
|
-
void free_ws_buffer(ws_s *owner, struct buffer_s buff) {
|
109
|
+
void free_ws_buffer(ws_s *owner, struct buffer_s buff) {
|
110
|
+
(void)(owner);
|
111
|
+
(void)(buff);
|
112
|
+
}
|
104
113
|
|
105
114
|
#undef round_up_buffer_size
|
106
115
|
|
@@ -177,6 +186,7 @@ Websocket defer
|
|
177
186
|
|
178
187
|
static void iodine_perform_defer(intptr_t uuid, protocol_s *protocol,
|
179
188
|
void *arg) {
|
189
|
+
(void)(uuid);
|
180
190
|
VALUE obj = protocol->service == WEBSOCKET_ID_STR
|
181
191
|
? get_handler(protocol)
|
182
192
|
: dyn_prot(protocol)->handler;
|
@@ -184,6 +194,7 @@ static void iodine_perform_defer(intptr_t uuid, protocol_s *protocol,
|
|
184
194
|
Registry.remove((VALUE)arg);
|
185
195
|
}
|
186
196
|
static void iodine_defer_fallback(intptr_t uuid, void *arg) {
|
197
|
+
(void)(uuid);
|
187
198
|
Registry.remove((VALUE)arg);
|
188
199
|
};
|
189
200
|
|
@@ -234,12 +245,15 @@ Websocket task performance
|
|
234
245
|
|
235
246
|
static void iodine_ws_perform_each_task(intptr_t fd, protocol_s *protocol,
|
236
247
|
void *data) {
|
248
|
+
(void)(fd);
|
237
249
|
VALUE handler = get_handler(protocol);
|
238
250
|
if (handler)
|
239
251
|
RubyCaller.call2((VALUE)data, call_proc_id, 1, &handler);
|
240
252
|
}
|
241
253
|
static void iodine_ws_finish_each_task(intptr_t fd, protocol_s *protocol,
|
242
254
|
void *data) {
|
255
|
+
(void)(fd);
|
256
|
+
(void)(protocol);
|
243
257
|
Registry.remove((VALUE)data);
|
244
258
|
}
|
245
259
|
|
@@ -315,6 +329,7 @@ sucessful event registration doesn't guaranty that the block will be called (the
|
|
315
329
|
connection might close between the event registration and the execution).
|
316
330
|
*/
|
317
331
|
static VALUE iodine_class_defer(VALUE self, VALUE ws_uuid) {
|
332
|
+
(void)(self);
|
318
333
|
intptr_t fd = FIX2LONG(ws_uuid);
|
319
334
|
if (!sock_isvalid(fd))
|
320
335
|
return Qfalse;
|
@@ -358,6 +373,7 @@ void ws_on_ready(ws_s *ws) {
|
|
358
373
|
RubyCaller.call(handler, on_ready_func_id);
|
359
374
|
}
|
360
375
|
void ws_on_data(ws_s *ws, char *data, size_t length, uint8_t is_text) {
|
376
|
+
(void)(data);
|
361
377
|
VALUE handler = get_handler(ws);
|
362
378
|
if (!handler)
|
363
379
|
return;
|
@@ -411,7 +427,10 @@ void iodine_websocket_upgrade(http_request_s *request,
|
|
411
427
|
|
412
428
|
/** Please implement your own callback for this event.
|
413
429
|
*/
|
414
|
-
static VALUE empty_func(VALUE self) {
|
430
|
+
static VALUE empty_func(VALUE self) {
|
431
|
+
(void)(self);
|
432
|
+
return Qnil;
|
433
|
+
}
|
415
434
|
// /* The `on_message(data)` callback is the main method for any websocket
|
416
435
|
// implementation. It is the only required callback for a websocket handler
|
417
436
|
// (without this handler, errors will occur).
|