gregwebs-oauth 0.3.6.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. data/History.txt +102 -0
  2. data/License.txt +20 -0
  3. data/Manifest.txt +84 -0
  4. data/README.rdoc +71 -0
  5. data/Rakefile +36 -0
  6. data/TODO +31 -0
  7. data/bin/oauth +5 -0
  8. data/examples/yql.rb +44 -0
  9. data/lib/oauth.rb +4 -0
  10. data/lib/oauth/cli.rb +378 -0
  11. data/lib/oauth/client.rb +4 -0
  12. data/lib/oauth/client/action_controller_request.rb +54 -0
  13. data/lib/oauth/client/helper.rb +85 -0
  14. data/lib/oauth/client/net_http.rb +103 -0
  15. data/lib/oauth/consumer.rb +354 -0
  16. data/lib/oauth/errors.rb +3 -0
  17. data/lib/oauth/errors/error.rb +4 -0
  18. data/lib/oauth/errors/problem.rb +14 -0
  19. data/lib/oauth/errors/unauthorized.rb +12 -0
  20. data/lib/oauth/helper.rb +78 -0
  21. data/lib/oauth/oauth.rb +11 -0
  22. data/lib/oauth/oauth_test_helper.rb +25 -0
  23. data/lib/oauth/request_proxy.rb +24 -0
  24. data/lib/oauth/request_proxy/action_controller_request.rb +61 -0
  25. data/lib/oauth/request_proxy/base.rb +166 -0
  26. data/lib/oauth/request_proxy/jabber_request.rb +41 -0
  27. data/lib/oauth/request_proxy/mock_request.rb +44 -0
  28. data/lib/oauth/request_proxy/net_http.rb +68 -0
  29. data/lib/oauth/request_proxy/rack_request.rb +40 -0
  30. data/lib/oauth/server.rb +66 -0
  31. data/lib/oauth/signature.rb +40 -0
  32. data/lib/oauth/signature/base.rb +91 -0
  33. data/lib/oauth/signature/hmac/base.rb +12 -0
  34. data/lib/oauth/signature/hmac/md5.rb +9 -0
  35. data/lib/oauth/signature/hmac/rmd160.rb +9 -0
  36. data/lib/oauth/signature/hmac/sha1.rb +9 -0
  37. data/lib/oauth/signature/hmac/sha2.rb +9 -0
  38. data/lib/oauth/signature/md5.rb +13 -0
  39. data/lib/oauth/signature/plaintext.rb +23 -0
  40. data/lib/oauth/signature/rsa/sha1.rb +45 -0
  41. data/lib/oauth/signature/sha1.rb +13 -0
  42. data/lib/oauth/token.rb +7 -0
  43. data/lib/oauth/tokens/access_token.rb +68 -0
  44. data/lib/oauth/tokens/consumer_token.rb +33 -0
  45. data/lib/oauth/tokens/request_token.rb +32 -0
  46. data/lib/oauth/tokens/server_token.rb +9 -0
  47. data/lib/oauth/tokens/token.rb +17 -0
  48. data/lib/oauth/version.rb +3 -0
  49. data/oauth.gemspec +49 -0
  50. data/script/destroy +14 -0
  51. data/script/generate +14 -0
  52. data/script/txt2html +74 -0
  53. data/setup.rb +1585 -0
  54. data/tasks/deployment.rake +34 -0
  55. data/tasks/environment.rake +7 -0
  56. data/tasks/website.rake +17 -0
  57. data/test/cases/oauth_case.rb +19 -0
  58. data/test/cases/spec/1_0-final/test_construct_request_url.rb +62 -0
  59. data/test/cases/spec/1_0-final/test_normalize_request_parameters.rb +88 -0
  60. data/test/cases/spec/1_0-final/test_parameter_encodings.rb +86 -0
  61. data/test/cases/spec/1_0-final/test_signature_base_strings.rb +77 -0
  62. data/test/keys/rsa.cert +11 -0
  63. data/test/keys/rsa.pem +16 -0
  64. data/test/test_access_token.rb +26 -0
  65. data/test/test_action_controller_request_proxy.rb +129 -0
  66. data/test/test_consumer.rb +362 -0
  67. data/test/test_helper.rb +14 -0
  68. data/test/test_hmac_sha1.rb +20 -0
  69. data/test/test_net_http_client.rb +185 -0
  70. data/test/test_net_http_request_proxy.rb +72 -0
  71. data/test/test_oauth_helper.rb +49 -0
  72. data/test/test_rack_request_proxy.rb +40 -0
  73. data/test/test_request_token.rb +51 -0
  74. data/test/test_rsa_sha1.rb +59 -0
  75. data/test/test_server.rb +40 -0
  76. data/test/test_signature.rb +19 -0
  77. data/test/test_signature_base.rb +32 -0
  78. data/test/test_signature_plain_text.rb +31 -0
  79. data/test/test_token.rb +14 -0
  80. data/website/index.html +87 -0
  81. data/website/index.txt +73 -0
  82. data/website/javascripts/rounded_corners_lite.inc.js +285 -0
  83. data/website/stylesheets/screen.css +138 -0
  84. data/website/template.rhtml +48 -0
  85. metadata +217 -0
@@ -0,0 +1,4 @@
1
+ module OAuth
2
+ module Client
3
+ end
4
+ end
@@ -0,0 +1,54 @@
1
+ require 'oauth/client/helper'
2
+ require 'oauth/request_proxy/action_controller_request'
3
+ require 'action_controller/test_process'
4
+
5
+ module ActionController
6
+ class Base
7
+ def process_with_oauth(request, response=nil)
8
+ request.apply_oauth!
9
+ process_without_oauth(request, response)
10
+ end
11
+
12
+ alias_method_chain :process, :oauth
13
+ end
14
+
15
+ class TestRequest
16
+ def self.use_oauth=(bool)
17
+ @use_oauth = bool
18
+ end
19
+
20
+ def self.use_oauth?
21
+ @use_oauth
22
+ end
23
+
24
+ def configure_oauth(consumer = nil, token = nil, options = {})
25
+ @oauth_options = { :consumer => consumer,
26
+ :token => token,
27
+ :scheme => 'header',
28
+ :signature_method => nil,
29
+ :nonce => nil,
30
+ :timestamp => nil }.merge(options)
31
+ end
32
+
33
+ def apply_oauth!
34
+ return unless ActionController::TestRequest.use_oauth? && @oauth_options
35
+
36
+ @oauth_helper = OAuth::Client::Helper.new(self, @oauth_options.merge(:request_uri => request_uri))
37
+ @oauth_helper.amend_user_agent_header(env)
38
+
39
+ self.send("set_oauth_#{@oauth_options[:scheme]}")
40
+ end
41
+
42
+ def set_oauth_header
43
+ env['Authorization'] = @oauth_helper.header
44
+ end
45
+
46
+ def set_oauth_parameters
47
+ @query_parameters = @oauth_helper.parameters_with_oauth
48
+ @query_parameters.merge!(:oauth_signature => @oauth_helper.signature)
49
+ end
50
+
51
+ def set_oauth_query_string
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,85 @@
1
+ require 'oauth/client'
2
+ require 'oauth/consumer'
3
+ require 'oauth/helper'
4
+ require 'oauth/token'
5
+ require 'oauth/version'
6
+ require 'oauth/signature/hmac/sha1'
7
+
8
+ module OAuth::Client
9
+ class Helper
10
+ include OAuth::Helper
11
+
12
+ def initialize(request, options = {})
13
+ @request = request
14
+ @options = options
15
+ @options[:signature_method] ||= 'HMAC-SHA1'
16
+ end
17
+
18
+ def options
19
+ @options
20
+ end
21
+
22
+ def nonce
23
+ options[:nonce] ||= generate_key
24
+ end
25
+
26
+ def timestamp
27
+ options[:timestamp] ||= generate_timestamp
28
+ end
29
+
30
+ def oauth_parameters
31
+ {
32
+ 'oauth_callback' => options[:oauth_callback],
33
+ 'oauth_consumer_key' => options[:consumer].key,
34
+ 'oauth_token' => options[:token] ? options[:token].token : '',
35
+ 'oauth_signature_method' => options[:signature_method],
36
+ 'oauth_timestamp' => timestamp,
37
+ 'oauth_nonce' => nonce,
38
+ 'oauth_verifier' => options[:oauth_verifier],
39
+ 'oauth_version' => '1.0'
40
+ }.reject { |k,v| v.to_s == "" }
41
+ end
42
+
43
+ def signature(extra_options = {})
44
+ OAuth::Signature.sign(@request, { :uri => options[:request_uri],
45
+ :consumer => options[:consumer],
46
+ :token => options[:token],
47
+ :unsigned_parameters => options[:unsigned_parameters]
48
+ }.merge(extra_options) )
49
+ end
50
+
51
+ def signature_base_string(extra_options = {})
52
+ OAuth::Signature.signature_base_string(@request, { :uri => options[:request_uri],
53
+ :consumer => options[:consumer],
54
+ :token => options[:token],
55
+ :parameters => oauth_parameters}.merge(extra_options) )
56
+ end
57
+
58
+ def amend_user_agent_header(headers)
59
+ @oauth_ua_string ||= "OAuth gem v#{OAuth::VERSION}"
60
+ if headers['User-Agent']
61
+ headers['User-Agent'] += " (#{@oauth_ua_string})"
62
+ else
63
+ headers['User-Agent'] = @oauth_ua_string
64
+ end
65
+ end
66
+
67
+ def header
68
+ parameters = oauth_parameters
69
+ parameters.merge!('oauth_signature' => signature(options.merge(:parameters => parameters)))
70
+
71
+ header_params_str = parameters.map { |k,v| "#{k}=\"#{escape(v)}\"" }.join(', ')
72
+
73
+ realm = "realm=\"#{options[:realm]}\", " if options[:realm]
74
+ "OAuth #{realm}#{header_params_str}"
75
+ end
76
+
77
+ def parameters
78
+ OAuth::RequestProxy.proxy(@request).parameters
79
+ end
80
+
81
+ def parameters_with_oauth
82
+ oauth_parameters.merge(parameters)
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,103 @@
1
+ require 'oauth/helper'
2
+ require 'oauth/client/helper'
3
+ require 'oauth/request_proxy/net_http'
4
+
5
+ class Net::HTTPRequest
6
+ include OAuth::Helper
7
+
8
+ attr_reader :oauth_helper
9
+
10
+ # Add the OAuth information to an HTTP request. Depending on the <tt>options[:scheme]</tt> setting
11
+ # this may add a header, additional query string parameters, or additional POST body parameters.
12
+ # The default scheme is +header+, in which the OAuth parameters as put into the +Authorization+
13
+ # header.
14
+ #
15
+ # * http - Configured Net::HTTP instance
16
+ # * consumer - OAuth::Consumer instance
17
+ # * token - OAuth::Token instance
18
+ # * options - Request-specific options (e.g. +request_uri+, +consumer+, +token+, +scheme+,
19
+ # +signature_method+, +nonce+, +timestamp+)
20
+ #
21
+ # This method also modifies the <tt>User-Agent</tt> header to add the OAuth gem version.
22
+ #
23
+ # See Also: {OAuth core spec version 1.0, section 5.4.1}[http://oauth.net/core/1.0#rfc.section.5.4.1]
24
+ def oauth!(http, consumer = nil, token = nil, options = {})
25
+ options = { :request_uri => oauth_full_request_uri(http),
26
+ :consumer => consumer,
27
+ :token => token,
28
+ :scheme => 'header',
29
+ :signature_method => nil,
30
+ :nonce => nil,
31
+ :timestamp => nil }.merge(options)
32
+
33
+ @oauth_helper = OAuth::Client::Helper.new(self, options)
34
+ @oauth_helper.amend_user_agent_header(self)
35
+ self.send("set_oauth_#{options[:scheme]}")
36
+ end
37
+
38
+ # Create a string suitable for signing for an HTTP request. This process involves parameter
39
+ # normalization as specified in the OAuth specification. The exact normalization also depends
40
+ # on the <tt>options[:scheme]</tt> being used so this must match what will be used for the request
41
+ # itself. The default scheme is +header+, in which the OAuth parameters as put into the +Authorization+
42
+ # header.
43
+ #
44
+ # * http - Configured Net::HTTP instance
45
+ # * consumer - OAuth::Consumer instance
46
+ # * token - OAuth::Token instance
47
+ # * options - Request-specific options (e.g. +request_uri+, +consumer+, +token+, +scheme+,
48
+ # +signature_method+, +nonce+, +timestamp+)
49
+ #
50
+ # See Also: {OAuth core spec version 1.0, section 9.1.1}[http://oauth.net/core/1.0#rfc.section.9.1.1]
51
+ def signature_base_string(http, consumer = nil, token = nil, options = {})
52
+ options = { :request_uri => oauth_full_request_uri(http),
53
+ :consumer => consumer,
54
+ :token => token,
55
+ :scheme => 'header',
56
+ :signature_method => nil,
57
+ :nonce => nil,
58
+ :timestamp => nil }.merge(options)
59
+
60
+ OAuth::Client::Helper.new(self, options).signature_base_string
61
+ end
62
+
63
+ private
64
+
65
+ def oauth_full_request_uri(http)
66
+ uri = URI.parse(self.path)
67
+ uri.host = http.address
68
+ uri.port = http.port
69
+
70
+ if http.respond_to?(:use_ssl?) && http.use_ssl?
71
+ uri.scheme = "https"
72
+ else
73
+ uri.scheme = "http"
74
+ end
75
+
76
+ uri.to_s
77
+ end
78
+
79
+ def set_oauth_header
80
+ self['Authorization'] = @oauth_helper.header
81
+ end
82
+
83
+ def set_oauth_body
84
+ self.set_form_data(@oauth_helper.parameters_with_oauth)
85
+ params_with_sig = @oauth_helper.parameters.merge(:oauth_signature => @oauth_helper.signature)
86
+ self.set_form_data(params_with_sig)
87
+ end
88
+
89
+ def set_oauth_query_string
90
+ oauth_params_str = @oauth_helper.oauth_parameters.map { |k,v| [escape(k), escape(v)] * "=" }.join("&")
91
+
92
+ uri = URI.parse(path)
93
+ if uri.query.to_s == ""
94
+ uri.query = oauth_params_str
95
+ else
96
+ uri.query = uri.query + "&" + oauth_params_str
97
+ end
98
+
99
+ @path = uri.to_s
100
+
101
+ @path << "&oauth_signature=#{escape(oauth_helper.signature)}"
102
+ end
103
+ end
@@ -0,0 +1,354 @@
1
+ require 'net/http'
2
+ require 'net/https'
3
+ require 'oauth/oauth'
4
+ require 'oauth/client/net_http'
5
+ require 'oauth/errors'
6
+
7
+ module OAuth
8
+ class Consumer
9
+ # determine the certificate authority path to verify SSL certs
10
+ CA_FILES = %w(/etc/ssl/certs/ca-certificates.crt /usr/share/curl/curl-ca-bundle.crt)
11
+ CA_FILES.each do |ca_file|
12
+ if File.exists?(ca_file)
13
+ CA_FILE = ca_file
14
+ break
15
+ end
16
+ end
17
+ CA_FILE = nil unless defined?(CA_FILE)
18
+
19
+ @@default_options = {
20
+ # Signature method used by server. Defaults to HMAC-SHA1
21
+ :signature_method => 'HMAC-SHA1',
22
+
23
+ # default paths on site. These are the same as the defaults set up by the generators
24
+ :request_token_path => '/oauth/request_token',
25
+ :authorize_path => '/oauth/authorize',
26
+ :access_token_path => '/oauth/access_token',
27
+
28
+ :proxy => nil,
29
+ # How do we send the oauth values to the server see
30
+ # http://oauth.net/core/1.0/#consumer_req_param for more info
31
+ #
32
+ # Possible values:
33
+ #
34
+ # :header - via the Authorize header (Default) ( option 1. in spec)
35
+ # :body - url form encoded in body of POST request ( option 2. in spec)
36
+ # :query_string - via the query part of the url ( option 3. in spec)
37
+ :scheme => :header,
38
+
39
+ # Default http method used for OAuth Token Requests (defaults to :post)
40
+ :http_method => :post,
41
+
42
+ # Add a custom ca_file for consumer
43
+ # :ca_file => '/etc/certs.pem'
44
+
45
+ :oauth_version => "1.0"
46
+ }
47
+
48
+ attr_accessor :options, :key, :secret
49
+ attr_writer :site, :http
50
+
51
+ # Create a new consumer instance by passing it a configuration hash:
52
+ #
53
+ # @consumer = OAuth::Consumer.new(key, secret, {
54
+ # :site => "http://term.ie",
55
+ # :scheme => :header,
56
+ # :http_method => :post,
57
+ # :request_token_path => "/oauth/example/request_token.php",
58
+ # :access_token_path => "/oauth/example/access_token.php",
59
+ # :authorize_path => "/oauth/example/authorize.php"
60
+ # })
61
+ #
62
+ # Start the process by requesting a token
63
+ #
64
+ # @request_token = @consumer.get_request_token
65
+ # session[:request_token] = @request_token
66
+ # redirect_to @request_token.authorize_url
67
+ #
68
+ # When user returns create an access_token
69
+ #
70
+ # @access_token = @request_token.get_access_token
71
+ # @photos=@access_token.get('/photos.xml')
72
+ #
73
+ def initialize(consumer_key, consumer_secret, options = {})
74
+ @key = consumer_key
75
+ @secret = consumer_secret
76
+
77
+ # ensure that keys are symbols
78
+ @options = @@default_options.merge(options.inject({}) { |options, (key, value)|
79
+ options[key.to_sym] = value
80
+ options
81
+ })
82
+ end
83
+
84
+ # The default http method
85
+ def http_method
86
+ @http_method ||= @options[:http_method] || :post
87
+ end
88
+
89
+ # The HTTP object for the site. The HTTP Object is what you get when you do Net::HTTP.new
90
+ def http
91
+ @http ||= create_http
92
+ end
93
+
94
+ # Contains the root URI for this site
95
+ def uri(custom_uri = nil)
96
+ if custom_uri
97
+ @uri = custom_uri
98
+ @http = create_http # yike, oh well. less intrusive this way
99
+ else # if no custom passed, we use existing, which, if unset, is set to site uri
100
+ @uri ||= URI.parse(site)
101
+ end
102
+ end
103
+
104
+ def get_access_token(request_token, request_options = {}, *arguments)
105
+ response = token_request(http_method, (access_token_url? ? access_token_url : access_token_path), request_token, request_options, *arguments)
106
+ OAuth::AccessToken.from_hash(self, response)
107
+ end
108
+
109
+ # Makes a request to the service for a new OAuth::RequestToken
110
+ #
111
+ # @request_token = @consumer.get_request_token
112
+ #
113
+ # To include OAuth parameters:
114
+ #
115
+ # @request_token = @consumer.get_request_token \
116
+ # :oauth_callback => "http://example.com/cb"
117
+ #
118
+ # To include application-specific parameters:
119
+ #
120
+ # @request_token = @consumer.get_request_token({}, :foo => "bar")
121
+ #
122
+ # TODO oauth_callback should be a mandatory parameter
123
+ def get_request_token(request_options = {}, *arguments)
124
+ # if oauth_callback wasn't provided, it is assumed that oauth_verifiers
125
+ # will be exchanged out of band
126
+ request_options[:oauth_callback] ||= OAuth::OUT_OF_BAND
127
+
128
+ response = token_request(http_method, (request_token_url? ? request_token_url : request_token_path), nil, request_options, *arguments)
129
+ OAuth::RequestToken.from_hash(self, response)
130
+ end
131
+
132
+ # Creates, signs and performs an http request.
133
+ # It's recommended to use the OAuth::Token classes to set this up correctly.
134
+ # request_options take precedence over consumer-wide options when signing
135
+ # a request.
136
+ # arguments are POST and PUT bodies (a Hash, string-encoded parameters, or
137
+ # absent), followed by additional HTTP headers.
138
+ #
139
+ # @consumer.request(:get, '/people', @token, { :scheme => :query_string })
140
+ # @consumer.request(:post, '/people', @token, {}, @person.to_xml, { 'Content-Type' => 'application/xml' })
141
+ #
142
+ def request(http_method, path, token = nil, request_options = {}, *arguments)
143
+ if path !~ /^\//
144
+ @http = create_http(path)
145
+ _uri = URI.parse(path)
146
+ path = "#{_uri.path}#{_uri.query ? "?#{_uri.query}" : ""}"
147
+ end
148
+
149
+ # override the request with your own, this is useful for file uploads which Net::HTTP does not do
150
+ req = create_signed_request(http_method, path, token, request_options, *arguments)
151
+ return nil if block_given? and yield(req) == :done
152
+ rsp = http.request(req)
153
+
154
+ # check for an error reported by the Problem Reporting extension
155
+ # (http://wiki.oauth.net/ProblemReporting)
156
+ # note: a 200 may actually be an error; check for an oauth_problem key to be sure
157
+ if !(headers = rsp.to_hash["www-authenticate"]).nil? &&
158
+ (h = headers.select { |h| h =~ /^OAuth / }).any? &&
159
+ h.first =~ /oauth_problem/
160
+
161
+ # puts "Header: #{h.first}"
162
+
163
+ # TODO doesn't handle broken responses from api.login.yahoo.com
164
+ # remove debug code when done
165
+ params = OAuth::Helper.parse_header(h.first)
166
+
167
+ # puts "Params: #{params.inspect}"
168
+ # puts "Body: #{rsp.body}"
169
+
170
+ raise OAuth::Problem.new(params.delete("oauth_problem"), rsp, params)
171
+ end
172
+
173
+ rsp
174
+ end
175
+
176
+ # Creates and signs an http request.
177
+ # It's recommended to use the Token classes to set this up correctly
178
+ def create_signed_request(http_method, path, token = nil, request_options = {}, *arguments)
179
+ request = create_http_request(http_method, path, *arguments)
180
+ sign!(request, token, request_options)
181
+ request
182
+ end
183
+
184
+ # Creates a request and parses the result as url_encoded. This is used internally for the RequestToken and AccessToken requests.
185
+ def token_request(http_method, path, token = nil, request_options = {}, *arguments)
186
+ response = request(http_method, path, token, request_options, *arguments)
187
+
188
+ case response.code.to_i
189
+
190
+ when (200..299)
191
+ # symbolize keys
192
+ # TODO this could be considered unexpected behavior; symbols or not?
193
+ # TODO this also drops subsequent values from multi-valued keys
194
+ CGI.parse(response.body).inject({}) do |h,(k,v)|
195
+ h[k.to_sym] = v.first
196
+ h[k] = v.first
197
+ h
198
+ end
199
+ when (300..399)
200
+ # this is a redirect
201
+ response.error!
202
+ when (400..499)
203
+ raise OAuth::Unauthorized, response
204
+ else
205
+ response.error!
206
+ end
207
+ end
208
+
209
+ # Sign the Request object. Use this if you have an externally generated http request object you want to sign.
210
+ def sign!(request, token = nil, request_options = {})
211
+ request.oauth!(http, self, token, options.merge(request_options))
212
+ end
213
+
214
+ # Return the signature_base_string
215
+ def signature_base_string(request, token = nil, request_options = {})
216
+ request.signature_base_string(http, self, token, options.merge(request_options))
217
+ end
218
+
219
+ def site
220
+ @options[:site].to_s
221
+ end
222
+
223
+ def scheme
224
+ @options[:scheme]
225
+ end
226
+
227
+ def request_token_path
228
+ @options[:request_token_path]
229
+ end
230
+
231
+ def authorize_path
232
+ @options[:authorize_path]
233
+ end
234
+
235
+ def access_token_path
236
+ @options[:access_token_path]
237
+ end
238
+
239
+ # TODO this is ugly, rewrite
240
+ def request_token_url
241
+ @options[:request_token_url] || site + request_token_path
242
+ end
243
+
244
+ def request_token_url?
245
+ @options.has_key?(:request_token_url)
246
+ end
247
+
248
+ def authorize_url
249
+ @options[:authorize_url] || site + authorize_path
250
+ end
251
+
252
+ def authorize_url?
253
+ @options.has_key?(:authorize_url)
254
+ end
255
+
256
+ def access_token_url
257
+ @options[:access_token_url] || site + access_token_path
258
+ end
259
+
260
+ def access_token_url?
261
+ @options.has_key?(:access_token_url)
262
+ end
263
+
264
+ def proxy
265
+ @options[:proxy]
266
+ end
267
+
268
+ protected
269
+
270
+ # Instantiates the http object
271
+ def create_http(_url = nil)
272
+ if _url.nil? || _url[0] =~ /^\//
273
+ our_uri = URI.parse(site)
274
+ else
275
+ our_uri = URI.parse(_url)
276
+ end
277
+
278
+ if proxy.nil?
279
+ http_object = Net::HTTP.new(our_uri.host, our_uri.port)
280
+ else
281
+ proxy_uri = proxy.is_a?(URI) ? proxy : URI.parse(proxy)
282
+ http_object = Net::HTTP.new(our_uri.host, our_uri.port, proxy_uri.host, proxy_uri.port, proxy_uri.user, proxy_uri.password)
283
+ end
284
+
285
+ http_object.use_ssl = (our_uri.scheme == 'https')
286
+
287
+ if @options[:ca_file] || CA_FILE
288
+ http_object.ca_file = @options[:ca_file] || CA_FILE
289
+ http_object.verify_mode = OpenSSL::SSL::VERIFY_PEER
290
+ http_object.verify_depth = 5
291
+ else
292
+ http_object.verify_mode = OpenSSL::SSL::VERIFY_NONE
293
+ end
294
+
295
+ http_object
296
+ end
297
+
298
+ # create the http request object for a given http_method and path
299
+ def create_http_request(http_method, path, *arguments)
300
+ http_method = http_method.to_sym
301
+
302
+ if [:post, :put].include?(http_method)
303
+ data = arguments.shift
304
+ data.reject! { |k,v| v.nil? } if data.is_a?(Hash)
305
+ end
306
+
307
+ headers = arguments.first.is_a?(Hash) ? arguments.shift : {}
308
+
309
+ case http_method
310
+ when :post
311
+ request = Net::HTTP::Post.new(path,headers)
312
+ request["Content-Length"] = 0 # Default to 0
313
+ when :put
314
+ request = Net::HTTP::Put.new(path,headers)
315
+ request["Content-Length"] = 0 # Default to 0
316
+ when :get
317
+ request = Net::HTTP::Get.new(path,headers)
318
+ when :delete
319
+ request = Net::HTTP::Delete.new(path,headers)
320
+ when :head
321
+ request = Net::HTTP::Head.new(path,headers)
322
+ else
323
+ raise ArgumentError, "Don't know how to handle http_method: :#{http_method.to_s}"
324
+ end
325
+
326
+ if data.is_a?(Hash)
327
+ request.set_form_data(data)
328
+ elsif data
329
+ if data.respond_to?(:read)
330
+ request.body_stream = data
331
+ if data.respond_to?(:length)
332
+ request["Content-Length"] = data.length
333
+ elsif data.respond_to?(:stat) && data.stat.respond_to?(:size)
334
+ request["Content-Length"] = data.stat.size
335
+ else
336
+ raise ArgumentError, "Don't know how to send a body_stream that doesn't respond to .length or .stat.size"
337
+ end
338
+ else
339
+ request.body = data.to_s
340
+ request["Content-Length"] = request.body.length
341
+ end
342
+ end
343
+
344
+ request
345
+ end
346
+
347
+ # Unset cached http instance because it cannot be marshalled when
348
+ # it has already been used and use_ssl is set to true
349
+ def marshal_dump(*args)
350
+ @http = nil
351
+ self
352
+ end
353
+ end
354
+ end