1 // Copyright 2017 The Gorilla WebSocket Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
17 type netDialerFunc func(network, addr string) (net.Conn, error)
19 func (fn netDialerFunc) Dial(network, addr string) (net.Conn, error) {
20 return fn(network, addr)
24 proxy_RegisterDialerType("http", func(proxyURL *url.URL, forwardDialer proxy_Dialer) (proxy_Dialer, error) {
25 return &httpProxyDialer{proxyURL: proxyURL, fowardDial: forwardDialer.Dial}, nil
29 type httpProxyDialer struct {
31 fowardDial func(network, addr string) (net.Conn, error)
34 func (hpd *httpProxyDialer) Dial(network string, addr string) (net.Conn, error) {
35 hostPort, _ := hostPortNoPort(hpd.proxyURL)
36 conn, err := hpd.fowardDial(network, hostPort)
41 connectHeader := make(http.Header)
42 if user := hpd.proxyURL.User; user != nil {
43 proxyUser := user.Username()
44 if proxyPassword, passwordSet := user.Password(); passwordSet {
45 credential := base64.StdEncoding.EncodeToString([]byte(proxyUser + ":" + proxyPassword))
46 connectHeader.Set("Proxy-Authorization", "Basic "+credential)
50 connectReq := &http.Request{
52 URL: &url.URL{Opaque: addr},
54 Header: connectHeader,
57 if err := connectReq.Write(conn); err != nil {
62 // Read response. It's OK to use and discard buffered reader here becaue
63 // the remote server does not speak until spoken to.
64 br := bufio.NewReader(conn)
65 resp, err := http.ReadResponse(br, connectReq)
71 if resp.StatusCode != 200 {
73 f := strings.SplitN(resp.Status, " ", 2)
74 return nil, errors.New(f[1])