128 lines
3.3 KiB
Go
128 lines
3.3 KiB
Go
|
package handlers
|
||
|
|
||
|
import (
|
||
|
"bufio"
|
||
|
"bytes"
|
||
|
"log"
|
||
|
"net/http"
|
||
|
"net/http/httptest"
|
||
|
"net/url"
|
||
|
"strings"
|
||
|
"testing"
|
||
|
)
|
||
|
|
||
|
func TestCleanHost(t *testing.T) {
|
||
|
tests := []struct {
|
||
|
in, want string
|
||
|
}{
|
||
|
{"www.google.com", "www.google.com"},
|
||
|
{"www.google.com foo", "www.google.com"},
|
||
|
{"www.google.com/foo", "www.google.com"},
|
||
|
{" first character is a space", ""},
|
||
|
}
|
||
|
for _, tt := range tests {
|
||
|
got := cleanHost(tt.in)
|
||
|
if tt.want != got {
|
||
|
t.Errorf("cleanHost(%q) = %q, want %q", tt.in, got, tt.want)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestCanonicalHost(t *testing.T) {
|
||
|
gorilla := "http://www.gorillatoolkit.org"
|
||
|
|
||
|
rr := httptest.NewRecorder()
|
||
|
r := newRequest("GET", "http://www.example.com/")
|
||
|
|
||
|
testHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})
|
||
|
|
||
|
// Test a re-direct: should return a 302 Found.
|
||
|
CanonicalHost(gorilla, http.StatusFound)(testHandler).ServeHTTP(rr, r)
|
||
|
|
||
|
if rr.Code != http.StatusFound {
|
||
|
t.Fatalf("bad status: got %v want %v", rr.Code, http.StatusFound)
|
||
|
}
|
||
|
|
||
|
if rr.Header().Get("Location") != gorilla+r.URL.Path {
|
||
|
t.Fatalf("bad re-direct: got %q want %q", rr.Header().Get("Location"), gorilla+r.URL.Path)
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
func TestKeepsQueryString(t *testing.T) {
|
||
|
google := "https://www.google.com"
|
||
|
|
||
|
rr := httptest.NewRecorder()
|
||
|
querystring := url.Values{"q": {"golang"}, "format": {"json"}}.Encode()
|
||
|
r := newRequest("GET", "http://www.example.com/search?"+querystring)
|
||
|
|
||
|
testHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})
|
||
|
CanonicalHost(google, http.StatusFound)(testHandler).ServeHTTP(rr, r)
|
||
|
|
||
|
want := google + r.URL.Path + "?" + querystring
|
||
|
if rr.Header().Get("Location") != want {
|
||
|
t.Fatalf("bad re-direct: got %q want %q", rr.Header().Get("Location"), want)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestBadDomain(t *testing.T) {
|
||
|
rr := httptest.NewRecorder()
|
||
|
r := newRequest("GET", "http://www.example.com/")
|
||
|
|
||
|
testHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})
|
||
|
|
||
|
// Test a bad domain - should return 200 OK.
|
||
|
CanonicalHost("%", http.StatusFound)(testHandler).ServeHTTP(rr, r)
|
||
|
|
||
|
if rr.Code != http.StatusOK {
|
||
|
t.Fatalf("bad status: got %v want %v", rr.Code, http.StatusOK)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestEmptyHost(t *testing.T) {
|
||
|
rr := httptest.NewRecorder()
|
||
|
r := newRequest("GET", "http://www.example.com/")
|
||
|
|
||
|
testHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})
|
||
|
|
||
|
// Test a domain that returns an empty url.Host from url.Parse.
|
||
|
CanonicalHost("hello.com", http.StatusFound)(testHandler).ServeHTTP(rr, r)
|
||
|
|
||
|
if rr.Code != http.StatusOK {
|
||
|
t.Fatalf("bad status: got %v want %v", rr.Code, http.StatusOK)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestHeaderWrites(t *testing.T) {
|
||
|
gorilla := "http://www.gorillatoolkit.org"
|
||
|
|
||
|
testHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||
|
w.WriteHeader(200)
|
||
|
})
|
||
|
|
||
|
// Catch the log output to ensure we don't write multiple headers.
|
||
|
var b bytes.Buffer
|
||
|
buf := bufio.NewWriter(&b)
|
||
|
tl := log.New(buf, "test: ", log.Lshortfile)
|
||
|
|
||
|
srv := httptest.NewServer(
|
||
|
CanonicalHost(gorilla, http.StatusFound)(testHandler))
|
||
|
defer srv.Close()
|
||
|
srv.Config.ErrorLog = tl
|
||
|
|
||
|
_, err := http.Get(srv.URL)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
err = buf.Flush()
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
// We rely on the error not changing: net/http does not export it.
|
||
|
if strings.Contains(b.String(), "multiple response.WriteHeader calls") {
|
||
|
t.Fatalf("re-direct did not return early: multiple header writes")
|
||
|
}
|
||
|
}
|