http 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of http might be problematic. Click here for more details.
- data/.travis.yml +8 -2
- data/CHANGES.md +6 -0
- data/README.md +5 -10
- data/http.gemspec +5 -3
- data/lib/http.rb +19 -1
- data/lib/http/chainable.rb +36 -12
- data/lib/http/client.rb +37 -74
- data/lib/http/compat/curb.rb +3 -2
- data/lib/http/options.rb +109 -0
- data/lib/http/request.rb +42 -0
- data/lib/http/response.rb +73 -7
- data/lib/http/uri_backport.rb +131 -0
- data/lib/http/version.rb +1 -1
- data/spec/http/compat/curb_spec.rb +1 -1
- data/spec/http/options/callbacks_spec.rb +62 -0
- data/spec/http/options/form_spec.rb +18 -0
- data/spec/http/options/headers_spec.rb +29 -0
- data/spec/http/options/merge_spec.rb +37 -0
- data/spec/http/options/new_spec.rb +39 -0
- data/spec/http/options/response_spec.rb +24 -0
- data/spec/http/options_spec.rb +26 -0
- data/spec/http/response_spec.rb +69 -0
- data/spec/http_spec.rb +24 -2
- data/spec/spec_helper.rb +1 -2
- data/spec/support/{mock_server.rb → example_server.rb} +11 -14
- metadata +80 -85
- data/lib/http/parameters.rb +0 -17
- data/parser/common.rl +0 -40
- data/parser/http.rl +0 -220
- data/parser/multipart.rl +0 -41
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Http::Options, "new" do
|
4
|
+
|
5
|
+
it 'supports a Options instance' do
|
6
|
+
opts = Http::Options.new
|
7
|
+
Http::Options.new(opts).should eq(opts)
|
8
|
+
end
|
9
|
+
|
10
|
+
context 'with a Hash' do
|
11
|
+
|
12
|
+
it 'coerces :response correctly' do
|
13
|
+
opts = Http::Options.new(:response => :object)
|
14
|
+
opts.response.should eq(:object)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'coerces :headers correctly' do
|
18
|
+
opts = Http::Options.new(:headers => {:accept => "json"})
|
19
|
+
opts.headers.should eq(:accept => "json")
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'coerces :form correctly' do
|
23
|
+
opts = Http::Options.new(:form => {:foo => 42})
|
24
|
+
opts.form.should eq(:foo => 42)
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'coerces :callbacks correctly' do
|
28
|
+
before, after = Proc.new{|r| :before}, Proc.new{|r| :after}
|
29
|
+
callbacks = {:request => [before], :response => [after]}
|
30
|
+
opts = Http::Options.new(:callbacks => callbacks)
|
31
|
+
opts.callbacks.should eq({
|
32
|
+
:request => [before],
|
33
|
+
:response => [after]
|
34
|
+
})
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Http::Options, "response" do
|
4
|
+
|
5
|
+
let(:opts){ Http::Options.new }
|
6
|
+
|
7
|
+
it 'defaults to :auto' do
|
8
|
+
opts.response.should eq(:auto)
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'may be specified with with_response' do
|
12
|
+
opts2 = opts.with_response(:body)
|
13
|
+
opts.response.should eq(:auto)
|
14
|
+
opts2.response.should eq(:body)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'recognizes invalid responses' do
|
18
|
+
lambda{
|
19
|
+
opts.with_response(:not_a_valid_response)
|
20
|
+
}.should raise_error(ArgumentError, /not_a_valid_response/)
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Http::Options do
|
4
|
+
|
5
|
+
let(:options){ Http::Options.new(:response => :body) }
|
6
|
+
|
7
|
+
it 'behaves like a Hash for reading' do
|
8
|
+
options[:response].should eq(:body)
|
9
|
+
options[:nosuchone].should be_nil
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'is able to coerce to a Hash' do
|
13
|
+
options.to_hash.should be_a(Hash)
|
14
|
+
options.to_hash[:response].should eq(:body)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'is stacktrace friendly' do
|
18
|
+
begin
|
19
|
+
options.with_response(:notrecognized)
|
20
|
+
true.should be_false
|
21
|
+
rescue ArgumentError => ex
|
22
|
+
puts ex.backtrace.first.should match(/options_spec/)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Http::Response do
|
4
|
+
|
5
|
+
let(:subject){ Http::Response.new }
|
6
|
+
|
7
|
+
describe "the response headers" do
|
8
|
+
|
9
|
+
it 'are available through Hash-like methods' do
|
10
|
+
subject["Content-Type"] = "text/plain"
|
11
|
+
subject["Content-Type"].should eq("text/plain")
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'are available through a `headers` accessor' do
|
15
|
+
subject["Content-Type"] = "text/plain"
|
16
|
+
subject.headers.should eq("Content-Type" => "text/plain")
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "parse_body" do
|
22
|
+
|
23
|
+
it 'works on a registered mime-type' do
|
24
|
+
subject["Content-Type"] = "application/json"
|
25
|
+
subject.body = ::JSON.dump("hello" => "World")
|
26
|
+
subject.parse_body.should eq("hello" => "World")
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'returns the body on an unregistered mime-type' do
|
30
|
+
subject["Content-Type"] = "text/plain"
|
31
|
+
subject.body = "Hello world"
|
32
|
+
subject.parse_body.should eq("Hello world")
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "to_a" do
|
38
|
+
|
39
|
+
it 'mimics Rack' do
|
40
|
+
subject.tap do |r|
|
41
|
+
r.status = 200
|
42
|
+
r.headers = {"Content-Type" => "text/plain"}
|
43
|
+
r.body = "Hello world"
|
44
|
+
end
|
45
|
+
expected = [
|
46
|
+
200,
|
47
|
+
{"Content-Type" => "text/plain"},
|
48
|
+
"Hello world"
|
49
|
+
]
|
50
|
+
subject.to_a.should eq(expected)
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'uses parse_body if known mime-type' do
|
54
|
+
subject.tap do |r|
|
55
|
+
r.status = 200
|
56
|
+
r.headers = {"Content-Type" => "application/json"}
|
57
|
+
r.body = ::JSON.dump("hello" => "World")
|
58
|
+
end
|
59
|
+
expected = [
|
60
|
+
200,
|
61
|
+
{"Content-Type" => "application/json"},
|
62
|
+
{"hello" => "World"}
|
63
|
+
]
|
64
|
+
subject.to_a.should eq(expected)
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
data/spec/http_spec.rb
CHANGED
@@ -2,8 +2,8 @@ require 'spec_helper'
|
|
2
2
|
require 'json'
|
3
3
|
|
4
4
|
describe Http do
|
5
|
-
let(:test_endpoint) { "http://127.0.0.1:#{
|
6
|
-
|
5
|
+
let(:test_endpoint) { "http://127.0.0.1:#{ExampleService::PORT}/" }
|
6
|
+
|
7
7
|
context "getting resources" do
|
8
8
|
it "should be easy" do
|
9
9
|
response = Http.get test_endpoint
|
@@ -16,6 +16,22 @@ describe Http do
|
|
16
16
|
response['json'].should be_true
|
17
17
|
end
|
18
18
|
end
|
19
|
+
|
20
|
+
context "with callbacks" do
|
21
|
+
it "fires a request callback" do
|
22
|
+
pending 'Http::Request is not yet implemented'
|
23
|
+
|
24
|
+
request = nil
|
25
|
+
Http.on(:request) {|r| request = r}.get test_endpoint
|
26
|
+
request.should be_a Http::Request
|
27
|
+
end
|
28
|
+
|
29
|
+
it "fires a response callback" do
|
30
|
+
response = nil
|
31
|
+
Http.on(:response) {|r| response = r}.get test_endpoint
|
32
|
+
response.should be_a Http::Response
|
33
|
+
end
|
34
|
+
end
|
19
35
|
end
|
20
36
|
|
21
37
|
context "posting to resources" do
|
@@ -32,4 +48,10 @@ describe Http do
|
|
32
48
|
response['content-type'].should match(/html/)
|
33
49
|
end
|
34
50
|
end
|
51
|
+
|
52
|
+
it "should be chainable" do
|
53
|
+
response = Http.accept(:json).on(:response){|r| seen = r}.get(test_endpoint)
|
54
|
+
response['json'].should be_true
|
55
|
+
end
|
56
|
+
|
35
57
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,15 +1,13 @@
|
|
1
1
|
require 'webrick'
|
2
2
|
|
3
|
-
|
3
|
+
class ExampleService < WEBrick::HTTPServlet::AbstractServlet
|
4
|
+
PORT = 65432
|
4
5
|
|
5
|
-
class MockService < WEBrick::HTTPServlet::AbstractServlet
|
6
|
-
class << self; attr_accessor :post_handler; end
|
7
|
-
|
8
6
|
def do_GET(request, response)
|
9
7
|
case request.path
|
10
8
|
when "/"
|
11
9
|
response.status = 200
|
12
|
-
|
10
|
+
|
13
11
|
case request['Accept']
|
14
12
|
when 'application/json'
|
15
13
|
response['Content-Type'] = 'application/json'
|
@@ -22,7 +20,7 @@ class MockService < WEBrick::HTTPServlet::AbstractServlet
|
|
22
20
|
response.status = 404
|
23
21
|
end
|
24
22
|
end
|
25
|
-
|
23
|
+
|
26
24
|
def do_POST(request, response)
|
27
25
|
case request.path
|
28
26
|
when "/"
|
@@ -31,13 +29,13 @@ class MockService < WEBrick::HTTPServlet::AbstractServlet
|
|
31
29
|
response.body = "passed :)"
|
32
30
|
else
|
33
31
|
response.status = 400
|
34
|
-
response.
|
32
|
+
response.body = "invalid! >:E"
|
35
33
|
end
|
36
34
|
else
|
37
35
|
response.status = 404
|
38
36
|
end
|
39
37
|
end
|
40
|
-
|
38
|
+
|
41
39
|
def do_HEAD(request, response)
|
42
40
|
case request.path
|
43
41
|
when "/"
|
@@ -49,11 +47,10 @@ class MockService < WEBrick::HTTPServlet::AbstractServlet
|
|
49
47
|
end
|
50
48
|
end
|
51
49
|
|
52
|
-
|
53
|
-
|
50
|
+
ExampleServer = WEBrick::HTTPServer.new(:Port => ExampleService::PORT, :AccessLog => [])
|
51
|
+
ExampleServer.mount "/", ExampleService
|
54
52
|
|
55
|
-
Thread.new
|
56
|
-
trap("INT")
|
53
|
+
t = Thread.new { ExampleServer.start }
|
54
|
+
trap("INT") { ExampleServer.shutdown; exit }
|
57
55
|
|
58
|
-
|
59
|
-
sleep 0.1
|
56
|
+
Thread.pass while t.status and t.status != "sleep"
|
metadata
CHANGED
@@ -1,78 +1,68 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: http
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 1
|
9
|
-
- 0
|
10
|
-
version: 0.1.0
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- Tony Arcieri
|
14
|
-
- Carl Lerche
|
15
9
|
autorequire:
|
16
10
|
bindir: bin
|
17
11
|
cert_chain: []
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
12
|
+
date: 2012-03-05 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: certified
|
16
|
+
requirement: &70273361267740 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
24
23
|
prerelease: false
|
25
|
-
|
24
|
+
version_requirements: *70273361267740
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rake
|
27
|
+
requirement: &70273361267320 !ruby/object:Gem::Requirement
|
26
28
|
none: false
|
27
|
-
requirements:
|
28
|
-
- -
|
29
|
-
- !ruby/object:Gem::Version
|
30
|
-
|
31
|
-
segments:
|
32
|
-
- 0
|
33
|
-
version: "0"
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
34
33
|
type: :development
|
35
|
-
version_requirements: *id001
|
36
|
-
- !ruby/object:Gem::Dependency
|
37
|
-
name: rspec
|
38
34
|
prerelease: false
|
39
|
-
|
35
|
+
version_requirements: *70273361267320
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rspec
|
38
|
+
requirement: &70273361266900 !ruby/object:Gem::Requirement
|
40
39
|
none: false
|
41
|
-
requirements:
|
42
|
-
- -
|
43
|
-
- !ruby/object:Gem::Version
|
44
|
-
|
45
|
-
segments:
|
46
|
-
- 2
|
47
|
-
- 6
|
48
|
-
- 0
|
49
|
-
version: 2.6.0
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
50
44
|
type: :development
|
51
|
-
version_requirements: *id002
|
52
|
-
- !ruby/object:Gem::Dependency
|
53
|
-
name: json
|
54
45
|
prerelease: false
|
55
|
-
|
46
|
+
version_requirements: *70273361266900
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: json
|
49
|
+
requirement: &70273361266480 !ruby/object:Gem::Requirement
|
56
50
|
none: false
|
57
|
-
requirements:
|
58
|
-
- -
|
59
|
-
- !ruby/object:Gem::Version
|
60
|
-
|
61
|
-
segments:
|
62
|
-
- 0
|
63
|
-
version: "0"
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
64
55
|
type: :development
|
65
|
-
|
66
|
-
|
67
|
-
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70273361266480
|
58
|
+
description: HTTP so awesome it will lure Catherine Zeta Jones into your unicorn petting
|
59
|
+
zoo
|
60
|
+
email:
|
68
61
|
- tony.arcieri@gmail.com
|
69
62
|
executables: []
|
70
|
-
|
71
63
|
extensions: []
|
72
|
-
|
73
64
|
extra_rdoc_files: []
|
74
|
-
|
75
|
-
files:
|
65
|
+
files:
|
76
66
|
- .gitignore
|
77
67
|
- .rspec
|
78
68
|
- .travis.yml
|
@@ -88,52 +78,57 @@ files:
|
|
88
78
|
- lib/http/compat/curb.rb
|
89
79
|
- lib/http/mime_type.rb
|
90
80
|
- lib/http/mime_types/json.rb
|
91
|
-
- lib/http/
|
81
|
+
- lib/http/options.rb
|
82
|
+
- lib/http/request.rb
|
92
83
|
- lib/http/response.rb
|
84
|
+
- lib/http/uri_backport.rb
|
93
85
|
- lib/http/version.rb
|
94
|
-
- parser/common.rl
|
95
|
-
- parser/http.rl
|
96
|
-
- parser/multipart.rl
|
97
86
|
- spec/http/compat/curb_spec.rb
|
87
|
+
- spec/http/options/callbacks_spec.rb
|
88
|
+
- spec/http/options/form_spec.rb
|
89
|
+
- spec/http/options/headers_spec.rb
|
90
|
+
- spec/http/options/merge_spec.rb
|
91
|
+
- spec/http/options/new_spec.rb
|
92
|
+
- spec/http/options/response_spec.rb
|
93
|
+
- spec/http/options_spec.rb
|
94
|
+
- spec/http/response_spec.rb
|
98
95
|
- spec/http_spec.rb
|
99
96
|
- spec/spec_helper.rb
|
100
|
-
- spec/support/
|
101
|
-
has_rdoc: true
|
97
|
+
- spec/support/example_server.rb
|
102
98
|
homepage: https://github.com/tarcieri/http
|
103
99
|
licenses: []
|
104
|
-
|
105
100
|
post_install_message:
|
106
101
|
rdoc_options: []
|
107
|
-
|
108
|
-
require_paths:
|
102
|
+
require_paths:
|
109
103
|
- lib
|
110
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
104
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
111
105
|
none: false
|
112
|
-
requirements:
|
113
|
-
- -
|
114
|
-
- !ruby/object:Gem::Version
|
115
|
-
|
116
|
-
|
117
|
-
- 0
|
118
|
-
version: "0"
|
119
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
120
111
|
none: false
|
121
|
-
requirements:
|
122
|
-
- -
|
123
|
-
- !ruby/object:Gem::Version
|
124
|
-
|
125
|
-
segments:
|
126
|
-
- 0
|
127
|
-
version: "0"
|
112
|
+
requirements:
|
113
|
+
- - ! '>='
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
version: '0'
|
128
116
|
requirements: []
|
129
|
-
|
130
117
|
rubyforge_project:
|
131
|
-
rubygems_version: 1.
|
118
|
+
rubygems_version: 1.8.17
|
132
119
|
signing_key:
|
133
120
|
specification_version: 3
|
134
|
-
summary:
|
135
|
-
test_files:
|
121
|
+
summary: HTTP should be easy
|
122
|
+
test_files:
|
136
123
|
- spec/http/compat/curb_spec.rb
|
124
|
+
- spec/http/options/callbacks_spec.rb
|
125
|
+
- spec/http/options/form_spec.rb
|
126
|
+
- spec/http/options/headers_spec.rb
|
127
|
+
- spec/http/options/merge_spec.rb
|
128
|
+
- spec/http/options/new_spec.rb
|
129
|
+
- spec/http/options/response_spec.rb
|
130
|
+
- spec/http/options_spec.rb
|
131
|
+
- spec/http/response_spec.rb
|
137
132
|
- spec/http_spec.rb
|
138
133
|
- spec/spec_helper.rb
|
139
|
-
- spec/support/
|
134
|
+
- spec/support/example_server.rb
|