rack-request_replication 0.0.2 → 0.0.3

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: 9f86b1abca6aee060bc978f2d9d03cc0241ff51e
4
- data.tar.gz: 8f5e982046204fc40f2c4369805b5b073795c679
3
+ metadata.gz: f066360d1270ffe1fd8bf8c0f6045c40884e7c4b
4
+ data.tar.gz: 3cb0501284af15b165271922a71627b418873907
5
5
  SHA512:
6
- metadata.gz: b67f6d7ecbf05611b54da1c862ce67fdd6e3ea58e53c01867bc0eb6f62d71aa845b2d23b762ac81aa5ad17a8033778f232eef6b264a4ad4854935c173f373a75
7
- data.tar.gz: cfe08f90f63f11b7232330c81c2ba43faea3f5bc9c13ea42cb9a5ba5c8fc8f0fab060b4d4eb37f8ac7126528edd0d0390530e8ebf68c540058c8089d5bde189e
6
+ metadata.gz: d38e8f9f3e53f44c2df81d9ee16b9e8459e54b8a8c454ef5c9abe2e2dbd5c8276dbcaecca6342d10421c616c942ce7e16f27bda9f03995223f5671c41d8c85ef
7
+ data.tar.gz: aad6649afb76b4b38beab7586e24fedf87640d66a98b35e98ad4b42e4b45d34c427b84064ace3f839a95088dd39400f0c1b8e03ca601a5e6fd014732169f6c5c
data/README.md CHANGED
@@ -1,8 +1,20 @@
1
- # Rack::RequestReplication
1
+ # Rack::RequestReplication - Replicate Rack app HTTP requests
2
2
 
3
3
  Replicate requests from one app instance to another. At
4
4
  [Springest](http://www.springest.com) we use this to test new features.
5
- We replicate all live requests to our staging environment.
5
+ We replicate all live requests to our staging environment to test new
6
+ code before it goes live. With real traffic!
7
+
8
+ ## Session support
9
+
10
+ It has support for sessions. To make use of it, you need to have Redis
11
+ running. Redis serves as a key-value store where sessions from the
12
+ Source App are linked to sessions from the Forward App. This way both
13
+ apps can have their own session management.
14
+
15
+ ## API Docs
16
+
17
+ Check out the official [API docs](http://rubydoc.info/gems/rack-request_replication)
6
18
 
7
19
  ## Installation
8
20
 
@@ -24,11 +36,20 @@ Or install it yourself as:
24
36
 
25
37
  ```ruby
26
38
  require 'sinatra/base'
39
+ require 'sinatra/cookies'
27
40
  require 'rack/request_replication'
28
41
 
29
42
  class TestApp < Sinatra::Base
30
43
  # Forward all requests to another app that runs on localhost, port 4568
31
- use Rack::RequestReplication::Forwarder, host: 'localhost', port: 4568
44
+ use Rack::RequestReplication::Forwarder,
45
+ host: 'localhost',
46
+ port: 4568,
47
+ session_key: 'rack.session',
48
+ redis: {
49
+ host: 'localhost',
50
+ port: 6379,
51
+ db: 'rack-request-replication'
52
+ }
32
53
 
33
54
  get '/' do
34
55
  'Hello World'
@@ -17,9 +17,13 @@ module Rack
17
17
  ##
18
18
  # @param [#call] app
19
19
  # @param [Hash{Symbol => Object}] options
20
- # @option options [String] :host ('localhost')
21
- # @option options [Integer] :port (8080)
22
- # @option options [String] :session_key ('rack.session')
20
+ # @option options [String] :host ('localhost')
21
+ # @option options [Integer] :port (8080)
22
+ # @option options [String] :session_key ('rack.session')
23
+ # @option options [Hash{Symbol => Object}] :redis
24
+ # @option redis [String] :host ('localhost')
25
+ # @option redis [Integer] :port (6379)
26
+ # @option redis [String] :db ('rack-request-replication')
23
27
  #
24
28
  def initialize( app, options = {} )
25
29
  @app = app
@@ -70,6 +74,14 @@ module Rack
70
74
  end
71
75
  end
72
76
 
77
+ ##
78
+ # Update cookies from the forwarded request using the session id
79
+ # from the cookie of the source app as a key. The cookie is stored
80
+ # in Redis.
81
+ #
82
+ # @param [Rack::Request] request
83
+ # @param [Net::HTTP::Response] response
84
+ #
73
85
  def update_cookies( request, response )
74
86
  return unless cookies_id( request )
75
87
  cookie = response.to_hash['set-cookie'].collect{|ea|ea[/^.*?;/]}.join rescue {}
@@ -77,13 +89,32 @@ module Rack
77
89
  redis.set( cookies_id( request), cookie )
78
90
  end
79
91
 
92
+ ##
93
+ # Cookies Hash to use for the forwarded request.
94
+ #
95
+ # Tries to find the cookies from earlier forwarded
96
+ # requests in the Redis store, otherwise falls back
97
+ # to the cookies from the source app.
98
+ #
99
+ # @param [Rack::Request] request
100
+ # @returns [Hash]
101
+ #
80
102
  def cookies( request )
81
103
  return ( request.cookies || "" ) unless cookies_id( request )
82
- cs = redis.get( cookies_id( request )) ||
104
+ redis.get( cookies_id( request )) ||
83
105
  request.cookies ||
84
106
  {}
85
107
  end
86
108
 
109
+ ##
110
+ # The key to use when looking up cookie stores in
111
+ # Redis for forwarding requests. Needed for session
112
+ # persistence over forwarded requests for the same
113
+ # user in the source app.
114
+ #
115
+ # @param [Rack::Request] request
116
+ # @returns [String]
117
+ #
87
118
  def cookies_id( request )
88
119
  cs = request.cookies
89
120
  sess = cs && cs[options[:session_key]]
@@ -91,32 +122,89 @@ module Rack
91
122
  sess_id
92
123
  end
93
124
 
125
+ ##
126
+ # Prepare a GET request to the forward app.
127
+ #
128
+ # The passed in options hash is ignored.
129
+ #
130
+ # @param [URI] uri
131
+ # @param [Hash{Symbol => Object}] opts ({})
132
+ # @returns [Net:HTTP::Get]
133
+ #
94
134
  def create_get_request( uri, opts = {} )
95
135
  Net::HTTP::Get.new uri.request_uri
96
136
  end
97
137
 
138
+ ##
139
+ # Prepare a POST request to the forward app.
140
+ #
141
+ # The passed in options hash contains all the
142
+ # data from the request that needs to be forwarded.
143
+ #
144
+ # @param [URI] uri
145
+ # @param [Hash{Symbol => Object}] opts ({})
146
+ # @returns [Net:HTTP::Post]
147
+ #
98
148
  def create_post_request( uri, opts = {} )
99
149
  forward_request = Net::HTTP::Post.new uri.request_uri
100
150
  forward_request.set_form_data opts[:params]
101
151
  forward_request
102
152
  end
103
153
 
154
+ ##
155
+ # Prepare a PUT request to the forward app.
156
+ #
157
+ # The passed in options hash contains all the
158
+ # data from the request that needs to be forwarded.
159
+ #
160
+ # @param [URI] uri
161
+ # @param [Hash{Symbol => Object}] opts ({})
162
+ # @returns [Net:HTTP::Put]
163
+ #
104
164
  def create_put_request( uri, opts = {} )
105
165
  forward_request = Net::HTTP::Put.new uri.request_uri
106
166
  forward_request.set_form_data opts[:params]
107
167
  forward_request
108
168
  end
109
169
 
170
+ ##
171
+ # Prepare a PATCH request to the forward app.
172
+ #
173
+ # The passed in options hash contains all the
174
+ # data from the request that needs to be forwarded.
175
+ #
176
+ # @param [URI] uri
177
+ # @param [Hash{Symbol => Object}] opts ({})
178
+ # @returns [Net:HTTP::Patch]
179
+ #
110
180
  def create_patch_request( uri, opts = {} )
111
181
  forward_request = Net::HTTP::Patch.new uri.request_uri
112
182
  forward_request.set_form_data opts[:params]
113
183
  forward_request
114
184
  end
115
185
 
186
+ ##
187
+ # Prepare a DELETE request to the forward app.
188
+ #
189
+ # The passed in options hash is ignored.
190
+ #
191
+ # @param [URI] uri
192
+ # @param [Hash{Symbol => Object}] opts ({})
193
+ # @returns [Net:HTTP::Delete]
194
+ #
116
195
  def create_delete_request( uri, opts = {} )
117
196
  Net::HTTP::Delete.new uri.request_uri
118
197
  end
119
198
 
199
+ ##
200
+ # Prepare a OPTIONS request to the forward app.
201
+ #
202
+ # The passed in options hash is ignored.
203
+ #
204
+ # @param [URI] uri
205
+ # @param [Hash{Symbol => Object}] opts ({})
206
+ # @returns [Net:HTTP::Options]
207
+ #
120
208
  def create_options_request( uri, opts = {} )
121
209
  Net::HTTP::Options.new uri.request_uri
122
210
  end
@@ -162,6 +250,13 @@ module Rack
162
250
  URI(url)
163
251
  end
164
252
 
253
+ ##
254
+ # The host to forward to including the port if
255
+ # the port does not match the current scheme.
256
+ #
257
+ # @param [Rack::Request] request
258
+ # @returns [String]
259
+ #
165
260
  def forward_host_with_port( request )
166
261
  host = options[:host].to_s
167
262
  host = "#{host}:#{options[:port]}" unless port_matches_scheme? request
@@ -179,6 +274,7 @@ module Rack
179
274
  db: 'rack-request-replication'
180
275
  }.merge(options[:redis]))
181
276
  end
277
+
182
278
  ##
183
279
  # Checks if the request scheme matches the destination port.
184
280
  #
@@ -189,10 +285,21 @@ module Rack
189
285
  options[:port].to_i == Rack::Request::DEFAULT_PORTS[clean_scheme(request)]
190
286
  end
191
287
 
288
+ ##
289
+ # Request scheme without the ://
290
+ #
291
+ # @param [Rack::Request] request
292
+ # @returns [String]
293
+ #
192
294
  def clean_scheme( request )
193
295
  request.scheme.match(/^\w+/)[0]
194
296
  end
195
297
 
298
+ ##
299
+ # Logger that logs to STDOUT
300
+ #
301
+ # @returns [Logger]
302
+ #
196
303
  def logger
197
304
  @logger ||= ::Logger.new(STDOUT)
198
305
  end
@@ -1,5 +1,5 @@
1
1
  module Rack
2
2
  module RequestReplication
3
- VERSION = "0.0.2"
3
+ VERSION = "0.0.3"
4
4
  end
5
5
  end
data/spec/app/test_app.rb CHANGED
@@ -9,7 +9,14 @@ class TestApp < Sinatra::Base
9
9
 
10
10
  enable :logging
11
11
 
12
- use Rack::RequestReplication::Forwarder, port: 4568
12
+ use Rack::RequestReplication::Forwarder, host: 'localhost',
13
+ port: 4568,
14
+ session_key: 'rack.session',
15
+ redis: {
16
+ host: 'localhost',
17
+ port: 6379,
18
+ db: 'rack-request-replication'
19
+ }
13
20
 
14
21
  get '/' do
15
22
  'GET OK'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-request_replication
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Wouter de Vos
@@ -151,7 +151,6 @@ files:
151
151
  - Rakefile
152
152
  - lib/rack/request_replication.rb
153
153
  - lib/rack/request_replication/forwarder.rb
154
- - lib/rack/request_replication/logger.rb
155
154
  - lib/rack/request_replication/version.rb
156
155
  - rack-request_replication.gemspec
157
156
  - spec/app/test_app.rb
@@ -1,8 +0,0 @@
1
- require 'logger'
2
-
3
- module Rack
4
- module RequestReplication
5
- class Logg
6
- end
7
- end
8
- end