Permalink
Browse files

Merge pull request #42 from robertjpayne/master

Add support for "status" reason and use latest stable http_parser
  • Loading branch information...
2 parents 0bf952e + 7e23d71 commit 7ef407e35247750e369746dec4ed4ed6c2265f73 @tmm1 committed Nov 1, 2017
@@ -64,6 +64,7 @@ public IRubyObject allocate(Ruby runtime, RubyClass klass) {
private IRubyObject on_body;
private IRubyObject on_message_complete;
+ private IRubyObject status;
private IRubyObject requestUrl;
private IRubyObject requestPath;
private IRubyObject queryString;
@@ -106,6 +107,18 @@ public RubyHttpParser(final Ruby runtime, RubyClass clazz) {
private void initSettings() {
this.settings = new ParserSettings();
+ this.settings.on_status = new HTTPDataCallback() {
+ public int cb(http_parser.lolevel.HTTPParser p, ByteBuffer buf, int pos, int len) {
+ byte[] data = fetchBytes(buf, pos, len);
+ if (runtime.is1_9() || runtime.is2_0()) {
+ ((RubyString) status).cat(data, 0, data.length, UTF8);
+ } else {
+ ((RubyString) status).cat(data);
+ }
+ return 0;
+ }
+ };
+
this.settings.on_url = new HTTPDataCallback() {
public int cb(http_parser.lolevel.HTTPParser p, ByteBuffer buf, int pos, int len) {
byte[] data = fetchBytes(buf, pos, len);
@@ -202,12 +215,14 @@ public int cb(http_parser.lolevel.HTTPParser p) {
headers = new RubyHash(runtime);
if (runtime.is1_9() || runtime.is2_0()) {
+ status = RubyString.newEmptyString(runtime, UTF8);
requestUrl = RubyString.newEmptyString(runtime, UTF8);
requestPath = RubyString.newEmptyString(runtime, UTF8);
queryString = RubyString.newEmptyString(runtime, UTF8);
fragment = RubyString.newEmptyString(runtime, UTF8);
upgradeData = RubyString.newEmptyString(runtime, UTF8);
} else {
+ status = RubyString.newEmptyString(runtime);
requestUrl = RubyString.newEmptyString(runtime);
requestPath = RubyString.newEmptyString(runtime);
queryString = RubyString.newEmptyString(runtime);
@@ -309,7 +324,8 @@ private void init() {
this.parser = new HTTPParser();
this.parser.HTTP_PARSER_STRICT = true;
this.headers = null;
-
+
+ this.status = runtime.getNil();
this.requestUrl = runtime.getNil();
this.requestPath = runtime.getNil();
this.queryString = runtime.getNil();
@@ -446,6 +462,11 @@ public IRubyObject getHeaders() {
return headers == null ? runtime.getNil() : headers;
}
+ @JRubyMethod(name = "status")
+ public IRubyObject getStatus() {
+ return status == null ? runtime.getNil() : status;
+ }
+
@JRubyMethod(name = "request_url")
public IRubyObject getRequestUrl() {
return requestUrl == null ? runtime.getNil() : requestUrl;
@@ -16,6 +16,7 @@
typedef struct ParserWrapper {
ryah_http_parser parser;
+ VALUE status;
VALUE request_url;
VALUE headers;
@@ -45,6 +46,7 @@ void ParserWrapper_init(ParserWrapper *wrapper) {
wrapper->parser.http_major = 0;
wrapper->parser.http_minor = 0;
+ wrapper->status = Qnil;
wrapper->request_url = Qnil;
wrapper->upgrade_data = Qnil;
@@ -59,6 +61,7 @@ void ParserWrapper_init(ParserWrapper *wrapper) {
void ParserWrapper_mark(void *data) {
if(data) {
ParserWrapper *wrapper = (ParserWrapper *) data;
+ rb_gc_mark_maybe(wrapper->status);
rb_gc_mark_maybe(wrapper->request_url);
rb_gc_mark_maybe(wrapper->upgrade_data);
rb_gc_mark_maybe(wrapper->headers);
@@ -101,6 +104,7 @@ static VALUE Smixed;
int on_message_begin(ryah_http_parser *parser) {
GET_WRAPPER(wrapper, parser);
+ wrapper->status = rb_str_new2("");
wrapper->request_url = rb_str_new2("");
wrapper->headers = rb_hash_new();
wrapper->upgrade_data = rb_str_new2("");
@@ -121,9 +125,28 @@ int on_message_begin(ryah_http_parser *parser) {
}
}
+int on_status(ryah_http_parser *parser, const char *at, size_t length) {
+ GET_WRAPPER(wrapper, parser);
+
+ if (at && length) {
+ if (wrapper->status == Qnil) {
+ wrapper->status = rb_str_new(at, length);
+ } else {
+ rb_str_cat(wrapper->status, at, length);
+ }
+ }
+ return 0;
+}
+
int on_url(ryah_http_parser *parser, const char *at, size_t length) {
GET_WRAPPER(wrapper, parser);
- rb_str_cat(wrapper->request_url, at, length);
+ if (at && length) {
+ if (wrapper->request_url == Qnil) {
+ wrapper->request_url = rb_str_new(at, length);
+ } else {
+ rb_str_cat(wrapper->request_url, at, length);
+ }
+ }
return 0;
}
@@ -136,7 +159,6 @@ int on_header_field(ryah_http_parser *parser, const char *at, size_t length) {
} else {
rb_str_cat(wrapper->curr_field_name, at, length);
}
-
return 0;
}
@@ -248,6 +270,7 @@ int on_message_complete(ryah_http_parser *parser) {
static ryah_http_parser_settings settings = {
.on_message_begin = on_message_begin,
+ .on_status = on_status,
.on_url = on_url,
.on_header_field = on_header_field,
.on_header_value = on_header_value,
@@ -439,6 +462,7 @@ VALUE Parser_status_code(VALUE self) {
return wrapper->name; \
}
+DEFINE_GETTER(status);
DEFINE_GETTER(request_url);
DEFINE_GETTER(headers);
DEFINE_GETTER(upgrade_data);
@@ -506,6 +530,7 @@ void Init_ruby_http_parser() {
rb_define_method(cParser, "http_method", Parser_http_method, 0);
rb_define_method(cParser, "status_code", Parser_status_code, 0);
+ rb_define_method(cParser, "status", Parser_status, 0);
rb_define_method(cParser, "request_url", Parser_request_url, 0);
rb_define_method(cParser, "headers", Parser_headers, 0);
rb_define_method(cParser, "upgrade_data", Parser_upgrade_data, 0);
View
@@ -1,3 +1,6 @@
+if defined?(Encoding)
+ Encoding.default_external = "UTF-8"
+end
require "spec_helper"
require "json"
@@ -377,23 +380,14 @@
expect(@parser.upgrade_data).to eq(test['upgrade'])
end
- fields = %w[
- http_major
- http_minor
- ]
+ expect(@parser.send("http_major")).to eq(test["http_major"])
+ expect(@parser.send("http_minor")).to eq(test["http_minor"])
if test['type'] == 'HTTP_REQUEST'
- fields += %w[
- request_url
- ]
+ expect(@parser.send("request_url")).to eq(test["request_url"].force_encoding(Encoding::BINARY))
else
- fields += %w[
- status_code
- ]
- end
-
- fields.each do |field|
- expect(@parser.send(field)).to eq(test[field])
+ expect(@parser.send("status_code")).to eq(test["status_code"])
+ expect(@parser.send("status")).to eq(test["status"].force_encoding(Encoding::BINARY))
end
expect(@headers.size).to eq(test['num_headers'])
@@ -442,7 +442,7 @@
{
"name": "line folding in header value",
"type": "HTTP_REQUEST",
- "raw": "GET / HTTP/1.1\r\nLine1: abc\r\n\tdef\r\n ghi\r\n\t\tjkl\r\n mno \r\n\t \tqrs\r\nLine2: \t line2\t\r\n\r\n",
+ "raw": "GET / HTTP/1.1\r\nLine1: abc\r\n\tdef\r\n ghi\r\n\t\tjkl\r\n mno \r\n\t \tqrs\r\nLine2: \t line2\t\r\n\r\n",
"should_keep_alive": true,
"message_complete_on_eof": false,
"http_major": 1,
@@ -454,7 +454,7 @@
"request_url": "/",
"num_headers": 2,
"headers": {
- "Line1": "abcdefghijklmno qrs",
+ "Line1": "abc\tdef ghi\t\tjkl mno \t \tqrs",
"Line2": "line2\t"
},
"body": "",
@@ -8,6 +8,7 @@
"http_major": 1,
"http_minor": 1,
"status_code": 301,
+ "status": "Moved Permanently",
"num_headers": 8,
"headers": {
"Location": "http://www.google.com/",
@@ -31,6 +32,7 @@
"http_major": 1,
"http_minor": 1,
"status_code": 200,
+ "status": "OK",
"num_headers": 5,
"headers": {
"Date": "Tue, 04 Aug 2009 07:59:32 GMT",
@@ -51,6 +53,7 @@
"http_major": 1,
"http_minor": 1,
"status_code": 404,
+ "status": "Not Found",
"num_headers": 0,
"headers": {
@@ -68,6 +71,7 @@
"http_major": 1,
"http_minor": 1,
"status_code": 301,
+ "status": "",
"num_headers": 0,
"headers": {
@@ -84,6 +88,7 @@
"http_major": 1,
"http_minor": 1,
"status_code": 200,
+ "status": "OK",
"num_headers": 2,
"headers": {
"Content-Type": "text/plain",
@@ -102,6 +107,7 @@
"http_major": 1,
"http_minor": 1,
"status_code": 200,
+ "status": "OK",
"num_headers": 2,
"headers": {
"Content-Type": "text/html; charset=utf-8",
@@ -119,6 +125,7 @@
"http_major": 1,
"http_minor": 1,
"status_code": 200,
+ "status": "OK",
"num_headers": 4,
"headers": {
"Content-Type": "text/html; charset=UTF-8",
@@ -138,6 +145,7 @@
"http_major": 1,
"http_minor": 1,
"status_code": 200,
+ "status": "OK",
"num_headers": 4,
"headers": {
"Server": "DCLK-AdSvr",
@@ -157,6 +165,7 @@
"http_major": 1,
"http_minor": 0,
"status_code": 301,
+ "status": "Moved Permanently",
"num_headers": 9,
"headers": {
"Date": "Thu, 03 Jun 2010 09:56:32 GMT",
@@ -181,6 +190,7 @@
"http_major": 1,
"http_minor": 1,
"status_code": 200,
+ "status": "OK",
"num_headers": 11,
"headers": {
"Date": "Tue, 28 Sep 2010 01:14:13 GMT",
@@ -207,6 +217,7 @@
"http_major": 1,
"http_minor": 1,
"status_code": 500,
+ "status": "Oriëntatieprobleem",
"num_headers": 3,
"headers": {
"Date": "Fri, 5 Nov 2010 23:07:12 GMT+2",
@@ -225,6 +236,7 @@
"http_major": 0,
"http_minor": 9,
"status_code": 200,
+ "status": "OK",
"num_headers": 0,
"headers": {
@@ -241,6 +253,7 @@
"http_major": 1,
"http_minor": 1,
"status_code": 200,
+ "status": "OK",
"num_headers": 1,
"headers": {
"Content-Type": "text/plain"
@@ -257,6 +270,7 @@
"http_major": 1,
"http_minor": 0,
"status_code": 200,
+ "status": "OK",
"num_headers": 1,
"headers": {
"Connection": "keep-alive"
@@ -274,6 +288,7 @@
"http_major": 1,
"http_minor": 0,
"status_code": 204,
+ "status": "No content",
"num_headers": 1,
"headers": {
"Connection": "keep-alive"
@@ -291,6 +306,7 @@
"http_major": 1,
"http_minor": 1,
"status_code": 200,
+ "status": "OK",
"num_headers": 0,
"headers": {
@@ -308,6 +324,7 @@
"http_major": 1,
"http_minor": 1,
"status_code": 204,
+ "status": "No content",
"num_headers": 0,
"headers": {
@@ -325,6 +342,7 @@
"http_major": 1,
"http_minor": 1,
"status_code": 204,
+ "status": "No content",
"num_headers": 1,
"headers": {
"Connection": "close"
@@ -342,6 +360,7 @@
"http_major": 1,
"http_minor": 1,
"status_code": 200,
+ "status": "OK",
"num_headers": 1,
"headers": {
"Transfer-Encoding": "chunked"
@@ -360,6 +379,7 @@
"http_major": 1,
"http_minor": 1,
"status_code": 200,
+ "status": "OK",
"num_headers": 7,
"headers": {
"Server": "Microsoft-IIS/6.0",

0 comments on commit 7ef407e

Please sign in to comment.