httpadapter 0.1.1 → 0.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.
- data/CHANGELOG +8 -0
- data/README +2 -0
- data/lib/httpadapter.rb +32 -3
- data/lib/httpadapter/adapters/net_http.rb +43 -1
- data/lib/httpadapter/adapters/rack.rb +5 -0
- data/lib/httpadapter/adapters/typhoeus.rb +37 -2
- data/lib/httpadapter/connection.rb +73 -0
- data/lib/httpadapter/version.rb +2 -2
- data/spec/httpadapter/adapters/net_http_transmission_spec.rb +130 -0
- data/spec/httpadapter/adapters/rack_request_spec.rb +11 -0
- data/spec/httpadapter/adapters/typhoeus_request_spec.rb +1 -1
- data/spec/httpadapter/adapters/typhoeus_transmission_spec.rb +89 -0
- data/spec/httpadapter/connection_spec.rb +107 -0
- data/spec/httpadapter_spec.rb +25 -1
- data/tasks/rubyforge.rake +6 -9
- metadata +9 -5
data/CHANGELOG
CHANGED
data/README
CHANGED
@@ -17,6 +17,8 @@ A library for translating HTTP request and response objects for various clients
|
|
17
17
|
|
18
18
|
- {HTTPAdapter::NetHTTPRequestAdapter}
|
19
19
|
- {HTTPAdapter::NetHTTPResponseAdapter}
|
20
|
+
- {HTTPAdapter::RackRequestAdapter}
|
21
|
+
- {HTTPAdapter::RackResponseAdapter}
|
20
22
|
- {HTTPAdapter::TyphoeusRequestAdapter}
|
21
23
|
- {HTTPAdapter::TyphoeusResponseAdapter}
|
22
24
|
|
data/lib/httpadapter.rb
CHANGED
@@ -12,7 +12,8 @@
|
|
12
12
|
# See the License for the specific language governing permissions and
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
|
-
require
|
15
|
+
require 'httpadapter/version'
|
16
|
+
require 'httpadapter/connection'
|
16
17
|
|
17
18
|
module HTTPAdapter #:nodoc:
|
18
19
|
##
|
@@ -109,12 +110,40 @@ module HTTPAdapter #:nodoc:
|
|
109
110
|
if adapter.respond_to?(:from_ary)
|
110
111
|
return adapter.from_ary(response)
|
111
112
|
else
|
113
|
+
raise TypeError, 'Expected adapter to implement .from_ary.'
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
##
|
118
|
+
# Transmits a request.
|
119
|
+
#
|
120
|
+
# @param [Array] request
|
121
|
+
# The request that will be sent.
|
122
|
+
# @param [#transmit] adapter
|
123
|
+
# The adapter object that will perform the transmission of the HTTP
|
124
|
+
# request. It must respond to <code>#transmit</code>. Typically a
|
125
|
+
# reference to a class is used.
|
126
|
+
# @param [HTTPAdapter::Connection] connection
|
127
|
+
# An object representing a connection. This object represents an open
|
128
|
+
# HTTP connection that is used to make multiple HTTP requests.
|
129
|
+
# @return [Array]
|
130
|
+
# The response given by the server.
|
131
|
+
#
|
132
|
+
# @return [Array] The implementation-specific response object.
|
133
|
+
def self.transmit(request, adapter, connection=nil)
|
134
|
+
request = self.verified_request(request)
|
135
|
+
if connection && !connection.kind_of?(HTTPAdapter::Connection)
|
112
136
|
raise TypeError,
|
113
|
-
"Expected
|
137
|
+
"Expected HTTPAdapter::Connection, got #{connection.class}."
|
138
|
+
end
|
139
|
+
if adapter.respond_to?(:transmit)
|
140
|
+
response = adapter.transmit(request, connection)
|
141
|
+
return self.verified_response(response)
|
142
|
+
else
|
143
|
+
raise TypeError, 'Expected adapter to implement .transmit.'
|
114
144
|
end
|
115
145
|
end
|
116
146
|
|
117
|
-
protected
|
118
147
|
##
|
119
148
|
# Verifies a request tuple matches the specification.
|
120
149
|
#
|
@@ -13,6 +13,7 @@
|
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
15
|
require 'httpadapter'
|
16
|
+
require 'httpadapter/connection'
|
16
17
|
require 'net/http'
|
17
18
|
require 'addressable/uri'
|
18
19
|
|
@@ -80,14 +81,55 @@ module HTTPAdapter #:nodoc:
|
|
80
81
|
request = request_class.new(uri.request_uri)
|
81
82
|
headers.each do |header, value|
|
82
83
|
request[header] = value
|
84
|
+
if header.downcase == 'Content-Type'.downcase
|
85
|
+
request.content_type = value
|
86
|
+
end
|
83
87
|
end
|
84
88
|
merged_body = ""
|
85
89
|
body.each do |chunk|
|
86
90
|
merged_body += chunk
|
87
91
|
end
|
88
|
-
|
92
|
+
if merged_body.length > 0
|
93
|
+
request.body = merged_body
|
94
|
+
elsif ['POST', 'PUT'].include?(method)
|
95
|
+
request.content_length = 0
|
96
|
+
end
|
89
97
|
return request
|
90
98
|
end
|
99
|
+
|
100
|
+
def self.transmit(request, connection=nil)
|
101
|
+
method, uri, headers, body = request
|
102
|
+
uri = Addressable::URI.parse(uri)
|
103
|
+
net_http_request = self.from_ary([method, uri, headers, body])
|
104
|
+
net_http_response = nil
|
105
|
+
unless connection
|
106
|
+
http = Net::HTTP.new(uri.host, uri.inferred_port)
|
107
|
+
if uri.normalized_scheme == 'https'
|
108
|
+
require 'net/https'
|
109
|
+
http.use_ssl = true
|
110
|
+
if http.respond_to?(:enable_post_connection_check=)
|
111
|
+
http.enable_post_connection_check = true
|
112
|
+
end
|
113
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
114
|
+
store = OpenSSL::X509::Store.new
|
115
|
+
store.set_default_paths
|
116
|
+
http.cert_store = store
|
117
|
+
end
|
118
|
+
http.start
|
119
|
+
connection = HTTPAdapter::Connection.new(
|
120
|
+
uri.host, uri.inferred_port, http,
|
121
|
+
:open => [:start, [], nil],
|
122
|
+
:close => [:finish, [], nil]
|
123
|
+
)
|
124
|
+
else
|
125
|
+
http = nil
|
126
|
+
end
|
127
|
+
net_http_response = connection.connection.request(net_http_request)
|
128
|
+
if http
|
129
|
+
connection.close
|
130
|
+
end
|
131
|
+
return NetHTTPResponseAdapter.new(net_http_response).to_ary
|
132
|
+
end
|
91
133
|
end
|
92
134
|
|
93
135
|
class NetHTTPResponseAdapter
|
@@ -87,6 +87,11 @@ module HTTPAdapter #:nodoc:
|
|
87
87
|
request = Rack::Request.new(env)
|
88
88
|
return request
|
89
89
|
end
|
90
|
+
|
91
|
+
def self.transmit(request, connection=nil)
|
92
|
+
raise NotImplementedError,
|
93
|
+
'No HTTP client implementation available to transmit a Rack::Request.'
|
94
|
+
end
|
90
95
|
end
|
91
96
|
|
92
97
|
class RackResponseAdapter
|
@@ -42,18 +42,44 @@ module HTTPAdapter #:nodoc:
|
|
42
42
|
method, uri, headers, body = array
|
43
43
|
method = method.to_s.downcase.to_sym
|
44
44
|
uri = Addressable::URI.parse(uri)
|
45
|
+
headers = Hash[headers]
|
45
46
|
merged_body = ""
|
46
47
|
body.each do |chunk|
|
47
48
|
merged_body += chunk
|
48
49
|
end
|
50
|
+
if merged_body == ''
|
51
|
+
merged_body = nil
|
52
|
+
end
|
49
53
|
request = Typhoeus::Request.new(
|
50
54
|
uri.to_str,
|
51
55
|
:method => method,
|
52
|
-
:headers =>
|
56
|
+
:headers => headers,
|
53
57
|
:body => merged_body
|
54
58
|
)
|
55
59
|
return request
|
56
60
|
end
|
61
|
+
|
62
|
+
def self.transmit(request, connection=nil)
|
63
|
+
method, uri, headers, body = request
|
64
|
+
uri = Addressable::URI.parse(uri)
|
65
|
+
typhoeus_request = self.from_ary([method, uri, headers, body])
|
66
|
+
typhoeus_response = nil
|
67
|
+
unless connection
|
68
|
+
hydra = Typhoeus::Hydra.new
|
69
|
+
connection = HTTPAdapter::Connection.new(
|
70
|
+
uri.host, uri.inferred_port, hydra,
|
71
|
+
:join => [:run, [], nil]
|
72
|
+
)
|
73
|
+
else
|
74
|
+
http = nil
|
75
|
+
end
|
76
|
+
typhoeus_request.on_complete do |response|
|
77
|
+
typhoeus_response = response
|
78
|
+
end
|
79
|
+
connection.connection.queue(typhoeus_request)
|
80
|
+
connection.join
|
81
|
+
return TyphoeusResponseAdapter.new(typhoeus_response).to_ary
|
82
|
+
end
|
57
83
|
end
|
58
84
|
|
59
85
|
class TyphoeusResponseAdapter
|
@@ -68,7 +94,16 @@ module HTTPAdapter #:nodoc:
|
|
68
94
|
status = @response.code.to_i
|
69
95
|
headers = []
|
70
96
|
@response.headers_hash.each do |header, value|
|
71
|
-
|
97
|
+
# Eh? Seriously? This is NOT a header!
|
98
|
+
next if header =~ /^HTTP\/\d\.\d \d{3} .+$/
|
99
|
+
if value.kind_of?(Array)
|
100
|
+
for repeated_header_value in value
|
101
|
+
# Header appears multiple times; common for Set-Cookie
|
102
|
+
headers << [header, repeated_header_value]
|
103
|
+
end
|
104
|
+
else
|
105
|
+
headers << [header, value]
|
106
|
+
end
|
72
107
|
end
|
73
108
|
body = @response.body || ""
|
74
109
|
return [status, headers, [body]]
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# Copyright (C) 2010 Google Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require 'httpadapter'
|
16
|
+
|
17
|
+
module HTTPAdapter #:nodoc:
|
18
|
+
class Connection
|
19
|
+
def initialize(host, port, connection, options={})
|
20
|
+
if !host.respond_to?(:to_str)
|
21
|
+
raise TypeError, "Expected String, got #{host.class}."
|
22
|
+
end
|
23
|
+
@host = host.to_str
|
24
|
+
if port.kind_of?(Symbol) || !port.respond_to?(:to_i)
|
25
|
+
raise TypeError, "Expected Integer, got #{port.class}."
|
26
|
+
end
|
27
|
+
@port = port.to_i
|
28
|
+
unless (1..65535) === @port
|
29
|
+
raise ArgumentError, "Invalid port number."
|
30
|
+
end
|
31
|
+
@connection = connection
|
32
|
+
@options = options
|
33
|
+
end
|
34
|
+
|
35
|
+
def open
|
36
|
+
if @options[:open]
|
37
|
+
method, args, block = @options[:open]
|
38
|
+
method ||= :open
|
39
|
+
args ||= []
|
40
|
+
return @connection.send(method, *args, &block)
|
41
|
+
else
|
42
|
+
# No-op
|
43
|
+
return nil
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def close
|
48
|
+
if @options[:close]
|
49
|
+
method, args, block = @options[:close]
|
50
|
+
method ||= :close
|
51
|
+
args ||= []
|
52
|
+
return @connection.send(method, *args, &block)
|
53
|
+
else
|
54
|
+
# No-op
|
55
|
+
return nil
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def join
|
60
|
+
if @options[:join]
|
61
|
+
method, args, block = @options[:join]
|
62
|
+
method ||= :join
|
63
|
+
args ||= []
|
64
|
+
return @connection.send(method, *args, &block)
|
65
|
+
else
|
66
|
+
# No-op
|
67
|
+
return nil
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
attr_reader :host, :port, :connection
|
72
|
+
end
|
73
|
+
end
|
data/lib/httpadapter/version.rb
CHANGED
@@ -0,0 +1,130 @@
|
|
1
|
+
# Copyright (C) 2010 Google Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require 'spec_helper'
|
16
|
+
|
17
|
+
require 'httpadapter/adapters/net_http'
|
18
|
+
|
19
|
+
if ([:enable_post_connection_check=, 'enable_post_connection_check='] &
|
20
|
+
Net::HTTP.instance_methods).empty?
|
21
|
+
class Net::HTTP
|
22
|
+
def enable_post_connection_check=(value)
|
23
|
+
# No-op
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe HTTPAdapter::NetHTTPRequestAdapter, 'transmitting a GET tuple' do
|
29
|
+
before do
|
30
|
+
@tuple = [
|
31
|
+
'GET',
|
32
|
+
'http://www.google.com/',
|
33
|
+
[],
|
34
|
+
[]
|
35
|
+
]
|
36
|
+
@response = HTTPAdapter.transmit(
|
37
|
+
@tuple, HTTPAdapter::NetHTTPRequestAdapter
|
38
|
+
)
|
39
|
+
@status, @headers, @chunked_body = @response
|
40
|
+
@body = ''
|
41
|
+
@chunked_body.each do |chunk|
|
42
|
+
@body += chunk
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'should have the correct status' do
|
47
|
+
@status.should == 200
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'should have response headers' do
|
51
|
+
@headers.should_not be_empty
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'should have a response body' do
|
55
|
+
@body.length.should > 0
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe HTTPAdapter::NetHTTPRequestAdapter, 'transmitting a GET tuple' do
|
60
|
+
before do
|
61
|
+
@tuple = [
|
62
|
+
'GET',
|
63
|
+
'https://www.google.com/',
|
64
|
+
[],
|
65
|
+
[]
|
66
|
+
]
|
67
|
+
@response = HTTPAdapter.transmit(
|
68
|
+
@tuple, HTTPAdapter::NetHTTPRequestAdapter
|
69
|
+
)
|
70
|
+
@status, @headers, @chunked_body = @response
|
71
|
+
@body = ''
|
72
|
+
@chunked_body.each do |chunk|
|
73
|
+
@body += chunk
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'should have the correct status' do
|
78
|
+
@status.should == 200
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'should have response headers' do
|
82
|
+
@headers.should_not be_empty
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'should have a response body' do
|
86
|
+
@body.length.should > 0
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe HTTPAdapter::NetHTTPRequestAdapter, 'transmitting with connection' do
|
91
|
+
before do
|
92
|
+
@connection = HTTPAdapter::Connection.new(
|
93
|
+
'www.google.com', 80,
|
94
|
+
Net::HTTP.new('www.google.com', 80),
|
95
|
+
:open => [:start],
|
96
|
+
:close => [:finish]
|
97
|
+
)
|
98
|
+
@connection.open
|
99
|
+
@tuple = [
|
100
|
+
'GET',
|
101
|
+
'http://www.google.com/',
|
102
|
+
[],
|
103
|
+
[]
|
104
|
+
]
|
105
|
+
@response = HTTPAdapter.transmit(
|
106
|
+
@tuple, HTTPAdapter::NetHTTPRequestAdapter, @connection
|
107
|
+
)
|
108
|
+
@status, @headers, @chunked_body = @response
|
109
|
+
@body = ''
|
110
|
+
@chunked_body.each do |chunk|
|
111
|
+
@body += chunk
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
after do
|
116
|
+
@connection.close
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'should have the correct status' do
|
120
|
+
@status.should == 200
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'should have response headers' do
|
124
|
+
@headers.should_not be_empty
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'should have a response body' do
|
128
|
+
@body.length.should > 0
|
129
|
+
end
|
130
|
+
end
|
@@ -226,3 +226,14 @@ describe HTTPAdapter::RackRequestAdapter,
|
|
226
226
|
@request.body.read.should == '{"three":3,"two":2,"one":1}'
|
227
227
|
end
|
228
228
|
end
|
229
|
+
|
230
|
+
describe HTTPAdapter::RackRequestAdapter, 'transmitting' do
|
231
|
+
it 'should raise an error indicating that transmission is not possible' do
|
232
|
+
(lambda do
|
233
|
+
HTTPAdapter.transmit(
|
234
|
+
['GET', 'http://www.google.com/', [], ['']],
|
235
|
+
HTTPAdapter::RackRequestAdapter
|
236
|
+
)
|
237
|
+
end).should raise_error(NotImplementedError)
|
238
|
+
end
|
239
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
# Copyright (C) 2010 Google Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require 'spec_helper'
|
16
|
+
|
17
|
+
require 'httpadapter/adapters/typhoeus'
|
18
|
+
|
19
|
+
describe HTTPAdapter::TyphoeusRequestAdapter, 'transmitting a GET tuple' do
|
20
|
+
before do
|
21
|
+
@tuple = [
|
22
|
+
'GET',
|
23
|
+
'http://www.google.com/',
|
24
|
+
[],
|
25
|
+
[]
|
26
|
+
]
|
27
|
+
@response = HTTPAdapter.transmit(
|
28
|
+
@tuple, HTTPAdapter::TyphoeusRequestAdapter
|
29
|
+
)
|
30
|
+
@status, @headers, @chunked_body = @response
|
31
|
+
@body = ''
|
32
|
+
@chunked_body.each do |chunk|
|
33
|
+
@body += chunk
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should have the correct status' do
|
38
|
+
@status.should == 200
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should have response headers' do
|
42
|
+
@headers.should_not be_empty
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should have a response body' do
|
46
|
+
@body.length.should > 0
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe HTTPAdapter::TyphoeusRequestAdapter, 'transmitting with connection' do
|
51
|
+
before do
|
52
|
+
@connection = HTTPAdapter::Connection.new(
|
53
|
+
'www.google.com', 80,
|
54
|
+
Typhoeus::Hydra.new,
|
55
|
+
:join => [:run, [], nil]
|
56
|
+
)
|
57
|
+
@connection.open
|
58
|
+
@tuple = [
|
59
|
+
'GET',
|
60
|
+
'http://www.google.com/',
|
61
|
+
[],
|
62
|
+
[]
|
63
|
+
]
|
64
|
+
@response = HTTPAdapter.transmit(
|
65
|
+
@tuple, HTTPAdapter::TyphoeusRequestAdapter, @connection
|
66
|
+
)
|
67
|
+
@status, @headers, @chunked_body = @response
|
68
|
+
@body = ''
|
69
|
+
@chunked_body.each do |chunk|
|
70
|
+
@body += chunk
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
after do
|
75
|
+
@connection.close
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'should have the correct status' do
|
79
|
+
@status.should == 200
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'should have response headers' do
|
83
|
+
@headers.should_not be_empty
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'should have a response body' do
|
87
|
+
@body.length.should > 0
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
# Copyright (C) 2010 Google Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require 'spec_helper'
|
16
|
+
|
17
|
+
require 'httpadapter/connection'
|
18
|
+
|
19
|
+
class StubbedConnection
|
20
|
+
def open
|
21
|
+
# Does nothing
|
22
|
+
end
|
23
|
+
|
24
|
+
def close
|
25
|
+
# Does nothing
|
26
|
+
end
|
27
|
+
|
28
|
+
def join
|
29
|
+
# Does nothing
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe HTTPAdapter::Connection, 'when wrapping a connection' do
|
34
|
+
before do
|
35
|
+
@connection = HTTPAdapter::Connection.new(
|
36
|
+
'www.example.com', 80, StubbedConnection.new,
|
37
|
+
:open => [:open, [], nil],
|
38
|
+
:close => [:close, [], nil],
|
39
|
+
:join => [:join, [], nil]
|
40
|
+
)
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'should be able to call open' do
|
44
|
+
@connection.open
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'should be able to call close' do
|
48
|
+
@connection.close
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'should be able to call join' do
|
52
|
+
@connection.join
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should be able to obtain a reference to the wrapped connection' do
|
56
|
+
@connection.connection.should be_kind_of(StubbedConnection)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe HTTPAdapter::Connection,
|
61
|
+
'when wrapping a connection that does not implement methods' do
|
62
|
+
it 'should perform no-ops' do
|
63
|
+
@connection = HTTPAdapter::Connection.new(
|
64
|
+
'www.example.com', 80, Object.new
|
65
|
+
)
|
66
|
+
@connection.open.should == nil
|
67
|
+
@connection.close.should == nil
|
68
|
+
@connection.join.should == nil
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe HTTPAdapter::Connection,
|
73
|
+
'when wrapping a connection using bogus parameters' do
|
74
|
+
it 'should raise an error for invalid hostnames' do
|
75
|
+
(lambda do
|
76
|
+
HTTPAdapter::Connection.new(42, 80, Object.new)
|
77
|
+
end).should raise_error(TypeError)
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'should raise an error for invalid port' do
|
81
|
+
(lambda do
|
82
|
+
HTTPAdapter::Connection.new('www.example.com', 0, Object.new)
|
83
|
+
end).should raise_error(ArgumentError)
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'should raise an error for invalid port' do
|
87
|
+
(lambda do
|
88
|
+
HTTPAdapter::Connection.new('www.example.com', 65536, Object.new)
|
89
|
+
end).should raise_error(ArgumentError)
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'should not raise an error for a valid port expressed as a String' do
|
93
|
+
HTTPAdapter::Connection.new('www.example.com', '80', Object.new)
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'should raise an error for invalid port' do
|
97
|
+
(lambda do
|
98
|
+
HTTPAdapter::Connection.new('www.example.com', '65536', Object.new)
|
99
|
+
end).should raise_error(ArgumentError)
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'should raise an error for invalid port' do
|
103
|
+
(lambda do
|
104
|
+
HTTPAdapter::Connection.new('www.example.com', :bogus, Object.new)
|
105
|
+
end).should raise_error(TypeError)
|
106
|
+
end
|
107
|
+
end
|
data/spec/httpadapter_spec.rb
CHANGED
@@ -20,10 +20,14 @@ class StubAdapter
|
|
20
20
|
def to_ary
|
21
21
|
return ['GET', '/', [], [""]]
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
def self.from_ary(array)
|
25
25
|
return Object.new
|
26
26
|
end
|
27
|
+
|
28
|
+
def self.transmit(request, connection=nil)
|
29
|
+
return [200, [], ['']]
|
30
|
+
end
|
27
31
|
end
|
28
32
|
|
29
33
|
class BogusAdapter
|
@@ -222,3 +226,23 @@ describe HTTPAdapter, 'when attempting to adapt a response' do
|
|
222
226
|
end).should raise_error(TypeError)
|
223
227
|
end
|
224
228
|
end
|
229
|
+
|
230
|
+
describe HTTPAdapter, 'when attempting to transmit a request' do
|
231
|
+
it 'should raise an error for invalid request objects' do
|
232
|
+
(lambda do
|
233
|
+
HTTPAdapter.transmit(42, StubAdapter)
|
234
|
+
end).should raise_error(TypeError)
|
235
|
+
end
|
236
|
+
|
237
|
+
it 'should raise an error for invalid adapter objects' do
|
238
|
+
(lambda do
|
239
|
+
HTTPAdapter.transmit(['GET', '/', [], ['']], BogusAdapter)
|
240
|
+
end).should raise_error(TypeError)
|
241
|
+
end
|
242
|
+
|
243
|
+
it 'should raise an error for invalid connection objects' do
|
244
|
+
(lambda do
|
245
|
+
HTTPAdapter.transmit(['GET', '/', [], ['']], StubAdapter, 42)
|
246
|
+
end).should raise_error(TypeError)
|
247
|
+
end
|
248
|
+
end
|
data/tasks/rubyforge.rake
CHANGED
@@ -36,9 +36,7 @@ namespace :doc do
|
|
36
36
|
host = "#{config['username']}@rubyforge.org"
|
37
37
|
remote_dir = RUBY_FORGE_PATH + "/api"
|
38
38
|
local_dir = "doc"
|
39
|
-
|
40
|
-
system("mkdir website/api")
|
41
|
-
end
|
39
|
+
system("mkdir -p website/api")
|
42
40
|
Rake::SshDirPublisher.new(host, remote_dir, local_dir).upload
|
43
41
|
end
|
44
42
|
end
|
@@ -55,9 +53,7 @@ namespace :spec do
|
|
55
53
|
host = "#{config['username']}@rubyforge.org"
|
56
54
|
remote_dir = RUBY_FORGE_PATH + "/specdoc"
|
57
55
|
local_dir = "specdoc"
|
58
|
-
|
59
|
-
system("mkdir website/specdoc")
|
60
|
-
end
|
56
|
+
system("mkdir -p website/specdoc")
|
61
57
|
Rake::SshDirPublisher.new(host, remote_dir, local_dir).upload
|
62
58
|
end
|
63
59
|
|
@@ -73,9 +69,7 @@ namespace :spec do
|
|
73
69
|
host = "#{config['username']}@rubyforge.org"
|
74
70
|
remote_dir = RUBY_FORGE_PATH + "/coverage"
|
75
71
|
local_dir = "coverage"
|
76
|
-
|
77
|
-
system("mkdir website/coverage")
|
78
|
-
end
|
72
|
+
system("mkdir -p website/coverage")
|
79
73
|
Rake::SshDirPublisher.new(host, remote_dir, local_dir).upload
|
80
74
|
end
|
81
75
|
end
|
@@ -93,6 +87,9 @@ namespace :website do
|
|
93
87
|
host = "#{config['username']}@rubyforge.org"
|
94
88
|
remote_dir = RUBY_FORGE_PATH
|
95
89
|
local_dir = "website"
|
90
|
+
system("mkdir -p website/api")
|
91
|
+
system("mkdir -p website/specdoc")
|
92
|
+
system("mkdir -p website/coverage")
|
96
93
|
Rake::SshDirPublisher.new(host, remote_dir, local_dir).upload
|
97
94
|
end
|
98
95
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: httpadapter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 23
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 2
|
9
|
+
- 0
|
10
|
+
version: 0.2.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Bob Aman
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-
|
18
|
+
date: 2010-09-07 00:00:00 -07:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -144,14 +144,18 @@ files:
|
|
144
144
|
- lib/httpadapter/adapters/net_http.rb
|
145
145
|
- lib/httpadapter/adapters/rack.rb
|
146
146
|
- lib/httpadapter/adapters/typhoeus.rb
|
147
|
+
- lib/httpadapter/connection.rb
|
147
148
|
- lib/httpadapter/version.rb
|
148
149
|
- lib/httpadapter.rb
|
149
150
|
- spec/httpadapter/adapters/net_http_request_spec.rb
|
150
151
|
- spec/httpadapter/adapters/net_http_response_spec.rb
|
152
|
+
- spec/httpadapter/adapters/net_http_transmission_spec.rb
|
151
153
|
- spec/httpadapter/adapters/rack_request_spec.rb
|
152
154
|
- spec/httpadapter/adapters/rack_response_spec.rb
|
153
155
|
- spec/httpadapter/adapters/typhoeus_request_spec.rb
|
154
156
|
- spec/httpadapter/adapters/typhoeus_response_spec.rb
|
157
|
+
- spec/httpadapter/adapters/typhoeus_transmission_spec.rb
|
158
|
+
- spec/httpadapter/connection_spec.rb
|
155
159
|
- spec/httpadapter_spec.rb
|
156
160
|
- spec/spec.opts
|
157
161
|
- spec/spec_helper.rb
|