faraday-http-cache 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 03db6f441525313b0456fb22845a0273138a1c50
4
+ data.tar.gz: 7ede80de69498baf306b98be866b37f3b04e4683
5
+ SHA512:
6
+ metadata.gz: f3136959afbad718ce611169c3cf86f3721360c4b9bb44fca9db13fcca5e9013dc144a5a40f180ed904757c9e286c009bccd80672bb145fcde1769c84713acac
7
+ data.tar.gz: 4c66329f3810782ac4a586cc69d94e14ad4e1353b4cba5da928b8230a9821593a4be2ba538c20c4bb37baff75849a9ce2f30be5c7299f0bb7b562fcaeeadc6f5
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright 2012 Plataformatec.
1
+ Copyright 2012-2013 Plataformatec.
2
2
 
3
3
  Licensed under the Apache License, Version 2.0 (the "License");
4
4
  you may not use this file except in compliance with the License.
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![Build Status](https://secure.travis-ci.org/plataformatec/faraday-http-cache.png)](https://travis-ci.org/plataformatec/faraday-http-cache)
4
4
 
5
- a [Faraday](https://github.com/technoweenie/faraday) middleware that respects HTTP cache,
5
+ a [Faraday](https://github.com/lostisland/faraday) middleware that respects HTTP cache,
6
6
  by checking expiration and validation of the stored responses.
7
7
 
8
8
  ## Installation
@@ -73,4 +73,4 @@ Twitter API again.
73
73
 
74
74
  ## License
75
75
 
76
- Copyright (c) 2012 Plataformatec. See LICENSE file.
76
+ Copyright (c) 2012-2013 Plataformatec. See LICENSE file.
@@ -105,7 +105,7 @@ module Faraday
105
105
  method == :get || method == :head
106
106
  end
107
107
 
108
- # Internal: Tries to located a valid response or forwards the call to the stack.
108
+ # Internal: Tries to locate a valid response or forwards the call to the stack.
109
109
  # * If no entry is present on the storage, the 'fetch' method will forward
110
110
  # the call to the remaining stack and return the new response.
111
111
  # * If a fresh response is found, the middleware will abort the remaining
@@ -151,8 +151,10 @@ module Faraday
151
151
  response = Response.new(env)
152
152
  if response.not_modified?
153
153
  trace :valid
154
- env.merge!(entry.payload)
155
- response = entry
154
+ updated_payload = entry.payload
155
+ updated_payload[:response_headers].update(response.payload[:response_headers])
156
+ env.update(updated_payload)
157
+ response = Response.new(updated_payload)
156
158
  end
157
159
  store(response)
158
160
  end
@@ -204,7 +206,7 @@ module Faraday
204
206
  # Returns a 'Hash' containing the ':status', ':body' and 'response_headers'
205
207
  # entries.
206
208
  def create_response(env)
207
- env.slice(:status, :body, :response_headers)
209
+ env.to_hash.slice(:status, :body, :response_headers)
208
210
  end
209
211
 
210
212
  # Internal: Creates a new 'Hash' containing the request information.
@@ -214,8 +216,8 @@ module Faraday
214
216
  # Returns a 'Hash' containing the ':method', ':url' and 'request_headers'
215
217
  # entries.
216
218
  def create_request(env)
217
- request = env.slice(:method, :url)
218
- request[:request_headers] = env[:request_headers].dup
219
+ request = env.to_hash.slice(:method, :url, :request_headers)
220
+ request[:request_headers] = request[:request_headers].dup
219
221
  request
220
222
  end
221
223
 
@@ -228,11 +230,15 @@ module Faraday
228
230
  return unless @logger
229
231
 
230
232
  method = @request[:method].to_s.upcase
231
- path = @request[:url].path
233
+ path = @request[:url].request_uri
232
234
  line = "HTTP Cache: [#{method} #{path}] #{@trace.join(', ')}"
233
235
  @logger.debug(line)
234
236
  end
235
237
  end
236
238
  end
237
239
 
238
- Faraday.register_middleware :http_cache => lambda { Faraday::HttpCache }
240
+ if Faraday.respond_to?(:register_middleware)
241
+ Faraday.register_middleware :http_cache => Faraday::HttpCache
242
+ elsif Faraday::Middleware.respond_to?(:register_middleware)
243
+ Faraday::Middleware.register_middleware :http_cache => Faraday::HttpCache
244
+ end
@@ -7,9 +7,8 @@ module Faraday
7
7
  class CacheControl
8
8
 
9
9
  # Internal: Initialize a new CacheControl.
10
- def initialize(string)
11
- @directives = {}
12
- parse(string)
10
+ def initialize(header)
11
+ @directives = parse(header.to_s)
13
12
  end
14
13
 
15
14
  # Internal: Checks if the 'public' directive is present.
@@ -79,33 +78,31 @@ module Faraday
79
78
 
80
79
  private
81
80
 
82
- # Internal: Parses the Cache Control string into the directives Hash.
83
- # Existing whitespaces are removed, and the string is splited on commas.
84
- # For each segment, everything before a '=' will be treated as the key
85
- # and the excedding will be treated as the value. If only the key is
86
- # present the assigned value will defaults to true.
81
+ # Internal: Parses the Cache Control string to a Hash.
82
+ # Existing whitespace will be removed and the string is split on commas.
83
+ # For each part everything before a '=' will be treated as the key
84
+ # and the exceeding will be treated as the value. If only the key is
85
+ # present then the assigned value will default to true.
87
86
  #
88
87
  # Examples:
89
88
  # parse("max-age=600")
90
- # @directives
91
- # # => { "max-age" => "600"}
89
+ # # => { "max-age" => "600"}
92
90
  #
93
91
  # parse("max-age")
94
- # @directives
95
- # # => { "max-age" => true }
92
+ # # => { "max-age" => true }
96
93
  #
97
- # Returns nothing.
98
- def parse(string)
99
- string = string.to_s
94
+ # Returns a Hash.
95
+ def parse(header)
96
+ directives = {}
100
97
 
101
- return if string.empty?
102
-
103
- string.delete(' ').split(',').each do |part|
98
+ header.delete(' ').split(',').each do |part|
104
99
  next if part.empty?
105
100
 
106
101
  name, value = part.split('=', 2)
107
- @directives[name.downcase] = (value || true) unless name.empty?
102
+ directives[name.downcase] = (value || true) unless name.empty?
108
103
  end
104
+
105
+ directives
109
106
  end
110
107
  end
111
108
  end
@@ -114,7 +114,16 @@ module Faraday
114
114
  #
115
115
  # Returns a new instance of a 'Faraday::Response' with the payload.
116
116
  def to_response(env)
117
- Faraday::Response.new(env.merge(@payload))
117
+ env.update(@payload)
118
+ Faraday::Response.new(env)
119
+ end
120
+
121
+ # Internal: Exposes a representation of the current
122
+ # payload that we can serialize and cache properly.
123
+ #
124
+ # Returns a 'Hash'.
125
+ def serializable_hash
126
+ @payload.slice(:status, :body, :response_headers)
118
127
  end
119
128
 
120
129
  private
@@ -32,8 +32,7 @@ module Faraday
32
32
  # response - The Faraday::HttpCache::Response instance to be stored.
33
33
  def write(request, response)
34
34
  key = cache_key_for(request)
35
- value = MultiJson.dump(response.payload)
36
-
35
+ value = MultiJson.dump(response.serializable_hash)
37
36
  cache.write(key, value)
38
37
  end
39
38
 
data/spec/json_spec.rb CHANGED
@@ -6,19 +6,16 @@ describe Faraday::HttpCache do
6
6
  let(:client) do
7
7
  Faraday.new(:url => ENV['FARADAY_SERVER']) do |stack|
8
8
  stack.response :json, :content_type => /\bjson$/
9
- stack.use Faraday::HttpCache, :logger => logger
9
+ stack.use :http_cache, :logger => logger
10
10
  adapter = ENV['FARADAY_ADAPTER']
11
11
  stack.headers['X-Faraday-Adapter'] = adapter
12
12
  stack.adapter adapter.to_sym
13
13
  end
14
14
  end
15
15
 
16
- before do
17
- client.get('clear')
18
- end
19
-
20
16
  it "works fine with other middlewares" do
17
+ client.get('clear')
21
18
  client.get('json').body['count'].should == 1
22
19
  client.get('json').body['count'].should == 1
23
20
  end
24
- end
21
+ end
@@ -83,6 +83,13 @@ describe Faraday::HttpCache do
83
83
  client.get('get')
84
84
  end
85
85
 
86
+ it "differs requests with different query strings in the log" do
87
+ logger.should_receive(:debug).with('HTTP Cache: [GET /get] miss, store')
88
+ logger.should_receive(:debug).with('HTTP Cache: [GET /get?q=what] miss, store')
89
+ client.get('get')
90
+ client.get('get', :q => "what")
91
+ end
92
+
86
93
  it "logs that a stored GET response is fresh" do
87
94
  client.get('get')
88
95
  logger.should_receive(:debug).with('HTTP Cache: [GET /get] fresh')
@@ -121,6 +128,26 @@ describe Faraday::HttpCache do
121
128
  date.should =~ /^\w{3}, \d{2} \w{3} \d{4} \d{2}:\d{2}:\d{2} GMT$/
122
129
  end
123
130
 
131
+ it "updates the 'Cache-Control' header when a response is validated" do
132
+ cache_control = client.get('etag').headers['Cache-Control']
133
+ client.get('etag').headers['Cache-Control'].should_not == cache_control
134
+ end
135
+
136
+ it "updates the 'Date' header when a response is validated" do
137
+ date = client.get('etag').headers['Date']
138
+ client.get('etag').headers['Date'].should_not == date
139
+ end
140
+
141
+ it "updates the 'Expires' header when a response is validated" do
142
+ expires = client.get('etag').headers['Expires']
143
+ client.get('etag').headers['Expires'].should_not == expires
144
+ end
145
+
146
+ it "updates the 'Vary' header when a response is validated" do
147
+ vary = client.get('etag').headers['Vary']
148
+ client.get('etag').headers['Vary'].should_not == vary
149
+ end
150
+
124
151
  describe 'Configuration options' do
125
152
  let(:app) { double("it's an app!") }
126
153
 
@@ -128,12 +128,12 @@ describe Faraday::HttpCache::Response do
128
128
 
129
129
  describe "response unboxing" do
130
130
  subject { described_class.new(:status => 200, :response_headers => {}, :body => "Hi!") }
131
- let(:env) { { :resquest => mock } }
132
131
 
132
+ let(:env) { { :method => :get } }
133
133
  let(:response) { subject.to_response(env) }
134
134
 
135
135
  it "merges the supplied env object with the response data" do
136
- response.env[:resquest].should be
136
+ response.env[:method].should be
137
137
  end
138
138
 
139
139
  it "returns a Faraday::Response" do
data/spec/storage_spec.rb CHANGED
@@ -5,7 +5,7 @@ describe Faraday::HttpCache::Storage do
5
5
  { :method => :get, :request_headers => {}, :url => URI.parse("http://foo.bar/") }
6
6
  end
7
7
 
8
- let(:response) { double(:payload => {}) }
8
+ let(:response) { double(:serializable_hash => {}) }
9
9
 
10
10
  let(:cache) { ActiveSupport::Cache.lookup_store }
11
11
 
@@ -20,7 +20,7 @@ describe Faraday::HttpCache::Storage do
20
20
 
21
21
  describe 'storing responses' do
22
22
  it 'writes the response json to the underlying cache using a digest as the key' do
23
- json = MultiJson.dump(response.payload)
23
+ json = MultiJson.dump(response.serializable_hash)
24
24
 
25
25
  cache.should_receive(:write).with('503ac9f7180ca1cdec49e8eb73a9cc0b47c27325', json)
26
26
  subject.write(request, response)
@@ -69,9 +69,9 @@ class TestApp < Sinatra::Base
69
69
  tag = settings.counter > 2 ? '1' : '2'
70
70
 
71
71
  if env['HTTP_IF_NONE_MATCH'] == tag
72
- [304, { 'ETag' => tag }, ""]
72
+ [304, { 'ETag' => tag, 'Cache-Control' => 'max-age=200', 'Date' => Time.now.httpdate, 'Expires' => (Time.now + 200).httpdate, 'Vary' => '*' }, ""]
73
73
  else
74
- [200, { 'ETag' => tag }, "#{settings.requests += 1}"]
74
+ [200, { 'ETag' => tag, 'Cache-Control' => 'max-age=0', 'Date' => settings.yesterday, 'Expires' => Time.now.httpdate, 'Vary' => 'Accept' }, "#{settings.requests += 1}"]
75
75
  end
76
76
  end
77
77
  end
metadata CHANGED
@@ -1,36 +1,32 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: faraday-http-cache
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
5
- prerelease:
4
+ version: 0.2.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Lucas Mazza
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2012-12-20 00:00:00.000000000 Z
11
+ date: 2013-06-03 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: activesupport
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ~>
17
+ - - '>='
20
18
  - !ruby/object:Gem::Version
21
19
  version: '3.0'
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ~>
24
+ - - '>='
28
25
  - !ruby/object:Gem::Version
29
26
  version: '3.0'
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: faraday
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
31
  - - ~>
36
32
  - !ruby/object:Gem::Version
@@ -38,7 +34,6 @@ dependencies:
38
34
  type: :runtime
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
38
  - - ~>
44
39
  - !ruby/object:Gem::Version
@@ -46,7 +41,6 @@ dependencies:
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: multi_json
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
45
  - - ~>
52
46
  - !ruby/object:Gem::Version
@@ -54,7 +48,6 @@ dependencies:
54
48
  type: :runtime
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
52
  - - ~>
60
53
  - !ruby/object:Gem::Version
@@ -83,33 +76,26 @@ files:
83
76
  - spec/support/test_server.rb
84
77
  homepage: https://github.com/plataformatec/faraday-http-cache
85
78
  licenses: []
79
+ metadata: {}
86
80
  post_install_message:
87
81
  rdoc_options: []
88
82
  require_paths:
89
83
  - lib
90
84
  required_ruby_version: !ruby/object:Gem::Requirement
91
- none: false
92
85
  requirements:
93
- - - ! '>='
86
+ - - '>='
94
87
  - !ruby/object:Gem::Version
95
88
  version: '0'
96
- segments:
97
- - 0
98
- hash: -4216884502397664395
99
89
  required_rubygems_version: !ruby/object:Gem::Requirement
100
- none: false
101
90
  requirements:
102
- - - ! '>='
91
+ - - '>='
103
92
  - !ruby/object:Gem::Version
104
93
  version: '0'
105
- segments:
106
- - 0
107
- hash: -4216884502397664395
108
94
  requirements: []
109
95
  rubyforge_project:
110
- rubygems_version: 1.8.24
96
+ rubygems_version: 2.0.0
111
97
  signing_key:
112
- specification_version: 3
98
+ specification_version: 4
113
99
  summary: A Faraday middleware that stores and validates cache expiration.
114
100
  test_files:
115
101
  - spec/cache_control_spec.rb