httpadapter 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|