Compare commits
No commits in common. "848d5e671416899d121ad1d085b54204ebd9410b" and "121720ca1429ca4e7071e62ffa249f0d846ac4c0" have entirely different histories.
848d5e6714
...
121720ca14
|
@ -58,7 +58,7 @@ route do |r|
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
The proxy will always be invoked. Headers and body are passed through unmodified in both directions with the exception of `Host` which is rewritten to match the target and `Via` which is created (or appended to if it already exists) to indicate the proxy path.
|
The proxy will always be invoked. Headers and body are passed through unmodified in both directions with the exception of `Host` which is rewritten to match the target.
|
||||||
|
|
||||||
Also provided is a conditional proxy:
|
Also provided is a conditional proxy:
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ route do |r|
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
With `proxy_when` the first optional parameter expects a truthy value or a block / lambda that returns a truthy value. This must be equivalent to `true` for the proxying to occur. The optional probability is a float between 0 and 1 indicating the probability that proxying will happen. Both parameters can be used alone or in isolation.
|
With `proxy_when` the first optional parameter expects a truthy value or a block / lambda that returns a truthy value. This must be equivalent to `true` for the proxying to occur. The optional probability is a float between 0 and 1 indicating the probability that proxying will happen. Both paramters can be used alone or in isolation.
|
||||||
|
|
||||||
If and only if proxying does not occur will the block be evaluated and return to Roda for rendering.
|
If and only if proxying does not occur will the block be evaluated and return to Roda for rendering.
|
||||||
|
|
||||||
|
|
|
@ -13,17 +13,13 @@ class Roda
|
||||||
# Respond to the configure method to set the destination when proxying
|
# Respond to the configure method to set the destination when proxying
|
||||||
# Expects the following options:
|
# Expects the following options:
|
||||||
# [to] Required. The scheme and host of the proxy. Should not end with a slash.
|
# [to] Required. The scheme and host of the proxy. Should not end with a slash.
|
||||||
# [path_prefix] Optional. The path to append to the above for proxying.
|
# [path] Optional. The path to append to the above for proxying.
|
||||||
# The current request path will be prefixed on to this value.
|
# Should begin with a +/+. Defaults to +/+.
|
||||||
# Should begin and end with a +/+. Defaults to +/+.
|
|
||||||
# For example, if the path prefix is +/foo/+ and the request received
|
|
||||||
# by Roda is +GET /postcode/lookup+, The proxied request will be dispatched
|
|
||||||
# to +GET /home/postcode/lookup+
|
|
||||||
# Example:
|
# Example:
|
||||||
# plugin :proxy, to: 'https://foo.bar', path: '/my/api'
|
# plugin :proxy, to: 'https://foo.bar', path: '/my/api'
|
||||||
def self.configure(app, opts = {})
|
def self.configure(app, opts = {})
|
||||||
app.opts[:proxy_to] = opts.fetch(:to, nil)
|
app.opts[:proxy_to] = opts.fetch(:to, nil)
|
||||||
app.opts[:proxy_path] = opts.fetch(:path_prefix, '/')
|
app.opts[:proxy_path] = opts.fetch(:path, '/')
|
||||||
|
|
||||||
raise 'Proxy host not set, use "plugin :proxy, to: http://example.com"' unless app.opts[:proxy_to]
|
raise 'Proxy host not set, use "plugin :proxy, to: http://example.com"' unless app.opts[:proxy_to]
|
||||||
end
|
end
|
||||||
|
@ -37,7 +33,6 @@ class Roda
|
||||||
def proxy
|
def proxy
|
||||||
method = Faraday.method(env['REQUEST_METHOD'].downcase.to_sym)
|
method = Faraday.method(env['REQUEST_METHOD'].downcase.to_sym)
|
||||||
f_response = method.call(_proxy_url) { |req| _proxy_request(req) }
|
f_response = method.call(_proxy_url) { |req| _proxy_request(req) }
|
||||||
# p f_response
|
|
||||||
_respond(f_response)
|
_respond(f_response)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -55,19 +50,17 @@ class Roda
|
||||||
shall_proxy = Random.rand(0.0..1.0) <= probability
|
shall_proxy = Random.rand(0.0..1.0) <= probability
|
||||||
|
|
||||||
if shall_proxy && ( condition.respond_to?(:call) ? condition.call : condition )
|
if shall_proxy && ( condition.respond_to?(:call) ? condition.call : condition )
|
||||||
proxy
|
|
||||||
else
|
|
||||||
yield(self)
|
yield(self)
|
||||||
|
else
|
||||||
|
proxy
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
|
||||||
def _proxy_url
|
def _proxy_url
|
||||||
@_proxy_url ||= URI(roda_class.opts[:proxy_to])
|
@_proxy_url ||= URI(roda_class.opts[:proxy_to])
|
||||||
.then { |uri| uri.path = roda_class.opts[:proxy_path]; uri } # prefix
|
.then { |uri| uri.path = roda_class.opts[:proxy_path]; uri }
|
||||||
.then { |uri| uri.path += env['PATH_INFO'][1..-1]; uri } # path
|
|
||||||
.then { |uri| uri.query = env['QUERY_STRING']; uri }
|
.then { |uri| uri.query = env['QUERY_STRING']; uri }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -80,11 +73,7 @@ class Roda
|
||||||
.split('_')
|
.split('_')
|
||||||
.map(&:capitalize)
|
.map(&:capitalize)
|
||||||
.join('-')
|
.join('-')
|
||||||
end
|
end.merge({ 'Host' => "#{_proxy_url.host}:#{_proxy_url.port}" })
|
||||||
.merge({
|
|
||||||
'Host' => "#{_proxy_url.host}:#{_proxy_url.port}",
|
|
||||||
'Via' => _via_header_string
|
|
||||||
})
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def _proxy_request(req)
|
def _proxy_request(req)
|
||||||
|
@ -93,17 +82,9 @@ class Roda
|
||||||
|
|
||||||
def _respond(proxied_response)
|
def _respond(proxied_response)
|
||||||
response.status = proxied_response.status
|
response.status = proxied_response.status
|
||||||
proxied_response
|
proxied_response.headers.each { |k, v| response[k] = v }
|
||||||
.headers
|
|
||||||
.reject { |k, v| k.downcase == 'transfer-encoding' }
|
|
||||||
.each { |k, v| response[k] = v }
|
|
||||||
response['Via'] = _via_header_string
|
|
||||||
response.write(proxied_response.body)
|
response.write(proxied_response.body)
|
||||||
end
|
end
|
||||||
|
|
||||||
def _via_header_string
|
|
||||||
"#{env['SERVER_PROTOCOL']} #{env['SERVER_NAME']}:#{env['SERVER_PORT']}"
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,6 @@
|
||||||
|
|
||||||
class Roda
|
class Roda
|
||||||
module Proxy
|
module Proxy
|
||||||
VERSION = '1.0.5'
|
VERSION = '0.1.0'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -8,17 +8,17 @@ Gem::Specification.new do |spec|
|
||||||
spec.authors = ['Nigel Brookes-Thomas']
|
spec.authors = ['Nigel Brookes-Thomas']
|
||||||
spec.email = ['nigel@brookes-thomas.co.uk']
|
spec.email = ['nigel@brookes-thomas.co.uk']
|
||||||
|
|
||||||
spec.summary = 'Reverse proxy plugin for Roda'
|
spec.summary = 'Proxy service for Roda'
|
||||||
spec.description = 'A very simple reverse proxy for Roda'
|
spec.description = 'Roda proxy service'
|
||||||
spec.homepage = 'https://github.com/BillyRuffian/roda-proxy'
|
spec.homepage = 'http://foo.bar'
|
||||||
spec.license = 'MIT'
|
spec.license = 'MIT'
|
||||||
spec.required_ruby_version = Gem::Requirement.new('>= 2.3.0')
|
spec.required_ruby_version = Gem::Requirement.new('>= 2.3.0')
|
||||||
|
|
||||||
spec.metadata['allowed_push_host'] = 'https://rubygems.org'
|
spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com'"
|
||||||
|
|
||||||
spec.metadata['homepage_uri'] = spec.homepage
|
spec.metadata['homepage_uri'] = spec.homepage
|
||||||
spec.metadata['source_code_uri'] = 'https://github.com/BillyRuffian/roda-proxy'
|
spec.metadata['source_code_uri'] = 'http://foo.bar'
|
||||||
spec.metadata['changelog_uri'] = 'https://github.com/BillyRuffian/roda-proxy'
|
spec.metadata['changelog_uri'] = 'http://foo.bar'
|
||||||
|
|
||||||
# Specify which files should be added to the gem when it is released.
|
# Specify which files should be added to the gem when it is released.
|
||||||
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
||||||
|
|
Loading…
Reference in New Issue