OSDN Git Service

new repo
[bytom/vapor.git] / vendor / golang.org / x / net / websocket / client.go
1 // Copyright 2009 The Go 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.
4
5 package websocket
6
7 import (
8         "bufio"
9         "io"
10         "net"
11         "net/http"
12         "net/url"
13 )
14
15 // DialError is an error that occurs while dialling a websocket server.
16 type DialError struct {
17         *Config
18         Err error
19 }
20
21 func (e *DialError) Error() string {
22         return "websocket.Dial " + e.Config.Location.String() + ": " + e.Err.Error()
23 }
24
25 // NewConfig creates a new WebSocket config for client connection.
26 func NewConfig(server, origin string) (config *Config, err error) {
27         config = new(Config)
28         config.Version = ProtocolVersionHybi13
29         config.Location, err = url.ParseRequestURI(server)
30         if err != nil {
31                 return
32         }
33         config.Origin, err = url.ParseRequestURI(origin)
34         if err != nil {
35                 return
36         }
37         config.Header = http.Header(make(map[string][]string))
38         return
39 }
40
41 // NewClient creates a new WebSocket client connection over rwc.
42 func NewClient(config *Config, rwc io.ReadWriteCloser) (ws *Conn, err error) {
43         br := bufio.NewReader(rwc)
44         bw := bufio.NewWriter(rwc)
45         err = hybiClientHandshake(config, br, bw)
46         if err != nil {
47                 return
48         }
49         buf := bufio.NewReadWriter(br, bw)
50         ws = newHybiClientConn(config, buf, rwc)
51         return
52 }
53
54 // Dial opens a new client connection to a WebSocket.
55 func Dial(url_, protocol, origin string) (ws *Conn, err error) {
56         config, err := NewConfig(url_, origin)
57         if err != nil {
58                 return nil, err
59         }
60         if protocol != "" {
61                 config.Protocol = []string{protocol}
62         }
63         return DialConfig(config)
64 }
65
66 var portMap = map[string]string{
67         "ws":  "80",
68         "wss": "443",
69 }
70
71 func parseAuthority(location *url.URL) string {
72         if _, ok := portMap[location.Scheme]; ok {
73                 if _, _, err := net.SplitHostPort(location.Host); err != nil {
74                         return net.JoinHostPort(location.Host, portMap[location.Scheme])
75                 }
76         }
77         return location.Host
78 }
79
80 // DialConfig opens a new client connection to a WebSocket with a config.
81 func DialConfig(config *Config) (ws *Conn, err error) {
82         var client net.Conn
83         if config.Location == nil {
84                 return nil, &DialError{config, ErrBadWebSocketLocation}
85         }
86         if config.Origin == nil {
87                 return nil, &DialError{config, ErrBadWebSocketOrigin}
88         }
89         dialer := config.Dialer
90         if dialer == nil {
91                 dialer = &net.Dialer{}
92         }
93         client, err = dialWithDialer(dialer, config)
94         if err != nil {
95                 goto Error
96         }
97         ws, err = NewClient(config, client)
98         if err != nil {
99                 client.Close()
100                 goto Error
101         }
102         return
103
104 Error:
105         return nil, &DialError{config, err}
106 }