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.
@@ -1,3 +1,5 @@
1
- module HttpParser
2
- VERSION = "1.0.5"
3
- end
1
+ # frozen_string_literal: true
2
+
3
+ module HttpParser
4
+ VERSION = "1.2.0"
5
+ end
@@ -1,45 +1,45 @@
1
- require 'http-parser'
2
-
3
- describe HttpParser::Parser, "#initialize" do
4
- before :each do
5
- @inst = HttpParser::Parser.new_instance
6
- end
7
-
8
- it "should return true when error" do
9
- expect(subject.parse(@inst, "GETS / HTTP/1.1\r\n")).to eq(true)
10
- expect(@inst.error?).to eq(true)
11
- end
12
-
13
- it "should return false on success" do
14
- expect(subject.parse(@inst, "GET / HTTP/1.1\r\n")).to eq(false)
15
- expect(@inst.error?).to eq(false)
16
- end
17
-
18
- it "the error should be inspectable" do
19
- expect(subject.parse(@inst, "GETS / HTTP/1.1\r\n")).to eq(true)
20
- expect(@inst.error).to be_kind_of(::HttpParser::Error::INVALID_METHOD)
21
- expect(@inst.error?).to eq(true)
22
- end
23
-
24
- it "raises different error types depending on the error" do
25
- expect(subject.parse(@inst, "GET / HTTP/23\r\n")).to eq(true)
26
- expect(@inst.error).to be_kind_of(::HttpParser::Error::INVALID_VERSION)
27
- expect(@inst.error?).to eq(true)
28
- end
29
-
30
- context "callback errors" do
31
- subject do
32
- described_class.new do |parser|
33
- parser.on_url { |inst, data| raise 'unhandled' }
34
- end
35
- end
36
-
37
- it "should handle unhandled errors gracefully" do
38
- expect(subject.parse(@inst, "GET /foo?q=1 HTTP/1.1")).to eq(true)
39
-
40
- expect(@inst.error?).to eq(true)
41
- expect(@inst.error).to be_kind_of(::HttpParser::Error::CALLBACK)
42
- end
43
- end
44
- end
45
-
1
+ require 'http-parser'
2
+
3
+ describe HttpParser::Parser, "#initialize" do
4
+ before :each do
5
+ @inst = HttpParser::Parser.new_instance
6
+ end
7
+
8
+ it "should return true when error" do
9
+ expect(subject.parse(@inst, "GETS / HTTP/1.1\r\n")).to eq(true)
10
+ expect(@inst.error?).to eq(true)
11
+ end
12
+
13
+ it "should return false on success" do
14
+ expect(subject.parse(@inst, "GET / HTTP/1.1\r\n")).to eq(false)
15
+ expect(@inst.error?).to eq(false)
16
+ end
17
+
18
+ it "the error should be inspectable" do
19
+ expect(subject.parse(@inst, "GETS / HTTP/1.1\r\n")).to eq(true)
20
+ expect(@inst.error).to be_kind_of(::HttpParser::Error::INVALID_METHOD)
21
+ expect(@inst.error?).to eq(true)
22
+ end
23
+
24
+ it "raises different error types depending on the error" do
25
+ expect(subject.parse(@inst, "GET / HTTP/23\r\n")).to eq(true)
26
+ expect(@inst.error).to be_kind_of(::HttpParser::Error::INVALID_VERSION)
27
+ expect(@inst.error?).to eq(true)
28
+ end
29
+
30
+ context "callback errors" do
31
+ subject do
32
+ described_class.new do |parser|
33
+ parser.on_url { |inst, data| raise 'unhandled' }
34
+ end
35
+ end
36
+
37
+ it "should handle unhandled errors gracefully" do
38
+ expect(subject.parse(@inst, "GET /foo?q=1 HTTP/1.1")).to eq(true)
39
+
40
+ expect(@inst.error?).to eq(true)
41
+ expect(@inst.error).to be_kind_of(::HttpParser::Error::CALLBACK)
42
+ end
43
+ end
44
+ end
45
+
@@ -1,78 +1,78 @@
1
- require 'http-parser'
2
-
3
- describe ::HttpParser::Instance, "#initialize" do
4
- context "when given a block" do
5
- it "should yield the new Instance" do
6
- expected = nil
7
-
8
- described_class.new { |inst| expected = inst }
9
-
10
- expect(expected).to be_kind_of(described_class)
11
- end
12
-
13
- it "should allow changing the parser type" do
14
- inst = described_class.new do |inst|
15
- inst.type = :request
16
- end
17
-
18
- expect(inst.type).to eq(:request)
19
- end
20
- end
21
-
22
- describe "#type" do
23
- it "should default to :both" do
24
- expect(subject.type).to eq(:both)
25
- end
26
-
27
- it "should convert the type to a Symbol" do
28
- subject[:type_flags] = ::HttpParser::TYPES[:request]
29
-
30
- expect(subject.type).to eq(:request)
31
- end
32
-
33
- it "should extract the type from the type_flags field" do
34
- subject[:type_flags] = ((0xff & ~0x3) | ::HttpParser::TYPES[:response])
35
-
36
- expect(subject.type).to eq(:response)
37
- end
38
- end
39
-
40
- describe "#type=" do
41
- it "should set the type" do
42
- subject.type = :response
43
-
44
- expect(subject.type).to eq(:response)
45
- end
46
-
47
- it "should not change flags" do
48
- flags = (0xff & ~0x3)
49
- subject[:type_flags] = flags
50
-
51
- subject.type = :request
52
-
53
- expect(subject[:type_flags]).to eq((flags | ::HttpParser::TYPES[:request]))
54
- end
55
- end
56
-
57
- describe "#stop!" do
58
- it "should throw :return, 1" do
59
- expect { subject.stop! }.to throw_symbol(:return,1)
60
- end
61
- end
62
-
63
- describe "#error!" do
64
- it "should throw :return, -1" do
65
- expect { subject.error! }.to throw_symbol(:return,-1)
66
- end
67
- end
68
-
69
- it "should not change the type" do
70
- inst = described_class.new do |inst|
71
- inst.type = :request
72
- end
73
-
74
- inst.reset!
75
- expect(inst.type).to eq(:request)
76
- end
77
- end
78
-
1
+ require 'http-parser'
2
+
3
+ describe ::HttpParser::Instance, "#initialize" do
4
+ context "when given a block" do
5
+ it "should yield the new Instance" do
6
+ expected = nil
7
+
8
+ described_class.new { |inst| expected = inst }
9
+
10
+ expect(expected).to be_kind_of(described_class)
11
+ end
12
+
13
+ it "should allow changing the parser type" do
14
+ inst = described_class.new do |inst|
15
+ inst.type = :request
16
+ end
17
+
18
+ expect(inst.type).to eq(:request)
19
+ end
20
+ end
21
+
22
+ describe "#type" do
23
+ it "should default to :both" do
24
+ expect(subject.type).to eq(:both)
25
+ end
26
+
27
+ it "should convert the type to a Symbol" do
28
+ subject[:type_flags] = ::HttpParser::TYPES[:request]
29
+
30
+ expect(subject.type).to eq(:request)
31
+ end
32
+
33
+ it "should extract the type from the type_flags field" do
34
+ subject[:type_flags] = ((0xff & ~0x3) | ::HttpParser::TYPES[:response])
35
+
36
+ expect(subject.type).to eq(:response)
37
+ end
38
+ end
39
+
40
+ describe "#type=" do
41
+ it "should set the type" do
42
+ subject.type = :response
43
+
44
+ expect(subject.type).to eq(:response)
45
+ end
46
+
47
+ it "should not change flags" do
48
+ flags = (0xff & ~0x3)
49
+ subject[:type_flags] = flags
50
+
51
+ subject.type = :request
52
+
53
+ expect(subject[:type_flags]).to eq((flags | ::HttpParser::TYPES[:request]))
54
+ end
55
+ end
56
+
57
+ describe "#stop!" do
58
+ it "should throw :return, 1" do
59
+ expect { subject.stop! }.to throw_symbol(:return,1)
60
+ end
61
+ end
62
+
63
+ describe "#error!" do
64
+ it "should throw :return, -1" do
65
+ expect { subject.error! }.to throw_symbol(:return,-1)
66
+ end
67
+ end
68
+
69
+ it "should not change the type" do
70
+ inst = described_class.new do |inst|
71
+ inst.type = :request
72
+ end
73
+
74
+ inst.reset!
75
+ expect(inst.type).to eq(:request)
76
+ end
77
+ end
78
+
@@ -1,313 +1,313 @@
1
- require 'http-parser'
2
-
3
- describe HttpParser::Parser, "#initialize" do
4
- before :each do
5
- @inst = HttpParser::Parser.new_instance
6
- end
7
-
8
- describe "callbacks" do
9
- describe "on_message_begin" do
10
- subject do
11
- described_class.new do |parser|
12
- parser.on_message_begin { @begun = true }
13
- end
14
- end
15
-
16
- it "should trigger on a new request" do
17
- subject.parse @inst, "GET / HTTP/1.1"
18
- expect(@begun).to eq(true)
19
- end
20
- end
21
-
22
- describe "on_url" do
23
- let(:expected) { '/foo?q=1' }
24
-
25
- subject do
26
- described_class.new do |parser|
27
- parser.on_url { |inst, data| @url = data }
28
- end
29
- end
30
-
31
- it "should pass the recognized url" do
32
- subject.parse @inst, "GET "
33
-
34
- expect(@url).to be_nil
35
-
36
- subject.parse @inst, "#{expected} HTTP/1.1"
37
-
38
- expect(@url).to eq(expected)
39
- end
40
- end
41
-
42
- describe "on_header_field" do
43
- let(:expected) { 'Host' }
44
-
45
- subject do
46
- described_class.new do |parser|
47
- parser.on_header_field { |inst, data| @header_field = data }
48
- end
49
- end
50
-
51
- it "should pass the recognized header-name" do
52
- subject.parse @inst, "GET /foo HTTP/1.1\r\n"
53
-
54
- expect(@header_field).to be_nil
55
-
56
- subject.parse @inst, "#{expected}: example.com\r\n"
57
-
58
- expect(@header_field).to eq(expected)
59
- end
60
- end
61
-
62
- describe "on_header_value" do
63
- let(:expected) { 'example.com' }
64
-
65
- subject do
66
- described_class.new do |parser|
67
- parser.on_header_value { |inst, data| @header_value = data }
68
- end
69
- end
70
-
71
- it "should pass the recognized header-value" do
72
- subject.parse @inst, "GET /foo HTTP/1.1\r\n"
73
-
74
- expect(@header_value).to be_nil
75
-
76
- subject.parse @inst, "Host: #{expected}\r\n"
77
-
78
- expect(@header_value).to eq(expected)
79
- end
80
- end
81
-
82
- describe "on_headers_complete" do
83
- subject do
84
- described_class.new do |parser|
85
- parser.on_headers_complete { @header_complete = true }
86
- end
87
- end
88
-
89
- it "should trigger on the last header" do
90
- subject.parse @inst, "GET / HTTP/1.1\r\nHost: example.com\r\n"
91
-
92
- expect(@header_complete).to be_nil
93
-
94
- subject.parse @inst, "\r\n"
95
-
96
- expect(@header_complete).to eq(true)
97
- end
98
-
99
- context "when #stop! is called" do
100
- subject do
101
- described_class.new do |parser|
102
- parser.on_headers_complete { @inst.stop! }
103
-
104
- parser.on_body { |inst, data| @body = data }
105
- end
106
- end
107
-
108
- it "should indicate there is no request body to parse" do
109
- subject.parse @inst, "GET / HTTP/1.1\r\nHost: example.com\r\n\r\nBody"
110
-
111
- expect(@body).to be_nil
112
- end
113
- end
114
- end
115
-
116
- describe "on_body" do
117
- let(:expected) { "Body" }
118
-
119
- subject do
120
- described_class.new do |parser|
121
- parser.on_body { |inst, data| @body = data }
122
- end
123
- end
124
-
125
- it "should trigger on the body" do
126
- subject.parse @inst, "POST / HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n"
127
-
128
- expect(@body).to be_nil
129
-
130
- subject.parse @inst, "#{"%x" % expected.length}\r\n#{expected}"
131
-
132
- expect(@body).to eq(expected)
133
- end
134
- end
135
-
136
- describe "on_message_complete" do
137
- subject do
138
- described_class.new do |parser|
139
- parser.on_message_complete { @message_complete = true }
140
- end
141
- end
142
-
143
- it "should trigger at the end of the message" do
144
- subject.parse @inst, "GET / HTTP/1.1\r\n"
145
-
146
- expect(@message_complete).to be_nil
147
-
148
- subject.parse @inst, "Host: example.com\r\n\r\n"
149
-
150
- expect(@message_complete).to eq(true)
151
- end
152
- end
153
- end
154
-
155
-
156
- describe "#http_method" do
157
- let(:expected) { :POST }
158
-
159
- it "should set the http_method field" do
160
- subject.parse @inst, "#{expected} / HTTP/1.1\r\n"
161
-
162
- expect(@inst.http_method).to eq(expected)
163
- end
164
- end
165
-
166
- describe "#http_major" do
167
- let(:expected) { 1 }
168
-
169
- before do
170
- @inst.type = :request
171
- end
172
-
173
- context "when parsing requests" do
174
- it "should set the http_major field" do
175
- subject.parse @inst, "GET / HTTP/#{expected}."
176
-
177
- expect(@inst.http_major).to eq(expected)
178
- end
179
- end
180
-
181
- context "when parsing responses" do
182
- before do
183
- @inst.type = :response
184
- end
185
-
186
- it "should set the http_major field" do
187
- subject.parse @inst, "HTTP/#{expected}."
188
-
189
- expect(@inst.http_major).to eq(expected)
190
- end
191
- end
192
- end
193
-
194
- describe "#http_minor" do
195
- let(:expected) { 2 }
196
-
197
- context "when parsing requests" do
198
- it "should set the http_minor field" do
199
- subject.parse @inst, "GET / HTTP/1.#{expected}\r\n"
200
-
201
- expect(@inst.http_minor).to eq(expected)
202
- end
203
- end
204
-
205
- context "when parsing responses" do
206
- before do
207
- @inst.type = :response
208
- end
209
-
210
- it "should set the http_major field" do
211
- subject.parse @inst, "HTTP/1.#{expected} "
212
-
213
- expect(@inst.http_minor).to eq(expected)
214
- end
215
- end
216
- end
217
-
218
- describe "#http_version" do
219
- let(:expected) { '1.1' }
220
-
221
- before do
222
- subject.parse @inst, "GET / HTTP/#{expected}\r\n"
223
- end
224
-
225
- it "should combine #http_major and #http_minor" do
226
- expect(@inst.http_version).to eq(expected)
227
- end
228
- end
229
-
230
- describe "#http_status" do
231
- context "when parsing requests" do
232
- before do
233
- subject.parse @inst, "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n"
234
- end
235
-
236
- it "should not be set" do
237
- expect(@inst.http_status).to be_zero
238
- end
239
- end
240
-
241
- context "when parsing responses" do
242
- let(:expected) { 200 }
243
-
244
- before do
245
- @inst.type = :response
246
- subject.parse @inst, "HTTP/1.1 #{expected} OK\r\n"
247
- subject.parse @inst, "Location: http://example.com/\r\n\r\n"
248
- end
249
-
250
- it "should set the http_status field" do
251
- expect(@inst.http_status).to eq(expected)
252
- end
253
- end
254
- end
255
-
256
- describe "#upgrade?" do
257
- let(:upgrade) { 'WebSocket' }
258
-
259
- before do
260
- subject.parse @inst, "GET /demo HTTP/1.1\r\n"
261
- subject.parse @inst, "Upgrade: #{upgrade}\r\n"
262
- subject.parse @inst, "Connection: Upgrade\r\n"
263
- subject.parse @inst, "Host: example.com\r\n"
264
- subject.parse @inst, "Origin: http://example.com\r\n"
265
- subject.parse @inst, "WebSocket-Protocol: sample\r\n"
266
- subject.parse @inst, "\r\n"
267
- end
268
-
269
- it "should return true if the Upgrade header was set" do
270
- expect(@inst.upgrade?).to eq(true)
271
- end
272
- end
273
-
274
- describe "pipelined requests" do
275
- subject do
276
- @begun = 0
277
- described_class.new do |parser|
278
- parser.on_message_begin { @begun += 1 }
279
- end
280
- end
281
-
282
- it "should trigger on a new request" do
283
- subject.parse @inst, "GET /demo HTTP/1.1\r\n\r\nGET /demo HTTP/1.1\r\n\r\n"
284
- expect(@begun).to eq(2)
285
- end
286
- end
287
-
288
- describe "method based instead of block based" do
289
- class SomeParserClass
290
- attr_reader :url
291
-
292
- def on_url(inst, data)
293
- @url = data
294
- end
295
- end
296
-
297
- let(:expected) { '/foo?q=1' }
298
-
299
- it "should simplify the process" do
300
- callbacks = SomeParserClass.new
301
- parser = described_class.new(callbacks)
302
-
303
- parser.parse @inst, "GET "
304
-
305
- expect(callbacks.url).to be_nil
306
-
307
- parser.parse @inst, "#{expected} HTTP/1.1"
308
-
309
- expect(callbacks.url).to eq(expected)
310
- end
311
- end
312
- end
313
-
1
+ require 'http-parser'
2
+
3
+ describe HttpParser::Parser, "#initialize" do
4
+ before :each do
5
+ @inst = HttpParser::Parser.new_instance
6
+ end
7
+
8
+ describe "callbacks" do
9
+ describe "on_message_begin" do
10
+ subject do
11
+ described_class.new do |parser|
12
+ parser.on_message_begin { @begun = true }
13
+ end
14
+ end
15
+
16
+ it "should trigger on a new request" do
17
+ subject.parse @inst, "GET / HTTP/1.1"
18
+ expect(@begun).to eq(true)
19
+ end
20
+ end
21
+
22
+ describe "on_url" do
23
+ let(:expected) { '/foo?q=1' }
24
+
25
+ subject do
26
+ described_class.new do |parser|
27
+ parser.on_url { |inst, data| @url = data }
28
+ end
29
+ end
30
+
31
+ it "should pass the recognized url" do
32
+ subject.parse @inst, "GET "
33
+
34
+ expect(@url).to be_nil
35
+
36
+ subject.parse @inst, "#{expected} HTTP/1.1"
37
+
38
+ expect(@url).to eq(expected)
39
+ end
40
+ end
41
+
42
+ describe "on_header_field" do
43
+ let(:expected) { 'Host' }
44
+
45
+ subject do
46
+ described_class.new do |parser|
47
+ parser.on_header_field { |inst, data| @header_field = data }
48
+ end
49
+ end
50
+
51
+ it "should pass the recognized header-name" do
52
+ subject.parse @inst, "GET /foo HTTP/1.1\r\n"
53
+
54
+ expect(@header_field).to be_nil
55
+
56
+ subject.parse @inst, "#{expected}: example.com\r\n"
57
+
58
+ expect(@header_field).to eq(expected)
59
+ end
60
+ end
61
+
62
+ describe "on_header_value" do
63
+ let(:expected) { 'example.com' }
64
+
65
+ subject do
66
+ described_class.new do |parser|
67
+ parser.on_header_value { |inst, data| @header_value = data }
68
+ end
69
+ end
70
+
71
+ it "should pass the recognized header-value" do
72
+ subject.parse @inst, "GET /foo HTTP/1.1\r\n"
73
+
74
+ expect(@header_value).to be_nil
75
+
76
+ subject.parse @inst, "Host: #{expected}\r\n"
77
+
78
+ expect(@header_value).to eq(expected)
79
+ end
80
+ end
81
+
82
+ describe "on_headers_complete" do
83
+ subject do
84
+ described_class.new do |parser|
85
+ parser.on_headers_complete { @header_complete = true }
86
+ end
87
+ end
88
+
89
+ it "should trigger on the last header" do
90
+ subject.parse @inst, "GET / HTTP/1.1\r\nHost: example.com\r\n"
91
+
92
+ expect(@header_complete).to be_nil
93
+
94
+ subject.parse @inst, "\r\n"
95
+
96
+ expect(@header_complete).to eq(true)
97
+ end
98
+
99
+ context "when #stop! is called" do
100
+ subject do
101
+ described_class.new do |parser|
102
+ parser.on_headers_complete { @inst.stop! }
103
+
104
+ parser.on_body { |inst, data| @body = data }
105
+ end
106
+ end
107
+
108
+ it "should indicate there is no request body to parse" do
109
+ subject.parse @inst, "GET / HTTP/1.1\r\nHost: example.com\r\n\r\nBody"
110
+
111
+ expect(@body).to be_nil
112
+ end
113
+ end
114
+ end
115
+
116
+ describe "on_body" do
117
+ let(:expected) { "Body" }
118
+
119
+ subject do
120
+ described_class.new do |parser|
121
+ parser.on_body { |inst, data| @body = data }
122
+ end
123
+ end
124
+
125
+ it "should trigger on the body" do
126
+ subject.parse @inst, "POST / HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n"
127
+
128
+ expect(@body).to be_nil
129
+
130
+ subject.parse @inst, "#{"%x" % expected.length}\r\n#{expected}"
131
+
132
+ expect(@body).to eq(expected)
133
+ end
134
+ end
135
+
136
+ describe "on_message_complete" do
137
+ subject do
138
+ described_class.new do |parser|
139
+ parser.on_message_complete { @message_complete = true }
140
+ end
141
+ end
142
+
143
+ it "should trigger at the end of the message" do
144
+ subject.parse @inst, "GET / HTTP/1.1\r\n"
145
+
146
+ expect(@message_complete).to be_nil
147
+
148
+ subject.parse @inst, "Host: example.com\r\n\r\n"
149
+
150
+ expect(@message_complete).to eq(true)
151
+ end
152
+ end
153
+ end
154
+
155
+
156
+ describe "#http_method" do
157
+ let(:expected) { :POST }
158
+
159
+ it "should set the http_method field" do
160
+ subject.parse @inst, "#{expected} / HTTP/1.1\r\n"
161
+
162
+ expect(@inst.http_method).to eq(expected)
163
+ end
164
+ end
165
+
166
+ describe "#http_major" do
167
+ let(:expected) { 1 }
168
+
169
+ before do
170
+ @inst.type = :request
171
+ end
172
+
173
+ context "when parsing requests" do
174
+ it "should set the http_major field" do
175
+ subject.parse @inst, "GET / HTTP/#{expected}."
176
+
177
+ expect(@inst.http_major).to eq(expected)
178
+ end
179
+ end
180
+
181
+ context "when parsing responses" do
182
+ before do
183
+ @inst.type = :response
184
+ end
185
+
186
+ it "should set the http_major field" do
187
+ subject.parse @inst, "HTTP/#{expected}."
188
+
189
+ expect(@inst.http_major).to eq(expected)
190
+ end
191
+ end
192
+ end
193
+
194
+ describe "#http_minor" do
195
+ let(:expected) { 2 }
196
+
197
+ context "when parsing requests" do
198
+ it "should set the http_minor field" do
199
+ subject.parse @inst, "GET / HTTP/1.#{expected}\r\n"
200
+
201
+ expect(@inst.http_minor).to eq(expected)
202
+ end
203
+ end
204
+
205
+ context "when parsing responses" do
206
+ before do
207
+ @inst.type = :response
208
+ end
209
+
210
+ it "should set the http_major field" do
211
+ subject.parse @inst, "HTTP/1.#{expected} "
212
+
213
+ expect(@inst.http_minor).to eq(expected)
214
+ end
215
+ end
216
+ end
217
+
218
+ describe "#http_version" do
219
+ let(:expected) { '1.1' }
220
+
221
+ before do
222
+ subject.parse @inst, "GET / HTTP/#{expected}\r\n"
223
+ end
224
+
225
+ it "should combine #http_major and #http_minor" do
226
+ expect(@inst.http_version).to eq(expected)
227
+ end
228
+ end
229
+
230
+ describe "#http_status" do
231
+ context "when parsing requests" do
232
+ before do
233
+ subject.parse @inst, "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n"
234
+ end
235
+
236
+ it "should not be set" do
237
+ expect(@inst.http_status).to be_zero
238
+ end
239
+ end
240
+
241
+ context "when parsing responses" do
242
+ let(:expected) { 200 }
243
+
244
+ before do
245
+ @inst.type = :response
246
+ subject.parse @inst, "HTTP/1.1 #{expected} OK\r\n"
247
+ subject.parse @inst, "Location: http://example.com/\r\n\r\n"
248
+ end
249
+
250
+ it "should set the http_status field" do
251
+ expect(@inst.http_status).to eq(expected)
252
+ end
253
+ end
254
+ end
255
+
256
+ describe "#upgrade?" do
257
+ let(:upgrade) { 'WebSocket' }
258
+
259
+ before do
260
+ subject.parse @inst, "GET /demo HTTP/1.1\r\n"
261
+ subject.parse @inst, "Upgrade: #{upgrade}\r\n"
262
+ subject.parse @inst, "Connection: Upgrade\r\n"
263
+ subject.parse @inst, "Host: example.com\r\n"
264
+ subject.parse @inst, "Origin: http://example.com\r\n"
265
+ subject.parse @inst, "WebSocket-Protocol: sample\r\n"
266
+ subject.parse @inst, "\r\n"
267
+ end
268
+
269
+ it "should return true if the Upgrade header was set" do
270
+ expect(@inst.upgrade?).to eq(true)
271
+ end
272
+ end
273
+
274
+ describe "pipelined requests" do
275
+ subject do
276
+ @begun = 0
277
+ described_class.new do |parser|
278
+ parser.on_message_begin { @begun += 1 }
279
+ end
280
+ end
281
+
282
+ it "should trigger on a new request" do
283
+ subject.parse @inst, "GET /demo HTTP/1.1\r\n\r\nGET /demo HTTP/1.1\r\n\r\n"
284
+ expect(@begun).to eq(2)
285
+ end
286
+ end
287
+
288
+ describe "method based instead of block based" do
289
+ class SomeParserClass
290
+ attr_reader :url
291
+
292
+ def on_url(inst, data)
293
+ @url = data
294
+ end
295
+ end
296
+
297
+ let(:expected) { '/foo?q=1' }
298
+
299
+ it "should simplify the process" do
300
+ callbacks = SomeParserClass.new
301
+ parser = described_class.new(callbacks)
302
+
303
+ parser.parse @inst, "GET "
304
+
305
+ expect(callbacks.url).to be_nil
306
+
307
+ parser.parse @inst, "#{expected} HTTP/1.1"
308
+
309
+ expect(callbacks.url).to eq(expected)
310
+ end
311
+ end
312
+ end
313
+