1
// Copyright 2013 Canonical Ltd.
2
// Licensed under the LGPLv3, see LICENCE file for details.
14
"github.com/juju/testing"
15
jc "github.com/juju/testing/checkers"
16
gc "gopkg.in/check.v1"
18
"github.com/juju/utils"
22
// The default Proxy implementation for HTTP transports,
23
// ProxyFromEnvironment, uses a sync.Once in Go 1.3 onwards.
24
// No tests should be dialing out, so no proxy should be
26
os.Setenv("http_proxy", "")
27
os.Setenv("HTTP_PROXY", "")
30
type httpSuite struct {
31
testing.IsolationSuite
32
Server *httptest.Server
35
var _ = gc.Suite(&httpSuite{})
37
func (s *httpSuite) SetUpTest(c *gc.C) {
38
s.IsolationSuite.SetUpTest(c)
39
// NewTLSServer returns a server which serves TLS, but
40
// its certificates are not validated by the default
41
// OS certificates, so any HTTPS request will fail
42
// unless a non-validating client is used.
43
s.Server = httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}))
46
func (s *httpSuite) TearDownTest(c *gc.C) {
50
s.IsolationSuite.TearDownTest(c)
53
func (s *httpSuite) TestDefaultClientFails(c *gc.C) {
54
_, err := http.Get(s.Server.URL)
55
c.Assert(err, gc.ErrorMatches, "(.|\n)*x509: certificate signed by unknown authority")
58
func (s *httpSuite) TestValidatingClientGetter(c *gc.C) {
59
client := utils.GetValidatingHTTPClient()
60
_, err := client.Get(s.Server.URL)
61
c.Assert(err, gc.ErrorMatches, "(.|\n)*x509: certificate signed by unknown authority")
63
client1 := utils.GetValidatingHTTPClient()
64
c.Assert(client1, gc.Not(gc.Equals), client)
67
func (s *httpSuite) TestNonValidatingClientGetter(c *gc.C) {
68
client := utils.GetNonValidatingHTTPClient()
69
resp, err := client.Get(s.Server.URL)
70
c.Assert(err, gc.IsNil)
72
c.Assert(resp.StatusCode, gc.Equals, http.StatusOK)
74
client1 := utils.GetNonValidatingHTTPClient()
75
c.Assert(client1, gc.Not(gc.Equals), client)
78
func (s *httpSuite) TestBasicAuthHeader(c *gc.C) {
79
header := utils.BasicAuthHeader("eric", "sekrit")
80
c.Assert(len(header), gc.Equals, 1)
81
auth := header.Get("Authorization")
82
fields := strings.Fields(auth)
83
c.Assert(len(fields), gc.Equals, 2)
84
basic, encoded := fields[0], fields[1]
85
c.Assert(basic, gc.Equals, "Basic")
86
decoded, err := base64.StdEncoding.DecodeString(encoded)
87
c.Assert(err, gc.IsNil)
88
c.Assert(string(decoded), gc.Equals, "eric:sekrit")
91
func (s *httpSuite) TestParseBasicAuthHeader(c *gc.C) {
99
about: "no Authorization header",
101
expectError: "invalid or missing HTTP auth header",
103
about: "empty Authorization header",
105
"Authorization": {""},
107
expectError: "invalid or missing HTTP auth header",
109
about: "Not basic encoding",
111
"Authorization": {"NotBasic stuff"},
113
expectError: "invalid or missing HTTP auth header",
115
about: "invalid base64",
117
"Authorization": {"Basic not-base64"},
119
expectError: "invalid HTTP auth encoding",
123
"Authorization": {"Basic " + base64.StdEncoding.EncodeToString([]byte("aladdin"))},
125
expectError: "invalid HTTP auth contents",
127
about: "valid credentials",
129
"Authorization": {"Basic " + base64.StdEncoding.EncodeToString([]byte("aladdin:open sesame"))},
131
expectUserid: "aladdin",
132
expectPassword: "open sesame",
134
for i, test := range tests {
135
c.Logf("test %d: %s", i, test.about)
136
u, p, err := utils.ParseBasicAuthHeader(test.h)
137
c.Assert(u, gc.Equals, test.expectUserid)
138
c.Assert(p, gc.Equals, test.expectPassword)
139
if test.expectError != "" {
140
c.Assert(err.Error(), gc.Equals, test.expectError)
142
c.Assert(err, gc.IsNil)
147
type dialSuite struct {
148
testing.IsolationSuite
151
var _ = gc.Suite(&dialSuite{})
153
func (s *dialSuite) TestDialRejectsNonLocal(c *gc.C) {
154
s.PatchValue(&utils.OutgoingAccessAllowed, false)
155
_, err := utils.Dial("tcp", "10.0.0.1:80")
156
c.Assert(err, gc.ErrorMatches, `access to address "10.0.0.1:80" not allowed`)
157
_, err = utils.Dial("tcp", "somehost:80")
158
c.Assert(err, gc.ErrorMatches, `access to address "somehost:80" not allowed`)
161
func (s *dialSuite) assertDial(c *gc.C, addr string) {
163
s.PatchValue(utils.NetDial, func(network, addr string) (net.Conn, error) {
164
c.Assert(network, gc.Equals, "tcp")
165
c.Assert(addr, gc.Equals, addr)
169
_, err := utils.Dial("tcp", addr)
170
c.Assert(err, gc.IsNil)
171
c.Assert(dialed, jc.IsTrue)
174
func (s *dialSuite) TestDialAllowsNonLocal(c *gc.C) {
175
s.PatchValue(&utils.OutgoingAccessAllowed, true)
176
s.assertDial(c, "10.0.0.1:80")
179
func (s *dialSuite) TestDialAllowsLocal(c *gc.C) {
180
s.PatchValue(&utils.OutgoingAccessAllowed, false)
181
s.assertDial(c, "127.0.0.1:1234")
182
s.assertDial(c, "localhost:1234")
185
func (s *dialSuite) TestInsecureClientNoAccess(c *gc.C) {
186
s.PatchValue(&utils.OutgoingAccessAllowed, false)
187
_, err := utils.GetNonValidatingHTTPClient().Get("http://10.0.0.1:1234")
188
c.Assert(err, gc.ErrorMatches, `.*access to address "10.0.0.1:1234" not allowed`)
191
func (s *dialSuite) TestSecureClientNoAccess(c *gc.C) {
192
s.PatchValue(&utils.OutgoingAccessAllowed, false)
193
_, err := utils.GetValidatingHTTPClient().Get("http://10.0.0.1:1234")
194
c.Assert(err, gc.ErrorMatches, `.*access to address "10.0.0.1:1234" not allowed`)