Skip to content

Commit 6f5e534

Browse files
authored
Return https if r.TLS is not nil (#126)
`go-httpbin` was incorrectly returning `http` as the scheme for its URL if you ran it with TLS specified via `HTTPS_CERT_FILE` and `HTTPS_KEY_FILE`. Update it to return https as the scheme in this case by checking if `r.TLS` is not nil Before: ``` $ mkcert test $ docker run -e HTTPS_CERT_FILE='/tmp/test.pem' -e HTTPS_KEY_FILE='/tmp/test-key.pem' -p 8080:8080 -v $(pwd):/tmp mccutchen/go-httpbin $ curl -sk https://localhost:8080/get | jq -r .url http://localhost:8080/get ``` After (TLS): ``` $ docker run -e HTTPS_CERT_FILE='/tmp/test.pem' -e HTTPS_KEY_FILE='/tmp/test-key.pem' -p 8080:8080 -v $(pwd):/tmp llimllib/go-httpbin $ curl -sk https://localhost:8080/get | jq -r .url https://localhost:8080/get ``` After (no TLS): ``` $ docker run -p 8080:8080 llimllib/go-httpbin $ curl -sk http://localhost:8080/get | jq -r .url http://localhost:8080/get ``` I got the idea for how to check the scheme from [this SO post](https://stackoverflow.com/a/61446922/42559)
1 parent a70a847 commit 6f5e534

File tree

2 files changed

+81
-0
lines changed

2 files changed

+81
-0
lines changed

httpbin/helpers.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ func getURL(r *http.Request) *url.URL {
5959
if scheme == "" && r.Header.Get("X-Forwarded-Ssl") == "on" {
6060
scheme = "https"
6161
}
62+
if scheme == "" && r.TLS != nil {
63+
scheme = "https"
64+
}
6265
if scheme == "" {
6366
scheme = "http"
6467
}

httpbin/helpers_test.go

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package httpbin
22

33
import (
4+
"crypto/tls"
45
"fmt"
56
"io"
67
"net/http"
8+
"net/url"
79
"reflect"
810
"testing"
911
"time"
@@ -33,6 +35,82 @@ func assertError(t *testing.T, got, expected error) {
3335
}
3436
}
3537

38+
func mustParse(s string) *url.URL {
39+
u, e := url.Parse(s)
40+
if e != nil {
41+
panic(e)
42+
}
43+
return u
44+
}
45+
46+
func TestGetURL(t *testing.T) {
47+
baseUrl, _ := url.Parse("http://example.com/something?foo=bar")
48+
tests := []struct {
49+
name string
50+
input *http.Request
51+
expected *url.URL
52+
}{
53+
{
54+
"basic test",
55+
&http.Request{
56+
URL: baseUrl,
57+
Header: http.Header{},
58+
},
59+
mustParse("http://example.com/something?foo=bar"),
60+
},
61+
{
62+
"if TLS is not nil, scheme is https",
63+
&http.Request{
64+
URL: baseUrl,
65+
TLS: &tls.ConnectionState{},
66+
Header: http.Header{},
67+
},
68+
mustParse("https://example.com/something?foo=bar"),
69+
},
70+
{
71+
"if X-Forwarded-Proto is present, scheme is that value",
72+
&http.Request{
73+
URL: baseUrl,
74+
Header: http.Header{"X-Forwarded-Proto": {"https"}},
75+
},
76+
mustParse("https://example.com/something?foo=bar"),
77+
},
78+
{
79+
"if X-Forwarded-Proto is present, scheme is that value (2)",
80+
&http.Request{
81+
URL: baseUrl,
82+
Header: http.Header{"X-Forwarded-Proto": {"bananas"}},
83+
},
84+
mustParse("bananas://example.com/something?foo=bar"),
85+
},
86+
{
87+
"if X-Forwarded-Ssl is 'on', scheme is https",
88+
&http.Request{
89+
URL: baseUrl,
90+
Header: http.Header{"X-Forwarded-Ssl": {"on"}},
91+
},
92+
mustParse("https://example.com/something?foo=bar"),
93+
},
94+
{
95+
"if request URL host is empty, host is request.host",
96+
&http.Request{
97+
URL: mustParse("http:///just/a/path"),
98+
Host: "zombo.com",
99+
},
100+
mustParse("http://zombo.com/just/a/path"),
101+
},
102+
}
103+
104+
for _, test := range tests {
105+
t.Run(test.name, func(t *testing.T) {
106+
res := getURL(test.input)
107+
if res.String() != test.expected.String() {
108+
t.Fatalf("expected %s, got %s", test.expected, res)
109+
}
110+
})
111+
}
112+
}
113+
36114
func TestParseDuration(t *testing.T) {
37115
okTests := []struct {
38116
input string

0 commit comments

Comments
 (0)