faraday-http-cache 0.1.1 → 0.2.0

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 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