noderb-http 0.0.1 → 0.0.3
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.
- data/ext/noderb_http_extension/Makefile +187 -0
- data/ext/noderb_http_extension/extconf.rb +1 -1
- data/ext/noderb_http_extension/http_parser.c +239 -95
- data/ext/noderb_http_extension/http_parser.h +88 -6
- data/ext/noderb_http_extension/http_parser.o +0 -0
- data/ext/noderb_http_extension/noderb_http.c +41 -50
- data/ext/noderb_http_extension/noderb_http.o +0 -0
- data/ext/noderb_http_extension/noderb_http_extension.bundle +0 -0
- data/lib/noderb/modules/http/parser.rb +112 -0
- data/lib/noderb/modules/http/version.rb +9 -0
- data/lib/noderb/modules/http.rb +2 -99
- data/lib/noderb-http.rb +2 -2
- data/test/cases/curl_get.rb +25 -0
- data/test/cases/patch_request.rb +29 -0
- data/test/cases/response.rb +38 -0
- data/test/cases/upgrade_request.rb +34 -0
- data/test/init.rb +62 -0
- metadata +13 -5
- data/ext/http_parser.o +0 -0
- data/ext/noderb_http.o +0 -0
@@ -28,7 +28,7 @@ extern "C" {
|
|
28
28
|
#define HTTP_PARSER_VERSION_MINOR 0
|
29
29
|
|
30
30
|
#include <sys/types.h>
|
31
|
-
#if defined(_WIN32) && !defined(__MINGW32__)
|
31
|
+
#if defined(_WIN32) && !defined(__MINGW32__) && !defined(_MSC_VER)
|
32
32
|
typedef __int8 int8_t;
|
33
33
|
typedef unsigned __int8 uint8_t;
|
34
34
|
typedef __int16 int16_t;
|
@@ -51,6 +51,13 @@ typedef int ssize_t;
|
|
51
51
|
# define HTTP_PARSER_STRICT 1
|
52
52
|
#endif
|
53
53
|
|
54
|
+
/* Compile with -DHTTP_PARSER_DEBUG=1 to add extra debugging information to
|
55
|
+
* the error reporting facility.
|
56
|
+
*/
|
57
|
+
#ifndef HTTP_PARSER_DEBUG
|
58
|
+
# define HTTP_PARSER_DEBUG 0
|
59
|
+
#endif
|
60
|
+
|
54
61
|
|
55
62
|
/* Maximium header size allowed */
|
56
63
|
#define HTTP_MAX_HEADER_SIZE (80*1024)
|
@@ -58,6 +65,7 @@ typedef int ssize_t;
|
|
58
65
|
|
59
66
|
typedef struct http_parser http_parser;
|
60
67
|
typedef struct http_parser_settings http_parser_settings;
|
68
|
+
typedef struct http_parser_result http_parser_result;
|
61
69
|
|
62
70
|
|
63
71
|
/* Callbacks should return non-zero to indicate an error. The parser will
|
@@ -125,6 +133,72 @@ enum flags
|
|
125
133
|
};
|
126
134
|
|
127
135
|
|
136
|
+
/* Map for errno-related constants
|
137
|
+
*
|
138
|
+
* The provided argument should be a macro that takes 2 arguments.
|
139
|
+
*/
|
140
|
+
#define HTTP_ERRNO_MAP(XX) \
|
141
|
+
/* No error */ \
|
142
|
+
XX(OK, "success") \
|
143
|
+
\
|
144
|
+
/* Callback-related errors */ \
|
145
|
+
XX(CB_message_begin, "the on_message_begin callback failed") \
|
146
|
+
XX(CB_path, "the on_path callback failed") \
|
147
|
+
XX(CB_query_string, "the on_query_string callback failed") \
|
148
|
+
XX(CB_url, "the on_url callback failed") \
|
149
|
+
XX(CB_fragment, "the on_fragment callback failed") \
|
150
|
+
XX(CB_header_field, "the on_header_field callback failed") \
|
151
|
+
XX(CB_header_value, "the on_header_value callback failed") \
|
152
|
+
XX(CB_headers_complete, "the on_headers_complete callback failed") \
|
153
|
+
XX(CB_body, "the on_body callback failed") \
|
154
|
+
XX(CB_message_complete, "the on_message_complete callback failed") \
|
155
|
+
\
|
156
|
+
/* Parsing-related errors */ \
|
157
|
+
XX(INVALID_EOF_STATE, "stream ended at an unexpected time") \
|
158
|
+
XX(HEADER_OVERFLOW, \
|
159
|
+
"too many header bytes seen; overflow detected") \
|
160
|
+
XX(CLOSED_CONNECTION, \
|
161
|
+
"data received after completed connection: close message") \
|
162
|
+
XX(INVALID_VERSION, "invalid HTTP version") \
|
163
|
+
XX(INVALID_STATUS, "invalid HTTP status code") \
|
164
|
+
XX(INVALID_METHOD, "invalid HTTP method") \
|
165
|
+
XX(INVALID_URL, "invalid URL") \
|
166
|
+
XX(INVALID_HOST, "invalid host") \
|
167
|
+
XX(INVALID_PORT, "invalid port") \
|
168
|
+
XX(INVALID_PATH, "invalid path") \
|
169
|
+
XX(INVALID_QUERY_STRING, "invalid query string") \
|
170
|
+
XX(INVALID_FRAGMENT, "invalid fragment") \
|
171
|
+
XX(LF_EXPECTED, "LF character expected") \
|
172
|
+
XX(INVALID_HEADER_TOKEN, "invalid character in header") \
|
173
|
+
XX(INVALID_CONTENT_LENGTH, \
|
174
|
+
"invalid character in content-length header") \
|
175
|
+
XX(INVALID_CHUNK_SIZE, \
|
176
|
+
"invalid character in chunk size header") \
|
177
|
+
XX(INVALID_CONSTANT, "invalid constant string") \
|
178
|
+
XX(INVALID_INTERNAL_STATE, "encountered unexpected internal state")\
|
179
|
+
XX(STRICT, "strict mode assertion failed") \
|
180
|
+
XX(UNKNOWN, "an unknown error occurred")
|
181
|
+
|
182
|
+
|
183
|
+
/* Define HPE_* values for each errno value above */
|
184
|
+
#define HTTP_ERRNO_GEN(n, s) HPE_##n,
|
185
|
+
enum http_errno {
|
186
|
+
HTTP_ERRNO_MAP(HTTP_ERRNO_GEN)
|
187
|
+
};
|
188
|
+
#undef HTTP_ERRNO_GEN
|
189
|
+
|
190
|
+
|
191
|
+
/* Get an http_errno value from an http_parser */
|
192
|
+
#define HTTP_PARSER_ERRNO(p) ((enum http_errno) (p)->http_errno)
|
193
|
+
|
194
|
+
/* Get the line number that generated the current error */
|
195
|
+
#if HTTP_PARSER_DEBUG
|
196
|
+
#define HTTP_PARSER_ERRNO_LINE(p) ((p)->error_lineno)
|
197
|
+
#else
|
198
|
+
#define HTTP_PARSER_ERRNO_LINE(p) 0
|
199
|
+
#endif
|
200
|
+
|
201
|
+
|
128
202
|
struct http_parser {
|
129
203
|
/** PRIVATE **/
|
130
204
|
unsigned char type : 2;
|
@@ -141,13 +215,18 @@ struct http_parser {
|
|
141
215
|
unsigned short http_minor;
|
142
216
|
unsigned short status_code; /* responses only */
|
143
217
|
unsigned char method; /* requests only */
|
218
|
+
unsigned char http_errno : 7;
|
144
219
|
|
145
220
|
/* 1 = Upgrade header was present and the parser has exited because of that.
|
146
221
|
* 0 = No upgrade header present.
|
147
222
|
* Should be checked when http_parser_execute() returns in addition to
|
148
223
|
* error checking.
|
149
224
|
*/
|
150
|
-
char upgrade;
|
225
|
+
char upgrade : 1;
|
226
|
+
|
227
|
+
#if HTTP_PARSER_DEBUG
|
228
|
+
uint32_t error_lineno;
|
229
|
+
#endif
|
151
230
|
|
152
231
|
/** PUBLIC **/
|
153
232
|
void *data; /* A pointer to get hook to the "connection" or "socket" object */
|
@@ -156,10 +235,7 @@ struct http_parser {
|
|
156
235
|
|
157
236
|
struct http_parser_settings {
|
158
237
|
http_cb on_message_begin;
|
159
|
-
http_data_cb on_path;
|
160
|
-
http_data_cb on_query_string;
|
161
238
|
http_data_cb on_url;
|
162
|
-
http_data_cb on_fragment;
|
163
239
|
http_data_cb on_header_field;
|
164
240
|
http_data_cb on_header_value;
|
165
241
|
http_cb on_headers_complete;
|
@@ -186,7 +262,13 @@ size_t http_parser_execute(http_parser *parser,
|
|
186
262
|
int http_should_keep_alive(http_parser *parser);
|
187
263
|
|
188
264
|
/* Returns a string version of the HTTP method. */
|
189
|
-
const char *http_method_str(enum http_method);
|
265
|
+
const char *http_method_str(enum http_method m);
|
266
|
+
|
267
|
+
/* Return a string name of the given error */
|
268
|
+
const char *http_errno_name(enum http_errno err);
|
269
|
+
|
270
|
+
/* Return a string description of the given error */
|
271
|
+
const char *http_errno_description(enum http_errno err);
|
190
272
|
|
191
273
|
#ifdef __cplusplus
|
192
274
|
}
|
Binary file
|
@@ -2,9 +2,11 @@
|
|
2
2
|
|
3
3
|
typedef struct {
|
4
4
|
long parser;
|
5
|
+
int pre_headers;
|
5
6
|
} nodeRb_http;
|
6
7
|
|
7
8
|
VALUE nodeRbHttpParser;
|
9
|
+
VALUE nodeRbHttpPointer;
|
8
10
|
|
9
11
|
VALUE nodeRb_get_object_from_id(long id) {
|
10
12
|
return rb_funcall(rb_const_get(rb_cObject, rb_intern("ObjectSpace")), rb_intern("_id2ref"), 1, rb_int2inum(id));
|
@@ -17,101 +19,89 @@ int nodeRb_http_on_message_begin(http_parser* parser) {
|
|
17
19
|
return 0;
|
18
20
|
}
|
19
21
|
|
20
|
-
int
|
21
|
-
nodeRb_http* client = parser->data;
|
22
|
-
VALUE self = nodeRb_get_object_from_id(client->parser);
|
23
|
-
if (http_should_keep_alive(parser)) {
|
24
|
-
rb_funcall(self, rb_intern("on_close_keep_alive"), 0);
|
25
|
-
};
|
26
|
-
rb_funcall(self, rb_intern("on_message_complete"), 0);
|
27
|
-
return 0;
|
28
|
-
}
|
29
|
-
|
30
|
-
int nodeRb_http_on_headers_complete(http_parser* parser) {
|
22
|
+
int nodeRb_http_on_url(http_parser* parser, const char *buf, size_t len) {
|
31
23
|
nodeRb_http* client = parser->data;
|
32
24
|
VALUE self = nodeRb_get_object_from_id(client->parser);
|
33
|
-
|
25
|
+
if(parser->type == HTTP_REQUEST){
|
26
|
+
rb_funcall(self, rb_intern("on_method"), 1, rb_str_new2(http_method_str(parser->method)));
|
27
|
+
}
|
28
|
+
rb_funcall(self, rb_intern("on_url"), 1, rb_str_new(buf, len));
|
34
29
|
return 0;
|
35
30
|
}
|
36
31
|
|
37
32
|
int nodeRb_http_on_header_field(http_parser* parser, const char *buf, size_t len) {
|
38
33
|
nodeRb_http* client = parser->data;
|
39
34
|
VALUE self = nodeRb_get_object_from_id(client->parser);
|
40
|
-
rb_funcall(self, rb_intern("
|
35
|
+
rb_funcall(self, rb_intern("on_header_field"), 1, rb_str_new(buf, len));
|
41
36
|
return 0;
|
42
37
|
}
|
43
38
|
|
44
39
|
int nodeRb_http_on_header_value(http_parser* parser, const char *buf, size_t len) {
|
45
40
|
nodeRb_http* client = parser->data;
|
46
41
|
VALUE self = nodeRb_get_object_from_id(client->parser);
|
47
|
-
rb_funcall(self, rb_intern("
|
42
|
+
rb_funcall(self, rb_intern("on_header_value"), 1, rb_str_new(buf, len));
|
48
43
|
return 0;
|
49
44
|
}
|
50
45
|
|
51
|
-
int
|
52
|
-
nodeRb_http* client = parser->data;
|
53
|
-
VALUE self = nodeRb_get_object_from_id(client->parser);
|
54
|
-
rb_funcall(self, rb_intern("on_method"), 1, rb_str_new2(http_method_str(parser->method)));
|
55
|
-
rb_funcall(self, rb_intern("on_path"), 1, rb_str_new(buf, len));
|
56
|
-
return 0;
|
57
|
-
}
|
58
|
-
|
59
|
-
int nodeRb_http_on_query_string(http_parser* parser, const char *buf, size_t len) {
|
60
|
-
nodeRb_http* client = parser->data;
|
61
|
-
VALUE self = nodeRb_get_object_from_id(client->parser);
|
62
|
-
rb_funcall(self, rb_intern("on_query_string"), 1, rb_str_new(buf, len));
|
63
|
-
return 0;
|
64
|
-
}
|
65
|
-
|
66
|
-
int nodeRb_http_on_url(http_parser* parser, const char *buf, size_t len) {
|
46
|
+
int nodeRb_http_on_headers_complete(http_parser* parser) {
|
67
47
|
nodeRb_http* client = parser->data;
|
68
48
|
VALUE self = nodeRb_get_object_from_id(client->parser);
|
69
|
-
rb_funcall(self, rb_intern("
|
49
|
+
rb_funcall(self, rb_intern("on_version"), 2, rb_int2inum(parser->http_major), rb_int2inum(parser->http_minor));
|
50
|
+
if(parser->type == HTTP_RESPONSE){
|
51
|
+
rb_funcall(self, rb_intern("on_status_code"), 1, rb_int2inum(parser->status_code));
|
52
|
+
}
|
53
|
+
if (http_should_keep_alive(parser)) {
|
54
|
+
rb_funcall(self, rb_intern("on_keep_alive"), 1, Qtrue);
|
55
|
+
}
|
56
|
+
rb_funcall(self, rb_intern("on_headers_complete"), 0);
|
70
57
|
return 0;
|
71
58
|
}
|
72
59
|
|
73
|
-
int
|
60
|
+
int nodeRb_http_on_body(http_parser* parser, const char *buf, size_t len) {
|
74
61
|
nodeRb_http* client = parser->data;
|
75
62
|
VALUE self = nodeRb_get_object_from_id(client->parser);
|
76
|
-
rb_funcall(self, rb_intern("
|
63
|
+
rb_funcall(self, rb_intern("on_body"), 1, rb_str_new(buf, len));
|
77
64
|
return 0;
|
78
65
|
}
|
79
66
|
|
80
|
-
int
|
67
|
+
int nodeRb_http_on_message_complete(http_parser* parser) {
|
81
68
|
nodeRb_http* client = parser->data;
|
82
69
|
VALUE self = nodeRb_get_object_from_id(client->parser);
|
83
|
-
rb_funcall(self, rb_intern("
|
70
|
+
rb_funcall(self, rb_intern("on_message_complete"), 0);
|
84
71
|
return 0;
|
85
72
|
}
|
86
73
|
|
87
|
-
VALUE nodeRb_http_setup(VALUE self) {
|
74
|
+
VALUE nodeRb_http_setup(VALUE self, VALUE type) {
|
88
75
|
http_parser_settings* settings = malloc(sizeof (http_parser_settings));
|
89
76
|
|
90
77
|
settings->on_message_begin = nodeRb_http_on_message_begin;
|
91
|
-
|
92
|
-
settings->on_headers_complete = nodeRb_http_on_headers_complete;
|
93
|
-
|
94
|
-
settings->on_path = nodeRb_http_on_path;
|
95
|
-
settings->on_query_string = nodeRb_http_on_query_string;
|
78
|
+
|
96
79
|
settings->on_url = nodeRb_http_on_url;
|
97
80
|
|
98
81
|
settings->on_header_field = nodeRb_http_on_header_field;
|
99
82
|
settings->on_header_value = nodeRb_http_on_header_value;
|
100
83
|
|
101
|
-
settings->
|
84
|
+
settings->on_headers_complete = nodeRb_http_on_headers_complete;
|
85
|
+
|
102
86
|
settings->on_body = nodeRb_http_on_body;
|
103
87
|
|
88
|
+
settings->on_message_complete = nodeRb_http_on_message_complete;
|
104
89
|
|
105
90
|
http_parser* parser = malloc(sizeof (http_parser));
|
106
|
-
|
91
|
+
|
92
|
+
if(ID2SYM(rb_intern("response")) == type){
|
93
|
+
http_parser_init(parser, HTTP_RESPONSE);
|
94
|
+
}else{
|
95
|
+
http_parser_init(parser, HTTP_REQUEST);
|
96
|
+
}
|
107
97
|
|
108
98
|
nodeRb_http* client = malloc(sizeof (nodeRb_http));
|
109
99
|
parser->data = client;
|
110
100
|
|
111
101
|
client->parser = rb_num2long(rb_obj_id(self));
|
112
102
|
|
113
|
-
rb_iv_set(self, "@settings", Data_Wrap_Struct(
|
114
|
-
rb_iv_set(self, "@parser", Data_Wrap_Struct(
|
103
|
+
rb_iv_set(self, "@settings", Data_Wrap_Struct(nodeRbHttpPointer, 0, NULL, settings));
|
104
|
+
rb_iv_set(self, "@parser", Data_Wrap_Struct(nodeRbHttpPointer, 0, NULL, parser));
|
115
105
|
};
|
116
106
|
|
117
107
|
VALUE nodeRb_http_parse(VALUE self, VALUE data) {
|
@@ -132,8 +122,8 @@ VALUE nodeRb_http_parse(VALUE self, VALUE data) {
|
|
132
122
|
|
133
123
|
if (parser->upgrade) {
|
134
124
|
rb_funcall(self, rb_intern("on_upgrade"), 0);
|
135
|
-
} else if (parsed != RSTRING_LEN(data)) {
|
136
|
-
rb_funcall(self, rb_intern("on_error"),
|
125
|
+
} else if (parsed != (unsigned) RSTRING_LEN(data)) {
|
126
|
+
rb_funcall(self, rb_intern("on_error"), 2, rb_str_new2(http_errno_name(parser->http_errno)), rb_str_new2(http_errno_description(parser->http_errno)));
|
137
127
|
};
|
138
128
|
};
|
139
129
|
|
@@ -149,7 +139,7 @@ VALUE nodeRb_http_dispose(VALUE self) {
|
|
149
139
|
free(parser);
|
150
140
|
};
|
151
141
|
|
152
|
-
void
|
142
|
+
void Init_noderb_http_extension() {
|
153
143
|
// Define module
|
154
144
|
VALUE nodeRb = rb_define_module("NodeRb");
|
155
145
|
// Modules
|
@@ -157,9 +147,10 @@ void Init_noderb_http() {
|
|
157
147
|
// Http
|
158
148
|
VALUE nodeRbHttp = rb_define_module_under(nodeRbModules, "Http");
|
159
149
|
// Http parser
|
160
|
-
|
150
|
+
nodeRbHttpPointer = rb_define_class_under(nodeRbHttp, "Pointer", rb_cObject);
|
151
|
+
nodeRbHttpParser = rb_define_module_under(nodeRbHttp, "Parser");
|
161
152
|
// Methods
|
162
|
-
rb_define_method(nodeRbHttpParser, "setup", nodeRb_http_setup,
|
153
|
+
rb_define_method(nodeRbHttpParser, "setup", nodeRb_http_setup, 1);
|
163
154
|
rb_define_method(nodeRbHttpParser, "parse", nodeRb_http_parse, 1);
|
164
155
|
rb_define_method(nodeRbHttpParser, "dispose", nodeRb_http_dispose, 0);
|
165
156
|
}
|
Binary file
|
Binary file
|
@@ -0,0 +1,112 @@
|
|
1
|
+
module NodeRb
|
2
|
+
module Modules
|
3
|
+
module Http
|
4
|
+
|
5
|
+
module Parser
|
6
|
+
|
7
|
+
def on_message_begin
|
8
|
+
@_header_name = ""
|
9
|
+
@_header_value = ""
|
10
|
+
@headers = {}
|
11
|
+
@body = ""
|
12
|
+
@method = ""
|
13
|
+
@url = ""
|
14
|
+
@status_code = 0
|
15
|
+
@upgrade = false
|
16
|
+
@keep_alive = false
|
17
|
+
@_active = true
|
18
|
+
end
|
19
|
+
|
20
|
+
def on_method method
|
21
|
+
@method = method
|
22
|
+
end
|
23
|
+
|
24
|
+
def on_url url
|
25
|
+
@url = url
|
26
|
+
end
|
27
|
+
|
28
|
+
def on_header_field name
|
29
|
+
if @_header_state == :value
|
30
|
+
on_header(@_header_name, @_header_value)
|
31
|
+
@_header_name = ""
|
32
|
+
@_header_value = ""
|
33
|
+
end
|
34
|
+
@_header_state = :field
|
35
|
+
@_header_name << name
|
36
|
+
end
|
37
|
+
|
38
|
+
def on_header_value value
|
39
|
+
@_header_state = :value
|
40
|
+
@_header_value ||= ""
|
41
|
+
@_header_value << value
|
42
|
+
end
|
43
|
+
|
44
|
+
def on_header name, value
|
45
|
+
@headers[name] = value if @_active
|
46
|
+
end
|
47
|
+
|
48
|
+
def on_version major, minor
|
49
|
+
@version_major = major if @_active
|
50
|
+
@version_minor = minor if @_active
|
51
|
+
end
|
52
|
+
|
53
|
+
def on_status_code status_code
|
54
|
+
@status_code = status_code if @_active
|
55
|
+
end
|
56
|
+
|
57
|
+
def on_keep_alive keep_alive
|
58
|
+
@keep_alive = keep_alive if @_active
|
59
|
+
end
|
60
|
+
|
61
|
+
def on_headers_complete
|
62
|
+
on_header(@_header_name, @_header_value)
|
63
|
+
@_header_name = ""
|
64
|
+
@_header_value = ""
|
65
|
+
on_message_header
|
66
|
+
end
|
67
|
+
|
68
|
+
def on_upgrade
|
69
|
+
@_active = false
|
70
|
+
@upgrade = true
|
71
|
+
end
|
72
|
+
|
73
|
+
def on_body body
|
74
|
+
@body << body if @_active
|
75
|
+
end
|
76
|
+
|
77
|
+
def on_message_complete
|
78
|
+
on_message_body
|
79
|
+
end
|
80
|
+
|
81
|
+
def on_error name, description
|
82
|
+
@_active = true
|
83
|
+
on_message_error(name, description)
|
84
|
+
end
|
85
|
+
|
86
|
+
def on_message_header
|
87
|
+
# User overrides this to get whole message header
|
88
|
+
# ------
|
89
|
+
# @headers => Hash
|
90
|
+
# @url => String
|
91
|
+
# @version_major => Integer
|
92
|
+
# @version_minor => Integer
|
93
|
+
# @status_code (response) => Integer
|
94
|
+
# @method (request) => String
|
95
|
+
# @upgrade => Boolean
|
96
|
+
# @keep_alive => Boolean
|
97
|
+
end
|
98
|
+
|
99
|
+
def on_message_body
|
100
|
+
# User overrides this to get whole message body
|
101
|
+
# @body => String
|
102
|
+
end
|
103
|
+
|
104
|
+
def on_message_error name, description
|
105
|
+
# User overrides this to be notified of errors
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
data/lib/noderb/modules/http.rb
CHANGED
@@ -1,99 +1,2 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
module Http
|
4
|
-
|
5
|
-
module Rack
|
6
|
-
|
7
|
-
def initialize
|
8
|
-
@env = {}
|
9
|
-
end
|
10
|
-
|
11
|
-
def on_header name, value
|
12
|
-
end
|
13
|
-
|
14
|
-
end
|
15
|
-
|
16
|
-
class Parser
|
17
|
-
|
18
|
-
def on_message_begin
|
19
|
-
end
|
20
|
-
|
21
|
-
def on_method method
|
22
|
-
end
|
23
|
-
|
24
|
-
def on_path path
|
25
|
-
end
|
26
|
-
|
27
|
-
def on_query_string query_string
|
28
|
-
end
|
29
|
-
|
30
|
-
def on_url url
|
31
|
-
end
|
32
|
-
|
33
|
-
def on_fragment fragment
|
34
|
-
end
|
35
|
-
|
36
|
-
def on_header_field_internal name
|
37
|
-
if @_header_state == :value
|
38
|
-
on_header_value(@_header_value)
|
39
|
-
on_header(@_header_name, @_header_value)
|
40
|
-
@_header_name = nil
|
41
|
-
@_header_value = nil
|
42
|
-
end
|
43
|
-
@_header_state = :field
|
44
|
-
@_header_name ||= ""
|
45
|
-
@_header_name << name
|
46
|
-
end
|
47
|
-
|
48
|
-
def on_header_field name
|
49
|
-
|
50
|
-
end
|
51
|
-
|
52
|
-
def on_header_value_internal value
|
53
|
-
if @_header_state == :field
|
54
|
-
on_header_field(@_header_name)
|
55
|
-
end
|
56
|
-
@_header_state = :value
|
57
|
-
@_header_value ||= ""
|
58
|
-
@_header_value << value
|
59
|
-
end
|
60
|
-
|
61
|
-
def on_header_value value
|
62
|
-
|
63
|
-
end
|
64
|
-
|
65
|
-
def on_header name, value
|
66
|
-
end
|
67
|
-
|
68
|
-
def on_headers_complete_internal
|
69
|
-
on_header_value(@_header_value)
|
70
|
-
on_header(@_header_name, @_header_value)
|
71
|
-
@_header_name = nil
|
72
|
-
@_header_value = nil
|
73
|
-
on_headers_complete
|
74
|
-
end
|
75
|
-
|
76
|
-
def on_headers_complete
|
77
|
-
|
78
|
-
end
|
79
|
-
|
80
|
-
def on_close_keep_alive
|
81
|
-
end
|
82
|
-
|
83
|
-
def on_upgrade
|
84
|
-
end
|
85
|
-
|
86
|
-
def on_body body
|
87
|
-
end
|
88
|
-
|
89
|
-
def on_message_complete
|
90
|
-
end
|
91
|
-
|
92
|
-
def on_error
|
93
|
-
end
|
94
|
-
|
95
|
-
end
|
96
|
-
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
1
|
+
require "noderb/modules/http/version"
|
2
|
+
require "noderb/modules/http/parser"
|
data/lib/noderb-http.rb
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
require 'noderb_http_extension
|
2
|
-
require
|
1
|
+
require 'noderb_http_extension'
|
2
|
+
require 'noderb/modules/http'
|
@@ -0,0 +1,25 @@
|
|
1
|
+
CASES << {
|
2
|
+
:name => "curl_get",
|
3
|
+
:type => :request,
|
4
|
+
:message_complete_on_eof => false,
|
5
|
+
:data => [
|
6
|
+
"GET /test HTTP/1.1\n",
|
7
|
+
"User-Agent: curl/7.18.0 (i486-pc-linux-gnu) libcurl/7.18.0 OpenSSL/0.9.8g zlib/1.2.3.3 libidn/1.1\n",
|
8
|
+
"Host: 0.0.0.0=5000\n",
|
9
|
+
"Accept: */*\n",
|
10
|
+
"\n"
|
11
|
+
],
|
12
|
+
:should_keep_alive => true,
|
13
|
+
:http_major => 1,
|
14
|
+
:http_minor => 1,
|
15
|
+
:method => "GET",
|
16
|
+
:request_url => "/test",
|
17
|
+
:num_headers => 3,
|
18
|
+
:headers => {
|
19
|
+
"User-Agent" => "curl/7.18.0 (i486-pc-linux-gnu) libcurl/7.18.0 OpenSSL/0.9.8g zlib/1.2.3.3 libidn/1.1",
|
20
|
+
"Host" => "0.0.0.0=5000",
|
21
|
+
"Accept" => "*/*",
|
22
|
+
},
|
23
|
+
:body => "",
|
24
|
+
:upgrade => false
|
25
|
+
}
|
@@ -0,0 +1,29 @@
|
|
1
|
+
CASES << {
|
2
|
+
:name => "patch_request",
|
3
|
+
:type => :request,
|
4
|
+
:message_complete_on_eof => false,
|
5
|
+
:data => [
|
6
|
+
"PATCH /file.txt HTTP/1.1\n",
|
7
|
+
"Host: www.example.com\n",
|
8
|
+
"Content-Type: application/example\n",
|
9
|
+
"If-Match: \"e0023aa4e\"\n",
|
10
|
+
"Content-Length: 10\n",
|
11
|
+
"\n",
|
12
|
+
"abcde",
|
13
|
+
"efghi"
|
14
|
+
],
|
15
|
+
:should_keep_alive => true,
|
16
|
+
:http_major => 1,
|
17
|
+
:http_minor => 1,
|
18
|
+
:method => "PATCH",
|
19
|
+
:request_url => "/file.txt",
|
20
|
+
:num_headers => 4,
|
21
|
+
:headers => {
|
22
|
+
"Host" => "www.example.com",
|
23
|
+
"Content-Length" => "10",
|
24
|
+
"If-Match" => "\"e0023aa4e\"",
|
25
|
+
"Content-Type" => "application/example"
|
26
|
+
},
|
27
|
+
:body => "abcdeefghi",
|
28
|
+
:upgrade => false
|
29
|
+
}
|
@@ -0,0 +1,38 @@
|
|
1
|
+
CASES << {
|
2
|
+
:name => "response",
|
3
|
+
:type => :response,
|
4
|
+
:message_complete_on_eof => false,
|
5
|
+
:data => [
|
6
|
+
"HTTP/1.0 301 Moved Permanently\n",
|
7
|
+
"Date: Thu, 03 Jun 2010 09:56:32 GMT\n",
|
8
|
+
"Server: Apache/2.2.3 (Red Hat)\n",
|
9
|
+
"Cache-Control: public\n",
|
10
|
+
"Pragma: \n",
|
11
|
+
"Location: http://www.bonjourmadame.fr/\n",
|
12
|
+
"Vary: Accept-Encoding\n",
|
13
|
+
"Content-Length: 0\n",
|
14
|
+
"Content-Type: text/html; charset=UTF-8\n",
|
15
|
+
"Connection: keep-alive\n",
|
16
|
+
"\n"
|
17
|
+
],
|
18
|
+
:should_keep_alive => true,
|
19
|
+
:http_major => 1,
|
20
|
+
:http_minor => 0,
|
21
|
+
:method => "",
|
22
|
+
:request_url => "",
|
23
|
+
:num_headers => 9,
|
24
|
+
:status_code => 301,
|
25
|
+
:headers => {
|
26
|
+
"Date" => "Thu, 03 Jun 2010 09:56:32 GMT",
|
27
|
+
"Server" => "Apache/2.2.3 (Red Hat)",
|
28
|
+
"Cache-Control" => "public",
|
29
|
+
"Pragma" => "",
|
30
|
+
"Location" => "http://www.bonjourmadame.fr/",
|
31
|
+
"Vary" => "Accept-Encoding",
|
32
|
+
"Content-Length" => "0",
|
33
|
+
"Content-Type" => "text/html; charset=UTF-8",
|
34
|
+
"Connection" => "keep-alive"
|
35
|
+
},
|
36
|
+
:upgrade => false,
|
37
|
+
:body => ""
|
38
|
+
}
|