~nskaggs/+junk/xenial-test

« back to all changes in this revision

Viewing changes to src/github.com/juju/utils/http_test.go

  • Committer: Nicholas Skaggs
  • Date: 2016-10-24 20:56:05 UTC
  • Revision ID: nicholas.skaggs@canonical.com-20161024205605-z8lta0uvuhtxwzwl
Initi with beta15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2013 Canonical Ltd.
 
2
// Licensed under the LGPLv3, see LICENCE file for details.
 
3
 
 
4
package utils_test
 
5
 
 
6
import (
 
7
        "encoding/base64"
 
8
        "net"
 
9
        "net/http"
 
10
        "net/http/httptest"
 
11
        "os"
 
12
        "strings"
 
13
 
 
14
        "github.com/juju/testing"
 
15
        jc "github.com/juju/testing/checkers"
 
16
        gc "gopkg.in/check.v1"
 
17
 
 
18
        "github.com/juju/utils"
 
19
)
 
20
 
 
21
func init() {
 
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
 
25
        // used.
 
26
        os.Setenv("http_proxy", "")
 
27
        os.Setenv("HTTP_PROXY", "")
 
28
}
 
29
 
 
30
type httpSuite struct {
 
31
        testing.IsolationSuite
 
32
        Server *httptest.Server
 
33
}
 
34
 
 
35
var _ = gc.Suite(&httpSuite{})
 
36
 
 
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) {}))
 
44
}
 
45
 
 
46
func (s *httpSuite) TearDownTest(c *gc.C) {
 
47
        if s.Server != nil {
 
48
                s.Server.Close()
 
49
        }
 
50
        s.IsolationSuite.TearDownTest(c)
 
51
}
 
52
 
 
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")
 
56
}
 
57
 
 
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")
 
62
 
 
63
        client1 := utils.GetValidatingHTTPClient()
 
64
        c.Assert(client1, gc.Not(gc.Equals), client)
 
65
}
 
66
 
 
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)
 
71
        resp.Body.Close()
 
72
        c.Assert(resp.StatusCode, gc.Equals, http.StatusOK)
 
73
 
 
74
        client1 := utils.GetNonValidatingHTTPClient()
 
75
        c.Assert(client1, gc.Not(gc.Equals), client)
 
76
}
 
77
 
 
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")
 
89
}
 
90
 
 
91
func (s *httpSuite) TestParseBasicAuthHeader(c *gc.C) {
 
92
        tests := []struct {
 
93
                about          string
 
94
                h              http.Header
 
95
                expectUserid   string
 
96
                expectPassword string
 
97
                expectError    string
 
98
        }{{
 
99
                about:       "no Authorization header",
 
100
                h:           http.Header{},
 
101
                expectError: "invalid or missing HTTP auth header",
 
102
        }, {
 
103
                about: "empty Authorization header",
 
104
                h: http.Header{
 
105
                        "Authorization": {""},
 
106
                },
 
107
                expectError: "invalid or missing HTTP auth header",
 
108
        }, {
 
109
                about: "Not basic encoding",
 
110
                h: http.Header{
 
111
                        "Authorization": {"NotBasic stuff"},
 
112
                },
 
113
                expectError: "invalid or missing HTTP auth header",
 
114
        }, {
 
115
                about: "invalid base64",
 
116
                h: http.Header{
 
117
                        "Authorization": {"Basic not-base64"},
 
118
                },
 
119
                expectError: "invalid HTTP auth encoding",
 
120
        }, {
 
121
                about: "no ':'",
 
122
                h: http.Header{
 
123
                        "Authorization": {"Basic " + base64.StdEncoding.EncodeToString([]byte("aladdin"))},
 
124
                },
 
125
                expectError: "invalid HTTP auth contents",
 
126
        }, {
 
127
                about: "valid credentials",
 
128
                h: http.Header{
 
129
                        "Authorization": {"Basic " + base64.StdEncoding.EncodeToString([]byte("aladdin:open sesame"))},
 
130
                },
 
131
                expectUserid:   "aladdin",
 
132
                expectPassword: "open sesame",
 
133
        }}
 
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)
 
141
                } else {
 
142
                        c.Assert(err, gc.IsNil)
 
143
                }
 
144
        }
 
145
}
 
146
 
 
147
type dialSuite struct {
 
148
        testing.IsolationSuite
 
149
}
 
150
 
 
151
var _ = gc.Suite(&dialSuite{})
 
152
 
 
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`)
 
159
}
 
160
 
 
161
func (s *dialSuite) assertDial(c *gc.C, addr string) {
 
162
        dialed := false
 
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)
 
166
                dialed = true
 
167
                return nil, nil
 
168
        })
 
169
        _, err := utils.Dial("tcp", addr)
 
170
        c.Assert(err, gc.IsNil)
 
171
        c.Assert(dialed, jc.IsTrue)
 
172
}
 
173
 
 
174
func (s *dialSuite) TestDialAllowsNonLocal(c *gc.C) {
 
175
        s.PatchValue(&utils.OutgoingAccessAllowed, true)
 
176
        s.assertDial(c, "10.0.0.1:80")
 
177
}
 
178
 
 
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")
 
183
}
 
184
 
 
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`)
 
189
}
 
190
 
 
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`)
 
195
}