resterl 0.0.14 → 0.0.15

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e927695ca56a351455ca5ea51eab5201f4663ba3
4
- data.tar.gz: 24d36643d33e40fe72f08496b27874bb8cccb1bd
3
+ metadata.gz: 065a5323c4a08bb01e76e6985f2d7c119633526b
4
+ data.tar.gz: b2d8eee11d66bdecb0c7cf82ab86ba4c48062965
5
5
  SHA512:
6
- metadata.gz: d3c59e6dd212727d2c538d5fe1cc530eef15d45303c385c8f273f0df8977d1e8800022eb760aaeb399e0dc20454f5c581fecb1a327f07c77d26339d2015bad88
7
- data.tar.gz: 34313e88f25883f86d235fca6c5467a0b124c3d07f4493643e1941ae7e553510ae314cfd0f36d120bc7dd3341f16b35e7084d91dded394176ddbf0083be39006
6
+ metadata.gz: 986afceceddfdc2fb116c3a4fdc7c2d0653b80c66bf52487d472f4ce12f2b0b943a7485eb7675f98ab9bcd60390067268bbdda00aa60b621012880a0a0f449d4
7
+ data.tar.gz: 19ea49a89a3022dc99ad064b83c4a9ac3501c9d5000ea34fbb159919ac8c84250f296cff78ea9db116360d3d8e6302cb6a8ada33fa58d19db2fcb56164aa1fb8
@@ -66,38 +66,33 @@ module Resterl
66
66
  private
67
67
 
68
68
  def new_get_request url, cache_key, params, headers, old_response
69
- # Ggf. ETag und Last-Modified auslesen
70
- if old_response
71
- etag = old_response.net_http_response['ETag']
72
- headers['If-None-Match'] = etag if etag
73
-
74
- last_modified = old_response.net_http_response['Last-Modified']
75
- headers['If-Modified-Since'] = last_modified if last_modified
76
- end
69
+ apply_conditional_headers(headers, old_response)
77
70
 
78
71
  # Anfrage stellen, ggf. ETag mit übergeben
79
72
  request = Resterl::GetRequest.new(self, url, params, headers)
80
73
  new_response = request.perform.response
81
74
 
82
- response, max_age_seconds = case new_response
83
- when Net::HTTPClientError,
84
- Net::HTTPServerError
85
- # Aus dem Cache muss nichts entfernt werden,
86
- # weil ja auch kein Eintrag (mehr) drin ist.
87
- new_response.error!
88
- when Net::HTTPNotModified
89
- # Wenn "304 Not Modified", dann altes
90
- # Ergebnis als neues Ergebnis verwenden
91
- r_temp = Resterl::Response.new(new_response)
92
- old_response.update_expires_at(
93
- r_temp.expires_at)
94
- [old_response, r_temp.expires_at - Time.now]
95
- when Net::HTTPSuccess
96
- r = Resterl::Response.new(new_response)
97
- [r, r.expires_at - Time.now]
98
- else
99
- raise 'unknown response'
100
- end
75
+ response, max_age_seconds =
76
+ case new_response
77
+ when Net::HTTPClientError,
78
+ Net::HTTPServerError
79
+ # Aus dem Cache muss nichts entfernt werden,
80
+ # weil ja auch kein Eintrag (mehr) drin ist.
81
+ new_response.error!
82
+ when Net::HTTPNotModified
83
+ # Wenn "304 Not Modified", dann altes
84
+ # Ergebnis als neues Ergebnis verwenden
85
+ r_temp = Resterl::Response.new(new_response)
86
+ old_response.update_expires_at(
87
+ r_temp.expires_at)
88
+ [old_response, r_temp.expires_at - Time.now]
89
+ when Net::HTTPSuccess
90
+ r = Resterl::Response.new(new_response,
91
+ options[:minimum_cache_lifetime])
92
+ [r, r.expires_at - Time.now]
93
+ else
94
+ raise 'unknown response'
95
+ end
101
96
 
102
97
  # Cachezeit berechnen
103
98
  expiry = [
@@ -111,6 +106,16 @@ module Resterl
111
106
  response
112
107
  end
113
108
 
109
+ # Ggf. ETag und Last-Modified auslesen
110
+ def apply_conditional_headers(headers, old_response)
111
+ return unless old_response
112
+ etag = old_response.net_http_response['ETag']
113
+ headers['If-None-Match'] = etag if etag
114
+
115
+ last_modified = old_response.net_http_response['Last-Modified']
116
+ headers['If-Modified-Since'] = last_modified if last_modified
117
+ end
118
+
114
119
  def setup_url url
115
120
  if url =~ /^http/
116
121
  url
@@ -6,7 +6,7 @@ class Resterl::DeleteRequest < Resterl::GenericRequest
6
6
  @data = data
7
7
  end
8
8
  def perform
9
- http, path = get_http_object_and_query_path
9
+ http, path = http_object_and_query_path
10
10
  request = Net::HTTP::Delete.new path, @headers
11
11
  apply_basic_auth request
12
12
  self.response = http.request(request)
@@ -1,45 +1,53 @@
1
- class Resterl::GenericRequest
2
- attr_accessor :rest_client, :url, :body, :response
3
- DEFAULT_HEADERS = {}
4
-
5
- def initialize client, url, query_params, headers
6
- @rest_client = client
7
- @url = url
8
- @query_params = query_params
9
- @headers = DEFAULT_HEADERS.merge headers
10
- end
11
-
12
- private
13
-
14
- def get_http_object_and_query_path
15
- uri = URI.parse(url)
16
- http = Net::HTTP.new(uri.host, uri.port)
17
- apply_ssl http, uri
18
-
19
- path_with_query = uri.path
20
- path_with_query << "?#{query_param_string}" unless query_param_string.blank?
21
-
22
- [http, path_with_query]
23
- end
24
-
25
- def query_param_string
26
- @query_param_string ||= begin
27
- @query_params.collect do |key, value|
28
- "#{URI.escape(key.to_s)}=#{URI.escape(value.to_s)}"
29
- end.join('&')
1
+ require 'active_support/core_ext/object/blank'
2
+
3
+ module Resterl
4
+ class GenericRequest
5
+ attr_accessor :rest_client, :url, :body, :response
6
+ DEFAULT_HEADERS = {}
7
+
8
+ def initialize client, url, query_params, headers
9
+ @rest_client = client
10
+ @url = url
11
+ @query_params = query_params
12
+ @headers = DEFAULT_HEADERS.merge headers
30
13
  end
31
- end
32
- def apply_basic_auth request
33
- ba = rest_client.options[:basic_auth]
34
- request.basic_auth(ba[:username], ba[:password]) if ba
35
- end
36
- def apply_ssl http, uri
37
- if uri.is_a? URI::HTTPS
14
+
15
+ private
16
+
17
+ def http_object_and_query_path
18
+ uri = URI.parse(url)
19
+ http = Net::HTTP.new(uri.host, uri.port)
20
+ apply_ssl http, uri
21
+
22
+ path_with_query = uri.path
23
+ unless query_param_string.blank?
24
+ path_with_query << "?#{query_param_string}"
25
+ end
26
+
27
+ [http, path_with_query]
28
+ end
29
+
30
+ def query_param_string
31
+ @query_param_string ||= begin
32
+ @query_params.collect do |key, value|
33
+ "#{URI.escape(key.to_s)}=#{URI.escape(value.to_s)}"
34
+ end.join('&')
35
+ end
36
+ end
37
+
38
+ def apply_basic_auth request
39
+ ba = rest_client.options[:basic_auth]
40
+ request.basic_auth(ba[:username], ba[:password]) if ba
41
+ end
42
+
43
+ def apply_ssl http, uri
44
+ return unless uri.is_a? URI::HTTPS
38
45
  http.use_ssl = true
39
46
  http.verify_mode = rest_client.options[:ssl_verify_mode]
40
47
  end
48
+
49
+ def redirect_url
50
+ response['location'] || response.body.match(/<a href=\"([^>]+)\">/i)[1]
51
+ end
41
52
  end
42
- def redirect_url
43
- response['location'] || response.body.match(/<a href=\"([^>]+)\">/i)[1]
44
- end
45
53
  end
@@ -11,7 +11,7 @@ class Resterl::GetRequest < Resterl::GenericRequest
11
11
  def perform
12
12
  raise TooManyRedirects if redirect_limit < 0
13
13
 
14
- http, path = get_http_object_and_query_path
14
+ http, path = http_object_and_query_path
15
15
  request = Net::HTTP::Get.new path, @headers
16
16
  apply_basic_auth request
17
17
  self.response = http.request(request)
@@ -4,7 +4,7 @@ class Resterl::PostRequest < Resterl::GenericRequest
4
4
  @data = data
5
5
  end
6
6
  def perform
7
- http, path = get_http_object_and_query_path
7
+ http, path = http_object_and_query_path
8
8
  request = Net::HTTP::Post.new path, @headers
9
9
  apply_basic_auth request
10
10
  request.body = @data
@@ -6,7 +6,7 @@ class Resterl::PutRequest < Resterl::GenericRequest
6
6
  @data = data
7
7
  end
8
8
  def perform
9
- http, path = get_http_object_and_query_path
9
+ http, path = http_object_and_query_path
10
10
  request = Net::HTTP::Put.new path, @headers
11
11
  apply_basic_auth request
12
12
  request.body = @data
@@ -1,33 +1,36 @@
1
- class Resterl::Response
2
- attr_reader :body, :expires_at, :net_http_response
1
+ module Resterl
2
+ class Response
3
+ attr_reader :body, :expires_at, :net_http_response
3
4
 
4
- def initialize(r)
5
- @net_http_response = r
6
- @body = r.body
7
- #@expires_in = extract_max_age
8
- @expires_at = Time.now + extract_max_age
9
- end
5
+ def initialize(r, minimum_cache_lifetime)
6
+ @net_http_response = r
7
+ @body = r.body
8
+ @expires_at = Time.now + [extract_max_age, minimum_cache_lifetime].max
9
+ end
10
10
 
11
- def expired?
12
- @expires_at < Time.now
13
- end
11
+ def expired?
12
+ @expires_at < Time.now
13
+ end
14
14
 
15
- def update_expires_at t
16
- @expires_at = t
17
- end
15
+ # rubocop:disable Style/TrivialAccessors
16
+ def update_expires_at t
17
+ @expires_at = t
18
+ end
19
+ # rubocop:enable Style/TrivialAccessors
18
20
 
19
- def header h
20
- @net_http_response[h]
21
- end
21
+ def header h
22
+ @net_http_response[h]
23
+ end
22
24
 
23
- def expires_in
24
- extract_max_age
25
- end
25
+ def expires_in
26
+ extract_max_age
27
+ end
28
+
29
+ private
26
30
 
27
- private
28
-
29
- def extract_max_age
30
- cc = @net_http_response['Cache-Control']
31
- cc.is_a?(String) ? cc[/max-age=(\d+)/, 1].to_i : 0
31
+ def extract_max_age
32
+ cc = @net_http_response['Cache-Control']
33
+ cc.is_a?(String) ? cc[/max-age=(\d+)/, 1].to_i : 0
34
+ end
32
35
  end
33
36
  end
@@ -1,3 +1,3 @@
1
1
  module Resterl
2
- VERSION = '0.0.14'
2
+ VERSION = '0.0.15'
3
3
  end
data/resterl.gemspec CHANGED
@@ -15,8 +15,11 @@ Gem::Specification.new do |s|
15
15
  s.executables = `git ls-files -- bin/*`.split("\n").map{|f|File.basename(f)}
16
16
  #s.require_paths = ["lib"]
17
17
 
18
+ s.add_runtime_dependency 'activesupport', '>= 2.3.18'
18
19
  s.add_runtime_dependency 'hashie', '~> 0.4.0'
19
20
  s.add_runtime_dependency 'yajl-ruby', '~> 1.1'
20
- s.add_development_dependency 'shoulda'
21
+ s.add_development_dependency 'rspec', '~> 3.1'
22
+ s.add_development_dependency 'webmock', '~> 1.20.4'
23
+ s.add_development_dependency 'timecop', '~> 0.7.1'
24
+ s.add_development_dependency 'pry'
21
25
  end
22
-
@@ -0,0 +1,36 @@
1
+ require_relative '../../spec_helper'
2
+
3
+ require 'webmock/rspec'
4
+ require 'timecop'
5
+
6
+ describe Resterl::Client do
7
+
8
+ describe 'minimum cache lifetime' do
9
+
10
+ before do
11
+ Timecop.freeze(Time.parse('2015-01-01 01:00'))
12
+
13
+ stub_request(:get, 'http://www.example.com/').to_return(
14
+ status: 200,
15
+ body: 'hello world',
16
+ headers: { cache_control: 'max-age=0, private, must-revalidate' }
17
+ ).then.to_raise('2 requests')
18
+ end
19
+ let(:client) { Resterl::Client.new }
20
+
21
+ it 'is used in "max-age=0" case' do
22
+ response = client.get 'http://www.example.com/', {}, {}
23
+ expect(response.expires_at).to eq Time.parse('2015-01-01 01:05')
24
+ end
25
+
26
+ it 'uses the caches' do
27
+ client.get 'http://www.example.com/', {}, {}
28
+
29
+ Timecop.freeze(Time.parse('2015-01-01 01:00:10'))
30
+
31
+ expect do
32
+ client.get 'http://www.example.com/', {}, {}
33
+ end.not_to raise_error
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,2 @@
1
+ require_relative '../lib/resterl'
2
+ require 'pry'
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: resterl
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.14
4
+ version: 0.0.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - Florian Dütsch
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-10-21 00:00:00.000000000 Z
11
+ date: 2015-02-03 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: 2.3.18
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: 2.3.18
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: hashie
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -39,7 +53,49 @@ dependencies:
39
53
  - !ruby/object:Gem::Version
40
54
  version: '1.1'
41
55
  - !ruby/object:Gem::Dependency
42
- name: shoulda
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '3.1'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: '3.1'
69
+ - !ruby/object:Gem::Dependency
70
+ name: webmock
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: 1.20.4
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: 1.20.4
83
+ - !ruby/object:Gem::Dependency
84
+ name: timecop
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ~>
88
+ - !ruby/object:Gem::Version
89
+ version: 0.7.1
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ~>
95
+ - !ruby/object:Gem::Version
96
+ version: 0.7.1
97
+ - !ruby/object:Gem::Dependency
98
+ name: pry
43
99
  requirement: !ruby/object:Gem::Requirement
44
100
  requirements:
45
101
  - - '>='
@@ -83,8 +139,8 @@ files:
83
139
  - lib/resterl/response.rb
84
140
  - lib/resterl/version.rb
85
141
  - resterl.gemspec
86
- - test/helper.rb
87
- - test/test_resterl.rb
142
+ - spec/lib/resterl/client.rb
143
+ - spec/spec_helper.rb
88
144
  homepage: http://github.com/Nix-wie-weg/resterl
89
145
  licenses: []
90
146
  metadata: {}
@@ -109,6 +165,6 @@ signing_key:
109
165
  specification_version: 4
110
166
  summary: Rudimentary HTTP client with focus on caching
111
167
  test_files:
112
- - test/helper.rb
113
- - test/test_resterl.rb
168
+ - spec/lib/resterl/client.rb
169
+ - spec/spec_helper.rb
114
170
  has_rdoc:
data/test/helper.rb DELETED
@@ -1,10 +0,0 @@
1
- require 'rubygems'
2
- require 'test/unit'
3
- require 'shoulda'
4
-
5
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
- $LOAD_PATH.unshift(File.dirname(__FILE__))
7
- require 'resterl'
8
-
9
- class Test::Unit::TestCase
10
- end
data/test/test_resterl.rb DELETED
@@ -1,57 +0,0 @@
1
- require 'helper'
2
-
3
- class TestResterl < Test::Unit::TestCase
4
-
5
- should 'load successfully' do
6
- dummy = nil
7
- cache = Resterl::Caches::KeyPrefixDecorator.new(
8
- Resterl::Caches::RailsMemcachedCache.new(dummy),
9
- 'prefix_'
10
- )
11
-
12
-
13
- ODIN_CLIENT = Resterl::Client.new(
14
- :base_uri => 'http://www.google.com/',
15
- :cache => cache
16
- )
17
- end
18
-
19
- context 'BaseObject' do
20
- should 'provide class level inheritable attributes' do
21
-
22
- assert_nil Resterl::BaseObject.resterl_client
23
- assert_nil Resterl::BaseObject.complete_mime_type
24
-
25
- assert_nothing_raised do
26
- class Test < Resterl::BaseObject
27
- self.resterl_client = nil
28
- self.complete_mime_type = 'text/plain'
29
- end
30
- end
31
-
32
- end
33
-
34
- should 'work with deeper nestings (cattr_inheritable)' do
35
-
36
- assert_nothing_raised do
37
-
38
- class Test::BaseObject < Resterl::BaseObject
39
- self.mime_type = :json
40
- self.resterl_client = 1
41
- end
42
-
43
- class Test::T1 < Test::BaseObject
44
-
45
- end
46
-
47
-
48
- Test::T1.complete_mime_type
49
- Test::T1.resterl_client
50
-
51
- end
52
-
53
- end
54
-
55
- end
56
-
57
- end