summaryrefslogtreecommitdiff
path: root/src/pkg/websocket/server.go
diff options
context:
space:
mode:
authorOndřej Surý <ondrej@sury.org>2011-01-17 12:40:45 +0100
committerOndřej Surý <ondrej@sury.org>2011-01-17 12:40:45 +0100
commit3e45412327a2654a77944249962b3652e6142299 (patch)
treebc3bf69452afa055423cbe0c5cfa8ca357df6ccf /src/pkg/websocket/server.go
parentc533680039762cacbc37db8dc7eed074c3e497be (diff)
downloadgolang-upstream/2011.01.12.tar.gz
Imported Upstream version 2011.01.12upstream/2011.01.12
Diffstat (limited to 'src/pkg/websocket/server.go')
-rw-r--r--src/pkg/websocket/server.go75
1 files changed, 35 insertions, 40 deletions
diff --git a/src/pkg/websocket/server.go b/src/pkg/websocket/server.go
index 00b537e27..dd797f24e 100644
--- a/src/pkg/websocket/server.go
+++ b/src/pkg/websocket/server.go
@@ -5,17 +5,15 @@
package websocket
import (
- "bytes"
- "crypto/md5"
- "encoding/binary"
"http"
"io"
"strings"
)
/*
- Handler is an interface to a WebSocket.
- A trivial example server is:
+Handler is an interface to a WebSocket.
+
+A trivial example server:
package main
@@ -41,8 +39,8 @@ import (
type Handler func(*Conn)
/*
- Gets key number from Sec-WebSocket-Key<n>: field as described
- in 5.2 Sending the server's opening handshake, 4.
+Gets key number from Sec-WebSocket-Key<n>: field as described
+in 5.2 Sending the server's opening handshake, 4.
*/
func getKeyNumber(s string) (r uint32) {
// 4. Let /key-number_n/ be the digits (characters in the range
@@ -59,8 +57,8 @@ func getKeyNumber(s string) (r uint32) {
}
// ServeHTTP implements the http.Handler interface for a Web Socket
-func (f Handler) ServeHTTP(c *http.Conn, req *http.Request) {
- rwc, buf, err := c.Hijack()
+func (f Handler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
+ rwc, buf, err := w.Hijack()
if err != nil {
panic("Hijack failed: " + err.String())
return
@@ -99,7 +97,12 @@ func (f Handler) ServeHTTP(c *http.Conn, req *http.Request) {
return
}
- location := "ws://" + req.Host + req.URL.RawPath
+ var location string
+ if w.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)
@@ -122,25 +125,11 @@ func (f Handler) ServeHTTP(c *http.Conn, req *http.Request) {
part2 := keyNumber2 / space2
// Step 8. let challenge to be concatination of part1, part2 and key3.
- challenge := make([]byte, 16)
- challengeBuf := bytes.NewBuffer(challenge)
- err = binary.Write(challengeBuf, binary.BigEndian, part1)
- if err != nil {
- return
- }
- err = binary.Write(challengeBuf, binary.BigEndian, part2)
- if err != nil {
- return
- }
- if n := copy(challenge[8:], key3); n != 8 {
- return
- }
// Step 9. get MD5 fingerprint of challenge.
- h := md5.New()
- if _, err = h.Write(challenge); err != nil {
+ response, err := getChallengeResponse(part1, part2, key3)
+ if err != nil {
return
}
- response := h.Sum()
// Step 10. send response status line.
buf.WriteString("HTTP/1.1 101 WebSocket Protocol Handshake\r\n")
@@ -149,7 +138,7 @@ func (f Handler) ServeHTTP(c *http.Conn, req *http.Request) {
buf.WriteString("Connection: Upgrade\r\n")
buf.WriteString("Sec-WebSocket-Location: " + location + "\r\n")
buf.WriteString("Sec-WebSocket-Origin: " + origin + "\r\n")
- protocol, found := req.Header["Sec-WebSocket-Protocol"]
+ protocol, found := req.Header["Sec-Websocket-Protocol"]
if found {
buf.WriteString("Sec-WebSocket-Protocol: " + protocol + "\r\n")
}
@@ -166,42 +155,48 @@ func (f Handler) ServeHTTP(c *http.Conn, req *http.Request) {
/*
- Draft75Handler is an interface to a WebSocket based on
- (soon obsolete) draft-hixie-thewebsocketprotocol-75.
+Draft75Handler is an interface to a WebSocket based on the
+(soon obsolete) draft-hixie-thewebsocketprotocol-75.
*/
type Draft75Handler func(*Conn)
// ServeHTTP implements the http.Handler interface for a Web Socket.
-func (f Draft75Handler) ServeHTTP(c *http.Conn, req *http.Request) {
+func (f Draft75Handler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
if req.Method != "GET" || req.Proto != "HTTP/1.1" {
- c.WriteHeader(http.StatusBadRequest)
- io.WriteString(c, "Unexpected request")
+ w.WriteHeader(http.StatusBadRequest)
+ io.WriteString(w, "Unexpected request")
return
}
if req.Header["Upgrade"] != "WebSocket" {
- c.WriteHeader(http.StatusBadRequest)
- io.WriteString(c, "missing Upgrade: WebSocket header")
+ w.WriteHeader(http.StatusBadRequest)
+ io.WriteString(w, "missing Upgrade: WebSocket header")
return
}
if req.Header["Connection"] != "Upgrade" {
- c.WriteHeader(http.StatusBadRequest)
- io.WriteString(c, "missing Connection: Upgrade header")
+ w.WriteHeader(http.StatusBadRequest)
+ io.WriteString(w, "missing Connection: Upgrade header")
return
}
origin, found := req.Header["Origin"]
if !found {
- c.WriteHeader(http.StatusBadRequest)
- io.WriteString(c, "missing Origin header")
+ w.WriteHeader(http.StatusBadRequest)
+ io.WriteString(w, "missing Origin header")
return
}
- rwc, buf, err := c.Hijack()
+ rwc, buf, err := w.Hijack()
if err != nil {
panic("Hijack failed: " + err.String())
return
}
defer rwc.Close()
- location := "ws://" + req.Host + req.URL.RawPath
+
+ var location string
+ if w.UsingTLS() {
+ location = "wss://" + req.Host + req.URL.RawPath
+ } else {
+ location = "ws://" + req.Host + req.URL.RawPath
+ }
// TODO(ukai): verify origin,location,protocol.