omnicontacts 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +39 -0
- data/README.md +83 -0
- data/Rakefile +6 -0
- data/lib/omnicontacts.rb +12 -0
- data/lib/omnicontacts/authorization/oauth1.rb +122 -0
- data/lib/omnicontacts/authorization/oauth2.rb +84 -0
- data/lib/omnicontacts/builder.rb +30 -0
- data/lib/omnicontacts/http_utils.rb +88 -0
- data/lib/omnicontacts/importer.rb +9 -0
- data/lib/omnicontacts/importer/gmail.rb +54 -0
- data/lib/omnicontacts/importer/hotmail.rb +46 -0
- data/lib/omnicontacts/importer/yahoo.rb +64 -0
- data/lib/omnicontacts/middleware/base_oauth.rb +97 -0
- data/lib/omnicontacts/middleware/oauth1.rb +68 -0
- data/lib/omnicontacts/middleware/oauth2.rb +66 -0
- data/omnicontacts.gemspec +25 -0
- data/spec/omnicontacts/authorization/oauth1_spec.rb +82 -0
- data/spec/omnicontacts/authorization/oauth2_spec.rb +92 -0
- data/spec/omnicontacts/http_utils_spec.rb +68 -0
- data/spec/omnicontacts/importer/gmail_spec.rb +40 -0
- data/spec/omnicontacts/importer/hotmail_spec.rb +47 -0
- data/spec/omnicontacts/importer/yahoo_spec.rb +42 -0
- data/spec/omnicontacts/middleware/oauth1_spec.rb +71 -0
- data/spec/omnicontacts/middleware/oauth2_spec.rb +62 -0
- data/spec/spec_helper.rb +10 -0
- metadata +139 -0
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
coverage
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
omnicontacts (0.1.0)
|
5
|
+
json
|
6
|
+
rack
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: http://rubygems.org/
|
10
|
+
specs:
|
11
|
+
diff-lcs (1.1.3)
|
12
|
+
json (1.6.5)
|
13
|
+
multi_json (1.1.0)
|
14
|
+
rack (1.4.1)
|
15
|
+
rack-test (0.6.1)
|
16
|
+
rack (>= 1.0)
|
17
|
+
rake (0.9.2.2)
|
18
|
+
rspec (2.8.0)
|
19
|
+
rspec-core (~> 2.8.0)
|
20
|
+
rspec-expectations (~> 2.8.0)
|
21
|
+
rspec-mocks (~> 2.8.0)
|
22
|
+
rspec-core (2.8.0)
|
23
|
+
rspec-expectations (2.8.0)
|
24
|
+
diff-lcs (~> 1.1.2)
|
25
|
+
rspec-mocks (2.8.0)
|
26
|
+
simplecov (0.6.1)
|
27
|
+
multi_json (~> 1.0)
|
28
|
+
simplecov-html (~> 0.5.3)
|
29
|
+
simplecov-html (0.5.3)
|
30
|
+
|
31
|
+
PLATFORMS
|
32
|
+
ruby
|
33
|
+
|
34
|
+
DEPENDENCIES
|
35
|
+
omnicontacts!
|
36
|
+
rack-test
|
37
|
+
rake
|
38
|
+
rspec
|
39
|
+
simplecov
|
data/README.md
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
= OmniContacts
|
2
|
+
|
3
|
+
Inspired by the popular OmniAuth, OmniContacts is a library that enables users of an application to import contacts from their email accounts.
|
4
|
+
The current version allows to import contacts from the three most popular web email providers: Gmail, Yahoo and Hotmail.
|
5
|
+
OmniContacts is a Rack middleware, therefore you can use it with Rails, Sinatra and with any other Rack-based framework.
|
6
|
+
|
7
|
+
OmniContacts uses the OAuth protocol to communicate with the contacts provider. Yahoo still uses OAuth 1.0, while both Gmail and Hotmail support OAuth 2.0.
|
8
|
+
In order to use OmniContacts, it is therefore necessary to first register your application with the providers you want to use and to obtain client_id and client_secret.
|
9
|
+
|
10
|
+
== Usage
|
11
|
+
|
12
|
+
Add OmniContacts as a dependency:
|
13
|
+
```ruby
|
14
|
+
gem "omnicontacts"
|
15
|
+
```
|
16
|
+
|
17
|
+
As for OmniAuth, there is a Builder facilitating the usage of multiple contacts importers. In the case of a Rails application, the following code could be placed at `config/initializers/omnicontacts.rb`:
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
require "omnicontacts"
|
21
|
+
|
22
|
+
Rails.application.middleware.use OmniContacts::Builder do
|
23
|
+
importer :gmail, "client_id", "client_secret", {:redirect_path => "/oauth2callback", :ssl_ca_file => "/etc/ssl/certs/curl-ca-bundle.crt"}
|
24
|
+
importer :yahoo, "consumer_id", "consumer_secret", {:callback_path => '/callback'}
|
25
|
+
importer :hotmail, "client_id", "client_secret"
|
26
|
+
end
|
27
|
+
|
28
|
+
```
|
29
|
+
|
30
|
+
Every importer expects `client_id` and `client_secret` as mandatory, while `:redirect_path` and `:ssl_ca_file` are optional.
|
31
|
+
Since Yahoo implements the version 1.0 of the OAuth protocol, naming is slightly different. Instead of `:redirect_path` you should use `:callback_path` as key in the hash providing the optional parameters.
|
32
|
+
While `:ssl_ca_file` is optional, it is highly recommended to set it on production environments for obvious security reasons.
|
33
|
+
On the other hand it makes things much easier to leave the default value for `:redirect_path` and `:callback path`, the reason of which will be clear after reading the following section.
|
34
|
+
|
35
|
+
== Integrating with your Application
|
36
|
+
|
37
|
+
To use OmniContacts you only need to redirect users to `/contacts/:importer`, where `:importer` can be google, yahoo or hotmail. Once the user has authorized your application, he will be redirected back to your website, to the path specified in `:redirect_path` (or `:callback_path` for yahoo). The user is redirected to `/contacts/:importer/callback` by default, which therefore makes things much simpler to not specify any value for `:redirect_path` or `:callback_path`.
|
38
|
+
The list of contacts can be accessed via the `omnicontacts.contacts` key in the environment hash. The list of contacts is a simple array of hashes. Each hash has two keys: `:email` and `:name`, containing the email and the name of the contact respectively.
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
def contacts_callback
|
42
|
+
@contacts = request.env['omnicontacts.contacts']
|
43
|
+
puts "List of contacts obtained from #{params[:importer]}:"
|
44
|
+
@contacts.each do |contact|
|
45
|
+
puts "Contact found: name => #{contact[:name]}, email => #{contact[:email]}"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
```
|
49
|
+
|
50
|
+
If the user does not authorize your application to access his/her contacts list, or any other inconvenience occurs, he/she is redirected to `/contacts/failure`. The query string will contain a parameter named `error_message` which specifies why the list of contacts could not be retrieved. `error_message` can have one of the following values: `not_authorized`, `timeout` and `internal_error`.
|
51
|
+
|
52
|
+
== Tips and tricks
|
53
|
+
|
54
|
+
OmniContacts supports OAuth 1.0 and OAuth 2.0 token refresh, but for both it needs to persist data between requests. OmniContacts stores access tokens in the session. If you hit the 4KB cookie storage limit you better opt for the Memcache or the Active Record storage.
|
55
|
+
|
56
|
+
Gmail requires you to register the redirect_path on their website along with your application. Make sure to use the same value present in the configuration file, or `/contacts/gmail/callback` if using the default.
|
57
|
+
|
58
|
+
Yahoo requires you to configure the Permissions your application requires. Make sure to go the Yahoo website and to select Read permission for Contacts.
|
59
|
+
|
60
|
+
Hotmail does not accept requests from localhost. This can be quite annoying during development, but unfortunately this is the way it is.
|
61
|
+
Hotmail presents another "peculiar" feature. Their API returns a Contact object, which does not contain an e-mail field! However, if the contact has either name, family name or both set to null, than there is a field called name which does contain the e-mail address. To summarize, a Hotmail contact will only be returned if the name field contains a valid e-mail address, otherwise it will be skipped. Another consequence is that OmniContacts can provide contacts with only the `:email` key set.
|
62
|
+
|
63
|
+
## License
|
64
|
+
|
65
|
+
Copyright (c) 2012 Diego81
|
66
|
+
|
67
|
+
Permission is hereby granted, free of charge, to any person obtaining a
|
68
|
+
copy of this software and associated documentation files (the "Software"),
|
69
|
+
to deal in the Software without restriction, including without limitation
|
70
|
+
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
71
|
+
and/or sell copies of the Software, and to permit persons to whom the
|
72
|
+
Software is furnished to do so, subject to the following conditions:
|
73
|
+
|
74
|
+
The above copyright notice and this permission notice shall be included
|
75
|
+
in all copies or substantial portions of the Software.
|
76
|
+
|
77
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
78
|
+
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
79
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
80
|
+
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
81
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
82
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
83
|
+
DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
data/lib/omnicontacts.rb
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
require "omnicontacts/http_utils"
|
2
|
+
require "base64"
|
3
|
+
|
4
|
+
# This module represent a OAuth 1.0 Client.
|
5
|
+
#
|
6
|
+
# Classes including the module must implement
|
7
|
+
# the following methods:
|
8
|
+
# * auth_host -> the host of the authorization server
|
9
|
+
# * auth_token_path -> the path to query to obtain a request token
|
10
|
+
# * consumer_key -> the registered consumer key of the client
|
11
|
+
# * consumer_secret -> the registered consumer secret of the client
|
12
|
+
# * callback -> the callback to include during the redirection step
|
13
|
+
# * auth_path -> the path on the authorization server to redirect the user to
|
14
|
+
# * access_token_path -> the path to query in order to obtain the access token
|
15
|
+
module OmniContacts
|
16
|
+
module Authorization
|
17
|
+
module OAuth1
|
18
|
+
include HTTPUtils
|
19
|
+
|
20
|
+
OAUTH_VERSION = "1.0"
|
21
|
+
|
22
|
+
# Obtain an authorization token from the server.
|
23
|
+
# The token is returned in an array along with the relative authorization token secret.
|
24
|
+
def fetch_authorization_token
|
25
|
+
request_token_response = https_post(auth_host, auth_token_path, request_token_req_params)
|
26
|
+
values_from_query_string(request_token_response, ["oauth_token", "oauth_token_secret"])
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def request_token_req_params
|
32
|
+
{
|
33
|
+
:oauth_consumer_key => consumer_key,
|
34
|
+
:oauth_nonce => encode(random_string),
|
35
|
+
:oauth_signature_method => "PLAINTEXT",
|
36
|
+
:oauth_signature => encode(consumer_secret + "&"),
|
37
|
+
:oauth_timestamp => timestamp,
|
38
|
+
:oauth_version => OAUTH_VERSION,
|
39
|
+
:oauth_callback => callback
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
def random_string
|
44
|
+
(0...50).map{ ('a'..'z').to_a[rand(26)] }.join
|
45
|
+
end
|
46
|
+
|
47
|
+
def timestamp
|
48
|
+
Time.now.to_i.to_s
|
49
|
+
end
|
50
|
+
|
51
|
+
def values_from_query_string query_string, keys_to_extract
|
52
|
+
map = query_string_to_map(query_string)
|
53
|
+
keys_to_extract.collect do |key|
|
54
|
+
if map.has_key?(key)
|
55
|
+
map[key]
|
56
|
+
else
|
57
|
+
raise "No value found for #{key} in #{query_string}"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
public
|
63
|
+
|
64
|
+
# Returns the url the user has to be redirected to do in order grant permission to the client application.
|
65
|
+
def authorization_url auth_token
|
66
|
+
"https://" + auth_host + auth_path + "?oauth_token=" + auth_token
|
67
|
+
end
|
68
|
+
|
69
|
+
# Fetches the access token from the authorization server.
|
70
|
+
# The method expects the authorization token, the authorization token secret and the authorization verifier.
|
71
|
+
# The result comprises the access token, the access token secret and a list of additional fields extracted from the server's response.
|
72
|
+
# The list of additional fields to extract is specified as last parameter
|
73
|
+
def fetch_access_token auth_token, auth_token_secret, auth_verifier, additional_fields_to_extract = []
|
74
|
+
access_token_resp = https_post(auth_host, access_token_path, access_token_req_params(auth_token, auth_token_secret, auth_verifier))
|
75
|
+
values_from_query_string(access_token_resp, ( ["oauth_token", "oauth_token_secret"] + additional_fields_to_extract) )
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
def access_token_req_params auth_token, auth_token_secret, auth_verifier
|
81
|
+
{
|
82
|
+
:oauth_consumer_key => consumer_key,
|
83
|
+
:oauth_nonce => encode(random_string),
|
84
|
+
:oauth_signature_method => "PLAINTEXT",
|
85
|
+
:oauth_signature => encode(consumer_secret + "&" + auth_token_secret),
|
86
|
+
:oauth_version => OAUTH_VERSION,
|
87
|
+
:oauth_timestamp => timestamp,
|
88
|
+
:oauth_token => auth_token,
|
89
|
+
:oauth_verifier => auth_verifier
|
90
|
+
}
|
91
|
+
end
|
92
|
+
|
93
|
+
public
|
94
|
+
|
95
|
+
# Calculates a signature using HMAC-SHA1 according to the OAuth 1.0 specifications.
|
96
|
+
#
|
97
|
+
# The base string is given is a RFC 3986 encoded concatenation of:
|
98
|
+
# * Uppercase HTTP method
|
99
|
+
# * An '&'
|
100
|
+
# * A url without any parameters
|
101
|
+
# * An '&'
|
102
|
+
# * All parameters to use in the request encoded themselves and sorted by key.
|
103
|
+
#
|
104
|
+
# The signature key is given by the concatenation of:
|
105
|
+
# * RFC 3986 encoded consumer secret
|
106
|
+
# * An '&'
|
107
|
+
# * RFC 3986 encoded token secret
|
108
|
+
def oauth_signature method, url, params, secret
|
109
|
+
encoded_method = encode(method.upcase)
|
110
|
+
encoded_url = encode(url)
|
111
|
+
# params must be in alphabetical order
|
112
|
+
encoded_params = encode(to_query_string(params.sort))
|
113
|
+
base_string = encoded_method + '&' + encoded_url + '&' + encoded_params
|
114
|
+
key = encode(consumer_secret) + '&' + secret
|
115
|
+
hmac_sha1 = OpenSSL::HMAC.digest('sha1', key, base_string)
|
116
|
+
# base64 encode results must be stripped
|
117
|
+
encode(Base64.encode64(hmac_sha1).strip)
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require "omnicontacts/http_utils"
|
2
|
+
require "json"
|
3
|
+
|
4
|
+
# This module represents an OAuth 2.0 client.
|
5
|
+
#
|
6
|
+
# Classes including the module must implement
|
7
|
+
# the following methods:
|
8
|
+
# * auth_host -> the host of the authorization server
|
9
|
+
# * authorize_path -> the path on the authorization server the redirect the use to
|
10
|
+
# * client_id -> the registered client id of the client
|
11
|
+
# * client_secret -> the registered client secret of the client
|
12
|
+
# * redirect_path -> the path the authorization server has to redirect the user back after authorization
|
13
|
+
# * auth_token_path -> the path to query once the user has granted permission to the application
|
14
|
+
# * scope -> the scope necessary to acquire the contacts list.
|
15
|
+
module OmniContacts
|
16
|
+
module Authorization
|
17
|
+
module OAuth2
|
18
|
+
include HTTPUtils
|
19
|
+
|
20
|
+
# Calculates the URL the user has to be redirected to in order to authorize
|
21
|
+
# the application to access his contacts list.
|
22
|
+
def authorization_url
|
23
|
+
"https://" + auth_host + authorize_path + "?" + authorize_url_params
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def authorize_url_params
|
29
|
+
to_query_string({
|
30
|
+
:client_id => client_id,
|
31
|
+
:scope => encode(scope),
|
32
|
+
:response_type => "code",
|
33
|
+
:access_type => "offline",
|
34
|
+
:approval_prompt => "force",
|
35
|
+
:redirect_uri => encode(redirect_uri)
|
36
|
+
})
|
37
|
+
end
|
38
|
+
|
39
|
+
public
|
40
|
+
|
41
|
+
# Fetches the access token from the authorization server using the given authorization code.
|
42
|
+
def fetch_access_token code
|
43
|
+
access_token_from_response https_post(auth_host, auth_token_path, token_req_params(code))
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def token_req_params code
|
49
|
+
{
|
50
|
+
:client_id => client_id,
|
51
|
+
:client_secret => client_secret,
|
52
|
+
:code => code,
|
53
|
+
:redirect_uri => encode(redirect_uri),
|
54
|
+
:grant_type => "authorization_code"
|
55
|
+
}
|
56
|
+
end
|
57
|
+
|
58
|
+
def access_token_from_response response
|
59
|
+
json = JSON.parse(response)
|
60
|
+
raise json["error"] if json["error"]
|
61
|
+
[ json["access_token"], json["token_type"], json["refresh_token"] ]
|
62
|
+
end
|
63
|
+
|
64
|
+
public
|
65
|
+
|
66
|
+
# Refreshes the access token using the provided refresh_token.
|
67
|
+
def refresh_access_token refresh_token
|
68
|
+
access_token_from_response https_post(auth_host, auth_token_path, refresh_token_req_params(refresh_token))
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def refresh_token_req_params refresh_token
|
74
|
+
{
|
75
|
+
:client_id => client_id,
|
76
|
+
:client_secret => client_secret,
|
77
|
+
:refresh_token => refresh_token,
|
78
|
+
:grant_type => "refresh_token"
|
79
|
+
}
|
80
|
+
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require "omnicontacts"
|
2
|
+
|
3
|
+
module OmniContacts
|
4
|
+
class Builder < Rack::Builder
|
5
|
+
def initialize(app,&block)
|
6
|
+
if rack14?
|
7
|
+
super
|
8
|
+
else
|
9
|
+
@app = app
|
10
|
+
super(&block)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def rack14?
|
15
|
+
Rack.release.split('.')[1].to_i >= 4
|
16
|
+
end
|
17
|
+
|
18
|
+
def importer importer, *args
|
19
|
+
middleware = OmniContacts::Importer.const_get(importer.to_s.capitalize)
|
20
|
+
use middleware, *args
|
21
|
+
rescue NameError
|
22
|
+
raise LoadError, "Could not find importer #{importer}."
|
23
|
+
end
|
24
|
+
|
25
|
+
def call env
|
26
|
+
@ins << @app unless @ins.include?(@app)
|
27
|
+
to_app.call(env)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require "net/http"
|
2
|
+
require "cgi"
|
3
|
+
require "openssl"
|
4
|
+
|
5
|
+
# This module contains a set of utility methods related to the HTTP protocol.
|
6
|
+
module OmniContacts
|
7
|
+
module HTTPUtils
|
8
|
+
|
9
|
+
SSL_PORT = 443
|
10
|
+
|
11
|
+
module_function
|
12
|
+
|
13
|
+
def query_string_to_map query_string
|
14
|
+
query_string.split('&').reduce({}) do |memo, key_value|
|
15
|
+
(key,value) = key_value.split('=')
|
16
|
+
memo[key]= value
|
17
|
+
memo
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_query_string map
|
22
|
+
map.collect do |key, value|
|
23
|
+
key.to_s + "=" + value
|
24
|
+
end.join("&")
|
25
|
+
end
|
26
|
+
|
27
|
+
# Encodes the given input according to RFC 3986
|
28
|
+
def encode to_encode
|
29
|
+
CGI.escape(to_encode)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Calculates the url of the host from a Rack environment.
|
33
|
+
# The result is in the form scheme://host:port
|
34
|
+
# If port is 80 the result is scheme://host
|
35
|
+
# According to Rack specification the HTTP_HOST variable is preferred over SERVER_NAME.
|
36
|
+
def host_url_from_rack_env env
|
37
|
+
port = ( (env["SERVER_PORT"] == 80) && "") || ":#{env['SERVER_PORT']}"
|
38
|
+
host = (env["HTTP_HOST"]) || (env["SERVER_NAME"] + port)
|
39
|
+
env["rack.url_scheme"] + "://" + host
|
40
|
+
end
|
41
|
+
|
42
|
+
# Classes including the module must respond to the ssl_ca_file message in order to use the following methods.
|
43
|
+
# The response will be the path to the CA file to use when making https requests.
|
44
|
+
# If the result of ssl_ca_file is nil no file is used. In this case a warn message is logged.
|
45
|
+
private
|
46
|
+
|
47
|
+
# Executes an HTTP GET request.
|
48
|
+
# It raises a RuntimeError if the response code is not equal to 200
|
49
|
+
def http_get host, path, params
|
50
|
+
connection = Net::HTTP.new(host)
|
51
|
+
process_http_response connection.request_get(path + "?" + to_query_string(params))
|
52
|
+
end
|
53
|
+
|
54
|
+
# Executes an HTTP POST request over SSL
|
55
|
+
# It raises a RuntimeError if the response code is not equal to 200
|
56
|
+
def https_post host,path, params
|
57
|
+
https_connection host do |connection|
|
58
|
+
connection.request_post(path, to_query_string(params))
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# Executes an HTTP GET request over SSL
|
63
|
+
# It raises a RuntimeError if the response code is not equal to 200
|
64
|
+
def https_get host, path, params, headers =[]
|
65
|
+
https_connection host do |connection|
|
66
|
+
connection.request_get(path + "?" + to_query_string(params), headers)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def https_connection (host)
|
71
|
+
connection = Net::HTTP.new(host, SSL_PORT)
|
72
|
+
connection.use_ssl = true
|
73
|
+
if ssl_ca_file
|
74
|
+
connection.ca_file = ssl_ca_file
|
75
|
+
else
|
76
|
+
logger << "No SSL ca file provided. It is highly reccomended to use one in production envinronments" if respond_to?(:logger) && logger
|
77
|
+
connection.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
78
|
+
end
|
79
|
+
process_http_response(yield(connection))
|
80
|
+
end
|
81
|
+
|
82
|
+
def process_http_response response
|
83
|
+
raise response.body if response.code != "200"
|
84
|
+
response.body
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
end
|