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