~ancarda/tls-redirector

ref: e4636a57dc63f656f5b8db32dd716c84038a09be tls-redirector/http_test.go -rw-r--r-- 3.3 KiB
e4636a57Mark Dain 2.4: Nice looking HTML error pages 8 months ago
                                                                                
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
package main

import (
	"io/ioutil"
	"math/rand"
	"net/http"
	"net/http/httptest"
	"os"
	"reflect"
	"testing"
	"testing/quick"
	"time"

	"github.com/spf13/afero"
	"github.com/stretchr/testify/assert"
)

const (
	TextPlain = "text/plain"
	TextHTML  = "text/html; charset=utf-8"
)

func randomString() string {
	v, ok := quick.Value(reflect.TypeOf(""),
		rand.New(rand.NewSource(time.Now().Unix())))

	if !ok {
		panic("wasn't able to generate a string")
	}

	return v.String()
}

func assertionsCommonToAllResponses(t *testing.T, res *http.Response) {
	assert.Equal(t, "nosniff", res.Header.Get("X-Content-Type-Options"))
	assert.Equal(t, "tls-redirector/2.4", res.Header.Get("Server"))
}

func TestNewApp_UsesRealFileSystem(t *testing.T) {
	app := newApp("")

	exists, err := afero.DirExists(app.fs, os.TempDir())
	assert.True(t, exists)
	assert.Nil(t, err)
}

func TestNewApp_StoresEnvSettings(t *testing.T) {
	someString := randomString()

	app := newApp(someString)
	assert.Equal(t, someString, app.acmeChallengeDir)
}

func TestServer_ServeACME_404(t *testing.T) {
	rr := httptest.NewRecorder()
	r, _ := http.NewRequest(http.MethodGet, "http://nowhere.invalid/.well-known/acme-challenge/z", nil)
	app{afero.NewMemMapFs(), "/"}.ServeHTTP(rr, r)
	res := rr.Result()

	assert.Equal(t, http.StatusNotFound, res.StatusCode)
	assert.Equal(t, TextHTML, res.Header.Get("Content-Type"))
	assertionsCommonToAllResponses(t, res)

	body, _ := ioutil.ReadAll(res.Body)
	assert.Contains(t, string(body), "File Not Found")
}

func TestServer_ServeACME_HappyPath(t *testing.T) {
	fs := afero.NewMemMapFs()
	f, _ := fs.Create("/ok")
	f.Write([]byte("12345678"))

	rr := httptest.NewRecorder()
	r, _ := http.NewRequest(http.MethodGet, "http://nowhere.invalid/.well-known/acme-challenge/ok", nil)
	app{fs, "/"}.ServeHTTP(rr, r)
	res := rr.Result()

	assert.Equal(t, http.StatusOK, res.StatusCode)
	assert.Equal(t, TextPlain, res.Header.Get("Content-Type"))
	assertionsCommonToAllResponses(t, res)

	body, _ := ioutil.ReadAll(res.Body)
	assert.Equal(t, "12345678", string(body))
}

func TestServer_NoHostHeader_WillError(t *testing.T) {
	rr := httptest.NewRecorder()
	r, _ := http.NewRequest(http.MethodGet, "", nil)
	app{}.ServeHTTP(rr, r)
	res := rr.Result()

	assert.Equal(t, http.StatusBadRequest, res.StatusCode)
	assert.Equal(t, TextHTML, res.Header.Get("Content-Type"))
	assertionsCommonToAllResponses(t, res)

	body, _ := ioutil.ReadAll(res.Body)
	assert.Contains(t, string(body), "header is empty or wasn't sent")
}

func TestServer_IPAddressHostHeader_IsRejected(t *testing.T) {
	rr := httptest.NewRecorder()
	r, _ := http.NewRequest(http.MethodGet, "http://127.0.0.1/", nil)
	app{}.ServeHTTP(rr, r)
	res := rr.Result()

	assert.Equal(t, http.StatusBadRequest, res.StatusCode)
	assert.Equal(t, TextHTML, res.Header.Get("Content-Type"))
	assertionsCommonToAllResponses(t, res)

	body, _ := ioutil.ReadAll(res.Body)
	assert.Contains(t, string(body), "looks like an IP address")
}

func TestServer_HappyPath(t *testing.T) {
	rr := httptest.NewRecorder()
	r, _ := http.NewRequest(http.MethodGet, "http://nowhere.invalid/", nil)
	app{}.ServeHTTP(rr, r)
	res := rr.Result()

	assert.Equal(t, http.StatusMovedPermanently, res.StatusCode)
	assert.Equal(t, TextHTML, res.Header.Get("Content-Type"))
	assertionsCommonToAllResponses(t, res)
	assert.Equal(t, "https://nowhere.invalid/", res.Header.Get("Location"))
}