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")
 | 
						|
	}
 | 
						|
}
 |