summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/gorilla/handlers/canonical_test.go
blob: 615e4b0568ee29fc7d7618072b379396e7ad697b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
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")
	}
}