mizu 0.0.1 → 0.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cd610e46c078a3e1c24113b369ea341fe0cd338171ed8f0ecf2a425cd4ba1eb6
4
- data.tar.gz: 69026e1dab931e90d3533a91624a4a0f39d06c602cf930c00df1f94010304586
3
+ metadata.gz: f384f4dbe7507bfef6161da9de278370dd4a125de35b0ac8ffd625b65a7cef8d
4
+ data.tar.gz: c28c5ef22449faf141d1df141318e0207fa78c9d9cd7bea4002f1cd057f1fd86
5
5
  SHA512:
6
- metadata.gz: 2d16f63e8b7ff4def6bc23a76d7c7d45cf8df978d56320706d8d36fbeec5c59a0393e6c9087e6633d5a7d2ed18344949dce47edda14b2f996319df4cb57e89d7
7
- data.tar.gz: 2b314fa76a45282f84753db1ef2034bb2cbfb1c95327cdb373e0c31ccc045afe69ab298692c961a38fed45b95bed513c2a79e444daff3aa23453e2d1a91590dc
6
+ metadata.gz: f841120450f173f28fabfe4ff7698fceff24f9d6d9053a18be3a84cca2a6352521096d1dd07ae111daf45acfd3fc1096cf18bc172192838a0c4d4fe87a623a86
7
+ data.tar.gz: 2f0be48674a6620eb012a0ef708ca9256ca773b9ce045efca9195adc0b9205eb2e76c10694e72f1febcf3da352c29e233230fa50aaceb97fb10fba298d9485dc
data/.gitmodules ADDED
@@ -0,0 +1,3 @@
1
+ [submodule "ext/mizu/picohttpparser"]
2
+ path = ext/mizu/picohttpparser
3
+ url = git@github.com:h2o/picohttpparser.git
@@ -0,0 +1,4 @@
1
+ require 'mkmf'
2
+ extension_name = 'mizu_ext'
3
+ dir_config(extension_name)
4
+ create_makefile(extension_name)
data/ext/mizu/parser.c ADDED
@@ -0,0 +1,196 @@
1
+ #include <ruby.h>
2
+ #include "picohttpparser/picohttpparser.c"
3
+
4
+ VALUE Mizu = Qnil;
5
+ VALUE MizuExceptions = Qnil;
6
+ VALUE MizuParser = Qnil;
7
+
8
+ VALUE HeadersTooLongError = Qnil;
9
+ VALUE ParseError = Qnil;
10
+
11
+ void Init_mizu_ext();
12
+ VALUE method_mizu_parser_alloc(VALUE klass);
13
+ VALUE method_mizu_parser_reset(VALUE self);
14
+ static void method_parser_mark(void *p);
15
+ static void method_mizu_parser_free(void *p);
16
+ VALUE method_mizu_parser_parse(VALUE self, VALUE data);
17
+ VALUE method_mizu_parser_version(VALUE self);
18
+ VALUE method_mizu_parser_offset(VALUE self);
19
+ VALUE method_mizu_parser_headers(VALUE self);
20
+ VALUE method_mizu_parser_method(VALUE self);
21
+ VALUE method_mizu_parser_path(VALUE self);
22
+ ID id_call;
23
+
24
+ typedef struct
25
+ {
26
+ char _buf[4096];
27
+ const char *_method;
28
+ const char *_path;
29
+ struct phr_header _headers[128];
30
+ size_t _buflen;
31
+ size_t _prevbuflen;
32
+ size_t _method_len;
33
+ size_t _path_len;
34
+ size_t _num_headers;
35
+ int _pret;
36
+ int _minor_version;
37
+ VALUE version;
38
+ VALUE offset;
39
+ VALUE headers;
40
+ VALUE method;
41
+ VALUE path;
42
+ } ParserWrapper;
43
+
44
+ void Init_mizu_ext()
45
+ {
46
+ Mizu = rb_define_module("Mizu");
47
+ MizuExceptions = rb_define_class_under(Mizu, "Exceptions", rb_cObject);
48
+ MizuParser = rb_define_class_under(Mizu, "Parser", rb_cObject);
49
+ HeadersTooLongError = rb_const_get(MizuExceptions, rb_intern("HeadersTooLongError"));
50
+ ParseError = rb_const_get(MizuExceptions, rb_intern("ParseError"));
51
+ rb_define_alloc_func(MizuParser, method_mizu_parser_alloc);
52
+ rb_define_method(MizuParser, "<<", method_mizu_parser_parse, 1);
53
+ rb_define_method(MizuParser, "reset!", method_mizu_parser_reset, 0);
54
+ rb_define_method(MizuParser, "version", method_mizu_parser_version, 0);
55
+ rb_define_method(MizuParser, "offset", method_mizu_parser_offset, 0);
56
+ rb_define_method(MizuParser, "headers", method_mizu_parser_headers, 0);
57
+ rb_define_method(MizuParser, "method", method_mizu_parser_method, 0);
58
+ rb_define_method(MizuParser, "path", method_mizu_parser_path, 0);
59
+ id_call = rb_intern("call");
60
+ }
61
+
62
+ VALUE method_mizu_parser_alloc(VALUE klass)
63
+ {
64
+ ParserWrapper *ptr = ALLOC(ParserWrapper);
65
+ ptr->_buflen = 0;
66
+ ptr->_prevbuflen = 0;
67
+ return Data_Wrap_Struct(klass, method_parser_mark, method_mizu_parser_free, ptr);
68
+ }
69
+
70
+ VALUE method_mizu_parser_reset(VALUE self)
71
+ {
72
+ ParserWrapper *wrapper;
73
+ Data_Get_Struct(self, ParserWrapper, wrapper);
74
+ wrapper->_buflen = 0;
75
+ wrapper->_prevbuflen = 0;
76
+ return Qnil;
77
+ }
78
+
79
+ static void method_parser_mark(void *p)
80
+ {
81
+ if (p)
82
+ {
83
+ ParserWrapper *wrapper = (ParserWrapper *)p;
84
+ rb_gc_mark_maybe(wrapper->version);
85
+ rb_gc_mark_maybe(wrapper->offset);
86
+ rb_gc_mark_maybe(wrapper->headers);
87
+ rb_gc_mark_maybe(wrapper->method);
88
+ rb_gc_mark_maybe(wrapper->path);
89
+ }
90
+ }
91
+
92
+ static void method_mizu_parser_free(void *p)
93
+ {
94
+ xfree(p);
95
+ }
96
+
97
+ VALUE method_mizu_parser_parse(VALUE self, VALUE data)
98
+ {
99
+ ParserWrapper *wrapper;
100
+ Data_Get_Struct(self, ParserWrapper, wrapper);
101
+ char *buffer = StringValueCStr(data);
102
+ ssize_t rret = strlen(buffer);
103
+ if (wrapper->_buflen + rret >= sizeof(wrapper->_buf))
104
+ {
105
+ rb_raise(HeadersTooLongError, "Request Headers Too Long");
106
+ }
107
+ memcpy(wrapper->_buf + wrapper->_buflen, buffer, rret);
108
+ wrapper->_prevbuflen = wrapper->_buflen;
109
+ wrapper->_buflen += rret;
110
+ wrapper->_num_headers = sizeof(wrapper->_headers) / sizeof(wrapper->_headers[0]);
111
+ wrapper->_pret = phr_parse_request(
112
+ wrapper->_buf,
113
+ wrapper->_buflen,
114
+ &(wrapper->_method),
115
+ &(wrapper->_method_len),
116
+ &(wrapper->_path),
117
+ &(wrapper->_path_len),
118
+ &(wrapper->_minor_version),
119
+ wrapper->_headers,
120
+ &(wrapper->_num_headers),
121
+ wrapper->_prevbuflen);
122
+
123
+ if (wrapper->_pret > 0)
124
+ {
125
+ // Parsed
126
+ size_t i;
127
+ ParserWrapper *wrapper;
128
+ Data_Get_Struct(self, ParserWrapper, wrapper);
129
+ VALUE headers;
130
+
131
+ wrapper->offset = ULONG2NUM(wrapper->_pret - wrapper->_prevbuflen);
132
+ wrapper->version = rb_sprintf("1.%d", wrapper->_minor_version);
133
+ wrapper->method = rb_str_new(wrapper->_method, wrapper->_method_len);
134
+ wrapper->path = rb_str_new(wrapper->_path, wrapper->_path_len);
135
+
136
+ headers = rb_hash_new();
137
+ for (i = 0; i < wrapper->_num_headers; i++)
138
+ {
139
+ VALUE header_name = rb_str_new(wrapper->_headers[i].name, wrapper->_headers[i].name_len);
140
+ VALUE header_value = rb_str_new(wrapper->_headers[i].value, wrapper->_headers[i].value_len);
141
+ rb_hash_aset(headers, header_name, header_value);
142
+ }
143
+
144
+ wrapper->headers = headers;
145
+ rb_funcall(rb_iv_get(self, "@callback"), id_call, 0);
146
+ }
147
+ else if (wrapper->_pret == -1)
148
+ {
149
+ rb_raise(ParseError, "Illegal HTTP/1.x Request");
150
+ }
151
+ else if (wrapper->_pret == -2)
152
+ {
153
+ return Qnil; // Incomplete parsing, needs more data.
154
+ }
155
+
156
+ if (wrapper->_buflen == sizeof(wrapper->_buf))
157
+ {
158
+ rb_raise(HeadersTooLongError, "Request Headers Too Long");
159
+ }
160
+ return Qnil;
161
+ }
162
+
163
+ VALUE method_mizu_parser_version(VALUE self)
164
+ {
165
+ ParserWrapper *p;
166
+ Data_Get_Struct(self, ParserWrapper, p);
167
+ return p->version;
168
+ }
169
+
170
+ VALUE method_mizu_parser_offset(VALUE self)
171
+ {
172
+ ParserWrapper *p;
173
+ Data_Get_Struct(self, ParserWrapper, p);
174
+ return p->offset;
175
+ }
176
+
177
+ VALUE method_mizu_parser_headers(VALUE self)
178
+ {
179
+ ParserWrapper *p;
180
+ Data_Get_Struct(self, ParserWrapper, p);
181
+ return p->headers;
182
+ }
183
+
184
+ VALUE method_mizu_parser_method(VALUE self)
185
+ {
186
+ ParserWrapper *p;
187
+ Data_Get_Struct(self, ParserWrapper, p);
188
+ return p->method;
189
+ }
190
+
191
+ VALUE method_mizu_parser_path(VALUE self)
192
+ {
193
+ ParserWrapper *p;
194
+ Data_Get_Struct(self, ParserWrapper, p);
195
+ return p->path;
196
+ }
@@ -0,0 +1,6 @@
1
+ module Mizu
2
+ class Exceptions
3
+ class ParseError < IOError; end
4
+ class HeadersTooLongError < IOError; end
5
+ end
6
+ end
@@ -0,0 +1,7 @@
1
+ module Mizu
2
+ class Parser
3
+ def on_complete(&block)
4
+ @callback = block
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,3 @@
1
+ module Mizu
2
+ VERSION = '0.0.1'.freeze
3
+ end
data/lib/mizu.rb ADDED
@@ -0,0 +1,4 @@
1
+ require_relative './mizu/version.rb'
2
+ require_relative './mizu/exceptions.rb'
3
+ require_relative './mizu/parser.rb'
4
+ require_relative 'mizu_ext'
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mizu
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - HeckPsi Lab
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-07-11 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2018-07-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake-compiler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.0'
13
27
  description: Mizu is a Ruby port of h2o/picohttpparser, designed to be merged in next
14
28
  generation of midori.
15
29
  email:
@@ -18,7 +32,14 @@ executables: []
18
32
  extensions: []
19
33
  extra_rdoc_files: []
20
34
  files:
35
+ - ".gitmodules"
21
36
  - LICENSE
37
+ - ext/mizu/extconf.rb
38
+ - ext/mizu/parser.c
39
+ - lib/mizu.rb
40
+ - lib/mizu/exceptions.rb
41
+ - lib/mizu/parser.rb
42
+ - lib/mizu/version.rb
22
43
  homepage: https://github.com/midori-rb/mizu
23
44
  licenses:
24
45
  - MIT