Commit a762bec0 authored by William Bezuidenhout's avatar William Bezuidenhout

Add hostname placeholder. Header uses replacer

On matched header rules, replacer is used to replace any placeholders
defined in header rules iex. X-Backend {hostname} where {hostname} will
be replaced by the hostname key present in the replacer

hostname key added to replacer. The value is determined by the output of
`os.Hostname()`
parent b75016e6
......@@ -20,13 +20,14 @@ type Headers struct {
// ServeHTTP implements the middleware.Handler interface and serves requests,
// setting headers on the response according to the configured rules.
func (h Headers) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) {
replacer := middleware.NewReplacer(r, nil, "")
for _, rule := range h.Rules {
if middleware.Path(r.URL.Path).Matches(rule.Path) {
for _, header := range rule.Headers {
if strings.HasPrefix(header.Name, "-") {
w.Header().Del(strings.TrimLeft(header.Name, "-"))
} else {
w.Header().Set(header.Name, header.Value)
w.Header().Set(header.Name, replacer.Replace(header.Value))
}
}
}
......
......@@ -3,12 +3,17 @@ package headers
import (
"net/http"
"net/http/httptest"
"os"
"testing"
"github.com/mholt/caddy/middleware"
)
func TestHeaders(t *testing.T) {
hostname, err := os.Hostname()
if err != nil {
t.Fatalf("Could not determine hostname: %v", err)
}
for i, test := range []struct {
from string
name string
......@@ -17,6 +22,7 @@ func TestHeaders(t *testing.T) {
{"/a", "Foo", "Bar"},
{"/a", "Bar", ""},
{"/a", "Baz", ""},
{"/a", "ServerName", hostname},
{"/b", "Foo", ""},
{"/b", "Bar", "Removed in /a"},
} {
......@@ -27,6 +33,7 @@ func TestHeaders(t *testing.T) {
Rules: []Rule{
{Path: "/a", Headers: []Header{
{Name: "Foo", Value: "Bar"},
{Name: "ServerName", Value: "{hostname}"},
{Name: "-Bar"},
}},
},
......
......@@ -4,6 +4,7 @@ import (
"net"
"net/http"
"net/url"
"os"
"path"
"strconv"
"strings"
......@@ -52,6 +53,13 @@ func NewReplacer(r *http.Request, rr *ResponseRecorder, emptyValue string) Repla
}
return "http"
}(),
"{hostname}": func() string {
name, err := os.Hostname()
if err != nil {
return ""
}
return name
}(),
"{host}": r.Host,
"{path}": r.URL.Path,
"{path_escaped}": url.QueryEscape(r.URL.Path),
......
......@@ -3,6 +3,7 @@ package middleware
import (
"net/http"
"net/http/httptest"
"os"
"strings"
"testing"
)
......@@ -53,6 +54,14 @@ func TestReplace(t *testing.T) {
request.Header.Set("ShorterVal", "1")
repl := NewReplacer(request, recordRequest, "-")
hostname, err := os.Hostname()
if err != nil {
t.Fatal("Failed to determine hostname\n")
}
if expected, actual := "This hostname is "+hostname, repl.Replace("This hostname is {hostname}"); expected != actual {
t.Errorf("{hostname} replacement: expected '%s', got '%s'", expected, actual)
}
if expected, actual := "This host is localhost.", repl.Replace("This host is {host}."); expected != actual {
t.Errorf("{host} replacement: expected '%s', got '%s'", expected, actual)
}
......
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