rack-translating_proxy 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +5 -0
- data/.travis.yml +15 -0
- data/Gemfile +7 -0
- data/README.md +104 -4
- data/Rakefile +8 -1
- data/lib/rack/translating_proxy.rb +22 -11
- data/rack-translating_proxy.gemspec +12 -11
- data/spec/example_target_host.rb +65 -0
- data/spec/example_translating_proxy.rb +17 -0
- data/spec/example_translating_proxy.ru +3 -0
- data/spec/integration_spec.rb +95 -0
- data/spec/script/example_target_host +12 -0
- data/spec/script/example_translating_proxy +12 -0
- data/spec/spec_helper.rb +1 -3
- data/spec/{translating_proxy_spec.rb → unit_spec.rb} +28 -12
- metadata +42 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a259b5d2146451b5435d013f63a516cd7d10a00a
|
4
|
+
data.tar.gz: 8275b196335016b6c3957dab8d56eb5ba6f67709
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 15f03547a3ad6ec121f9fc60bf797934ca8d908cb708e0fe7e4af183e72c521e0ea1f14d3aa2387246be8c45523e795671366a552bd8f5bcdc8666884fa67706
|
7
|
+
data.tar.gz: 09a7fc463e2ebc2ccaf839b665a83cc466613e8d9e9bae647cc2d9030bba95c8e27d6309f93aed25b0948fa1af1a4c26c1a4f3f9c0214885e6423d6785645f67
|
data/.rubocop.yml
ADDED
data/.travis.yml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
rvm:
|
2
|
+
- 2.0.0
|
3
|
+
- 2.1
|
4
|
+
- ruby-head
|
5
|
+
|
6
|
+
matrix:
|
7
|
+
allow_failures:
|
8
|
+
- rvm: ruby-head
|
9
|
+
|
10
|
+
before_script:
|
11
|
+
- "./spec/script/example_target_host fast &"
|
12
|
+
- "./spec/script/example_translating_proxy fast &"
|
13
|
+
- "sleep 5"
|
14
|
+
|
15
|
+
bundler_args: --without local_development
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,11 +1,95 @@
|
|
1
1
|
# Rack::TranslatingProxy
|
2
|
+
[![Build Status](https://travis-ci.org/promptworks/rack-translating_proxy.png?branch=master)](https://travis-ci.org/promptworks/rack-translating_proxy.png)
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/rack-translating_proxy.svg)](http://badge.fury.io/rb/rack-translating_proxy)
|
4
|
+
[![Code Climate](https://codeclimate.com/github/promptworks/rack-translating_proxy/badges/gpa.svg)](https://codeclimate.com/github/promptworks/rack-translating_proxy)
|
5
|
+
[![Dependency Status](https://gemnasium.com/promptworks/rack-translating_proxy.svg)](https://gemnasium.com/promptworks/rack-translating_proxy)
|
2
6
|
|
3
|
-
|
4
|
-
|
7
|
+
An HTTP proxy that `gsub`s the contents of the requests and responses in order to make a mostly transparent proxy.
|
8
|
+
|
9
|
+
It aids in the development and testing of integration with external services, especially when the browser has to interact with those services directly.
|
10
|
+
Often, these services will only redirect to certain, predefined URLs, but your test suite spins up its services dynamically.
|
11
|
+
This includes services like OAuth/OpenId and payment gateways (e.g. Stripe, Cybersource).
|
5
12
|
|
6
13
|
## Usage
|
7
14
|
|
8
|
-
|
15
|
+
Inherit from `Rack::TranslatingProxy` and implement `#target_host` and `#request_mapping` hook methods to customize your translating proxy Rack app.
|
16
|
+
|
17
|
+
``` ruby
|
18
|
+
class MyTranslatingProxy < Rack::TranslatingProxy
|
19
|
+
def target_host
|
20
|
+
# ...
|
21
|
+
end
|
22
|
+
|
23
|
+
def request_mapping
|
24
|
+
# ...
|
25
|
+
end
|
26
|
+
end
|
27
|
+
```
|
28
|
+
|
29
|
+
### Target host
|
30
|
+
|
31
|
+
``` ruby
|
32
|
+
def target_host
|
33
|
+
'https://example.com'
|
34
|
+
end
|
35
|
+
```
|
36
|
+
|
37
|
+
Implement this method to specify which host the proxy will send all the requests to.
|
38
|
+
If the app is running on `http://localhost:5555`, then if you call `http://localhost:5555/some/path` you will actually receive the contents of `https:///example.com/some/path`
|
39
|
+
|
40
|
+
The scheme (`http://` vs `http://`) does not need to match between the proxy and target host.
|
41
|
+
|
42
|
+
There is no need to memoize this method.
|
43
|
+
|
44
|
+
### Request mapping
|
45
|
+
|
46
|
+
``` ruby
|
47
|
+
def request_mapping
|
48
|
+
{
|
49
|
+
'some string' => 'another string',
|
50
|
+
'some other string' => 'another another string'
|
51
|
+
}
|
52
|
+
end
|
53
|
+
```
|
54
|
+
|
55
|
+
Implement this method to specify which strings will be translated and to what. On requests, the keys will be translated to the values, and in the responses, the values will be translated into the keys.
|
56
|
+
In this example, in the request, any instance or `some string` will be translated to `another string` before the proxy makes the request to the target host. When the target host responds, the proxy will translate any instance of `another string` into `some string`.
|
57
|
+
|
58
|
+
On the request, the proxy will `gsub` the path, the query string, the `location` header(s) and the request body. On the response, the proxy will `gsub` the response body.
|
59
|
+
|
60
|
+
You will often want to include a rule for the target host to rewrite the proxy's current URL to the target host's URL.
|
61
|
+
This is useful particularly for handling redirects.
|
62
|
+
For example, if you have a mapping rule like `'http://localost:5555' => 'https://externalservice.com'`, when a service redirects to `https://externalservice.com/payment-accepted`, the proxy will rewrite that to `http://localhost:555/payment-accepted`.
|
63
|
+
|
64
|
+
There is no need to memoize this method.
|
65
|
+
|
66
|
+
|
67
|
+
### Example: OAuth service
|
68
|
+
|
69
|
+
Here is an example of a translating proxy for an OAuth service.
|
70
|
+
|
71
|
+
``` ruby
|
72
|
+
class OAuthProxy < Rack::TranslatingProxy
|
73
|
+
# the host to proxy
|
74
|
+
def target_host
|
75
|
+
'https://externalservice.com'
|
76
|
+
end
|
77
|
+
|
78
|
+
def request_mapping
|
79
|
+
{
|
80
|
+
# the URI of this proxy => URI of the target
|
81
|
+
'http://localhost:5555' => target_host,
|
82
|
+
|
83
|
+
# our dev app server => URI that the OAuth implementation has on
|
84
|
+
# file and wants to redirect to
|
85
|
+
'http://localhost:3000' => 'https://dev.mydomain.com',
|
86
|
+
}
|
87
|
+
end
|
88
|
+
end
|
89
|
+
```
|
90
|
+
|
91
|
+
Assuming you run the proxy on `localhost:5555`, you can configure your OAuth-enabled app to point to `http://localhost:5555`.
|
92
|
+
Your test suite and your browser can hit the real OAuth server.
|
9
93
|
|
10
94
|
## Installation
|
11
95
|
|
@@ -21,9 +105,25 @@ Or install it yourself as:
|
|
21
105
|
|
22
106
|
$ gem install rack-translating_proxy
|
23
107
|
|
108
|
+
## Development
|
109
|
+
|
110
|
+
Make sure you are running the test servers:
|
111
|
+
|
112
|
+
./spec/script/example_target_host
|
113
|
+
./spec/script/example_translating_proxy
|
114
|
+
|
115
|
+
Then, run
|
116
|
+
|
117
|
+
rake
|
118
|
+
|
119
|
+
The test servers will update automatically because they are using [shotgun](https://github.com/rtomayko/shotgun).
|
120
|
+
If you don't need them to reload on every request, run one or both of them with the `fast` parameter, like
|
121
|
+
|
122
|
+
./spec/script/example_target_host fast
|
123
|
+
|
24
124
|
## Contributing
|
25
125
|
|
26
|
-
1. Fork it ( http://github.com
|
126
|
+
1. Fork it ( http://github.com/promptworks/rack-translating_proxy/fork )
|
27
127
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
28
128
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
29
129
|
4. Push to the branch (`git push origin my-new-feature`)
|
data/Rakefile
CHANGED
@@ -3,10 +3,10 @@ require 'rack/proxy'
|
|
3
3
|
module Rack
|
4
4
|
class TranslatingProxy < Rack::Proxy
|
5
5
|
def rewrite_env(env)
|
6
|
-
rewrite_request_url
|
7
|
-
rewrite_request_body
|
6
|
+
rewrite_request_url env
|
7
|
+
rewrite_request_body env
|
8
8
|
rewrite_request_query_string env
|
9
|
-
rewrite_request_path
|
9
|
+
rewrite_request_path env
|
10
10
|
|
11
11
|
env
|
12
12
|
end
|
@@ -25,7 +25,9 @@ module Rack
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def rewrite_request_string(str)
|
28
|
-
rewrite_string(
|
28
|
+
rewrite_string(
|
29
|
+
str, request_mapping, URI.method(:encode_www_form_component)
|
30
|
+
)
|
29
31
|
end
|
30
32
|
|
31
33
|
def rewrite_request_query_string(env)
|
@@ -33,7 +35,8 @@ module Rack
|
|
33
35
|
end
|
34
36
|
|
35
37
|
def rewrite_request_path(env)
|
36
|
-
env['
|
38
|
+
env['PATH_INFO'] = rewrite_request_string(env['PATH_INFO'])
|
39
|
+
env['REQUEST_URI'] = rewrite_request_string(env['REQUEST_URI'])
|
37
40
|
end
|
38
41
|
|
39
42
|
def rewrite_string(string, mapping, transform = proc { |x| x })
|
@@ -60,23 +63,31 @@ module Rack
|
|
60
63
|
status, headers, body = triplet
|
61
64
|
rewrite_response_location headers
|
62
65
|
remove_interfering_response_headers headers
|
63
|
-
|
66
|
+
body = rewrite_response_body(body)
|
67
|
+
headers['Content-Length'] = body.size.to_s
|
68
|
+
[status, headers, [body]]
|
64
69
|
end
|
65
70
|
|
66
71
|
def rewrite_response_location(headers)
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
72
|
+
return unless headers['location']
|
73
|
+
|
74
|
+
headers['location'] = headers['location'].map do |location|
|
75
|
+
rewrite_string(location, _response_mapping)
|
71
76
|
end
|
72
77
|
end
|
73
78
|
|
74
79
|
def remove_interfering_response_headers(headers)
|
75
80
|
headers.reject! do |key, _|
|
76
|
-
%w
|
81
|
+
%w(status connection transfer-encoding).include?(key)
|
77
82
|
end
|
78
83
|
end
|
79
84
|
|
85
|
+
def rewrite_response_body(body)
|
86
|
+
str = rewrite_string(body.to_s, _response_mapping)
|
87
|
+
rewrite_string(str, _response_mapping,
|
88
|
+
URI.method(:encode_www_form_component))
|
89
|
+
end
|
90
|
+
|
80
91
|
def request_mapping
|
81
92
|
fail 'Not implemented'
|
82
93
|
end
|
@@ -3,22 +3,23 @@ lib = File.expand_path('../lib', __FILE__)
|
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
|
-
spec.name =
|
7
|
-
spec.version = '0.1.
|
8
|
-
spec.authors = [
|
9
|
-
spec.email = [
|
6
|
+
spec.name = 'rack-translating_proxy'
|
7
|
+
spec.version = '0.1.1'
|
8
|
+
spec.authors = ['Mike Nicholaides']
|
9
|
+
spec.email = ['mike.nicholaides@gmail.com']
|
10
10
|
spec.summary = 'Proxy that translates strings'
|
11
11
|
spec.description = 'Proxy that translates strings'
|
12
|
-
spec.homepage =
|
13
|
-
spec.license =
|
12
|
+
spec.homepage = ''
|
13
|
+
spec.license = 'MIT'
|
14
14
|
|
15
15
|
spec.files = `git ls-files -z`.split("\x0")
|
16
|
-
spec.executables = spec.files.grep(
|
17
|
-
spec.test_files = spec.files.grep(
|
18
|
-
spec.require_paths = [
|
16
|
+
spec.executables = spec.files.grep(/^bin\//) { |f| File.basename(f) }
|
17
|
+
spec.test_files = spec.files.grep(/^(test|spec|features)\//)
|
18
|
+
spec.require_paths = ['lib']
|
19
19
|
|
20
20
|
spec.add_dependency 'rack-proxy', '~> 0.5'
|
21
21
|
|
22
|
-
spec.add_development_dependency
|
23
|
-
spec.add_development_dependency
|
22
|
+
spec.add_development_dependency 'bundler', '~> 1.5'
|
23
|
+
spec.add_development_dependency 'rake'
|
24
|
+
spec.add_development_dependency 'rubocop', '0.25'
|
24
25
|
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'sinatra'
|
2
|
+
require 'base64'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
get '/a-GET-request' do
|
6
|
+
'here is my GET request'
|
7
|
+
end
|
8
|
+
|
9
|
+
get '/' do
|
10
|
+
'here is my GET request to /'
|
11
|
+
end
|
12
|
+
|
13
|
+
get '/a-path' do
|
14
|
+
'a GET request to /'
|
15
|
+
end
|
16
|
+
|
17
|
+
post '/' do
|
18
|
+
params.inspect
|
19
|
+
end
|
20
|
+
|
21
|
+
put '/' do
|
22
|
+
params.inspect
|
23
|
+
end
|
24
|
+
|
25
|
+
delete '/' do
|
26
|
+
params.inspect
|
27
|
+
end
|
28
|
+
|
29
|
+
patch '/' do
|
30
|
+
params.inspect
|
31
|
+
end
|
32
|
+
|
33
|
+
### a redirect scenario
|
34
|
+
get '/a-redirect' do
|
35
|
+
redirect '/redirected-page'
|
36
|
+
end
|
37
|
+
|
38
|
+
get '/redirected-page' do
|
39
|
+
'the redirected page'
|
40
|
+
end
|
41
|
+
|
42
|
+
get '/rewritten-path' do
|
43
|
+
'You are at /rewritten-path'
|
44
|
+
end
|
45
|
+
|
46
|
+
get '/page' do
|
47
|
+
params.inspect
|
48
|
+
end
|
49
|
+
|
50
|
+
post '/page' do
|
51
|
+
params.inspect
|
52
|
+
end
|
53
|
+
|
54
|
+
get '/page-with-stuff' do
|
55
|
+
'<a href="http://localhost/rewritten-path?rewrote+with+SPACE">' \
|
56
|
+
'rewrote with SPACE'
|
57
|
+
end
|
58
|
+
|
59
|
+
get '/reflect' do
|
60
|
+
Base64.encode64(params.to_json)
|
61
|
+
end
|
62
|
+
|
63
|
+
post '/reflect' do
|
64
|
+
Base64.encode64(params.to_json)
|
65
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'rack/translating_proxy'
|
2
|
+
|
3
|
+
class ExampleTranslatingProxy < Rack::TranslatingProxy
|
4
|
+
def target_host
|
5
|
+
'http://localhost:5556'
|
6
|
+
end
|
7
|
+
|
8
|
+
def request_mapping
|
9
|
+
{
|
10
|
+
# the proxy what the target host thinks it is
|
11
|
+
'http://localhost:5555' => 'http://localhost',
|
12
|
+
|
13
|
+
'rewritable' => 'rewritten',
|
14
|
+
'rewrite with space' => 'rewrote with SPACE'
|
15
|
+
}
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require 'json'
|
3
|
+
require 'base64'
|
4
|
+
|
5
|
+
describe 'proxying' do
|
6
|
+
let(:proxy_host) { 'http://localhost:5555' }
|
7
|
+
|
8
|
+
let(:http) do
|
9
|
+
Faraday.new(url: proxy_host) do |faraday|
|
10
|
+
faraday.request :url_encoded
|
11
|
+
faraday.adapter Faraday.default_adapter
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
%w( get post put patch delete ).each do |http_method|
|
16
|
+
define_method(http_method) do |*args|
|
17
|
+
@last_response = http.public_send(http_method, *args)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
attr_reader :last_response
|
22
|
+
|
23
|
+
specify 'a GET request to /' do
|
24
|
+
get '/'
|
25
|
+
expect(last_response).to be_success
|
26
|
+
expect(last_response.body).to include 'here is my GET request to /'
|
27
|
+
end
|
28
|
+
|
29
|
+
specify 'a GET request' do
|
30
|
+
get '/a-GET-request'
|
31
|
+
expect(last_response).to be_success
|
32
|
+
expect(last_response.body).to include 'here is my GET request'
|
33
|
+
end
|
34
|
+
|
35
|
+
specify 'a POST request' do
|
36
|
+
post '/', 'the' => 'data'
|
37
|
+
expect(last_response).to be_success
|
38
|
+
expect(last_response.body).to include({ 'the' => 'data' }.inspect)
|
39
|
+
end
|
40
|
+
|
41
|
+
specify 'a PUT request' do
|
42
|
+
put '/', 'the' => 'data'
|
43
|
+
expect(last_response).to be_success
|
44
|
+
expect(last_response.body).to include({ 'the' => 'data' }.inspect)
|
45
|
+
end
|
46
|
+
|
47
|
+
specify 'a PATCH request' do
|
48
|
+
patch '/', 'the' => 'data'
|
49
|
+
expect(last_response).to be_success
|
50
|
+
expect(last_response.body).to include({ 'the' => 'data' }.inspect)
|
51
|
+
end
|
52
|
+
|
53
|
+
specify 'a DELETE request' do
|
54
|
+
delete '/', 'the' => 'data'
|
55
|
+
expect(last_response).to be_success
|
56
|
+
expect(last_response.body).to include({ 'the' => 'data' }.inspect)
|
57
|
+
end
|
58
|
+
|
59
|
+
specify 'handling a redirect' do
|
60
|
+
get '/a-redirect'
|
61
|
+
expect(last_response.headers['location']).to eq 'http://localhost:5555/redirected-page'
|
62
|
+
expect(last_response.status).to be 302
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'on a request' do
|
66
|
+
let(:reflected_params) do
|
67
|
+
# encoded as Base64 so it's not de-translated on the way back
|
68
|
+
JSON.parse(Base64.decode64(last_response.body))
|
69
|
+
end
|
70
|
+
|
71
|
+
specify 'rewriting the path' do
|
72
|
+
get '/rewritable-path'
|
73
|
+
expect(last_response).to be_success
|
74
|
+
end
|
75
|
+
|
76
|
+
specify 'rewriting the query string' do
|
77
|
+
get '/reflect?rewrite+with+space=something'
|
78
|
+
expect(reflected_params).to include 'rewrote with SPACE' => 'something'
|
79
|
+
end
|
80
|
+
|
81
|
+
specify 'rewriting body contents' do
|
82
|
+
post '/reflect', 'rewrite with space' => 'something'
|
83
|
+
expect(reflected_params).to include 'rewrote with SPACE' => 'something'
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
context 'on a response' do
|
88
|
+
specify 'rewriting links in a page' do
|
89
|
+
get '/page-with-stuff'
|
90
|
+
expect(last_response.body).to eq \
|
91
|
+
'<a href="http://localhost:5555/rewritable-path?rewrite+with+space">' \
|
92
|
+
'rewrite with space'
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -2,9 +2,7 @@ RSpec.configure do |config|
|
|
2
2
|
config.filter_run :focus
|
3
3
|
config.run_all_when_everything_filtered = true
|
4
4
|
|
5
|
-
if config.files_to_run.one?
|
6
|
-
config.default_formatter = 'doc'
|
7
|
-
end
|
5
|
+
config.default_formatter = 'doc' if config.files_to_run.one?
|
8
6
|
|
9
7
|
config.order = :random
|
10
8
|
|
@@ -15,27 +15,32 @@ end
|
|
15
15
|
describe ExampleTranslatingProxy do
|
16
16
|
let(:app) { described_class.new }
|
17
17
|
|
18
|
-
describe
|
18
|
+
describe '#rewrite_env' do
|
19
19
|
subject { app.rewrite_env(Hash.new { '' }.merge(env)) }
|
20
20
|
let(:env) { {} }
|
21
21
|
|
22
|
-
describe
|
22
|
+
describe 'rewriting the uri' do
|
23
23
|
its(['HTTP_HOST']) { is_expected.to eq 'target-host.url' }
|
24
24
|
its(['SERVER_PORT']) { is_expected.to eq 443 }
|
25
25
|
its(['rack.url_scheme']) { is_expected.to eq 'https' }
|
26
26
|
end
|
27
27
|
|
28
|
-
describe
|
28
|
+
describe 'rewriting the PATH_INFO' do
|
29
|
+
let(:env) { { 'PATH_INFO' => '/path/with/a+word' } }
|
30
|
+
its(['PATH_INFO']) { is_expected.to eq '/path/with/another+word' }
|
31
|
+
end
|
32
|
+
|
33
|
+
describe 'rewriting the REQUEST_URI' do
|
29
34
|
let(:env) { { 'REQUEST_URI' => '/path/with/a+word' } }
|
30
35
|
its(['REQUEST_URI']) { is_expected.to eq '/path/with/another+word' }
|
31
36
|
end
|
32
37
|
|
33
|
-
describe
|
38
|
+
describe 'rewriting the query string' do
|
34
39
|
let(:env) { { 'QUERY_STRING' => 'a+word&something-else' } }
|
35
40
|
its(['QUERY_STRING']) { is_expected.to eq 'another+word&something-else' }
|
36
41
|
end
|
37
42
|
|
38
|
-
describe
|
43
|
+
describe 'rewriting the body' do
|
39
44
|
context 'when it is a string' do
|
40
45
|
let(:env) { { 'rack.input' => 'my+string+with+a+word' } }
|
41
46
|
specify do
|
@@ -56,12 +61,12 @@ describe ExampleTranslatingProxy do
|
|
56
61
|
end
|
57
62
|
end
|
58
63
|
|
59
|
-
describe
|
64
|
+
describe '#rewrite_response' do
|
60
65
|
subject { app.rewrite_response(triplet) }
|
61
66
|
|
62
67
|
let(:triplet) { [given_status, given_headers, given_body] }
|
63
68
|
let(:given_status) { double }
|
64
|
-
let(:given_body) {
|
69
|
+
let(:given_body) { '' }
|
65
70
|
let(:given_headers) do
|
66
71
|
{
|
67
72
|
'location' => %w(
|
@@ -69,22 +74,33 @@ describe ExampleTranslatingProxy do
|
|
69
74
|
https://target.url:8765/path
|
70
75
|
),
|
71
76
|
|
72
|
-
'status' => [
|
77
|
+
'status' => ['302 Found'],
|
73
78
|
'connection' => ['close'],
|
74
|
-
'transfer-encoding' => [
|
79
|
+
'transfer-encoding' => ['chunked']
|
75
80
|
}
|
76
81
|
end
|
77
82
|
|
78
83
|
let(:rewritten_status) { subject[0] }
|
79
84
|
let(:rewritten_headers) { subject[1] }
|
80
|
-
let(:rewritten_body) { subject[2] }
|
85
|
+
let(:rewritten_body) { subject[2].join }
|
81
86
|
|
82
87
|
specify { expect(rewritten_body).to eq given_body }
|
83
88
|
specify { expect(rewritten_status).to eq given_status }
|
84
89
|
|
85
90
|
specify do
|
86
|
-
expect(rewritten_headers).to eq \
|
87
|
-
|
91
|
+
expect(rewritten_headers['location']).to eq \
|
92
|
+
%w(http://proxy.url:1234/path http://proxy.url:5678/path)
|
93
|
+
end
|
94
|
+
|
95
|
+
context 'when the body needs to be rewritten' do
|
96
|
+
let(:given_body) { 'another word' }
|
97
|
+
specify { expect(rewritten_body).to eq 'a word' }
|
98
|
+
end
|
99
|
+
|
100
|
+
context 'when the body needs to be rewritten with URL encoded stuff' do
|
101
|
+
let(:given_body) { 'another+word' }
|
102
|
+
specify { expect(rewritten_body).to eq 'a+word' }
|
103
|
+
specify { expect(rewritten_headers['Content-Length']).to eq '6' }
|
88
104
|
end
|
89
105
|
end
|
90
106
|
end
|
metadata
CHANGED
@@ -1,57 +1,71 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-translating_proxy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Nicholaides
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-09-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack-proxy
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0.5'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - ~>
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0.5'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - ~>
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '1.5'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - ~>
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '1.5'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rake
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rubocop
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.25'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.25'
|
55
69
|
description: Proxy that translates strings
|
56
70
|
email:
|
57
71
|
- mike.nicholaides@gmail.com
|
@@ -59,16 +73,24 @@ executables: []
|
|
59
73
|
extensions: []
|
60
74
|
extra_rdoc_files: []
|
61
75
|
files:
|
62
|
-
- .gitignore
|
63
|
-
- .rspec
|
76
|
+
- ".gitignore"
|
77
|
+
- ".rspec"
|
78
|
+
- ".rubocop.yml"
|
79
|
+
- ".travis.yml"
|
64
80
|
- Gemfile
|
65
81
|
- LICENSE.txt
|
66
82
|
- README.md
|
67
83
|
- Rakefile
|
68
84
|
- lib/rack/translating_proxy.rb
|
69
85
|
- rack-translating_proxy.gemspec
|
86
|
+
- spec/example_target_host.rb
|
87
|
+
- spec/example_translating_proxy.rb
|
88
|
+
- spec/example_translating_proxy.ru
|
89
|
+
- spec/integration_spec.rb
|
90
|
+
- spec/script/example_target_host
|
91
|
+
- spec/script/example_translating_proxy
|
70
92
|
- spec/spec_helper.rb
|
71
|
-
- spec/
|
93
|
+
- spec/unit_spec.rb
|
72
94
|
homepage: ''
|
73
95
|
licenses:
|
74
96
|
- MIT
|
@@ -79,12 +101,12 @@ require_paths:
|
|
79
101
|
- lib
|
80
102
|
required_ruby_version: !ruby/object:Gem::Requirement
|
81
103
|
requirements:
|
82
|
-
- -
|
104
|
+
- - ">="
|
83
105
|
- !ruby/object:Gem::Version
|
84
106
|
version: '0'
|
85
107
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
86
108
|
requirements:
|
87
|
-
- -
|
109
|
+
- - ">="
|
88
110
|
- !ruby/object:Gem::Version
|
89
111
|
version: '0'
|
90
112
|
requirements: []
|
@@ -94,5 +116,11 @@ signing_key:
|
|
94
116
|
specification_version: 4
|
95
117
|
summary: Proxy that translates strings
|
96
118
|
test_files:
|
119
|
+
- spec/example_target_host.rb
|
120
|
+
- spec/example_translating_proxy.rb
|
121
|
+
- spec/example_translating_proxy.ru
|
122
|
+
- spec/integration_spec.rb
|
123
|
+
- spec/script/example_target_host
|
124
|
+
- spec/script/example_translating_proxy
|
97
125
|
- spec/spec_helper.rb
|
98
|
-
- spec/
|
126
|
+
- spec/unit_spec.rb
|