* inclhack.def (aix_once_init_[12]): New fixes.
[official-gcc.git] / libgo / go / websocket / client.go
blobb7eaafda163bfddea7f837f82bbb54ad1ab2ab87
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.
5 package websocket
7 import (
8 "bufio"
9 "crypto/tls"
10 "io"
11 "net"
12 "os"
13 "url"
16 // DialError is an error that occurs while dialling a websocket server.
17 type DialError struct {
18 *Config
19 Error os.Error
22 func (e *DialError) String() string {
23 return "websocket.Dial " + e.Config.Location.String() + ": " + e.Error.String()
26 // NewConfig creates a new WebSocket config for client connection.
27 func NewConfig(server, origin string) (config *Config, err os.Error) {
28 config = new(Config)
29 config.Version = ProtocolVersionHybi13
30 config.Location, err = url.ParseRequest(server)
31 if err != nil {
32 return
34 config.Origin, err = url.ParseRequest(origin)
35 if err != nil {
36 return
38 return
41 // NewClient creates a new WebSocket client connection over rwc.
42 func NewClient(config *Config, rwc io.ReadWriteCloser) (ws *Conn, err os.Error) {
43 br := bufio.NewReader(rwc)
44 bw := bufio.NewWriter(rwc)
45 switch config.Version {
46 case ProtocolVersionHixie75:
47 err = hixie75ClientHandshake(config, br, bw)
48 case ProtocolVersionHixie76, ProtocolVersionHybi00:
49 err = hixie76ClientHandshake(config, br, bw)
50 case ProtocolVersionHybi08, ProtocolVersionHybi13:
51 err = hybiClientHandshake(config, br, bw)
52 default:
53 err = ErrBadProtocolVersion
55 if err != nil {
56 return
58 buf := bufio.NewReadWriter(br, bw)
59 switch config.Version {
60 case ProtocolVersionHixie75, ProtocolVersionHixie76, ProtocolVersionHybi00:
61 ws = newHixieClientConn(config, buf, rwc)
62 case ProtocolVersionHybi08, ProtocolVersionHybi13:
63 ws = newHybiClientConn(config, buf, rwc)
65 return
69 Dial opens a new client connection to a WebSocket.
71 A trivial example client:
73 package main
75 import (
76 "http"
77 "log"
78 "strings"
79 "websocket"
82 func main() {
83 origin := "http://localhost/"
84 url := "ws://localhost/ws"
85 ws, err := websocket.Dial(url, "", origin)
86 if err != nil {
87 log.Fatal(err)
89 if _, err := ws.Write([]byte("hello, world!\n")); err != nil {
90 log.Fatal(err)
92 var msg = make([]byte, 512);
93 if n, err := ws.Read(msg); err != nil {
94 log.Fatal(err)
96 // use msg[0:n]
99 func Dial(url_, protocol, origin string) (ws *Conn, err os.Error) {
100 config, err := NewConfig(url_, origin)
101 if err != nil {
102 return nil, err
104 return DialConfig(config)
107 // DialConfig opens a new client connection to a WebSocket with a config.
108 func DialConfig(config *Config) (ws *Conn, err os.Error) {
109 var client net.Conn
110 if config.Location == nil {
111 return nil, &DialError{config, ErrBadWebSocketLocation}
113 if config.Origin == nil {
114 return nil, &DialError{config, ErrBadWebSocketOrigin}
116 switch config.Location.Scheme {
117 case "ws":
118 client, err = net.Dial("tcp", config.Location.Host)
120 case "wss":
121 client, err = tls.Dial("tcp", config.Location.Host, config.TlsConfig)
123 default:
124 err = ErrBadScheme
126 if err != nil {
127 goto Error
130 ws, err = NewClient(config, client)
131 if err != nil {
132 goto Error
134 return
136 Error:
137 return nil, &DialError{config, err}