OSDN Git Service

libgo: Update to weekly.2011-12-02.
[pf3gnuchains/gcc-fork.git] / libgo / go / 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         "crypto/tls"
10         "io"
11         "net"
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.ParseRequest(server)
30         if err != nil {
31                 return
32         }
33         config.Origin, err = url.ParseRequest(origin)
34         if err != nil {
35                 return
36         }
37         return
38 }
39
40 // NewClient creates a new WebSocket client connection over rwc.
41 func NewClient(config *Config, rwc io.ReadWriteCloser) (ws *Conn, err error) {
42         br := bufio.NewReader(rwc)
43         bw := bufio.NewWriter(rwc)
44         switch config.Version {
45         case ProtocolVersionHixie75:
46                 err = hixie75ClientHandshake(config, br, bw)
47         case ProtocolVersionHixie76, ProtocolVersionHybi00:
48                 err = hixie76ClientHandshake(config, br, bw)
49         case ProtocolVersionHybi08, ProtocolVersionHybi13:
50                 err = hybiClientHandshake(config, br, bw)
51         default:
52                 err = ErrBadProtocolVersion
53         }
54         if err != nil {
55                 return
56         }
57         buf := bufio.NewReadWriter(br, bw)
58         switch config.Version {
59         case ProtocolVersionHixie75, ProtocolVersionHixie76, ProtocolVersionHybi00:
60                 ws = newHixieClientConn(config, buf, rwc)
61         case ProtocolVersionHybi08, ProtocolVersionHybi13:
62                 ws = newHybiClientConn(config, buf, rwc)
63         }
64         return
65 }
66
67 /*
68 Dial opens a new client connection to a WebSocket.
69
70 A trivial example client:
71
72         package main
73
74         import (
75                 "log"
76                 "net/http"
77                 "strings"
78                 "websocket"
79         )
80
81         func main() {
82                 origin := "http://localhost/"
83                 url := "ws://localhost/ws" 
84                 ws, err := websocket.Dial(url, "", origin)
85                 if err != nil {
86                         log.Fatal(err)
87                 }
88                 if _, err := ws.Write([]byte("hello, world!\n")); err != nil {
89                         log.Fatal(err)
90                 }
91                 var msg = make([]byte, 512);
92                 if n, err := ws.Read(msg); err != nil {
93                         log.Fatal(err)
94                 }
95                 // use msg[0:n]
96         }
97 */
98 func Dial(url_, protocol, origin string) (ws *Conn, err error) {
99         config, err := NewConfig(url_, origin)
100         if err != nil {
101                 return nil, err
102         }
103         return DialConfig(config)
104 }
105
106 // DialConfig opens a new client connection to a WebSocket with a config.
107 func DialConfig(config *Config) (ws *Conn, err error) {
108         var client net.Conn
109         if config.Location == nil {
110                 return nil, &DialError{config, ErrBadWebSocketLocation}
111         }
112         if config.Origin == nil {
113                 return nil, &DialError{config, ErrBadWebSocketOrigin}
114         }
115         switch config.Location.Scheme {
116         case "ws":
117                 client, err = net.Dial("tcp", config.Location.Host)
118
119         case "wss":
120                 client, err = tls.Dial("tcp", config.Location.Host, config.TlsConfig)
121
122         default:
123                 err = ErrBadScheme
124         }
125         if err != nil {
126                 goto Error
127         }
128
129         ws, err = NewClient(config, client)
130         if err != nil {
131                 goto Error
132         }
133         return
134
135 Error:
136         return nil, &DialError{config, err}
137 }