aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/golang.org/x/net/websocket/client.go
blob: 69a4ac7eefecc1276bbfbe6cc49e0cd9218dafe6 (plain) (blame)
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
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package websocket

import (
    "bufio"
    "io"
    "net"
    "net/http"
    "net/url"
)

// DialError is an error that occurs while dialling a websocket server.
type DialError struct {
    *Config
    Err error
}

func (e *DialError) Error() string {
    return "websocket.Dial " + e.Config.Location.String() + ": " + e.Err.Error()
}

// NewConfig creates a new WebSocket config for client connection.
func NewConfig(server, origin string) (config *Config, err error) {
    config = new(Config)
    config.Version = ProtocolVersionHybi13
    config.Location, err = url.ParseRequestURI(server)
    if err != nil {
        return
    }
    config.Origin, err = url.ParseRequestURI(origin)
    if err != nil {
        return
    }
    config.Header = http.Header(make(map[string][]string))
    return
}

// NewClient creates a new WebSocket client connection over rwc.
func NewClient(config *Config, rwc io.ReadWriteCloser) (ws *Conn, err error) {
    br := bufio.NewReader(rwc)
    bw := bufio.NewWriter(rwc)
    err = hybiClientHandshake(config, br, bw)
    if err != nil {
        return
    }
    buf := bufio.NewReadWriter(br, bw)
    ws = newHybiClientConn(config, buf, rwc)
    return
}

// Dial opens a new client connection to a WebSocket.
func Dial(url_, protocol, origin string) (ws *Conn, err error) {
    config, err := NewConfig(url_, origin)
    if err != nil {
        return nil, err
    }
    if protocol != "" {
        config.Protocol = []string{protocol}
    }
    return DialConfig(config)
}

var portMap = map[string]string{
    "ws":  "80",
    "wss": "443",
}

func parseAuthority(location *url.URL) string {
    if _, ok := portMap[location.Scheme]; ok {
        if _, _, err := net.SplitHostPort(location.Host); err != nil {
            return net.JoinHostPort(location.Host, portMap[location.Scheme])
        }
    }
    return location.Host
}

// DialConfig opens a new client connection to a WebSocket with a config.
func DialConfig(config *Config) (ws *Conn, err error) {
    var client net.Conn
    if config.Location == nil {
        return nil, &DialError{config, ErrBadWebSocketLocation}
    }
    if config.Origin == nil {
        return nil, &DialError{config, ErrBadWebSocketOrigin}
    }
    dialer := config.Dialer
    if dialer == nil {
        dialer = &net.Dialer{}
    }
    client, err = dialWithDialer(dialer, config)
    if err != nil {
        goto Error
    }
    ws, err = NewClient(config, client)
    if err != nil {
        client.Close()
        goto Error
    }
    return

Error:
    return nil, &DialError{config, err}
}