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 +4 -4
- data/README.md +24 -3
- data/lib/rack/request_replication/forwarder.rb +111 -4
- data/lib/rack/request_replication/version.rb +1 -1
- data/spec/app/test_app.rb +8 -1
- metadata +1 -2
- data/lib/rack/request_replication/logger.rb +0 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f066360d1270ffe1fd8bf8c0f6045c40884e7c4b
|
4
|
+
data.tar.gz: 3cb0501284af15b165271922a71627b418873907
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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,
|
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]
|
21
|
-
# @option options [Integer]
|
22
|
-
# @option options [String]
|
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
|
-
|
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
|
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,
|
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.
|
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
|