rack-request_replication 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
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