http_parser.rb 0.7.0 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +3 -2
- data/ext/ruby_http_parser/org/ruby_http_parser/RubyHttpParser.java +9 -23
- data/ext/ruby_http_parser/ruby_http_parser.c +22 -2
- data/http_parser.rb.gemspec +1 -1
- data/spec/parser_spec.rb +29 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cb02853976523252e0d5f36af3ba83b363010d4c163d9a4951b419054e7486ae
|
4
|
+
data.tar.gz: 3b7ac3ea5df5866582e0f68653d205764498e60e01835d2e19661cf4e1089d1b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 67516e3f1024e4bbf8dd00ae441646d53ca279313683b6f8da24668901c59b364608ecd9c69dab63709d9f89245ddc5363e0865f294a5af9d8e0b39d4712328f
|
7
|
+
data.tar.gz: 505a790706bc8f84404c2c6dd7e2b0025d591ca30311ca93d4eda4cf58a274c105acf68ed029ce96e38b04b040b86d4e953cf944a80a1e66a72f2a737d8cbfba
|
data/Rakefile
CHANGED
@@ -8,6 +8,9 @@ import http_parser.lolevel.HTTPDataCallback;
|
|
8
8
|
import http_parser.lolevel.ParserSettings;
|
9
9
|
|
10
10
|
import java.nio.ByteBuffer;
|
11
|
+
import java.util.Arrays;
|
12
|
+
import java.util.ArrayList;
|
13
|
+
import java.util.List;
|
11
14
|
|
12
15
|
import org.jcodings.Encoding;
|
13
16
|
import org.jcodings.specific.UTF8Encoding;
|
@@ -64,7 +67,6 @@ public class RubyHttpParser extends RubyObject {
|
|
64
67
|
private IRubyObject on_body;
|
65
68
|
private IRubyObject on_message_complete;
|
66
69
|
|
67
|
-
private IRubyObject status;
|
68
70
|
private IRubyObject requestUrl;
|
69
71
|
private IRubyObject requestPath;
|
70
72
|
private IRubyObject queryString;
|
@@ -82,6 +84,10 @@ public class RubyHttpParser extends RubyObject {
|
|
82
84
|
|
83
85
|
private static final Encoding UTF8 = UTF8Encoding.INSTANCE;
|
84
86
|
|
87
|
+
private static final List<String> VALUE_TYPES = new ArrayList<String>(
|
88
|
+
Arrays.asList("mixed", "arrays", "strings")
|
89
|
+
);
|
90
|
+
|
85
91
|
public RubyHttpParser(final Ruby runtime, RubyClass clazz) {
|
86
92
|
super(runtime, clazz);
|
87
93
|
|
@@ -107,18 +113,6 @@ public class RubyHttpParser extends RubyObject {
|
|
107
113
|
private void initSettings() {
|
108
114
|
this.settings = new ParserSettings();
|
109
115
|
|
110
|
-
this.settings.on_status = new HTTPDataCallback() {
|
111
|
-
public int cb(http_parser.lolevel.HTTPParser p, ByteBuffer buf, int pos, int len) {
|
112
|
-
byte[] data = fetchBytes(buf, pos, len);
|
113
|
-
if (runtime.is1_9() || runtime.is2_0()) {
|
114
|
-
((RubyString) status).cat(data, 0, data.length, UTF8);
|
115
|
-
} else {
|
116
|
-
((RubyString) status).cat(data);
|
117
|
-
}
|
118
|
-
return 0;
|
119
|
-
}
|
120
|
-
};
|
121
|
-
|
122
116
|
this.settings.on_url = new HTTPDataCallback() {
|
123
117
|
public int cb(http_parser.lolevel.HTTPParser p, ByteBuffer buf, int pos, int len) {
|
124
118
|
byte[] data = fetchBytes(buf, pos, len);
|
@@ -215,14 +209,12 @@ public class RubyHttpParser extends RubyObject {
|
|
215
209
|
headers = new RubyHash(runtime);
|
216
210
|
|
217
211
|
if (runtime.is1_9() || runtime.is2_0()) {
|
218
|
-
status = RubyString.newEmptyString(runtime, UTF8);
|
219
212
|
requestUrl = RubyString.newEmptyString(runtime, UTF8);
|
220
213
|
requestPath = RubyString.newEmptyString(runtime, UTF8);
|
221
214
|
queryString = RubyString.newEmptyString(runtime, UTF8);
|
222
215
|
fragment = RubyString.newEmptyString(runtime, UTF8);
|
223
216
|
upgradeData = RubyString.newEmptyString(runtime, UTF8);
|
224
217
|
} else {
|
225
|
-
status = RubyString.newEmptyString(runtime);
|
226
218
|
requestUrl = RubyString.newEmptyString(runtime);
|
227
219
|
requestPath = RubyString.newEmptyString(runtime);
|
228
220
|
queryString = RubyString.newEmptyString(runtime);
|
@@ -324,8 +316,7 @@ public class RubyHttpParser extends RubyObject {
|
|
324
316
|
this.parser = new HTTPParser();
|
325
317
|
this.parser.HTTP_PARSER_STRICT = true;
|
326
318
|
this.headers = null;
|
327
|
-
|
328
|
-
this.status = runtime.getNil();
|
319
|
+
|
329
320
|
this.requestUrl = runtime.getNil();
|
330
321
|
this.requestPath = runtime.getNil();
|
331
322
|
this.queryString = runtime.getNil();
|
@@ -462,11 +453,6 @@ public class RubyHttpParser extends RubyObject {
|
|
462
453
|
return headers == null ? runtime.getNil() : headers;
|
463
454
|
}
|
464
455
|
|
465
|
-
@JRubyMethod(name = "status")
|
466
|
-
public IRubyObject getStatus() {
|
467
|
-
return status == null ? runtime.getNil() : status;
|
468
|
-
}
|
469
|
-
|
470
456
|
@JRubyMethod(name = "request_url")
|
471
457
|
public IRubyObject getRequestUrl() {
|
472
458
|
return requestUrl == null ? runtime.getNil() : requestUrl;
|
@@ -495,7 +481,7 @@ public class RubyHttpParser extends RubyObject {
|
|
495
481
|
@JRubyMethod(name = "header_value_type=")
|
496
482
|
public IRubyObject set_header_value_type(IRubyObject val) {
|
497
483
|
String valString = val.toString();
|
498
|
-
if (valString
|
484
|
+
if (!VALUE_TYPES.contains(valString)) {
|
499
485
|
throw runtime.newArgumentError("Invalid header value type");
|
500
486
|
}
|
501
487
|
header_value_type = val;
|
@@ -316,7 +316,17 @@ VALUE Parser_initialize(int argc, VALUE *argv, VALUE self) {
|
|
316
316
|
ParserWrapper *wrapper = NULL;
|
317
317
|
DATA_GET(self, ParserWrapper, wrapper);
|
318
318
|
|
319
|
-
|
319
|
+
VALUE default_header_value_type = Qnil;
|
320
|
+
|
321
|
+
if (argc > 0 && RB_TYPE_P(argv[argc-1], T_HASH)) {
|
322
|
+
ID keyword_ids[1];
|
323
|
+
keyword_ids[0] = rb_intern("default_header_value_type");
|
324
|
+
rb_get_kwargs(argv[argc-1], keyword_ids, 0, 1, &default_header_value_type);
|
325
|
+
if (default_header_value_type == Qundef) {
|
326
|
+
default_header_value_type = Qnil;
|
327
|
+
}
|
328
|
+
--argc;
|
329
|
+
}
|
320
330
|
|
321
331
|
if (argc == 1) {
|
322
332
|
wrapper->callback_object = argv[0];
|
@@ -324,7 +334,13 @@ VALUE Parser_initialize(int argc, VALUE *argv, VALUE self) {
|
|
324
334
|
|
325
335
|
if (argc == 2) {
|
326
336
|
wrapper->callback_object = argv[0];
|
327
|
-
|
337
|
+
default_header_value_type = argv[1];
|
338
|
+
}
|
339
|
+
|
340
|
+
if (default_header_value_type == Qnil) {
|
341
|
+
wrapper->header_value_type = rb_iv_get(CLASS_OF(self), "@default_header_value_type");
|
342
|
+
} else {
|
343
|
+
wrapper->header_value_type = default_header_value_type;
|
328
344
|
}
|
329
345
|
|
330
346
|
return self;
|
@@ -489,6 +505,10 @@ VALUE Parser_reset(VALUE self) {
|
|
489
505
|
}
|
490
506
|
|
491
507
|
void Init_ruby_http_parser() {
|
508
|
+
#ifdef HAVE_RB_EXT_RACTOR_SAFE
|
509
|
+
rb_ext_ractor_safe(true);
|
510
|
+
#endif
|
511
|
+
|
492
512
|
VALUE mHTTP = rb_define_module("HTTP");
|
493
513
|
cParser = rb_define_class_under(mHTTP, "Parser", rb_cObject);
|
494
514
|
cRequestParser = rb_define_class_under(mHTTP, "RequestParser", cParser);
|
data/http_parser.rb.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "http_parser.rb"
|
3
|
-
s.version = "0.
|
3
|
+
s.version = "0.8.0"
|
4
4
|
s.summary = "Simple callback-based HTTP request/response parser"
|
5
5
|
s.description = "Ruby bindings to https://github.com/joyent/http-parser and https://github.com/http-parser/http-parser.java"
|
6
6
|
|
data/spec/parser_spec.rb
CHANGED
@@ -31,6 +31,25 @@ describe HTTP::Parser do
|
|
31
31
|
expect(@parser.header_value_type).to eq(:mixed)
|
32
32
|
end
|
33
33
|
|
34
|
+
it "should be able to run in non-main ractors" do
|
35
|
+
skip unless Kernel.const_defined?(:Ractor)
|
36
|
+
default_header_value_type = HTTP::Parser.default_header_value_type
|
37
|
+
r = Ractor.new(default_header_value_type) { |type|
|
38
|
+
parser = HTTP::Parser.new(default_header_value_type: type)
|
39
|
+
done = false
|
40
|
+
parser.on_message_complete = proc {
|
41
|
+
done = true
|
42
|
+
}
|
43
|
+
parser <<
|
44
|
+
"GET /ractor HTTP/1.1\r\n" +
|
45
|
+
"Content-Length: 5\r\n" +
|
46
|
+
"\r\n" +
|
47
|
+
"World"
|
48
|
+
done
|
49
|
+
}
|
50
|
+
expect(r.take).to be true
|
51
|
+
end
|
52
|
+
|
34
53
|
it "should allow us to set the header value type" do
|
35
54
|
[:mixed, :arrays, :strings].each do |type|
|
36
55
|
@parser.header_value_type = type
|
@@ -38,6 +57,9 @@ describe HTTP::Parser do
|
|
38
57
|
|
39
58
|
parser_tmp = HTTP::Parser.new(nil, type)
|
40
59
|
expect(parser_tmp.header_value_type).to eq(type)
|
60
|
+
|
61
|
+
parser_tmp2 = HTTP::Parser.new(default_header_value_type: type)
|
62
|
+
expect(parser_tmp2.header_value_type).to eq(type)
|
41
63
|
end
|
42
64
|
end
|
43
65
|
|
@@ -384,10 +406,15 @@ describe HTTP::Parser do
|
|
384
406
|
expect(@parser.send("http_minor")).to eq(test["http_minor"])
|
385
407
|
|
386
408
|
if test['type'] == 'HTTP_REQUEST'
|
387
|
-
|
409
|
+
if defined?(JRUBY_VERSION)
|
410
|
+
expect(@parser.send("request_url")).to eq(test["request_url"])
|
411
|
+
else
|
412
|
+
# It's created by rb_str_new(), so that encoding is Encoding::ASCII_8BIT a.k.a Encoding::BINARY
|
413
|
+
expect(@parser.send("request_url")).to eq(test["request_url"].force_encoding(Encoding::ASCII_8BIT))
|
414
|
+
end
|
388
415
|
else
|
389
416
|
expect(@parser.send("status_code")).to eq(test["status_code"])
|
390
|
-
expect(@parser.send("status")).to eq(test["status"].force_encoding(Encoding::
|
417
|
+
expect(@parser.send("status")).to eq(test["status"].force_encoding(Encoding::ASCII_8BIT)) if !defined?(JRUBY_VERSION)
|
391
418
|
end
|
392
419
|
|
393
420
|
expect(@headers.size).to eq(test['num_headers'])
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: http_parser.rb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marc-Andre Cournoyer
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2021-
|
12
|
+
date: 2021-09-01 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake-compiler
|