cryx-rest-client 0.9.1 → 0.9.2
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/Rakefile +1 -1
- data/lib/restclient.rb +0 -1
- data/lib/restclient/request.rb +8 -2
- data/lib/restclient/resource.rb +12 -0
- data/lib/restclient/response.rb +0 -46
- data/rest-client.gemspec +1 -1
- data/spec/request_spec.rb +16 -0
- data/spec/response_spec.rb +0 -61
- metadata +2 -2
data/Rakefile
CHANGED
data/lib/restclient.rb
CHANGED
@@ -8,7 +8,6 @@ require File.dirname(__FILE__) + '/restclient/logging'
|
|
8
8
|
require File.dirname(__FILE__) + '/restclient/request'
|
9
9
|
require File.dirname(__FILE__) + '/restclient/response'
|
10
10
|
require File.dirname(__FILE__) + '/restclient/resource'
|
11
|
-
require File.dirname(__FILE__) + '/restclient/cacheable_resource'
|
12
11
|
require File.dirname(__FILE__) + '/restclient/exceptions'
|
13
12
|
|
14
13
|
|
data/lib/restclient/request.rb
CHANGED
@@ -7,7 +7,7 @@ module RestClient
|
|
7
7
|
#
|
8
8
|
class Request
|
9
9
|
include Logging
|
10
|
-
attr_reader :method, :url, :payload, :headers, :cookies, :user, :password, :timeout, :open_timeout
|
10
|
+
attr_reader :method, :url, :payload, :headers, :cookies, :user, :password, :timeout, :open_timeout, :ssl
|
11
11
|
|
12
12
|
def self.execute(args)
|
13
13
|
new(args).execute
|
@@ -23,6 +23,7 @@ module RestClient
|
|
23
23
|
@password = args[:password]
|
24
24
|
@timeout = args[:timeout]
|
25
25
|
@open_timeout = args[:open_timeout]
|
26
|
+
@ssl = args[:ssl] || {}
|
26
27
|
end
|
27
28
|
|
28
29
|
def execute
|
@@ -95,7 +96,12 @@ module RestClient
|
|
95
96
|
|
96
97
|
net = net_http_class.new(uri.host, uri.port)
|
97
98
|
net.use_ssl = uri.is_a?(URI::HTTPS)
|
98
|
-
net.
|
99
|
+
if net.use_ssl?
|
100
|
+
net.verify_mode = ssl[:verify_mode] || OpenSSL::SSL::VERIFY_NONE
|
101
|
+
net.ca_file = ssl[:ca_file] if ssl[:ca_file]
|
102
|
+
net.cert = ssl[:cert] if ssl[:cert]
|
103
|
+
net.key = ssl[:key] if ssl[:key]
|
104
|
+
end
|
99
105
|
net.read_timeout = @timeout if @timeout
|
100
106
|
net.open_timeout = @open_timeout if @open_timeout
|
101
107
|
|
data/lib/restclient/resource.rb
CHANGED
@@ -12,6 +12,18 @@ module RestClient
|
|
12
12
|
# resource = RestClient::Resource.new('http://protected/resource', :user => 'user', :password => 'password')
|
13
13
|
# resource.delete
|
14
14
|
#
|
15
|
+
# With SSL Client Certificates:
|
16
|
+
#
|
17
|
+
# key = OpenSSL::PKey::RSA.new( File.open("mykey.pem").read, "mypassphrase or nil for interactive prompt" )
|
18
|
+
# cert = OpenSSL::X509::Certificate.new( File.open("mycert.pem").read )
|
19
|
+
# ca_file = "CAcert.pem"
|
20
|
+
# resource = RestClient::Resource.new('https://protected/resource', :ssl => {:key => key, :cert => cert, :ca_file => ca_file, :verify_mode => OpenSSL::SSL::VERIFY_PEER})
|
21
|
+
# resource.delete
|
22
|
+
#
|
23
|
+
# or (without peer verification):
|
24
|
+
# resource = RestClient::Resource.new('https://protected/resource', :ssl => {:key => key, :cert => cert})
|
25
|
+
# resource.delete
|
26
|
+
#
|
15
27
|
# With a timeout (seconds):
|
16
28
|
#
|
17
29
|
# RestClient::Resource.new('http://slow', :timeout => 10)
|
data/lib/restclient/response.rb
CHANGED
@@ -9,15 +9,6 @@ module RestClient
|
|
9
9
|
include Logging
|
10
10
|
attr_reader :net_http_res
|
11
11
|
|
12
|
-
# the headers that makes a response cacheable
|
13
|
-
REQUIRED_HEADERS = [
|
14
|
-
[:date, :last_modified], [:date, :expires_value], [:date, :cache_control], [:etag]
|
15
|
-
].freeze
|
16
|
-
|
17
|
-
REGEXP = {
|
18
|
-
:max_age => /max-age\s?=\s?(\d+)/
|
19
|
-
}.freeze
|
20
|
-
|
21
12
|
def initialize(string, net_http_res)
|
22
13
|
@net_http_res = net_http_res
|
23
14
|
super(string || "")
|
@@ -52,42 +43,5 @@ module RestClient
|
|
52
43
|
out
|
53
44
|
end
|
54
45
|
end
|
55
|
-
|
56
|
-
# Checks if the response is still fresh by comparing its current age to the max allowed age or the expires value.
|
57
|
-
# http://tools.ietf.org/html/rfc2616#section-13.2.3
|
58
|
-
def fresh?(options = {})
|
59
|
-
date_value = Time.parse(headers[:date]) rescue nil
|
60
|
-
return false if date_value.nil?
|
61
|
-
local_response_time = headers[:local_response_time] || date_value
|
62
|
-
local_request_time = headers[:local_request_time] || date_value
|
63
|
-
age_value = headers[:age].to_i rescue 0
|
64
|
-
expires_value = Time.parse(headers[:expires]) rescue nil
|
65
|
-
max_age_value = headers[:cache_control].scan(REGEXP[:max_age]).flatten[0].to_i rescue nil
|
66
|
-
user_max_age = options[:cache_control].scan(REGEXP[:max_age]).flatten[0].to_i rescue nil
|
67
|
-
# age calculation
|
68
|
-
apparent_age = [0, local_response_time - date_value].max
|
69
|
-
corrected_received_age = [apparent_age, age_value].max
|
70
|
-
response_delay = local_response_time - local_request_time;
|
71
|
-
corrected_initial_age = corrected_received_age + response_delay;
|
72
|
-
resident_time = Time.now - local_response_time;
|
73
|
-
current_age = corrected_initial_age + resident_time;
|
74
|
-
max_age = max_age_value ? (user_max_age ? [max_age_value, user_max_age].min : max_age_value) : (user_max_age ? user_max_age : nil)
|
75
|
-
if max_age then current_age < max_age
|
76
|
-
elsif expires_value then current_age < (expires_value - date_value)
|
77
|
-
else false; end
|
78
|
-
end
|
79
|
-
|
80
|
-
# Checks if the response is cacheable by comparing its headers to the set of headers that make a response cacheable.
|
81
|
-
# See the REQUIRED_HEADERS constant for more information
|
82
|
-
def cacheable?
|
83
|
-
REQUIRED_HEADERS.each do |required_headers|
|
84
|
-
available_headers = headers.keys & required_headers
|
85
|
-
has_required_headers = available_headers.length == required_headers.length
|
86
|
-
required_headers_are_not_empty = !headers.values_at(*available_headers).map{|value| value.nil? || value.empty?}.include?(true)
|
87
|
-
return true if has_required_headers && required_headers_are_not_empty
|
88
|
-
end
|
89
|
-
display_log "# [cache] the response is not cacheable"
|
90
|
-
false
|
91
|
-
end
|
92
46
|
end
|
93
47
|
end
|
data/rest-client.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "rest-client"
|
3
|
-
s.version = "0.9.
|
3
|
+
s.version = "0.9.2"
|
4
4
|
s.summary = "Simple REST client for Ruby, inspired by microframework syntax for specifying actions."
|
5
5
|
s.description = "A simple REST client for Ruby, inspired by the Sinatra microframework style of specifying actions: get, put, post, delete."
|
6
6
|
s.author = "Adam Wiggins"
|
data/spec/request_spec.rb
CHANGED
@@ -14,6 +14,7 @@ describe RestClient::Request do
|
|
14
14
|
Net::HTTP.stub!(:new).and_return(@net)
|
15
15
|
@net.stub!(:start).and_yield(@http)
|
16
16
|
@net.stub!(:use_ssl=)
|
17
|
+
@net.stub!(:use_ssl?)
|
17
18
|
@net.stub!(:verify_mode=)
|
18
19
|
end
|
19
20
|
|
@@ -135,6 +136,21 @@ describe RestClient::Request do
|
|
135
136
|
@request.transmit(@uri, 'req', 'payload')
|
136
137
|
end
|
137
138
|
|
139
|
+
it "uses the key, cert, ca_file and verify_mode provided by the user when SSL is used" do
|
140
|
+
@uri.stub!(:is_a?).with(URI::HTTPS).and_return(true)
|
141
|
+
ssl = {:ca_file => mock('ca_file'), :key => mock('key'), :cert => mock('cert'), :verify_mode => OpenSSL::SSL::VERIFY_PEER}
|
142
|
+
@net.should_receive(:use_ssl?).and_return(true)
|
143
|
+
@net.should_receive(:ca_file=).with(ssl[:ca_file])
|
144
|
+
@net.should_receive(:key=).with(ssl[:key])
|
145
|
+
@net.should_receive(:cert=).with(ssl[:cert])
|
146
|
+
@net.should_receive(:verify_mode=).with(ssl[:verify_mode])
|
147
|
+
@http.stub!(:request)
|
148
|
+
@request.stub!(:ssl).and_return(ssl)
|
149
|
+
@request.stub!(:process_result)
|
150
|
+
@request.stub!(:response_log)
|
151
|
+
@request.transmit(@uri, 'req', 'payload')
|
152
|
+
end
|
153
|
+
|
138
154
|
it "sends nil payloads" do
|
139
155
|
@http.should_receive(:request).with('req', nil)
|
140
156
|
@request.should_receive(:process_result)
|
data/spec/response_spec.rb
CHANGED
@@ -38,67 +38,6 @@ describe RestClient::Response do
|
|
38
38
|
it "can access the net http result directly" do
|
39
39
|
@response.net_http_res.should == @net_http_res
|
40
40
|
end
|
41
|
-
|
42
|
-
context "response cacheability" do
|
43
|
-
it "should not be cacheable if the headers do not contain freshness or validation information" do
|
44
|
-
@response.stub!(:headers).and_return({})
|
45
|
-
@response.should_not be_cacheable
|
46
|
-
end
|
47
|
-
it "should be cacheable if the headers include at least an etag (not empty)" do
|
48
|
-
@response.stub!(:headers).and_return({:etag => 'whatever'})
|
49
|
-
@response.should be_cacheable
|
50
|
-
end
|
51
|
-
it "should be cacheable if the headers include at least the date and last-modified values (not empty)" do
|
52
|
-
@response.stub!(:headers).and_return(basic_headers.merge( {:last_modified => (Time.now-10).httpdate} ))
|
53
|
-
@response.should be_cacheable
|
54
|
-
end
|
55
|
-
it "should not be cacheable (last-modified not empty but date not valid)" do
|
56
|
-
@response.stub!(:headers).and_return( {:last_modified => (Time.now-10).httpdate} )
|
57
|
-
@response.should_not be_cacheable
|
58
|
-
end
|
59
|
-
it "should not be cacheable (date OK but last-modified empty)" do
|
60
|
-
@response.stub!(:headers).and_return( {:date => (Time.now-10).httpdate, :last_modified => nil} )
|
61
|
-
@response.should_not be_cacheable
|
62
|
-
end
|
63
|
-
it "should not be cacheable (date OK but expires empty)" do
|
64
|
-
@response.stub!(:headers).and_return( {:date => (Time.now-10).httpdate, :expires => nil} )
|
65
|
-
@response.should_not be_cacheable
|
66
|
-
end
|
67
|
-
it "should not be cacheable (expires OK but date empty)" do
|
68
|
-
@response.stub!(:headers).and_return( {:date => nil, :expires => (Time.now+10).httpdate} )
|
69
|
-
@response.should_not be_cacheable
|
70
|
-
end
|
71
|
-
end
|
72
|
-
context "response freshness" do
|
73
|
-
it "should not be fresh if there is no Date header" do
|
74
|
-
@response.stub!(:headers).and_return(basic_headers.merge( {:date => nil} ))
|
75
|
-
@response.should_not be_fresh
|
76
|
-
end
|
77
|
-
it "should be fresh if Expires is in the future" do
|
78
|
-
@response.stub!(:headers).and_return(basic_headers.merge({:expires => (Time.now+1).httpdate}))
|
79
|
-
@response.should be_fresh
|
80
|
-
end
|
81
|
-
it "should not be fresh if Expires is in the past" do
|
82
|
-
@response.stub!(:headers).and_return(basic_headers.merge({:expires => (Time.now-1).httpdate}))
|
83
|
-
@response.should_not be_fresh
|
84
|
-
end
|
85
|
-
it "should not be fresh if its current age is greater than or equal to the max-age allowed" do
|
86
|
-
@response.stub!(:headers).and_return(basic_headers.merge({:date => (Time.now-10).httpdate, :cache_control => 'max-age=10'}))
|
87
|
-
@response.should_not be_fresh
|
88
|
-
end
|
89
|
-
it "should be fresh if its current age is lower than the max-age allowed" do
|
90
|
-
@response.stub!(:headers).and_return(basic_headers.merge({:date => (Time.now-10).httpdate, :cache_control => 'max-age=11'}))
|
91
|
-
@response.should be_fresh
|
92
|
-
end
|
93
|
-
it "should not be fresh if its current age is greater than the user defined max-age" do
|
94
|
-
@response.stub!(:headers).and_return(basic_headers.merge({:date => (Time.now-10).httpdate, :cache_control => 'max-age=11'}))
|
95
|
-
@response.should_not be_fresh(:cache_control => 'max-age=10')
|
96
|
-
end
|
97
|
-
it "should not be fresh even if the user defined max-age is greater than the response max-age" do
|
98
|
-
@response.stub!(:headers).and_return(basic_headers.merge({:date => (Time.now-10).httpdate, :cache_control => 'max-age=10'}))
|
99
|
-
@response.should_not be_fresh(:cache_control => 'max-age=11')
|
100
|
-
end
|
101
|
-
end
|
102
41
|
|
103
42
|
it "accepts nil strings and sets it to empty for the case of HEAD" do
|
104
43
|
RestClient::Response.new(nil, @net_http_res).should == ""
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cryx-rest-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adam Wiggins
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-02-
|
12
|
+
date: 2009-02-25 00:00:00 -08:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|