header map[string]string // reply header parameters
written int64 // number of bytes written in body
status int // status code passed to WriteHeader
+ usingTLS bool // a flag indicating connection over TLS
}
// Create new connection from rwc.
}
c.handler = handler
c.rwc = rwc
+ _, c.usingTLS = rwc.(*tls.Conn)
br := bufio.NewReader(rwc)
bw := bufio.NewWriter(rwc)
c.buf = bufio.NewReadWriter(br, bw)
return req, nil
}
+// UsingTLS returns true if the connection uses transport layer security (TLS).
+func (c *Conn) UsingTLS() bool {
+ return c.usingTLS
+}
+
// SetHeader sets a header line in the eventual reply.
// For example, SetHeader("Content-Type", "text/html; charset=utf-8")
// will result in the header line
"bufio"
"bytes"
"container/vector"
+ "crypto/tls"
"fmt"
"http"
"io"
}
var (
+ ErrBadScheme = os.ErrorString("bad scheme")
ErrBadStatus = &ProtocolError{"bad status"}
ErrBadUpgrade = &ProtocolError{"missing or bad upgrade"}
ErrBadWebSocketOrigin = &ProtocolError{"missing or bad WebSocket-Origin"}
secKeyRandomChars [0x30 - 0x21 + 0x7F - 0x3A]byte
)
+type DialError struct {
+ URL string
+ Protocol string
+ Origin string
+ Error os.Error
+}
+
+func (e *DialError) String() string {
+ return "websocket.Dial " + e.URL + ": " + e.Error.String()
+}
+
func init() {
i := 0
for ch := byte(0x21); ch < 0x30; ch++ {
}
*/
func Dial(url, protocol, origin string) (ws *Conn, err os.Error) {
+ var client net.Conn
+
parsedUrl, err := http.ParseURL(url)
if err != nil {
- return
+ goto Error
+ }
+
+ switch parsedUrl.Scheme {
+ case "ws":
+ client, err = net.Dial("tcp", "", parsedUrl.Host)
+
+ case "wss":
+ client, err = tls.Dial("tcp", "", parsedUrl.Host)
+
+ default:
+ err = ErrBadScheme
}
- client, err := net.Dial("tcp", "", parsedUrl.Host)
if err != nil {
- return
+ goto Error
+ }
+
+ ws, err = newClient(parsedUrl.RawPath, parsedUrl.Host, origin, url, protocol, client, handshake)
+ if err != nil {
+ goto Error
}
- return newClient(parsedUrl.RawPath, parsedUrl.Host, origin, url, protocol, client, handshake)
+ return
+
+Error:
+ return nil, &DialError{url, protocol, origin, err}
}
/*
return
}
- location := "ws://" + req.Host + req.URL.RawPath
+ var location string
+ if c.UsingTLS() {
+ location = "wss://" + req.Host + req.URL.RawPath
+ } else {
+ location = "ws://" + req.Host + req.URL.RawPath
+ }
// Step 4. get key number in Sec-WebSocket-Key<n> fields.
keyNumber1 := getKeyNumber(key1)
return
}
defer rwc.Close()
- location := "ws://" + req.Host + req.URL.RawPath
+
+ var location string
+ if c.UsingTLS() {
+ location = "wss://" + req.Host + req.URL.RawPath
+ } else {
+ location = "ws://" + req.Host + req.URL.RawPath
+ }
// TODO(ukai): verify origin,location,protocol.