segregate 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
+ [![Code Climate](https://codeclimate.com/github/benSlaughter/segregate.png)](https://codeclimate.com/github/benSlaughter/segregate)
5
+ [![Build Status](https://travis-ci.org/benSlaughter/segregate.png?branch=master)](https://travis-ci.org/benSlaughter/segregate)
6
+ [![Dependency Status](https://gemnasium.com/benSlaughter/segregate.png)](https://gemnasium.com/benSlaughter/segregate)
7
+ [![Coverage Status](https://coveralls.io/repos/benSlaughter/segregate/badge.png?branch=master)](https://coveralls.io/r/benSlaughter/segregate?branch=master)
8
+ [![Gem Version](https://badge.fury.io/rb/segregate.png)](http://badge.fury.io/rb/segregate)
9
+
10
+ An http parser that also includes URI parsing and retaining and rebuilding the original data
@@ -0,0 +1,13 @@
1
+ class Segregate
2
+ HTTP_METHODS = [
3
+ "OPTIONS",
4
+ "GET",
5
+ "HEAD",
6
+ "POST",
7
+ "PUT",
8
+ "DELETE",
9
+ "TRACE",
10
+ "CONNECT",
11
+ "PATCH"
12
+ ]
13
+ end
@@ -0,0 +1,5 @@
1
+ class Segregate
2
+ REQUEST_LINE = /^(#{HTTP_METHODS.join("|")})\s(\*|\S+)\sHTTP\/(\d).(\d)$/
3
+ STATUS_LINE = /^HTTP\/(\d).(\d)\s(\d{3})\s([\w\s\-]+)$/
4
+ UNKNOWN_REQUEST_LINE = /^(\w+)\s(\*|\S+)\sHTTP\/(\d).(\d)$/
5
+ end
@@ -0,0 +1,4 @@
1
+ class Segregate
2
+ VERSION = "0.1.0".freeze
3
+ DATE = "2014-02-03".freeze
4
+ end
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
@@ -0,0 +1,13 @@
1
+ require 'coveralls'
2
+
3
+ Coveralls.wear!
4
+ require 'segregate'
5
+
6
+ RSpec.configure do |config|
7
+ config.color_enabled = true
8
+ config.formatter = :documentation
9
+ end
10
+
11
+ def fixture_path
12
+ File.expand_path("../fixtures/", __FILE__)
13
+ end
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: