segregate 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 +7 -0
- data/LICENSE +20 -0
- data/README.md +10 -0
- data/lib/segregate/http_methods.rb +13 -0
- data/lib/segregate/http_regular_expressions.rb +5 -0
- data/lib/segregate/version.rb +4 -0
- data/lib/segregate.rb +162 -0
- data/spec/segregate_spec.rb +399 -0
- data/spec/spec_helper.rb +13 -0
- metadata +125 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8ebb52ffc2a9364921143e72be4e33c036fe241b
|
4
|
+
data.tar.gz: 4dd0ee7bd05e7718fb57918f5ae416783a2266d5
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 92bf21b2a568e476884189262dd195ab31487d4e3451104f492b4d0e8a8b62dc9897e85a718c812086c85edb5cf2d9574a4ca05b973407ad45c5665395d6b6e6
|
7
|
+
data.tar.gz: 65eb168efe658013e9dfd428814792d3a4369c94c14b3ea52ae03f965a4492ec354381f505b61880fc6343f3411a7dc95c13e91cc85e19e7dbee04f489065f04
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2014 Ben Slaughter
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
7
|
+
the Software without restriction, including without limitation the rights to
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
9
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
10
|
+
subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
19
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
20
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
Segregate
|
2
|
+
=========
|
3
|
+
|
4
|
+
[](https://codeclimate.com/github/benSlaughter/segregate)
|
5
|
+
[](https://travis-ci.org/benSlaughter/segregate)
|
6
|
+
[](https://gemnasium.com/benSlaughter/segregate)
|
7
|
+
[](https://coveralls.io/r/benSlaughter/segregate?branch=master)
|
8
|
+
[](http://badge.fury.io/rb/segregate)
|
9
|
+
|
10
|
+
An http parser that also includes URI parsing and retaining and rebuilding the original data
|
data/lib/segregate.rb
ADDED
@@ -0,0 +1,162 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'hashie'
|
3
|
+
require 'segregate/http_methods'
|
4
|
+
require 'segregate/http_regular_expressions'
|
5
|
+
|
6
|
+
class Segregate
|
7
|
+
attr_reader :uri, :request_method, :status_code, :status_phrase, :http_version, :headers, :body
|
8
|
+
|
9
|
+
def method_missing meth, *args, &block
|
10
|
+
if @uri.respond_to? meth
|
11
|
+
@uri.send meth, *args, &block
|
12
|
+
else
|
13
|
+
super
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def respond_to?(meth, include_private = false)
|
18
|
+
@uri.respond_to?(meth, include_private) || super
|
19
|
+
end
|
20
|
+
|
21
|
+
def initialize
|
22
|
+
@uri = nil
|
23
|
+
@request_method = nil
|
24
|
+
@status_code = nil
|
25
|
+
@status_phrase = nil
|
26
|
+
@http_version = [nil, nil]
|
27
|
+
|
28
|
+
@headers = Hashie::Mash.new
|
29
|
+
@body = ""
|
30
|
+
|
31
|
+
@request = false
|
32
|
+
@response = false
|
33
|
+
|
34
|
+
@first_line_complete = false
|
35
|
+
@headers_complete = false
|
36
|
+
@body_complete = false
|
37
|
+
@header_order = []
|
38
|
+
end
|
39
|
+
|
40
|
+
def request?
|
41
|
+
@request
|
42
|
+
end
|
43
|
+
|
44
|
+
def response?
|
45
|
+
@response
|
46
|
+
end
|
47
|
+
|
48
|
+
def headers_complete?
|
49
|
+
@headers_complete
|
50
|
+
end
|
51
|
+
|
52
|
+
def body_complete?
|
53
|
+
@body_complete
|
54
|
+
end
|
55
|
+
|
56
|
+
def request_line
|
57
|
+
request? ? "%s %s HTTP/%d.%d" % [request_method, request_url.to_s, *http_version] : nil
|
58
|
+
end
|
59
|
+
|
60
|
+
def status_line
|
61
|
+
response? ? "HTTP/%d.%d %d %s" % [*http_version, status_code, status_phrase] : nil
|
62
|
+
end
|
63
|
+
|
64
|
+
def request_url
|
65
|
+
uri ? uri.to_s : nil
|
66
|
+
end
|
67
|
+
|
68
|
+
def major_http_version
|
69
|
+
http_version[0]
|
70
|
+
end
|
71
|
+
|
72
|
+
def minor_http_version
|
73
|
+
http_version[1]
|
74
|
+
end
|
75
|
+
|
76
|
+
def parse data
|
77
|
+
raise "ERROR: parsing completed" if @body_complete
|
78
|
+
|
79
|
+
data = StringIO.new data
|
80
|
+
|
81
|
+
read_first_line data unless @first_line_complete
|
82
|
+
read_headers data unless @headers_complete
|
83
|
+
read_body data unless data.eof?
|
84
|
+
end
|
85
|
+
|
86
|
+
private
|
87
|
+
|
88
|
+
def read data, size = nil
|
89
|
+
if size
|
90
|
+
data.read(size + 2).chomp("\r\n")
|
91
|
+
else
|
92
|
+
data.readline.chomp("\r\n")
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def read_first_line data
|
97
|
+
line = read data
|
98
|
+
|
99
|
+
if line =~ REQUEST_LINE
|
100
|
+
parse_request_line line
|
101
|
+
elsif line =~ STATUS_LINE
|
102
|
+
parse_status_line line
|
103
|
+
elsif line =~ UNKNOWN_REQUEST_LINE
|
104
|
+
raise "ERROR: Unknown http method: %s" % line[/^\S+/]
|
105
|
+
else
|
106
|
+
raise "ERROR: Unknown first line: %s" % line
|
107
|
+
end
|
108
|
+
|
109
|
+
@first_line_complete = true
|
110
|
+
end
|
111
|
+
|
112
|
+
def parse_request_line line
|
113
|
+
@request = true
|
114
|
+
@request_method, url, @http_version[0], @http_version[1] = line.scan(REQUEST_LINE).flatten
|
115
|
+
@http_version.map! {|v| v.to_i}
|
116
|
+
@uri = URI.parse url
|
117
|
+
end
|
118
|
+
|
119
|
+
def parse_status_line line
|
120
|
+
@response = true
|
121
|
+
@http_version[0], @http_version[1], code, @status_phrase = line.scan(STATUS_LINE).flatten
|
122
|
+
@http_version.map! {|v| v.to_i}
|
123
|
+
@status_code = code.to_i
|
124
|
+
end
|
125
|
+
|
126
|
+
def read_headers data
|
127
|
+
while !data.eof? && !@headers_complete
|
128
|
+
line = read data
|
129
|
+
if line.empty?
|
130
|
+
@headers_complete = true
|
131
|
+
else
|
132
|
+
key, value = line.split(":")
|
133
|
+
@headers[key.downcase] = value.strip
|
134
|
+
@header_order << key.downcase
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def read_body data
|
140
|
+
if headers.key? 'content-length'
|
141
|
+
parse_body data
|
142
|
+
elsif headers['content-encoding'] == 'chunked'
|
143
|
+
parse_chunked_data data
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
def parse_body data
|
148
|
+
@body = read data, headers['content-length'].to_i
|
149
|
+
@body_complete = true
|
150
|
+
end
|
151
|
+
|
152
|
+
def parse_chunked_data data
|
153
|
+
while !data.eof? && !@body_complete
|
154
|
+
chunk_size = read(data).to_i
|
155
|
+
if chunk_size == 0
|
156
|
+
@body_complete = true
|
157
|
+
else
|
158
|
+
@body << read(data, chunk_size)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
@@ -0,0 +1,399 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Segregate do
|
4
|
+
it 'should be an instance of Class' do
|
5
|
+
expect(Segregate).to be_an_instance_of Class
|
6
|
+
end
|
7
|
+
|
8
|
+
describe '::new' do
|
9
|
+
it 'returns an instance of Segregate' do
|
10
|
+
expect(Segregate.new).to be_an_instance_of Segregate
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'has the inital values' do
|
14
|
+
@parser = Segregate.new
|
15
|
+
expect(@parser.request?).to be_false
|
16
|
+
expect(@parser.response?).to be_false
|
17
|
+
expect(@parser.uri).to be_nil
|
18
|
+
expect(@parser.request_line).to be_nil
|
19
|
+
expect(@parser.request_method).to be_nil
|
20
|
+
expect(@parser.request_url).to be_nil
|
21
|
+
expect(@parser.status_line).to be_nil
|
22
|
+
expect(@parser.status_code).to be_nil
|
23
|
+
expect(@parser.status_phrase).to be_nil
|
24
|
+
expect(@parser.http_version).to eq [nil, nil]
|
25
|
+
expect(@parser.major_http_version).to be_nil
|
26
|
+
expect(@parser.minor_http_version).to be_nil
|
27
|
+
expect(@parser.headers).to be_empty
|
28
|
+
expect(@parser.body).to be_empty
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'a new parser has been created' do
|
33
|
+
before(:each) do
|
34
|
+
@parser = Segregate.new
|
35
|
+
end
|
36
|
+
|
37
|
+
describe '#parse' do
|
38
|
+
it 'accepts one argument' do
|
39
|
+
expect(@parser).to respond_to(:parse).with(1).argument
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'errors if an incorrect first line is received' do
|
43
|
+
expect{ @parser.parse "fail\r\n" }.to raise_error RuntimeError, 'ERROR: Unknown first line: fail'
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'errors if an incorrect http method is received' do
|
47
|
+
expect{ @parser.parse "FAIL /endpoint HTTP/1.1\r\n" }.to raise_error RuntimeError, 'ERROR: Unknown http method: FAIL'
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'a request line has been parsed' do
|
52
|
+
before(:each) do
|
53
|
+
@parser.parse "GET /endpoint HTTP/1.1\r\n"
|
54
|
+
end
|
55
|
+
|
56
|
+
describe '#request_line' do
|
57
|
+
it 'returns a string' do
|
58
|
+
expect(@parser.request_line).to be_an_instance_of String
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'returns a request line' do
|
62
|
+
expect(@parser.request_line).to match Segregate::REQUEST_LINE
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe '#status_line' do
|
67
|
+
it 'returns nil' do
|
68
|
+
expect(@parser.status_line).to be_nil
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe '#request?' do
|
73
|
+
it 'returns true' do
|
74
|
+
expect(@parser.request?).to be_an_instance_of TrueClass
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe '#response?' do
|
79
|
+
it 'returns false' do
|
80
|
+
expect(@parser.response?).to be_an_instance_of FalseClass
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe '#http_version' do
|
85
|
+
it 'returns an array' do
|
86
|
+
expect(@parser.http_version).to be_an_instance_of Array
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'returns [1, 1]' do
|
90
|
+
expect(@parser.http_version).to eql [1,1]
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe '#major_http_version' do
|
95
|
+
it 'returns an integer' do
|
96
|
+
expect(@parser.major_http_version).to be_an_instance_of Fixnum
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'returns 1' do
|
100
|
+
expect(@parser.major_http_version).to eql 1
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
describe '#minor_http_version' do
|
105
|
+
it 'returns an integer' do
|
106
|
+
expect(@parser.minor_http_version).to be_an_instance_of Fixnum
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'returns 1' do
|
110
|
+
expect(@parser.minor_http_version).to eql 1
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
describe '#request_method' do
|
115
|
+
it 'returns an string' do
|
116
|
+
expect(@parser.request_method).to be_an_instance_of String
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'returns GET' do
|
120
|
+
expect(@parser.request_method).to eq 'GET'
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
describe '#request_url' do
|
125
|
+
it 'returns an string' do
|
126
|
+
expect(@parser.request_url).to be_an_instance_of String
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'returns /endpoint' do
|
130
|
+
expect(@parser.request_url).to eq '/endpoint'
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
describe '#status_code' do
|
135
|
+
it 'returns nil' do
|
136
|
+
expect(@parser.status_code).to be_nil
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
describe '#status_phrase' do
|
141
|
+
it 'returns nil' do
|
142
|
+
expect(@parser.status_phrase).to be_nil
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
describe '#uri' do
|
147
|
+
it 'returns a URI' do
|
148
|
+
expect(@parser.uri).to be_an_instance_of URI::Generic
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
describe '#method_missing' do
|
153
|
+
it 'returns the uri methods' do
|
154
|
+
expect(@parser.path).to eq '/endpoint'
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'raises an error if uri does not respond to the method' do
|
158
|
+
expect{ @parser.not_present }.to raise_error NoMethodError, /undefined method `not_present'/
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
describe '#respond_to?' do
|
163
|
+
it 'responds to the uri path' do
|
164
|
+
expect(@parser.respond_to? :uri).to be_true
|
165
|
+
expect(@parser.respond_to? :path).to be_true
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
context 'a response line has been parsed' do
|
171
|
+
before(:each) do
|
172
|
+
@parser.parse "HTTP/1.1 200 OK\r\n"
|
173
|
+
end
|
174
|
+
|
175
|
+
describe '#request_line' do
|
176
|
+
it 'returns nil' do
|
177
|
+
expect(@parser.request_line).to be_nil
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
describe '#status_line' do
|
182
|
+
it 'returns a string' do
|
183
|
+
expect(@parser.status_line).to be_an_instance_of String
|
184
|
+
end
|
185
|
+
|
186
|
+
it 'returns a status line' do
|
187
|
+
expect(@parser.status_line).to match Segregate::STATUS_LINE
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
describe '#request?' do
|
192
|
+
it 'returns false' do
|
193
|
+
expect(@parser.request?).to be_an_instance_of FalseClass
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
describe '#response?' do
|
198
|
+
it 'returns true' do
|
199
|
+
expect(@parser.response?).to be_an_instance_of TrueClass
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
describe '#http_version' do
|
204
|
+
it 'returns an array' do
|
205
|
+
expect(@parser.http_version).to be_an_instance_of Array
|
206
|
+
end
|
207
|
+
|
208
|
+
it 'returns [1, 1]' do
|
209
|
+
expect(@parser.http_version).to eql [1,1]
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
describe '#major_http_version' do
|
214
|
+
it 'returns an integer' do
|
215
|
+
expect(@parser.major_http_version).to be_an_instance_of Fixnum
|
216
|
+
end
|
217
|
+
|
218
|
+
it 'returns 1' do
|
219
|
+
expect(@parser.major_http_version).to eql 1
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
describe '#minor_http_version' do
|
224
|
+
it 'returns an integer' do
|
225
|
+
expect(@parser.minor_http_version).to be_an_instance_of Fixnum
|
226
|
+
end
|
227
|
+
|
228
|
+
it 'returns 1' do
|
229
|
+
expect(@parser.minor_http_version).to eql 1
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
describe '#request_method' do
|
234
|
+
it 'returns nil' do
|
235
|
+
expect(@parser.request_method).to be_nil
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
describe '#request_url' do
|
240
|
+
it 'returns nil' do
|
241
|
+
expect(@parser.request_url).to be_nil
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
describe '#status_code' do
|
246
|
+
it 'returns an integer' do
|
247
|
+
expect(@parser.status_code).to be_an_instance_of Fixnum
|
248
|
+
end
|
249
|
+
|
250
|
+
it 'returns 200' do
|
251
|
+
expect(@parser.status_code).to eql 200
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
describe '#status_phrase' do
|
256
|
+
it 'returns an string' do
|
257
|
+
expect(@parser.status_phrase).to be_an_instance_of String
|
258
|
+
end
|
259
|
+
|
260
|
+
it 'returns OK' do
|
261
|
+
expect(@parser.status_phrase).to eq 'OK'
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
describe '#uri' do
|
266
|
+
it 'returns nil' do
|
267
|
+
expect(@parser.uri).to be_nil
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
context 'a header has been parsed' do
|
273
|
+
before(:each) do
|
274
|
+
@parser.parse "GET /endpoint HTTP/1.1\r\n"
|
275
|
+
@parser.parse "Accept: application/json\r\n"
|
276
|
+
end
|
277
|
+
|
278
|
+
describe '#headers' do
|
279
|
+
it 'returns an instans of a hashie mash' do
|
280
|
+
expect(@parser.headers).to be_an_instance_of Hashie::Mash
|
281
|
+
end
|
282
|
+
|
283
|
+
it 'contains the parsed header' do
|
284
|
+
expect(@parser.headers).to respond_to(:accept)
|
285
|
+
expect(@parser.headers.accept).to eq 'application/json'
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
describe '#headers_complete?' do
|
290
|
+
it 'returns false' do
|
291
|
+
expect(@parser.headers_complete?).to be_an_instance_of FalseClass
|
292
|
+
end
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
context 'all headers have been parsed' do
|
297
|
+
before(:each) do
|
298
|
+
@parser.parse "GET /endpoint HTTP/1.1\r\n"
|
299
|
+
@parser.parse "Accept: application/json\r\n"
|
300
|
+
@parser.parse "Host: www.google.com\r\n"
|
301
|
+
@parser.parse "\r\n"
|
302
|
+
end
|
303
|
+
|
304
|
+
describe '#headers' do
|
305
|
+
it 'returns an instans of a hashie mash' do
|
306
|
+
expect(@parser.headers).to be_an_instance_of Hashie::Mash
|
307
|
+
end
|
308
|
+
|
309
|
+
it 'contains all the parsed headers' do
|
310
|
+
expect(@parser.headers).to respond_to(:accept)
|
311
|
+
expect(@parser.headers).to respond_to(:host)
|
312
|
+
expect(@parser.headers.accept).to eq 'application/json'
|
313
|
+
expect(@parser.headers.host).to eq 'www.google.com'
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
describe '#headers_complete?' do
|
318
|
+
it 'returns true' do
|
319
|
+
expect(@parser.headers_complete?).to be_an_instance_of TrueClass
|
320
|
+
end
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
324
|
+
context 'a body has been parsed' do
|
325
|
+
before(:each) do
|
326
|
+
@parser.parse "GET /endpoint HTTP/1.1\r\n"
|
327
|
+
@parser.parse "Host: www.google.com\r\n"
|
328
|
+
@parser.parse "Content-Length: 20\r\n"
|
329
|
+
@parser.parse "\r\n"
|
330
|
+
@parser.parse "This is the content!\r\n\r\n"
|
331
|
+
end
|
332
|
+
|
333
|
+
describe '#body' do
|
334
|
+
it 'returns a string' do
|
335
|
+
expect(@parser.body).to be_an_instance_of String
|
336
|
+
end
|
337
|
+
|
338
|
+
it 'contains the body text' do
|
339
|
+
expect(@parser.body).to eq "This is the content!"
|
340
|
+
end
|
341
|
+
end
|
342
|
+
|
343
|
+
describe '#body_complete?' do
|
344
|
+
it 'returns true' do
|
345
|
+
expect(@parser.body_complete?).to be_an_instance_of TrueClass
|
346
|
+
end
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
350
|
+
context 'a partial chunked body has been parsed' do
|
351
|
+
before(:each) do
|
352
|
+
@parser.parse "GET /endpoint HTTP/1.1\r\n"
|
353
|
+
@parser.parse "Host: www.google.com\r\n"
|
354
|
+
@parser.parse "Content-Encoding: chunked\r\n"
|
355
|
+
@parser.parse "\r\n"
|
356
|
+
@parser.parse "26\r\nThis is the first content!\r\n"
|
357
|
+
end
|
358
|
+
|
359
|
+
describe '#body' do
|
360
|
+
it 'returns a string' do
|
361
|
+
expect(@parser.body).to be_an_instance_of String
|
362
|
+
end
|
363
|
+
|
364
|
+
it 'contains the body text' do
|
365
|
+
expect(@parser.body).to eq "This is the first content!"
|
366
|
+
end
|
367
|
+
end
|
368
|
+
|
369
|
+
describe '#body_complete?' do
|
370
|
+
it 'returns false' do
|
371
|
+
expect(@parser.body_complete?).to be_an_instance_of FalseClass
|
372
|
+
end
|
373
|
+
end
|
374
|
+
|
375
|
+
context 'the body parsing is completed' do
|
376
|
+
before(:each) do
|
377
|
+
@parser.parse "27\r\nThis is the second content!\r\n"
|
378
|
+
@parser.parse "0\r\n\r\n"
|
379
|
+
end
|
380
|
+
|
381
|
+
describe '#body' do
|
382
|
+
it 'returns a string' do
|
383
|
+
expect(@parser.body).to be_an_instance_of String
|
384
|
+
end
|
385
|
+
|
386
|
+
it 'contains the body text' do
|
387
|
+
expect(@parser.body).to eq "This is the first content!This is the second content!"
|
388
|
+
end
|
389
|
+
end
|
390
|
+
|
391
|
+
describe '#body_complete?' do
|
392
|
+
it 'returns true' do
|
393
|
+
expect(@parser.body_complete?).to be_an_instance_of TrueClass
|
394
|
+
end
|
395
|
+
end
|
396
|
+
end
|
397
|
+
end
|
398
|
+
end
|
399
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,125 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: segregate
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ben Slaughter
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-02-03 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: yard
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: coveralls
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: hashie
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description: An http parser that also includes URI parsing and retaining and rebuilding
|
84
|
+
the original data
|
85
|
+
email: b.p.slaughter@gmail.com
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- README.md
|
91
|
+
- LICENSE
|
92
|
+
- lib/segregate/http_methods.rb
|
93
|
+
- lib/segregate/http_regular_expressions.rb
|
94
|
+
- lib/segregate/version.rb
|
95
|
+
- lib/segregate.rb
|
96
|
+
- spec/segregate_spec.rb
|
97
|
+
- spec/spec_helper.rb
|
98
|
+
homepage: http://benslaughter.github.io/segregate/
|
99
|
+
licenses:
|
100
|
+
- MIT
|
101
|
+
metadata: {}
|
102
|
+
post_install_message:
|
103
|
+
rdoc_options: []
|
104
|
+
require_paths:
|
105
|
+
- lib
|
106
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - '>='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
112
|
+
requirements:
|
113
|
+
- - '>='
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
version: '0'
|
116
|
+
requirements: []
|
117
|
+
rubyforge_project:
|
118
|
+
rubygems_version: 2.0.3
|
119
|
+
signing_key:
|
120
|
+
specification_version: 4
|
121
|
+
summary: Segregate http parser
|
122
|
+
test_files:
|
123
|
+
- spec/segregate_spec.rb
|
124
|
+
- spec/spec_helper.rb
|
125
|
+
has_rdoc:
|