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 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: