Commit 148aec7d authored by Terence Lee's avatar Terence Lee

Merge pull request #27 from hone/proxy_env

ability to use env vars in proxies origin with `${}`
parents 21a24261 a951d737
...@@ -112,6 +112,25 @@ For single page web applications like Ember, it's common to back the application ...@@ -112,6 +112,25 @@ For single page web applications like Ember, it's common to back the application
} }
``` ```
##### Interpolating Env Var Values
It's common to want to be able to test the frontend against various backends. The `origin` key supports environment variable substitution using `${ENV_VAR_NAME}`. For instance, if there was a staging and production Heroku app for your API, you could setup the config above like the following:
```json
{
"proxies": {
"/api/": {
"origin": "https://${API_APP_NAME}.herokuapp.com/"
}
}
}
```
Then using the [config vars](https://devcenter.heroku.com/articles/config-vars), you can point the frontend app to the appropriate backend. To match the original proxy setup:
```bash
$ heroku config:set API_APP_NAME="hone-ember-todo-rails"
```
#### Custom Headers #### Custom Headers
Using the headers key, you can set custom response headers. It uses the same operators for pathing as [Custom Routes](#custom-routes). Using the headers key, you can set custom response headers. It uses the same operators for pathing as [Custom Routes](#custom-routes).
......
...@@ -20,11 +20,12 @@ class NginxConfig ...@@ -20,11 +20,12 @@ class NginxConfig
json["encoding"] ||= DEFAULT[:encoding] json["encoding"] ||= DEFAULT[:encoding]
json["proxies"] ||= {} json["proxies"] ||= {}
json["proxies"].each do |loc, hash| json["proxies"].each do |loc, hash|
if hash["origin"][-1] != "/" evaled_origin = NginxConfigUtil.interpolate(hash['origin'], ENV)
json["proxies"][loc].merge!("origin" => hash["origin"] + "/") if evaled_origin != "/"
json["proxies"][loc].merge!("origin" => evaled_origin + "/")
end end
uri = URI(hash["origin"]) uri = URI(evaled_origin)
json["proxies"][loc]["path"] = uri.path json["proxies"][loc]["path"] = uri.path
uri.path = "" uri.path = ""
json["proxies"][loc]["host"] = uri.to_s json["proxies"][loc]["host"] = uri.to_s
......
...@@ -44,4 +44,16 @@ module NginxConfigUtil ...@@ -44,4 +44,16 @@ module NginxConfigUtil
false false
end end
def self.interpolate(string, vars)
regex = /\${(\w*?)}/
string.scan(regex).inject(string) do |acc, capture|
var_name = capture.first
value = vars[var_name] if vars
acc.sub!("${#{var_name}}", value) if value
acc
end
end
end end
...@@ -16,4 +16,70 @@ RSpec.describe NginxConfigUtil do ...@@ -16,4 +16,70 @@ RSpec.describe NginxConfigUtil do
end end
end end
end end
describe ".interpolate" do
context "single instance" do
let(:string) { "hello ${FOO}" }
let(:env) do
{
"FOO" => "world"
}
end
let(:result) { "hello world" }
it "should interpolate" do
expect(NginxConfigUtil.interpolate(string, env)).to eq(result)
end
end
context "multiple instances" do
let(:string) { "${FOO}, ${BAR}" }
let(:env) do
{
"FOO" => "hello",
"BAR" => "world"
}
end
let(:result) { "hello, world" }
it "should interpolate" do
expect(NginxConfigUtil.interpolate(string, env)).to eq(result)
end
end
context "instance not found" do
let(:string) { "${FOO}" }
let(:env) { {} }
let(:result) { "${FOO}" }
it "should interpolate" do
expect(NginxConfigUtil.interpolate(string, env)).to eq(result)
end
end
context "vars is nil" do
let(:string) { "${FOO}" }
let(:env) { nil }
let(:result) { "${FOO}" }
it "should interpolate" do
expect(NginxConfigUtil.interpolate(string, env)).to eq(result)
end
end
context "complex example" do
let(:string) { "${FOO} ${BAR} ${BAZ} ${FOO}" }
let(:env) do
{
"FOO" => "foo",
"BAZ" => "baz"
}
end
let(:result) { "foo ${BAR} baz foo" }
it "should interpolate" do
expect(NginxConfigUtil.interpolate(string, env)).to eq(result)
end
end
end
end end
...@@ -196,6 +196,34 @@ STATIC_JSON ...@@ -196,6 +196,34 @@ STATIC_JSON
expect(response.body.chomp).to eq("api") expect(response.body.chomp).to eq("api")
end end
end end
context "env var substitution" do
before do
File.open(static_json_path, "w") do |file|
file.puts <<STATIC_JSON
{
"proxies": {
"/api/": {
"origin": "http://${PROXY_HOST}/foo"
}
}
}
STATIC_JSON
end
end
let(:env) do
{
"PROXY_HOST" => "#{AppRunner::HOST_IP}:#{AppRunner::HOST_PORT}"
}
end
it "should proxy requests" do
response = app.get("/api/bar/")
expect(response.code).to eq("200")
expect(response.body.chomp).to eq("api")
end
end
end end
describe "custom headers" do describe "custom headers" do
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment