http-parser 1.0.5 → 1.2.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 +4 -4
- data/LICENSE +20 -20
- data/README.md +69 -69
- data/Rakefile +19 -19
- data/ext/Rakefile +8 -8
- data/ext/http-parser/http_parser.c +2470 -2234
- data/ext/http-parser/http_parser.h +362 -318
- data/http-parser.gemspec +35 -33
- data/lib/http-parser.rb +11 -9
- data/lib/http-parser/errors.rb +77 -74
- data/lib/http-parser/ext.rb +9 -7
- data/lib/http-parser/parser.rb +258 -224
- data/lib/http-parser/types.rb +335 -311
- data/lib/http-parser/version.rb +5 -3
- data/spec/error_spec.rb +45 -45
- data/spec/instance_spec.rb +78 -78
- data/spec/parser_spec.rb +313 -313
- metadata +51 -46
data/http-parser.gemspec
CHANGED
@@ -1,33 +1,35 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
s.
|
9
|
-
s.
|
10
|
-
s.
|
11
|
-
s.
|
12
|
-
s.
|
13
|
-
s.
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
s.add_development_dependency '
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
s.
|
29
|
-
s.
|
30
|
-
|
31
|
-
s.
|
32
|
-
|
33
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# -*- encoding: utf-8 -*-
|
3
|
+
|
4
|
+
$:.push File.expand_path("../lib", __FILE__)
|
5
|
+
require "http-parser/version"
|
6
|
+
|
7
|
+
Gem::Specification.new do |s|
|
8
|
+
s.name = "http-parser"
|
9
|
+
s.version = HttpParser::VERSION
|
10
|
+
s.authors = ["Stephen von Takach"]
|
11
|
+
s.email = ["steve@cotag.me"]
|
12
|
+
s.license = 'MIT'
|
13
|
+
s.homepage = "https://github.com/cotag/http-parser"
|
14
|
+
s.summary = "Ruby bindings to joyent/http-parser"
|
15
|
+
s.description = <<-EOF
|
16
|
+
A super fast http parser for ruby.
|
17
|
+
Cross platform and multiple ruby implementation support thanks to ffi.
|
18
|
+
EOF
|
19
|
+
|
20
|
+
|
21
|
+
s.add_dependency 'ffi-compiler', '>= 1.0', '< 2.0'
|
22
|
+
|
23
|
+
s.add_development_dependency 'rake', '~> 11.2'
|
24
|
+
s.add_development_dependency 'rspec', '~> 3.5'
|
25
|
+
s.add_development_dependency 'yard', '~> 0.9'
|
26
|
+
|
27
|
+
|
28
|
+
s.files = Dir["{lib}/**/*"] + %w(Rakefile http-parser.gemspec README.md LICENSE)
|
29
|
+
s.files += ["ext/http-parser/http_parser.c", "ext/http-parser/http_parser.h"]
|
30
|
+
s.test_files = Dir["spec/**/*"]
|
31
|
+
s.extra_rdoc_files = ["README.md"]
|
32
|
+
|
33
|
+
s.extensions << "ext/Rakefile"
|
34
|
+
s.require_paths = ["lib"]
|
35
|
+
end
|
data/lib/http-parser.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require "
|
4
|
-
|
5
|
-
require "http-parser/
|
6
|
-
require "http-parser/
|
7
|
-
|
8
|
-
|
9
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "ffi" # Bindings to C libraries
|
4
|
+
|
5
|
+
require "http-parser/ext" # Loads http-parser ext
|
6
|
+
require "http-parser/errors" # http-parser error definitions
|
7
|
+
require "http-parser/types" # http-parser data structures
|
8
|
+
require "http-parser/parser" # the core http-parser abstraction
|
9
|
+
|
10
|
+
module HttpParser
|
11
|
+
end
|
data/lib/http-parser/errors.rb
CHANGED
@@ -1,74 +1,77 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
class
|
12
|
-
class
|
13
|
-
|
14
|
-
|
15
|
-
class
|
16
|
-
class
|
17
|
-
class
|
18
|
-
class
|
19
|
-
class
|
20
|
-
class
|
21
|
-
class
|
22
|
-
class
|
23
|
-
class
|
24
|
-
class
|
25
|
-
class
|
26
|
-
class
|
27
|
-
class
|
28
|
-
class
|
29
|
-
class
|
30
|
-
class
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
:
|
40
|
-
:
|
41
|
-
:
|
42
|
-
:
|
43
|
-
:
|
44
|
-
:
|
45
|
-
:
|
46
|
-
|
47
|
-
:
|
48
|
-
:
|
49
|
-
|
50
|
-
:
|
51
|
-
:
|
52
|
-
:
|
53
|
-
:
|
54
|
-
:
|
55
|
-
:
|
56
|
-
:
|
57
|
-
:
|
58
|
-
:
|
59
|
-
:
|
60
|
-
:
|
61
|
-
:
|
62
|
-
:
|
63
|
-
:
|
64
|
-
:
|
65
|
-
:
|
66
|
-
:
|
67
|
-
|
68
|
-
:
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module HttpParser
|
4
|
+
class Error < StandardError
|
5
|
+
class OK < Error; end
|
6
|
+
|
7
|
+
# Any callback-related errors
|
8
|
+
class CALLBACK < Error; end
|
9
|
+
|
10
|
+
# Parsing-related errors
|
11
|
+
class INVALID_EOF_STATE < Error; end
|
12
|
+
class HEADER_OVERFLOW < Error; end
|
13
|
+
class CLOSED_CONNECTION < Error; end
|
14
|
+
|
15
|
+
class INVALID_VERSION < Error; end
|
16
|
+
class INVALID_STATUS < Error; end
|
17
|
+
class INVALID_METHOD < Error; end
|
18
|
+
class INVALID_URL < Error; end
|
19
|
+
class INVALID_HOST < Error; end
|
20
|
+
class INVALID_PORT < Error; end
|
21
|
+
class INVALID_PATH < Error; end
|
22
|
+
class INVALID_QUERY_STRING < Error; end
|
23
|
+
class INVALID_FRAGMENT < Error; end
|
24
|
+
class LF_EXPECTED < Error; end
|
25
|
+
class INVALID_HEADER_TOKEN < Error; end
|
26
|
+
class INVALID_CONTENT_LENGTH < Error; end
|
27
|
+
class INVALID_CHUNK_SIZE < Error; end
|
28
|
+
class INVALID_CONSTANT < Error; end
|
29
|
+
class INVALID_INTERNAL_STATE < Error; end
|
30
|
+
class STRICT < Error; end
|
31
|
+
class PAUSED < Error; end
|
32
|
+
|
33
|
+
class UNKNOWN < Error; end
|
34
|
+
end
|
35
|
+
|
36
|
+
ERRORS = {
|
37
|
+
:OK => Error::OK,
|
38
|
+
|
39
|
+
:CB_message_begin => Error::CALLBACK,
|
40
|
+
:CB_url => Error::CALLBACK,
|
41
|
+
:CB_header_field => Error::CALLBACK,
|
42
|
+
:CB_header_value => Error::CALLBACK,
|
43
|
+
:CB_headers_complete => Error::CALLBACK,
|
44
|
+
:CB_body => Error::CALLBACK,
|
45
|
+
:CB_message_complete => Error::CALLBACK,
|
46
|
+
:CB_status => Error::CALLBACK,
|
47
|
+
:CB_chunk_header => Error::CALLBACK,
|
48
|
+
:CB_chunk_complete => Error::CALLBACK,
|
49
|
+
|
50
|
+
:INVALID_EOF_STATE => Error::INVALID_EOF_STATE,
|
51
|
+
:HEADER_OVERFLOW => Error::HEADER_OVERFLOW,
|
52
|
+
:CLOSED_CONNECTION => Error::CLOSED_CONNECTION,
|
53
|
+
:INVALID_VERSION => Error::INVALID_VERSION,
|
54
|
+
:INVALID_STATUS => Error::INVALID_STATUS,
|
55
|
+
:INVALID_METHOD => Error::INVALID_METHOD,
|
56
|
+
:INVALID_URL => Error::INVALID_URL,
|
57
|
+
:INVALID_HOST => Error::INVALID_HOST,
|
58
|
+
:INVALID_PORT => Error::INVALID_PORT,
|
59
|
+
:INVALID_PATH => Error::INVALID_PATH,
|
60
|
+
:INVALID_QUERY_STRING => Error::INVALID_QUERY_STRING,
|
61
|
+
:INVALID_FRAGMENT => Error::INVALID_FRAGMENT,
|
62
|
+
:LF_EXPECTED => Error::LF_EXPECTED,
|
63
|
+
:INVALID_HEADER_TOKEN => Error::INVALID_HEADER_TOKEN,
|
64
|
+
:INVALID_CONTENT_LENGTH => Error::INVALID_CONTENT_LENGTH,
|
65
|
+
:INVALID_CHUNK_SIZE => Error::INVALID_CHUNK_SIZE,
|
66
|
+
:INVALID_CONSTANT => Error::INVALID_CONSTANT,
|
67
|
+
:INVALID_INTERNAL_STATE => Error::INVALID_INTERNAL_STATE,
|
68
|
+
:STRICT => Error::STRICT,
|
69
|
+
:PAUSED => Error::PAUSED,
|
70
|
+
|
71
|
+
:UNKNOWN => Error::UNKNOWN
|
72
|
+
}
|
73
|
+
|
74
|
+
attach_function :err_desc, :http_errno_description, [:int], :string
|
75
|
+
attach_function :err_name, :http_errno_name, [:int], :string
|
76
|
+
end
|
77
|
+
|
data/lib/http-parser/ext.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'ffi'
|
4
|
+
require 'ffi-compiler/loader'
|
5
|
+
|
6
|
+
module HttpParser
|
7
|
+
extend FFI::Library
|
8
|
+
ffi_lib FFI::Compiler::Loader.find('http-parser-ext')
|
9
|
+
end
|
data/lib/http-parser/parser.rb
CHANGED
@@ -1,224 +1,258 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
#
|
35
|
-
#
|
36
|
-
#
|
37
|
-
#
|
38
|
-
#
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
#
|
50
|
-
#
|
51
|
-
#
|
52
|
-
# @
|
53
|
-
# The
|
54
|
-
#
|
55
|
-
#
|
56
|
-
#
|
57
|
-
#
|
58
|
-
#
|
59
|
-
#
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
#
|
71
|
-
#
|
72
|
-
#
|
73
|
-
#
|
74
|
-
#
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
#
|
86
|
-
#
|
87
|
-
#
|
88
|
-
# @
|
89
|
-
# The
|
90
|
-
#
|
91
|
-
#
|
92
|
-
#
|
93
|
-
#
|
94
|
-
#
|
95
|
-
#
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
#
|
107
|
-
#
|
108
|
-
#
|
109
|
-
# @
|
110
|
-
# The
|
111
|
-
#
|
112
|
-
#
|
113
|
-
#
|
114
|
-
#
|
115
|
-
#
|
116
|
-
#
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
#
|
128
|
-
#
|
129
|
-
#
|
130
|
-
#
|
131
|
-
#
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
#
|
143
|
-
#
|
144
|
-
#
|
145
|
-
# @
|
146
|
-
# The
|
147
|
-
#
|
148
|
-
#
|
149
|
-
#
|
150
|
-
#
|
151
|
-
#
|
152
|
-
# @
|
153
|
-
#
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
#
|
165
|
-
#
|
166
|
-
#
|
167
|
-
#
|
168
|
-
#
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
#
|
180
|
-
#
|
181
|
-
#
|
182
|
-
#
|
183
|
-
#
|
184
|
-
#
|
185
|
-
#
|
186
|
-
#
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module HttpParser
|
4
|
+
class Parser
|
5
|
+
CALLBACKS = [
|
6
|
+
:on_message_begin, :on_url, :on_status, :on_header_field, :on_header_value,
|
7
|
+
:on_headers_complete, :on_body, :on_message_complete, :on_chunk_header, :on_chunk_complete
|
8
|
+
]
|
9
|
+
|
10
|
+
#
|
11
|
+
# Returns a new request/response instance variable
|
12
|
+
#
|
13
|
+
def self.new_instance &block
|
14
|
+
::HttpParser::Instance.new &block
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
#
|
19
|
+
# Initializes the Parser instance.
|
20
|
+
#
|
21
|
+
def initialize(callback_obj = nil)
|
22
|
+
@settings = ::HttpParser::Settings.new
|
23
|
+
@callbacks = {} # so GC doesn't clean them up on java
|
24
|
+
|
25
|
+
if not callback_obj.nil?
|
26
|
+
CALLBACKS.each do |callback|
|
27
|
+
self.__send__(callback, &callback_obj.method(callback)) if callback_obj.respond_to? callback
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
yield self if block_given?
|
32
|
+
end
|
33
|
+
|
34
|
+
#
|
35
|
+
# Registers an `on_message_begin` callback.
|
36
|
+
#
|
37
|
+
# @yield [instance]
|
38
|
+
# The given block will be called when the HTTP message begins.
|
39
|
+
#
|
40
|
+
# @yieldparam [HttpParser::Instance] instance
|
41
|
+
# The state so far of the request / response being processed.
|
42
|
+
#
|
43
|
+
def on_message_begin(&block)
|
44
|
+
cb = Callback.new(&block)
|
45
|
+
@callbacks[:on_message_begin] = cb
|
46
|
+
@settings[:on_message_begin] = cb
|
47
|
+
end
|
48
|
+
|
49
|
+
#
|
50
|
+
# Registers an `on_url` callback.
|
51
|
+
#
|
52
|
+
# @yield [instance, url]
|
53
|
+
# The given block will be called when the Request URI is recognized
|
54
|
+
# within the Request-Line.
|
55
|
+
#
|
56
|
+
# @yieldparam [HttpParser::Instance] instance
|
57
|
+
# The state so far of the request / response being processed.
|
58
|
+
#
|
59
|
+
# @yieldparam [String] url
|
60
|
+
# The recognized Request URI.
|
61
|
+
#
|
62
|
+
# @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5.1.2
|
63
|
+
#
|
64
|
+
def on_url(&block)
|
65
|
+
cb = DataCallback.new(&block)
|
66
|
+
@callbacks[:on_url] = cb
|
67
|
+
@settings[:on_url] = cb
|
68
|
+
end
|
69
|
+
|
70
|
+
#
|
71
|
+
# Registers an `on_status_complete` callback.
|
72
|
+
#
|
73
|
+
# @yield [instance]
|
74
|
+
# The given block will be called when the status is recognized.
|
75
|
+
#
|
76
|
+
# @yieldparam [HttpParser::Instance] instance
|
77
|
+
# The state so far of the request / response being processed.
|
78
|
+
#
|
79
|
+
def on_status(&block)
|
80
|
+
cb = DataCallback.new(&block)
|
81
|
+
@callbacks[:on_status] = cb
|
82
|
+
@settings[:on_status] = cb
|
83
|
+
end
|
84
|
+
|
85
|
+
#
|
86
|
+
# Registers an `on_header_field` callback.
|
87
|
+
#
|
88
|
+
# @yield [instance, field]
|
89
|
+
# The given block will be called when a Header name is recognized
|
90
|
+
# in the Headers.
|
91
|
+
#
|
92
|
+
# @yieldparam [HttpParser::Instance] instance
|
93
|
+
# The state so far of the request / response being processed.
|
94
|
+
#
|
95
|
+
# @yieldparam [String] field
|
96
|
+
# A recognized Header name.
|
97
|
+
#
|
98
|
+
# @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.5
|
99
|
+
#
|
100
|
+
def on_header_field(&block)
|
101
|
+
cb = DataCallback.new(&block)
|
102
|
+
@callbacks[:on_header_field] = cb
|
103
|
+
@settings[:on_header_field] = cb
|
104
|
+
end
|
105
|
+
|
106
|
+
#
|
107
|
+
# Registers an `on_header_value` callback.
|
108
|
+
#
|
109
|
+
# @yield [instance, value]
|
110
|
+
# The given block will be called when a Header value is recognized
|
111
|
+
# in the Headers.
|
112
|
+
#
|
113
|
+
# @yieldparam [HttpParser::Instance] instance
|
114
|
+
# The state so far of the request / response being processed.
|
115
|
+
#
|
116
|
+
# @yieldparam [String] value
|
117
|
+
# A recognized Header value.
|
118
|
+
#
|
119
|
+
# @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.5
|
120
|
+
#
|
121
|
+
def on_header_value(&block)
|
122
|
+
cb = DataCallback.new(&block)
|
123
|
+
@callbacks[:on_header_value] = cb
|
124
|
+
@settings[:on_header_value] = cb
|
125
|
+
end
|
126
|
+
|
127
|
+
#
|
128
|
+
# Registers an `on_headers_complete` callback.
|
129
|
+
#
|
130
|
+
# @yield [instance]
|
131
|
+
# The given block will be called when the Headers stop.
|
132
|
+
#
|
133
|
+
# @yieldparam [HttpParser::Instance] instance
|
134
|
+
# The state so far of the request / response being processed.
|
135
|
+
#
|
136
|
+
def on_headers_complete(&block)
|
137
|
+
cb = Callback.new(&block)
|
138
|
+
@callbacks[:on_headers_complete] = cb
|
139
|
+
@settings[:on_headers_complete] = cb
|
140
|
+
end
|
141
|
+
|
142
|
+
#
|
143
|
+
# Registers an `on_body` callback.
|
144
|
+
#
|
145
|
+
# @yield [instance, body]
|
146
|
+
# The given block will be called when the body is recognized in the
|
147
|
+
# message body.
|
148
|
+
#
|
149
|
+
# @yieldparam [HttpParser::Instance] instance
|
150
|
+
# The state so far of the request / response being processed.
|
151
|
+
#
|
152
|
+
# @yieldparam [String] body
|
153
|
+
# The full body or a chunk of the body from a chunked
|
154
|
+
# Transfer-Encoded stream.
|
155
|
+
#
|
156
|
+
# @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.5
|
157
|
+
#
|
158
|
+
def on_body(&block)
|
159
|
+
cb = DataCallback.new(&block)
|
160
|
+
@callbacks[:on_body] = cb
|
161
|
+
@settings[:on_body] = cb
|
162
|
+
end
|
163
|
+
|
164
|
+
#
|
165
|
+
# Registers an `on_message_begin` callback.
|
166
|
+
#
|
167
|
+
# @yield [instance]
|
168
|
+
# The given block will be called when the message completes.
|
169
|
+
#
|
170
|
+
# @yieldparam [HttpParser::Instance] instance
|
171
|
+
# The state so far of the request / response being processed.
|
172
|
+
#
|
173
|
+
def on_message_complete(&block)
|
174
|
+
cb = Callback.new(&block)
|
175
|
+
@callbacks[:on_message_complete] = cb
|
176
|
+
@settings[:on_message_complete] = cb
|
177
|
+
end
|
178
|
+
|
179
|
+
#
|
180
|
+
# Registers an `on_chunk_header` callback.
|
181
|
+
#
|
182
|
+
# @yield [instance]
|
183
|
+
# The given block will be called when a new chunk header is received.
|
184
|
+
#
|
185
|
+
# @yieldparam [HttpParser::Instance] instance
|
186
|
+
# The state so far of the request / response being processed.
|
187
|
+
#
|
188
|
+
def on_chunk_header(&block)
|
189
|
+
cb = Callback.new(&block)
|
190
|
+
@callbacks[:on_message_complete] = cb
|
191
|
+
@settings[:on_message_complete] = cb
|
192
|
+
end
|
193
|
+
|
194
|
+
#
|
195
|
+
# Registers an `on_chunk_complete` callback.
|
196
|
+
#
|
197
|
+
# @yield [instance]
|
198
|
+
# The given block will be called when the current chunk completes.
|
199
|
+
#
|
200
|
+
# @yieldparam [HttpParser::Instance] instance
|
201
|
+
# The state so far of the request / response being processed.
|
202
|
+
#
|
203
|
+
def on_chunk_complete(&block)
|
204
|
+
cb = Callback.new(&block)
|
205
|
+
@callbacks[:on_message_complete] = cb
|
206
|
+
@settings[:on_message_complete] = cb
|
207
|
+
end
|
208
|
+
|
209
|
+
#
|
210
|
+
# Parses data.
|
211
|
+
#
|
212
|
+
# @param [HttpParser::Instance] inst
|
213
|
+
# The state so far of the request / response being processed.
|
214
|
+
#
|
215
|
+
# @param [String] data
|
216
|
+
# The data to parse against the instance specified.
|
217
|
+
#
|
218
|
+
# @return [Boolean]
|
219
|
+
# Returns true if the data was parsed successfully.
|
220
|
+
#
|
221
|
+
def parse(inst, data)
|
222
|
+
::HttpParser.http_parser_execute(inst, @settings, data, data.length)
|
223
|
+
return inst.error?
|
224
|
+
end
|
225
|
+
|
226
|
+
|
227
|
+
protected
|
228
|
+
|
229
|
+
|
230
|
+
class Callback < ::FFI::Function
|
231
|
+
#
|
232
|
+
# Creates a new Parser callback.
|
233
|
+
#
|
234
|
+
def self.new(&block)
|
235
|
+
super(:int, [::HttpParser::Instance.ptr]) do |parser|
|
236
|
+
begin
|
237
|
+
catch(:return) { yield(parser); 0 }
|
238
|
+
rescue
|
239
|
+
-1
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
class DataCallback < ::FFI::Function
|
246
|
+
def self.new(&block)
|
247
|
+
super(:int, [::HttpParser::Instance.ptr, :pointer, :size_t]) do |parser, buffer, length|
|
248
|
+
begin
|
249
|
+
data = buffer.get_bytes(0, length)
|
250
|
+
catch(:return) { yield(parser, data); 0 }
|
251
|
+
rescue
|
252
|
+
-1
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|
257
|
+
end
|
258
|
+
end
|