http-parser-lite 0.2.0 → 0.3.0
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/CHANGELOG +5 -0
- data/README.md +15 -3
- data/ext/http-parser/ruby_http_parser.c +20 -10
- data/lib/http-parser.rb +17 -2
- data/test/test_http_parser.rb +47 -0
- metadata +2 -2
data/CHANGELOG
CHANGED
data/README.md
CHANGED
@@ -52,10 +52,9 @@ parser << "GET http://www.google.com/ HTTP/1.1\r\n\r\n"
|
|
52
52
|
|
53
53
|
```
|
54
54
|
HTTP::Parser
|
55
|
-
.new
|
56
|
-
|
57
|
-
#reset
|
55
|
+
.new(type = HTTP::Parser::TYPE_BOTH)
|
58
56
|
|
57
|
+
#reset(type = nil)
|
59
58
|
#parse(data)
|
60
59
|
#<<(data)
|
61
60
|
|
@@ -73,6 +72,19 @@ HTTP::Parser
|
|
73
72
|
#pause
|
74
73
|
#resume
|
75
74
|
#paused?
|
75
|
+
|
76
|
+
#error?
|
77
|
+
#error
|
78
|
+
|
79
|
+
Constants:
|
80
|
+
|
81
|
+
* HTTP::Parser::TYPE_REQUEST
|
82
|
+
* HTTP::Parser::TYPE_RESPONSE
|
83
|
+
* HTTP::Parser::TYPE_BOTH
|
84
|
+
|
85
|
+
Exceptions:
|
86
|
+
|
87
|
+
* HTTP::Parser::Error
|
76
88
|
```
|
77
89
|
|
78
90
|
## License
|
@@ -25,17 +25,13 @@ http_parser* rb_http_parser_handle(VALUE self) {
|
|
25
25
|
return parser;
|
26
26
|
}
|
27
27
|
|
28
|
-
VALUE rb_parser_callback_for(VALUE self, VALUE name) {
|
29
|
-
return rb_hash_aref(rb_iv_get(self, "@callbacks"), name);
|
30
|
-
}
|
31
|
-
|
32
28
|
void rb_parser_callback_call(VALUE self, const char *name, char *data, size_t length) {
|
33
|
-
VALUE
|
34
|
-
if (!NIL_P(
|
29
|
+
VALUE callback = rb_hash_aref(rb_iv_get(self, "@callbacks"), ID2SYM(rb_intern(name)));
|
30
|
+
if (!NIL_P(callback)) {
|
35
31
|
VALUE args = rb_ary_new();
|
36
32
|
if (data)
|
37
33
|
rb_ary_push(args, rb_str_new(data, length));
|
38
|
-
rb_proc_call(
|
34
|
+
rb_proc_call(callback, args);
|
39
35
|
}
|
40
36
|
}
|
41
37
|
|
@@ -92,9 +88,9 @@ VALUE rb_parser_parse(VALUE self, VALUE data) {
|
|
92
88
|
return Qtrue;
|
93
89
|
}
|
94
90
|
|
95
|
-
VALUE
|
91
|
+
VALUE rb_parser_reset_bang(VALUE self, VALUE type) {
|
96
92
|
http_parser *parser = rb_http_parser_handle(self);
|
97
|
-
http_parser_init(parser,
|
93
|
+
http_parser_init(parser, FIX2INT(type));
|
98
94
|
return Qtrue;
|
99
95
|
}
|
100
96
|
|
@@ -132,6 +128,17 @@ VALUE rb_parser_http_status(VALUE self) {
|
|
132
128
|
return INT2NUM(parser->status_code);
|
133
129
|
}
|
134
130
|
|
131
|
+
VALUE rb_parser_error_q(VALUE self) {
|
132
|
+
http_parser *parser = rb_http_parser_handle(self);
|
133
|
+
return HTTP_PARSER_ERRNO(parser) != HPE_OK ? Qtrue : Qfalse;
|
134
|
+
}
|
135
|
+
|
136
|
+
VALUE rb_parser_error(VALUE self) {
|
137
|
+
http_parser *parser = rb_http_parser_handle(self);
|
138
|
+
int errno = HTTP_PARSER_ERRNO(parser);
|
139
|
+
return errno != HPE_OK ? rb_str_new2(http_errno_description(errno)) : Qnil;
|
140
|
+
}
|
141
|
+
|
135
142
|
Init_http_parser() {
|
136
143
|
mHTTP = rb_define_module("HTTP");
|
137
144
|
cParser = rb_define_class_under(mHTTP, "Parser", rb_cObject);
|
@@ -144,8 +151,11 @@ Init_http_parser() {
|
|
144
151
|
rb_define_method(cParser, "pause", rb_parser_pause, 0);
|
145
152
|
rb_define_method(cParser, "resume", rb_parser_resume, 0);
|
146
153
|
rb_define_method(cParser, "paused?", rb_parser_is_paused, 0);
|
147
|
-
rb_define_method(cParser, "
|
154
|
+
rb_define_method(cParser, "error?", rb_parser_error_q, 0);
|
155
|
+
rb_define_method(cParser, "error", rb_parser_error, 0);
|
148
156
|
rb_define_method(cParser, "http_method", rb_parser_http_method, 0);
|
149
157
|
rb_define_method(cParser, "http_version", rb_parser_http_version, 0);
|
150
158
|
rb_define_method(cParser, "http_status", rb_parser_http_status, 0);
|
159
|
+
|
160
|
+
rb_define_private_method(cParser, "reset!", rb_parser_reset_bang, 1);
|
151
161
|
}
|
data/lib/http-parser.rb
CHANGED
@@ -2,7 +2,10 @@ require 'http-parser/http_parser'
|
|
2
2
|
|
3
3
|
module HTTP
|
4
4
|
class Parser
|
5
|
-
|
5
|
+
TYPE_REQUEST = 0
|
6
|
+
TYPE_RESPONSE = 1
|
7
|
+
TYPE_BOTH = 2
|
8
|
+
CALLBACKS = %w(on_url on_header_field on_header_value on_body on_message_begin on_message_complete)
|
6
9
|
|
7
10
|
CALLBACKS.each do |name|
|
8
11
|
define_method(name) do |&block|
|
@@ -11,8 +14,20 @@ module HTTP
|
|
11
14
|
end
|
12
15
|
end
|
13
16
|
|
14
|
-
|
17
|
+
attr_reader :type
|
18
|
+
|
19
|
+
def initialize type = TYPE_BOTH
|
15
20
|
@callbacks = {}
|
21
|
+
reset(type)
|
22
|
+
end
|
23
|
+
|
24
|
+
def reset value = nil
|
25
|
+
if value
|
26
|
+
raise ArgumentError, "Invalid parser type #{value}" unless [0, 1, 2].include?(value)
|
27
|
+
@type = value
|
28
|
+
end
|
29
|
+
|
30
|
+
reset!(@type)
|
16
31
|
end
|
17
32
|
end
|
18
33
|
end
|
data/test/test_http_parser.rb
CHANGED
@@ -106,4 +106,51 @@ describe 'http-parser' do
|
|
106
106
|
|
107
107
|
assert %w(/hello X-Test-Field 1), got
|
108
108
|
end
|
109
|
+
|
110
|
+
it 'should create parser of appropriate type' do
|
111
|
+
parser = HTTP::Parser.new(HTTP::Parser::TYPE_REQUEST)
|
112
|
+
assert parser << "GET /hello HTTP/1.1\r\n\r\n"
|
113
|
+
assert_raises(HTTP::Parser::Error) do
|
114
|
+
parser << "HTTP/1.1 200 OK\r\n\r\n"
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'should be able to reset parser to another type' do
|
119
|
+
parser.reset(HTTP::Parser::TYPE_RESPONSE)
|
120
|
+
assert parser << "HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n"
|
121
|
+
assert_raises(HTTP::Parser::Error) do
|
122
|
+
parser << "GET / HTTP/1.1\r\n\r\n"
|
123
|
+
end
|
124
|
+
|
125
|
+
parser.reset(HTTP::Parser::TYPE_REQUEST)
|
126
|
+
assert parser << "GET / HTTP/1.1\r\n\r\n"
|
127
|
+
end
|
128
|
+
|
129
|
+
it '#reset should validate parser type' do
|
130
|
+
assert_raises(ArgumentError) do
|
131
|
+
parser.reset("foo")
|
132
|
+
end
|
133
|
+
assert_raises(ArgumentError) do
|
134
|
+
parser.reset(4)
|
135
|
+
end
|
136
|
+
assert parser.reset(0)
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'should expose parser error status' do
|
140
|
+
parser.reset(HTTP::Parser::TYPE_REQUEST)
|
141
|
+
|
142
|
+
assert parser << "GET / HTTP/1.1\r\n\r\n"
|
143
|
+
assert !parser.error?
|
144
|
+
|
145
|
+
assert_raises(HTTP::Parser::Error) do
|
146
|
+
parser << "HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n"
|
147
|
+
end
|
148
|
+
assert parser.error?
|
149
|
+
assert_match %r{invalid http method}i, parser.error
|
150
|
+
|
151
|
+
# reset should give you a clean slate
|
152
|
+
parser.reset(HTTP::Parser::TYPE_REQUEST)
|
153
|
+
assert !parser.error?
|
154
|
+
assert !parser.error
|
155
|
+
end
|
109
156
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: http-parser-lite
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-06-
|
12
|
+
date: 2012-06-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|