From bb346a3ae1b6c250fdcb28b97280d3512a7fe219 Mon Sep 17 00:00:00 2001
From: Felix Lange <fjl@twurst.com>
Date: Tue, 17 Feb 2015 12:37:09 +0100
Subject: rpc/ws: switch to golang.org/x/net

code.google.com/p/go.net is deprecated and will cause
problems in future versions of Go.
---
 .../code.google.com/p/go.net/websocket/client.go   |  98 ----
 .../p/go.net/websocket/exampledial_test.go         |  31 --
 .../p/go.net/websocket/examplehandler_test.go      |  26 -
 .../src/code.google.com/p/go.net/websocket/hybi.go | 564 --------------------
 .../p/go.net/websocket/hybi_test.go                | 590 ---------------------
 .../code.google.com/p/go.net/websocket/server.go   | 114 ----
 .../p/go.net/websocket/websocket.go                | 411 --------------
 .../p/go.net/websocket/websocket_test.go           | 341 ------------
 .../src/golang.org/x/net/websocket/client.go       | 112 ++++
 .../golang.org/x/net/websocket/exampledial_test.go |  31 ++
 .../x/net/websocket/examplehandler_test.go         |  26 +
 .../src/golang.org/x/net/websocket/hybi.go         | 564 ++++++++++++++++++++
 .../src/golang.org/x/net/websocket/hybi_test.go    | 590 +++++++++++++++++++++
 .../src/golang.org/x/net/websocket/server.go       | 114 ++++
 .../src/golang.org/x/net/websocket/websocket.go    | 411 ++++++++++++++
 .../golang.org/x/net/websocket/websocket_test.go   | 414 +++++++++++++++
 16 files changed, 2262 insertions(+), 2175 deletions(-)
 delete mode 100644 Godeps/_workspace/src/code.google.com/p/go.net/websocket/client.go
 delete mode 100644 Godeps/_workspace/src/code.google.com/p/go.net/websocket/exampledial_test.go
 delete mode 100644 Godeps/_workspace/src/code.google.com/p/go.net/websocket/examplehandler_test.go
 delete mode 100644 Godeps/_workspace/src/code.google.com/p/go.net/websocket/hybi.go
 delete mode 100644 Godeps/_workspace/src/code.google.com/p/go.net/websocket/hybi_test.go
 delete mode 100644 Godeps/_workspace/src/code.google.com/p/go.net/websocket/server.go
 delete mode 100644 Godeps/_workspace/src/code.google.com/p/go.net/websocket/websocket.go
 delete mode 100644 Godeps/_workspace/src/code.google.com/p/go.net/websocket/websocket_test.go
 create mode 100644 Godeps/_workspace/src/golang.org/x/net/websocket/client.go
 create mode 100644 Godeps/_workspace/src/golang.org/x/net/websocket/exampledial_test.go
 create mode 100644 Godeps/_workspace/src/golang.org/x/net/websocket/examplehandler_test.go
 create mode 100644 Godeps/_workspace/src/golang.org/x/net/websocket/hybi.go
 create mode 100644 Godeps/_workspace/src/golang.org/x/net/websocket/hybi_test.go
 create mode 100644 Godeps/_workspace/src/golang.org/x/net/websocket/server.go
 create mode 100644 Godeps/_workspace/src/golang.org/x/net/websocket/websocket.go
 create mode 100644 Godeps/_workspace/src/golang.org/x/net/websocket/websocket_test.go

(limited to 'Godeps/_workspace')

diff --git a/Godeps/_workspace/src/code.google.com/p/go.net/websocket/client.go b/Godeps/_workspace/src/code.google.com/p/go.net/websocket/client.go
deleted file mode 100644
index a861bb92c..000000000
--- a/Godeps/_workspace/src/code.google.com/p/go.net/websocket/client.go
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package websocket
-
-import (
-	"bufio"
-	"crypto/tls"
-	"io"
-	"net"
-	"net/http"
-	"net/url"
-)
-
-// DialError is an error that occurs while dialling a websocket server.
-type DialError struct {
-	*Config
-	Err error
-}
-
-func (e *DialError) Error() string {
-	return "websocket.Dial " + e.Config.Location.String() + ": " + e.Err.Error()
-}
-
-// NewConfig creates a new WebSocket config for client connection.
-func NewConfig(server, origin string) (config *Config, err error) {
-	config = new(Config)
-	config.Version = ProtocolVersionHybi13
-	config.Location, err = url.ParseRequestURI(server)
-	if err != nil {
-		return
-	}
-	config.Origin, err = url.ParseRequestURI(origin)
-	if err != nil {
-		return
-	}
-	config.Header = http.Header(make(map[string][]string))
-	return
-}
-
-// NewClient creates a new WebSocket client connection over rwc.
-func NewClient(config *Config, rwc io.ReadWriteCloser) (ws *Conn, err error) {
-	br := bufio.NewReader(rwc)
-	bw := bufio.NewWriter(rwc)
-	err = hybiClientHandshake(config, br, bw)
-	if err != nil {
-		return
-	}
-	buf := bufio.NewReadWriter(br, bw)
-	ws = newHybiClientConn(config, buf, rwc)
-	return
-}
-
-// Dial opens a new client connection to a WebSocket.
-func Dial(url_, protocol, origin string) (ws *Conn, err error) {
-	config, err := NewConfig(url_, origin)
-	if err != nil {
-		return nil, err
-	}
-	if protocol != "" {
-		config.Protocol = []string{protocol}
-	}
-	return DialConfig(config)
-}
-
-// DialConfig opens a new client connection to a WebSocket with a config.
-func DialConfig(config *Config) (ws *Conn, err error) {
-	var client net.Conn
-	if config.Location == nil {
-		return nil, &DialError{config, ErrBadWebSocketLocation}
-	}
-	if config.Origin == nil {
-		return nil, &DialError{config, ErrBadWebSocketOrigin}
-	}
-	switch config.Location.Scheme {
-	case "ws":
-		client, err = net.Dial("tcp", config.Location.Host)
-
-	case "wss":
-		client, err = tls.Dial("tcp", config.Location.Host, config.TlsConfig)
-
-	default:
-		err = ErrBadScheme
-	}
-	if err != nil {
-		goto Error
-	}
-
-	ws, err = NewClient(config, client)
-	if err != nil {
-		goto Error
-	}
-	return
-
-Error:
-	return nil, &DialError{config, err}
-}
diff --git a/Godeps/_workspace/src/code.google.com/p/go.net/websocket/exampledial_test.go b/Godeps/_workspace/src/code.google.com/p/go.net/websocket/exampledial_test.go
deleted file mode 100644
index 777a66895..000000000
--- a/Godeps/_workspace/src/code.google.com/p/go.net/websocket/exampledial_test.go
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package websocket_test
-
-import (
-	"fmt"
-	"log"
-
-	"code.google.com/p/go.net/websocket"
-)
-
-// This example demonstrates a trivial client.
-func ExampleDial() {
-	origin := "http://localhost/"
-	url := "ws://localhost:12345/ws"
-	ws, err := websocket.Dial(url, "", origin)
-	if err != nil {
-		log.Fatal(err)
-	}
-	if _, err := ws.Write([]byte("hello, world!\n")); err != nil {
-		log.Fatal(err)
-	}
-	var msg = make([]byte, 512)
-	var n int
-	if n, err = ws.Read(msg); err != nil {
-		log.Fatal(err)
-	}
-	fmt.Printf("Received: %s.\n", msg[:n])
-}
diff --git a/Godeps/_workspace/src/code.google.com/p/go.net/websocket/examplehandler_test.go b/Godeps/_workspace/src/code.google.com/p/go.net/websocket/examplehandler_test.go
deleted file mode 100644
index 47b0bb9b5..000000000
--- a/Godeps/_workspace/src/code.google.com/p/go.net/websocket/examplehandler_test.go
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package websocket_test
-
-import (
-	"io"
-	"net/http"
-
-	"code.google.com/p/go.net/websocket"
-)
-
-// Echo the data received on the WebSocket.
-func EchoServer(ws *websocket.Conn) {
-	io.Copy(ws, ws)
-}
-
-// This example demonstrates a trivial echo server.
-func ExampleHandler() {
-	http.Handle("/echo", websocket.Handler(EchoServer))
-	err := http.ListenAndServe(":12345", nil)
-	if err != nil {
-		panic("ListenAndServe: " + err.Error())
-	}
-}
diff --git a/Godeps/_workspace/src/code.google.com/p/go.net/websocket/hybi.go b/Godeps/_workspace/src/code.google.com/p/go.net/websocket/hybi.go
deleted file mode 100644
index f8c0b2e29..000000000
--- a/Godeps/_workspace/src/code.google.com/p/go.net/websocket/hybi.go
+++ /dev/null
@@ -1,564 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package websocket
-
-// This file implements a protocol of hybi draft.
-// http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-17
-
-import (
-	"bufio"
-	"bytes"
-	"crypto/rand"
-	"crypto/sha1"
-	"encoding/base64"
-	"encoding/binary"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"net/http"
-	"net/url"
-	"strings"
-)
-
-const (
-	websocketGUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
-
-	closeStatusNormal            = 1000
-	closeStatusGoingAway         = 1001
-	closeStatusProtocolError     = 1002
-	closeStatusUnsupportedData   = 1003
-	closeStatusFrameTooLarge     = 1004
-	closeStatusNoStatusRcvd      = 1005
-	closeStatusAbnormalClosure   = 1006
-	closeStatusBadMessageData    = 1007
-	closeStatusPolicyViolation   = 1008
-	closeStatusTooBigData        = 1009
-	closeStatusExtensionMismatch = 1010
-
-	maxControlFramePayloadLength = 125
-)
-
-var (
-	ErrBadMaskingKey         = &ProtocolError{"bad masking key"}
-	ErrBadPongMessage        = &ProtocolError{"bad pong message"}
-	ErrBadClosingStatus      = &ProtocolError{"bad closing status"}
-	ErrUnsupportedExtensions = &ProtocolError{"unsupported extensions"}
-	ErrNotImplemented        = &ProtocolError{"not implemented"}
-
-	handshakeHeader = map[string]bool{
-		"Host":                   true,
-		"Upgrade":                true,
-		"Connection":             true,
-		"Sec-Websocket-Key":      true,
-		"Sec-Websocket-Origin":   true,
-		"Sec-Websocket-Version":  true,
-		"Sec-Websocket-Protocol": true,
-		"Sec-Websocket-Accept":   true,
-	}
-)
-
-// A hybiFrameHeader is a frame header as defined in hybi draft.
-type hybiFrameHeader struct {
-	Fin        bool
-	Rsv        [3]bool
-	OpCode     byte
-	Length     int64
-	MaskingKey []byte
-
-	data *bytes.Buffer
-}
-
-// A hybiFrameReader is a reader for hybi frame.
-type hybiFrameReader struct {
-	reader io.Reader
-
-	header hybiFrameHeader
-	pos    int64
-	length int
-}
-
-func (frame *hybiFrameReader) Read(msg []byte) (n int, err error) {
-	n, err = frame.reader.Read(msg)
-	if err != nil {
-		return 0, err
-	}
-	if frame.header.MaskingKey != nil {
-		for i := 0; i < n; i++ {
-			msg[i] = msg[i] ^ frame.header.MaskingKey[frame.pos%4]
-			frame.pos++
-		}
-	}
-	return n, err
-}
-
-func (frame *hybiFrameReader) PayloadType() byte { return frame.header.OpCode }
-
-func (frame *hybiFrameReader) HeaderReader() io.Reader {
-	if frame.header.data == nil {
-		return nil
-	}
-	if frame.header.data.Len() == 0 {
-		return nil
-	}
-	return frame.header.data
-}
-
-func (frame *hybiFrameReader) TrailerReader() io.Reader { return nil }
-
-func (frame *hybiFrameReader) Len() (n int) { return frame.length }
-
-// A hybiFrameReaderFactory creates new frame reader based on its frame type.
-type hybiFrameReaderFactory struct {
-	*bufio.Reader
-}
-
-// NewFrameReader reads a frame header from the connection, and creates new reader for the frame.
-// See Section 5.2 Base Framing protocol for detail.
-// http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-17#section-5.2
-func (buf hybiFrameReaderFactory) NewFrameReader() (frame frameReader, err error) {
-	hybiFrame := new(hybiFrameReader)
-	frame = hybiFrame
-	var header []byte
-	var b byte
-	// First byte. FIN/RSV1/RSV2/RSV3/OpCode(4bits)
-	b, err = buf.ReadByte()
-	if err != nil {
-		return
-	}
-	header = append(header, b)
-	hybiFrame.header.Fin = ((header[0] >> 7) & 1) != 0
-	for i := 0; i < 3; i++ {
-		j := uint(6 - i)
-		hybiFrame.header.Rsv[i] = ((header[0] >> j) & 1) != 0
-	}
-	hybiFrame.header.OpCode = header[0] & 0x0f
-
-	// Second byte. Mask/Payload len(7bits)
-	b, err = buf.ReadByte()
-	if err != nil {
-		return
-	}
-	header = append(header, b)
-	mask := (b & 0x80) != 0
-	b &= 0x7f
-	lengthFields := 0
-	switch {
-	case b <= 125: // Payload length 7bits.
-		hybiFrame.header.Length = int64(b)
-	case b == 126: // Payload length 7+16bits
-		lengthFields = 2
-	case b == 127: // Payload length 7+64bits
-		lengthFields = 8
-	}
-	for i := 0; i < lengthFields; i++ {
-		b, err = buf.ReadByte()
-		if err != nil {
-			return
-		}
-		header = append(header, b)
-		hybiFrame.header.Length = hybiFrame.header.Length*256 + int64(b)
-	}
-	if mask {
-		// Masking key. 4 bytes.
-		for i := 0; i < 4; i++ {
-			b, err = buf.ReadByte()
-			if err != nil {
-				return
-			}
-			header = append(header, b)
-			hybiFrame.header.MaskingKey = append(hybiFrame.header.MaskingKey, b)
-		}
-	}
-	hybiFrame.reader = io.LimitReader(buf.Reader, hybiFrame.header.Length)
-	hybiFrame.header.data = bytes.NewBuffer(header)
-	hybiFrame.length = len(header) + int(hybiFrame.header.Length)
-	return
-}
-
-// A HybiFrameWriter is a writer for hybi frame.
-type hybiFrameWriter struct {
-	writer *bufio.Writer
-
-	header *hybiFrameHeader
-}
-
-func (frame *hybiFrameWriter) Write(msg []byte) (n int, err error) {
-	var header []byte
-	var b byte
-	if frame.header.Fin {
-		b |= 0x80
-	}
-	for i := 0; i < 3; i++ {
-		if frame.header.Rsv[i] {
-			j := uint(6 - i)
-			b |= 1 << j
-		}
-	}
-	b |= frame.header.OpCode
-	header = append(header, b)
-	if frame.header.MaskingKey != nil {
-		b = 0x80
-	} else {
-		b = 0
-	}
-	lengthFields := 0
-	length := len(msg)
-	switch {
-	case length <= 125:
-		b |= byte(length)
-	case length < 65536:
-		b |= 126
-		lengthFields = 2
-	default:
-		b |= 127
-		lengthFields = 8
-	}
-	header = append(header, b)
-	for i := 0; i < lengthFields; i++ {
-		j := uint((lengthFields - i - 1) * 8)
-		b = byte((length >> j) & 0xff)
-		header = append(header, b)
-	}
-	if frame.header.MaskingKey != nil {
-		if len(frame.header.MaskingKey) != 4 {
-			return 0, ErrBadMaskingKey
-		}
-		header = append(header, frame.header.MaskingKey...)
-		frame.writer.Write(header)
-		data := make([]byte, length)
-		for i := range data {
-			data[i] = msg[i] ^ frame.header.MaskingKey[i%4]
-		}
-		frame.writer.Write(data)
-		err = frame.writer.Flush()
-		return length, err
-	}
-	frame.writer.Write(header)
-	frame.writer.Write(msg)
-	err = frame.writer.Flush()
-	return length, err
-}
-
-func (frame *hybiFrameWriter) Close() error { return nil }
-
-type hybiFrameWriterFactory struct {
-	*bufio.Writer
-	needMaskingKey bool
-}
-
-func (buf hybiFrameWriterFactory) NewFrameWriter(payloadType byte) (frame frameWriter, err error) {
-	frameHeader := &hybiFrameHeader{Fin: true, OpCode: payloadType}
-	if buf.needMaskingKey {
-		frameHeader.MaskingKey, err = generateMaskingKey()
-		if err != nil {
-			return nil, err
-		}
-	}
-	return &hybiFrameWriter{writer: buf.Writer, header: frameHeader}, nil
-}
-
-type hybiFrameHandler struct {
-	conn        *Conn
-	payloadType byte
-}
-
-func (handler *hybiFrameHandler) HandleFrame(frame frameReader) (r frameReader, err error) {
-	if handler.conn.IsServerConn() {
-		// The client MUST mask all frames sent to the server.
-		if frame.(*hybiFrameReader).header.MaskingKey == nil {
-			handler.WriteClose(closeStatusProtocolError)
-			return nil, io.EOF
-		}
-	} else {
-		// The server MUST NOT mask all frames.
-		if frame.(*hybiFrameReader).header.MaskingKey != nil {
-			handler.WriteClose(closeStatusProtocolError)
-			return nil, io.EOF
-		}
-	}
-	if header := frame.HeaderReader(); header != nil {
-		io.Copy(ioutil.Discard, header)
-	}
-	switch frame.PayloadType() {
-	case ContinuationFrame:
-		frame.(*hybiFrameReader).header.OpCode = handler.payloadType
-	case TextFrame, BinaryFrame:
-		handler.payloadType = frame.PayloadType()
-	case CloseFrame:
-		return nil, io.EOF
-	case PingFrame:
-		pingMsg := make([]byte, maxControlFramePayloadLength)
-		n, err := io.ReadFull(frame, pingMsg)
-		if err != nil && err != io.ErrUnexpectedEOF {
-			return nil, err
-		}
-		io.Copy(ioutil.Discard, frame)
-		n, err = handler.WritePong(pingMsg[:n])
-		if err != nil {
-			return nil, err
-		}
-		return nil, nil
-	case PongFrame:
-		return nil, ErrNotImplemented
-	}
-	return frame, nil
-}
-
-func (handler *hybiFrameHandler) WriteClose(status int) (err error) {
-	handler.conn.wio.Lock()
-	defer handler.conn.wio.Unlock()
-	w, err := handler.conn.frameWriterFactory.NewFrameWriter(CloseFrame)
-	if err != nil {
-		return err
-	}
-	msg := make([]byte, 2)
-	binary.BigEndian.PutUint16(msg, uint16(status))
-	_, err = w.Write(msg)
-	w.Close()
-	return err
-}
-
-func (handler *hybiFrameHandler) WritePong(msg []byte) (n int, err error) {
-	handler.conn.wio.Lock()
-	defer handler.conn.wio.Unlock()
-	w, err := handler.conn.frameWriterFactory.NewFrameWriter(PongFrame)
-	if err != nil {
-		return 0, err
-	}
-	n, err = w.Write(msg)
-	w.Close()
-	return n, err
-}
-
-// newHybiConn creates a new WebSocket connection speaking hybi draft protocol.
-func newHybiConn(config *Config, buf *bufio.ReadWriter, rwc io.ReadWriteCloser, request *http.Request) *Conn {
-	if buf == nil {
-		br := bufio.NewReader(rwc)
-		bw := bufio.NewWriter(rwc)
-		buf = bufio.NewReadWriter(br, bw)
-	}
-	ws := &Conn{config: config, request: request, buf: buf, rwc: rwc,
-		frameReaderFactory: hybiFrameReaderFactory{buf.Reader},
-		frameWriterFactory: hybiFrameWriterFactory{
-			buf.Writer, request == nil},
-		PayloadType:        TextFrame,
-		defaultCloseStatus: closeStatusNormal}
-	ws.frameHandler = &hybiFrameHandler{conn: ws}
-	return ws
-}
-
-// generateMaskingKey generates a masking key for a frame.
-func generateMaskingKey() (maskingKey []byte, err error) {
-	maskingKey = make([]byte, 4)
-	if _, err = io.ReadFull(rand.Reader, maskingKey); err != nil {
-		return
-	}
-	return
-}
-
-// generateNonce generates a nonce consisting of a randomly selected 16-byte
-// value that has been base64-encoded.
-func generateNonce() (nonce []byte) {
-	key := make([]byte, 16)
-	if _, err := io.ReadFull(rand.Reader, key); err != nil {
-		panic(err)
-	}
-	nonce = make([]byte, 24)
-	base64.StdEncoding.Encode(nonce, key)
-	return
-}
-
-// getNonceAccept computes the base64-encoded SHA-1 of the concatenation of
-// the nonce ("Sec-WebSocket-Key" value) with the websocket GUID string.
-func getNonceAccept(nonce []byte) (expected []byte, err error) {
-	h := sha1.New()
-	if _, err = h.Write(nonce); err != nil {
-		return
-	}
-	if _, err = h.Write([]byte(websocketGUID)); err != nil {
-		return
-	}
-	expected = make([]byte, 28)
-	base64.StdEncoding.Encode(expected, h.Sum(nil))
-	return
-}
-
-// Client handshake described in draft-ietf-hybi-thewebsocket-protocol-17
-func hybiClientHandshake(config *Config, br *bufio.Reader, bw *bufio.Writer) (err error) {
-	bw.WriteString("GET " + config.Location.RequestURI() + " HTTP/1.1\r\n")
-
-	bw.WriteString("Host: " + config.Location.Host + "\r\n")
-	bw.WriteString("Upgrade: websocket\r\n")
-	bw.WriteString("Connection: Upgrade\r\n")
-	nonce := generateNonce()
-	if config.handshakeData != nil {
-		nonce = []byte(config.handshakeData["key"])
-	}
-	bw.WriteString("Sec-WebSocket-Key: " + string(nonce) + "\r\n")
-	bw.WriteString("Origin: " + strings.ToLower(config.Origin.String()) + "\r\n")
-
-	if config.Version != ProtocolVersionHybi13 {
-		return ErrBadProtocolVersion
-	}
-
-	bw.WriteString("Sec-WebSocket-Version: " + fmt.Sprintf("%d", config.Version) + "\r\n")
-	if len(config.Protocol) > 0 {
-		bw.WriteString("Sec-WebSocket-Protocol: " + strings.Join(config.Protocol, ", ") + "\r\n")
-	}
-	// TODO(ukai): send Sec-WebSocket-Extensions.
-	err = config.Header.WriteSubset(bw, handshakeHeader)
-	if err != nil {
-		return err
-	}
-
-	bw.WriteString("\r\n")
-	if err = bw.Flush(); err != nil {
-		return err
-	}
-
-	resp, err := http.ReadResponse(br, &http.Request{Method: "GET"})
-	if err != nil {
-		return err
-	}
-	if resp.StatusCode != 101 {
-		return ErrBadStatus
-	}
-	if strings.ToLower(resp.Header.Get("Upgrade")) != "websocket" ||
-		strings.ToLower(resp.Header.Get("Connection")) != "upgrade" {
-		return ErrBadUpgrade
-	}
-	expectedAccept, err := getNonceAccept(nonce)
-	if err != nil {
-		return err
-	}
-	if resp.Header.Get("Sec-WebSocket-Accept") != string(expectedAccept) {
-		return ErrChallengeResponse
-	}
-	if resp.Header.Get("Sec-WebSocket-Extensions") != "" {
-		return ErrUnsupportedExtensions
-	}
-	offeredProtocol := resp.Header.Get("Sec-WebSocket-Protocol")
-	if offeredProtocol != "" {
-		protocolMatched := false
-		for i := 0; i < len(config.Protocol); i++ {
-			if config.Protocol[i] == offeredProtocol {
-				protocolMatched = true
-				break
-			}
-		}
-		if !protocolMatched {
-			return ErrBadWebSocketProtocol
-		}
-		config.Protocol = []string{offeredProtocol}
-	}
-
-	return nil
-}
-
-// newHybiClientConn creates a client WebSocket connection after handshake.
-func newHybiClientConn(config *Config, buf *bufio.ReadWriter, rwc io.ReadWriteCloser) *Conn {
-	return newHybiConn(config, buf, rwc, nil)
-}
-
-// A HybiServerHandshaker performs a server handshake using hybi draft protocol.
-type hybiServerHandshaker struct {
-	*Config
-	accept []byte
-}
-
-func (c *hybiServerHandshaker) ReadHandshake(buf *bufio.Reader, req *http.Request) (code int, err error) {
-	c.Version = ProtocolVersionHybi13
-	if req.Method != "GET" {
-		return http.StatusMethodNotAllowed, ErrBadRequestMethod
-	}
-	// HTTP version can be safely ignored.
-
-	if strings.ToLower(req.Header.Get("Upgrade")) != "websocket" ||
-		!strings.Contains(strings.ToLower(req.Header.Get("Connection")), "upgrade") {
-		return http.StatusBadRequest, ErrNotWebSocket
-	}
-
-	key := req.Header.Get("Sec-Websocket-Key")
-	if key == "" {
-		return http.StatusBadRequest, ErrChallengeResponse
-	}
-	version := req.Header.Get("Sec-Websocket-Version")
-	switch version {
-	case "13":
-		c.Version = ProtocolVersionHybi13
-	default:
-		return http.StatusBadRequest, ErrBadWebSocketVersion
-	}
-	var scheme string
-	if req.TLS != nil {
-		scheme = "wss"
-	} else {
-		scheme = "ws"
-	}
-	c.Location, err = url.ParseRequestURI(scheme + "://" + req.Host + req.URL.RequestURI())
-	if err != nil {
-		return http.StatusBadRequest, err
-	}
-	protocol := strings.TrimSpace(req.Header.Get("Sec-Websocket-Protocol"))
-	if protocol != "" {
-		protocols := strings.Split(protocol, ",")
-		for i := 0; i < len(protocols); i++ {
-			c.Protocol = append(c.Protocol, strings.TrimSpace(protocols[i]))
-		}
-	}
-	c.accept, err = getNonceAccept([]byte(key))
-	if err != nil {
-		return http.StatusInternalServerError, err
-	}
-	return http.StatusSwitchingProtocols, nil
-}
-
-// Origin parses Origin header in "req".
-// If origin is "null", returns (nil, nil).
-func Origin(config *Config, req *http.Request) (*url.URL, error) {
-	var origin string
-	switch config.Version {
-	case ProtocolVersionHybi13:
-		origin = req.Header.Get("Origin")
-	}
-	if origin == "null" {
-		return nil, nil
-	}
-	return url.ParseRequestURI(origin)
-}
-
-func (c *hybiServerHandshaker) AcceptHandshake(buf *bufio.Writer) (err error) {
-	if len(c.Protocol) > 0 {
-		if len(c.Protocol) != 1 {
-			// You need choose a Protocol in Handshake func in Server.
-			return ErrBadWebSocketProtocol
-		}
-	}
-	buf.WriteString("HTTP/1.1 101 Switching Protocols\r\n")
-	buf.WriteString("Upgrade: websocket\r\n")
-	buf.WriteString("Connection: Upgrade\r\n")
-	buf.WriteString("Sec-WebSocket-Accept: " + string(c.accept) + "\r\n")
-	if len(c.Protocol) > 0 {
-		buf.WriteString("Sec-WebSocket-Protocol: " + c.Protocol[0] + "\r\n")
-	}
-	// TODO(ukai): send Sec-WebSocket-Extensions.
-	if c.Header != nil {
-		err := c.Header.WriteSubset(buf, handshakeHeader)
-		if err != nil {
-			return err
-		}
-	}
-	buf.WriteString("\r\n")
-	return buf.Flush()
-}
-
-func (c *hybiServerHandshaker) NewServerConn(buf *bufio.ReadWriter, rwc io.ReadWriteCloser, request *http.Request) *Conn {
-	return newHybiServerConn(c.Config, buf, rwc, request)
-}
-
-// newHybiServerConn returns a new WebSocket connection speaking hybi draft protocol.
-func newHybiServerConn(config *Config, buf *bufio.ReadWriter, rwc io.ReadWriteCloser, request *http.Request) *Conn {
-	return newHybiConn(config, buf, rwc, request)
-}
diff --git a/Godeps/_workspace/src/code.google.com/p/go.net/websocket/hybi_test.go b/Godeps/_workspace/src/code.google.com/p/go.net/websocket/hybi_test.go
deleted file mode 100644
index d6a19108a..000000000
--- a/Godeps/_workspace/src/code.google.com/p/go.net/websocket/hybi_test.go
+++ /dev/null
@@ -1,590 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package websocket
-
-import (
-	"bufio"
-	"bytes"
-	"fmt"
-	"io"
-	"net/http"
-	"net/url"
-	"strings"
-	"testing"
-)
-
-// Test the getNonceAccept function with values in
-// http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-17
-func TestSecWebSocketAccept(t *testing.T) {
-	nonce := []byte("dGhlIHNhbXBsZSBub25jZQ==")
-	expected := []byte("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=")
-	accept, err := getNonceAccept(nonce)
-	if err != nil {
-		t.Errorf("getNonceAccept: returned error %v", err)
-		return
-	}
-	if !bytes.Equal(expected, accept) {
-		t.Errorf("getNonceAccept: expected %q got %q", expected, accept)
-	}
-}
-
-func TestHybiClientHandshake(t *testing.T) {
-	b := bytes.NewBuffer([]byte{})
-	bw := bufio.NewWriter(b)
-	br := bufio.NewReader(strings.NewReader(`HTTP/1.1 101 Switching Protocols
-Upgrade: websocket
-Connection: Upgrade
-Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
-Sec-WebSocket-Protocol: chat
-
-`))
-	var err error
-	config := new(Config)
-	config.Location, err = url.ParseRequestURI("ws://server.example.com/chat")
-	if err != nil {
-		t.Fatal("location url", err)
-	}
-	config.Origin, err = url.ParseRequestURI("http://example.com")
-	if err != nil {
-		t.Fatal("origin url", err)
-	}
-	config.Protocol = append(config.Protocol, "chat")
-	config.Protocol = append(config.Protocol, "superchat")
-	config.Version = ProtocolVersionHybi13
-
-	config.handshakeData = map[string]string{
-		"key": "dGhlIHNhbXBsZSBub25jZQ==",
-	}
-	err = hybiClientHandshake(config, br, bw)
-	if err != nil {
-		t.Errorf("handshake failed: %v", err)
-	}
-	req, err := http.ReadRequest(bufio.NewReader(b))
-	if err != nil {
-		t.Fatalf("read request: %v", err)
-	}
-	if req.Method != "GET" {
-		t.Errorf("request method expected GET, but got %q", req.Method)
-	}
-	if req.URL.Path != "/chat" {
-		t.Errorf("request path expected /chat, but got %q", req.URL.Path)
-	}
-	if req.Proto != "HTTP/1.1" {
-		t.Errorf("request proto expected HTTP/1.1, but got %q", req.Proto)
-	}
-	if req.Host != "server.example.com" {
-		t.Errorf("request Host expected server.example.com, but got %v", req.Host)
-	}
-	var expectedHeader = map[string]string{
-		"Connection":             "Upgrade",
-		"Upgrade":                "websocket",
-		"Sec-Websocket-Key":      config.handshakeData["key"],
-		"Origin":                 config.Origin.String(),
-		"Sec-Websocket-Protocol": "chat, superchat",
-		"Sec-Websocket-Version":  fmt.Sprintf("%d", ProtocolVersionHybi13),
-	}
-	for k, v := range expectedHeader {
-		if req.Header.Get(k) != v {
-			t.Errorf(fmt.Sprintf("%s expected %q but got %q", k, v, req.Header.Get(k)))
-		}
-	}
-}
-
-func TestHybiClientHandshakeWithHeader(t *testing.T) {
-	b := bytes.NewBuffer([]byte{})
-	bw := bufio.NewWriter(b)
-	br := bufio.NewReader(strings.NewReader(`HTTP/1.1 101 Switching Protocols
-Upgrade: websocket
-Connection: Upgrade
-Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
-Sec-WebSocket-Protocol: chat
-
-`))
-	var err error
-	config := new(Config)
-	config.Location, err = url.ParseRequestURI("ws://server.example.com/chat")
-	if err != nil {
-		t.Fatal("location url", err)
-	}
-	config.Origin, err = url.ParseRequestURI("http://example.com")
-	if err != nil {
-		t.Fatal("origin url", err)
-	}
-	config.Protocol = append(config.Protocol, "chat")
-	config.Protocol = append(config.Protocol, "superchat")
-	config.Version = ProtocolVersionHybi13
-	config.Header = http.Header(make(map[string][]string))
-	config.Header.Add("User-Agent", "test")
-
-	config.handshakeData = map[string]string{
-		"key": "dGhlIHNhbXBsZSBub25jZQ==",
-	}
-	err = hybiClientHandshake(config, br, bw)
-	if err != nil {
-		t.Errorf("handshake failed: %v", err)
-	}
-	req, err := http.ReadRequest(bufio.NewReader(b))
-	if err != nil {
-		t.Fatalf("read request: %v", err)
-	}
-	if req.Method != "GET" {
-		t.Errorf("request method expected GET, but got %q", req.Method)
-	}
-	if req.URL.Path != "/chat" {
-		t.Errorf("request path expected /chat, but got %q", req.URL.Path)
-	}
-	if req.Proto != "HTTP/1.1" {
-		t.Errorf("request proto expected HTTP/1.1, but got %q", req.Proto)
-	}
-	if req.Host != "server.example.com" {
-		t.Errorf("request Host expected server.example.com, but got %v", req.Host)
-	}
-	var expectedHeader = map[string]string{
-		"Connection":             "Upgrade",
-		"Upgrade":                "websocket",
-		"Sec-Websocket-Key":      config.handshakeData["key"],
-		"Origin":                 config.Origin.String(),
-		"Sec-Websocket-Protocol": "chat, superchat",
-		"Sec-Websocket-Version":  fmt.Sprintf("%d", ProtocolVersionHybi13),
-		"User-Agent":             "test",
-	}
-	for k, v := range expectedHeader {
-		if req.Header.Get(k) != v {
-			t.Errorf(fmt.Sprintf("%s expected %q but got %q", k, v, req.Header.Get(k)))
-		}
-	}
-}
-
-func TestHybiServerHandshake(t *testing.T) {
-	config := new(Config)
-	handshaker := &hybiServerHandshaker{Config: config}
-	br := bufio.NewReader(strings.NewReader(`GET /chat HTTP/1.1
-Host: server.example.com
-Upgrade: websocket
-Connection: Upgrade
-Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
-Origin: http://example.com
-Sec-WebSocket-Protocol: chat, superchat
-Sec-WebSocket-Version: 13
-
-`))
-	req, err := http.ReadRequest(br)
-	if err != nil {
-		t.Fatal("request", err)
-	}
-	code, err := handshaker.ReadHandshake(br, req)
-	if err != nil {
-		t.Errorf("handshake failed: %v", err)
-	}
-	if code != http.StatusSwitchingProtocols {
-		t.Errorf("status expected %q but got %q", http.StatusSwitchingProtocols, code)
-	}
-	expectedProtocols := []string{"chat", "superchat"}
-	if fmt.Sprintf("%v", config.Protocol) != fmt.Sprintf("%v", expectedProtocols) {
-		t.Errorf("protocol expected %q but got %q", expectedProtocols, config.Protocol)
-	}
-	b := bytes.NewBuffer([]byte{})
-	bw := bufio.NewWriter(b)
-
-	config.Protocol = config.Protocol[:1]
-
-	err = handshaker.AcceptHandshake(bw)
-	if err != nil {
-		t.Errorf("handshake response failed: %v", err)
-	}
-	expectedResponse := strings.Join([]string{
-		"HTTP/1.1 101 Switching Protocols",
-		"Upgrade: websocket",
-		"Connection: Upgrade",
-		"Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",
-		"Sec-WebSocket-Protocol: chat",
-		"", ""}, "\r\n")
-
-	if b.String() != expectedResponse {
-		t.Errorf("handshake expected %q but got %q", expectedResponse, b.String())
-	}
-}
-
-func TestHybiServerHandshakeNoSubProtocol(t *testing.T) {
-	config := new(Config)
-	handshaker := &hybiServerHandshaker{Config: config}
-	br := bufio.NewReader(strings.NewReader(`GET /chat HTTP/1.1
-Host: server.example.com
-Upgrade: websocket
-Connection: Upgrade
-Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
-Origin: http://example.com
-Sec-WebSocket-Version: 13
-
-`))
-	req, err := http.ReadRequest(br)
-	if err != nil {
-		t.Fatal("request", err)
-	}
-	code, err := handshaker.ReadHandshake(br, req)
-	if err != nil {
-		t.Errorf("handshake failed: %v", err)
-	}
-	if code != http.StatusSwitchingProtocols {
-		t.Errorf("status expected %q but got %q", http.StatusSwitchingProtocols, code)
-	}
-	if len(config.Protocol) != 0 {
-		t.Errorf("len(config.Protocol) expected 0, but got %q", len(config.Protocol))
-	}
-	b := bytes.NewBuffer([]byte{})
-	bw := bufio.NewWriter(b)
-
-	err = handshaker.AcceptHandshake(bw)
-	if err != nil {
-		t.Errorf("handshake response failed: %v", err)
-	}
-	expectedResponse := strings.Join([]string{
-		"HTTP/1.1 101 Switching Protocols",
-		"Upgrade: websocket",
-		"Connection: Upgrade",
-		"Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",
-		"", ""}, "\r\n")
-
-	if b.String() != expectedResponse {
-		t.Errorf("handshake expected %q but got %q", expectedResponse, b.String())
-	}
-}
-
-func TestHybiServerHandshakeHybiBadVersion(t *testing.T) {
-	config := new(Config)
-	handshaker := &hybiServerHandshaker{Config: config}
-	br := bufio.NewReader(strings.NewReader(`GET /chat HTTP/1.1
-Host: server.example.com
-Upgrade: websocket
-Connection: Upgrade
-Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
-Sec-WebSocket-Origin: http://example.com
-Sec-WebSocket-Protocol: chat, superchat
-Sec-WebSocket-Version: 9
-
-`))
-	req, err := http.ReadRequest(br)
-	if err != nil {
-		t.Fatal("request", err)
-	}
-	code, err := handshaker.ReadHandshake(br, req)
-	if err != ErrBadWebSocketVersion {
-		t.Errorf("handshake expected err %q but got %q", ErrBadWebSocketVersion, err)
-	}
-	if code != http.StatusBadRequest {
-		t.Errorf("status expected %q but got %q", http.StatusBadRequest, code)
-	}
-}
-
-func testHybiFrame(t *testing.T, testHeader, testPayload, testMaskedPayload []byte, frameHeader *hybiFrameHeader) {
-	b := bytes.NewBuffer([]byte{})
-	frameWriterFactory := &hybiFrameWriterFactory{bufio.NewWriter(b), false}
-	w, _ := frameWriterFactory.NewFrameWriter(TextFrame)
-	w.(*hybiFrameWriter).header = frameHeader
-	_, err := w.Write(testPayload)
-	w.Close()
-	if err != nil {
-		t.Errorf("Write error %q", err)
-	}
-	var expectedFrame []byte
-	expectedFrame = append(expectedFrame, testHeader...)
-	expectedFrame = append(expectedFrame, testMaskedPayload...)
-	if !bytes.Equal(expectedFrame, b.Bytes()) {
-		t.Errorf("frame expected %q got %q", expectedFrame, b.Bytes())
-	}
-	frameReaderFactory := &hybiFrameReaderFactory{bufio.NewReader(b)}
-	r, err := frameReaderFactory.NewFrameReader()
-	if err != nil {
-		t.Errorf("Read error %q", err)
-	}
-	if header := r.HeaderReader(); header == nil {
-		t.Errorf("no header")
-	} else {
-		actualHeader := make([]byte, r.Len())
-		n, err := header.Read(actualHeader)
-		if err != nil {
-			t.Errorf("Read header error %q", err)
-		} else {
-			if n < len(testHeader) {
-				t.Errorf("header too short %q got %q", testHeader, actualHeader[:n])
-			}
-			if !bytes.Equal(testHeader, actualHeader[:n]) {
-				t.Errorf("header expected %q got %q", testHeader, actualHeader[:n])
-			}
-		}
-	}
-	if trailer := r.TrailerReader(); trailer != nil {
-		t.Errorf("unexpected trailer %q", trailer)
-	}
-	frame := r.(*hybiFrameReader)
-	if frameHeader.Fin != frame.header.Fin ||
-		frameHeader.OpCode != frame.header.OpCode ||
-		len(testPayload) != int(frame.header.Length) {
-		t.Errorf("mismatch %v (%d) vs %v", frameHeader, len(testPayload), frame)
-	}
-	payload := make([]byte, len(testPayload))
-	_, err = r.Read(payload)
-	if err != nil {
-		t.Errorf("read %v", err)
-	}
-	if !bytes.Equal(testPayload, payload) {
-		t.Errorf("payload %q vs %q", testPayload, payload)
-	}
-}
-
-func TestHybiShortTextFrame(t *testing.T) {
-	frameHeader := &hybiFrameHeader{Fin: true, OpCode: TextFrame}
-	payload := []byte("hello")
-	testHybiFrame(t, []byte{0x81, 0x05}, payload, payload, frameHeader)
-
-	payload = make([]byte, 125)
-	testHybiFrame(t, []byte{0x81, 125}, payload, payload, frameHeader)
-}
-
-func TestHybiShortMaskedTextFrame(t *testing.T) {
-	frameHeader := &hybiFrameHeader{Fin: true, OpCode: TextFrame,
-		MaskingKey: []byte{0xcc, 0x55, 0x80, 0x20}}
-	payload := []byte("hello")
-	maskedPayload := []byte{0xa4, 0x30, 0xec, 0x4c, 0xa3}
-	header := []byte{0x81, 0x85}
-	header = append(header, frameHeader.MaskingKey...)
-	testHybiFrame(t, header, payload, maskedPayload, frameHeader)
-}
-
-func TestHybiShortBinaryFrame(t *testing.T) {
-	frameHeader := &hybiFrameHeader{Fin: true, OpCode: BinaryFrame}
-	payload := []byte("hello")
-	testHybiFrame(t, []byte{0x82, 0x05}, payload, payload, frameHeader)
-
-	payload = make([]byte, 125)
-	testHybiFrame(t, []byte{0x82, 125}, payload, payload, frameHeader)
-}
-
-func TestHybiControlFrame(t *testing.T) {
-	frameHeader := &hybiFrameHeader{Fin: true, OpCode: PingFrame}
-	payload := []byte("hello")
-	testHybiFrame(t, []byte{0x89, 0x05}, payload, payload, frameHeader)
-
-	frameHeader = &hybiFrameHeader{Fin: true, OpCode: PongFrame}
-	testHybiFrame(t, []byte{0x8A, 0x05}, payload, payload, frameHeader)
-
-	frameHeader = &hybiFrameHeader{Fin: true, OpCode: CloseFrame}
-	payload = []byte{0x03, 0xe8} // 1000
-	testHybiFrame(t, []byte{0x88, 0x02}, payload, payload, frameHeader)
-}
-
-func TestHybiLongFrame(t *testing.T) {
-	frameHeader := &hybiFrameHeader{Fin: true, OpCode: TextFrame}
-	payload := make([]byte, 126)
-	testHybiFrame(t, []byte{0x81, 126, 0x00, 126}, payload, payload, frameHeader)
-
-	payload = make([]byte, 65535)
-	testHybiFrame(t, []byte{0x81, 126, 0xff, 0xff}, payload, payload, frameHeader)
-
-	payload = make([]byte, 65536)
-	testHybiFrame(t, []byte{0x81, 127, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00}, payload, payload, frameHeader)
-}
-
-func TestHybiClientRead(t *testing.T) {
-	wireData := []byte{0x81, 0x05, 'h', 'e', 'l', 'l', 'o',
-		0x89, 0x05, 'h', 'e', 'l', 'l', 'o', // ping
-		0x81, 0x05, 'w', 'o', 'r', 'l', 'd'}
-	br := bufio.NewReader(bytes.NewBuffer(wireData))
-	bw := bufio.NewWriter(bytes.NewBuffer([]byte{}))
-	conn := newHybiConn(newConfig(t, "/"), bufio.NewReadWriter(br, bw), nil, nil)
-
-	msg := make([]byte, 512)
-	n, err := conn.Read(msg)
-	if err != nil {
-		t.Errorf("read 1st frame, error %q", err)
-	}
-	if n != 5 {
-		t.Errorf("read 1st frame, expect 5, got %d", n)
-	}
-	if !bytes.Equal(wireData[2:7], msg[:n]) {
-		t.Errorf("read 1st frame %v, got %v", wireData[2:7], msg[:n])
-	}
-	n, err = conn.Read(msg)
-	if err != nil {
-		t.Errorf("read 2nd frame, error %q", err)
-	}
-	if n != 5 {
-		t.Errorf("read 2nd frame, expect 5, got %d", n)
-	}
-	if !bytes.Equal(wireData[16:21], msg[:n]) {
-		t.Errorf("read 2nd frame %v, got %v", wireData[16:21], msg[:n])
-	}
-	n, err = conn.Read(msg)
-	if err == nil {
-		t.Errorf("read not EOF")
-	}
-	if n != 0 {
-		t.Errorf("expect read 0, got %d", n)
-	}
-}
-
-func TestHybiShortRead(t *testing.T) {
-	wireData := []byte{0x81, 0x05, 'h', 'e', 'l', 'l', 'o',
-		0x89, 0x05, 'h', 'e', 'l', 'l', 'o', // ping
-		0x81, 0x05, 'w', 'o', 'r', 'l', 'd'}
-	br := bufio.NewReader(bytes.NewBuffer(wireData))
-	bw := bufio.NewWriter(bytes.NewBuffer([]byte{}))
-	conn := newHybiConn(newConfig(t, "/"), bufio.NewReadWriter(br, bw), nil, nil)
-
-	step := 0
-	pos := 0
-	expectedPos := []int{2, 5, 16, 19}
-	expectedLen := []int{3, 2, 3, 2}
-	for {
-		msg := make([]byte, 3)
-		n, err := conn.Read(msg)
-		if step >= len(expectedPos) {
-			if err == nil {
-				t.Errorf("read not EOF")
-			}
-			if n != 0 {
-				t.Errorf("expect read 0, got %d", n)
-			}
-			return
-		}
-		pos = expectedPos[step]
-		endPos := pos + expectedLen[step]
-		if err != nil {
-			t.Errorf("read from %d, got error %q", pos, err)
-			return
-		}
-		if n != endPos-pos {
-			t.Errorf("read from %d, expect %d, got %d", pos, endPos-pos, n)
-		}
-		if !bytes.Equal(wireData[pos:endPos], msg[:n]) {
-			t.Errorf("read from %d, frame %v, got %v", pos, wireData[pos:endPos], msg[:n])
-		}
-		step++
-	}
-}
-
-func TestHybiServerRead(t *testing.T) {
-	wireData := []byte{0x81, 0x85, 0xcc, 0x55, 0x80, 0x20,
-		0xa4, 0x30, 0xec, 0x4c, 0xa3, // hello
-		0x89, 0x85, 0xcc, 0x55, 0x80, 0x20,
-		0xa4, 0x30, 0xec, 0x4c, 0xa3, // ping: hello
-		0x81, 0x85, 0xed, 0x83, 0xb4, 0x24,
-		0x9a, 0xec, 0xc6, 0x48, 0x89, // world
-	}
-	br := bufio.NewReader(bytes.NewBuffer(wireData))
-	bw := bufio.NewWriter(bytes.NewBuffer([]byte{}))
-	conn := newHybiConn(newConfig(t, "/"), bufio.NewReadWriter(br, bw), nil, new(http.Request))
-
-	expected := [][]byte{[]byte("hello"), []byte("world")}
-
-	msg := make([]byte, 512)
-	n, err := conn.Read(msg)
-	if err != nil {
-		t.Errorf("read 1st frame, error %q", err)
-	}
-	if n != 5 {
-		t.Errorf("read 1st frame, expect 5, got %d", n)
-	}
-	if !bytes.Equal(expected[0], msg[:n]) {
-		t.Errorf("read 1st frame %q, got %q", expected[0], msg[:n])
-	}
-
-	n, err = conn.Read(msg)
-	if err != nil {
-		t.Errorf("read 2nd frame, error %q", err)
-	}
-	if n != 5 {
-		t.Errorf("read 2nd frame, expect 5, got %d", n)
-	}
-	if !bytes.Equal(expected[1], msg[:n]) {
-		t.Errorf("read 2nd frame %q, got %q", expected[1], msg[:n])
-	}
-
-	n, err = conn.Read(msg)
-	if err == nil {
-		t.Errorf("read not EOF")
-	}
-	if n != 0 {
-		t.Errorf("expect read 0, got %d", n)
-	}
-}
-
-func TestHybiServerReadWithoutMasking(t *testing.T) {
-	wireData := []byte{0x81, 0x05, 'h', 'e', 'l', 'l', 'o'}
-	br := bufio.NewReader(bytes.NewBuffer(wireData))
-	bw := bufio.NewWriter(bytes.NewBuffer([]byte{}))
-	conn := newHybiConn(newConfig(t, "/"), bufio.NewReadWriter(br, bw), nil, new(http.Request))
-	// server MUST close the connection upon receiving a non-masked frame.
-	msg := make([]byte, 512)
-	_, err := conn.Read(msg)
-	if err != io.EOF {
-		t.Errorf("read 1st frame, expect %q, but got %q", io.EOF, err)
-	}
-}
-
-func TestHybiClientReadWithMasking(t *testing.T) {
-	wireData := []byte{0x81, 0x85, 0xcc, 0x55, 0x80, 0x20,
-		0xa4, 0x30, 0xec, 0x4c, 0xa3, // hello
-	}
-	br := bufio.NewReader(bytes.NewBuffer(wireData))
-	bw := bufio.NewWriter(bytes.NewBuffer([]byte{}))
-	conn := newHybiConn(newConfig(t, "/"), bufio.NewReadWriter(br, bw), nil, nil)
-
-	// client MUST close the connection upon receiving a masked frame.
-	msg := make([]byte, 512)
-	_, err := conn.Read(msg)
-	if err != io.EOF {
-		t.Errorf("read 1st frame, expect %q, but got %q", io.EOF, err)
-	}
-}
-
-// Test the hybiServerHandshaker supports firefox implementation and
-// checks Connection request header include (but it's not necessary
-// equal to) "upgrade"
-func TestHybiServerFirefoxHandshake(t *testing.T) {
-	config := new(Config)
-	handshaker := &hybiServerHandshaker{Config: config}
-	br := bufio.NewReader(strings.NewReader(`GET /chat HTTP/1.1
-Host: server.example.com
-Upgrade: websocket
-Connection: keep-alive, upgrade
-Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
-Origin: http://example.com
-Sec-WebSocket-Protocol: chat, superchat
-Sec-WebSocket-Version: 13
-
-`))
-	req, err := http.ReadRequest(br)
-	if err != nil {
-		t.Fatal("request", err)
-	}
-	code, err := handshaker.ReadHandshake(br, req)
-	if err != nil {
-		t.Errorf("handshake failed: %v", err)
-	}
-	if code != http.StatusSwitchingProtocols {
-		t.Errorf("status expected %q but got %q", http.StatusSwitchingProtocols, code)
-	}
-	b := bytes.NewBuffer([]byte{})
-	bw := bufio.NewWriter(b)
-
-	config.Protocol = []string{"chat"}
-
-	err = handshaker.AcceptHandshake(bw)
-	if err != nil {
-		t.Errorf("handshake response failed: %v", err)
-	}
-	expectedResponse := strings.Join([]string{
-		"HTTP/1.1 101 Switching Protocols",
-		"Upgrade: websocket",
-		"Connection: Upgrade",
-		"Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",
-		"Sec-WebSocket-Protocol: chat",
-		"", ""}, "\r\n")
-
-	if b.String() != expectedResponse {
-		t.Errorf("handshake expected %q but got %q", expectedResponse, b.String())
-	}
-}
diff --git a/Godeps/_workspace/src/code.google.com/p/go.net/websocket/server.go b/Godeps/_workspace/src/code.google.com/p/go.net/websocket/server.go
deleted file mode 100644
index 70322133c..000000000
--- a/Godeps/_workspace/src/code.google.com/p/go.net/websocket/server.go
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package websocket
-
-import (
-	"bufio"
-	"fmt"
-	"io"
-	"net/http"
-)
-
-func newServerConn(rwc io.ReadWriteCloser, buf *bufio.ReadWriter, req *http.Request, config *Config, handshake func(*Config, *http.Request) error) (conn *Conn, err error) {
-	var hs serverHandshaker = &hybiServerHandshaker{Config: config}
-	code, err := hs.ReadHandshake(buf.Reader, req)
-	if err == ErrBadWebSocketVersion {
-		fmt.Fprintf(buf, "HTTP/1.1 %03d %s\r\n", code, http.StatusText(code))
-		fmt.Fprintf(buf, "Sec-WebSocket-Version: %s\r\n", SupportedProtocolVersion)
-		buf.WriteString("\r\n")
-		buf.WriteString(err.Error())
-		buf.Flush()
-		return
-	}
-	if err != nil {
-		fmt.Fprintf(buf, "HTTP/1.1 %03d %s\r\n", code, http.StatusText(code))
-		buf.WriteString("\r\n")
-		buf.WriteString(err.Error())
-		buf.Flush()
-		return
-	}
-	if handshake != nil {
-		err = handshake(config, req)
-		if err != nil {
-			code = http.StatusForbidden
-			fmt.Fprintf(buf, "HTTP/1.1 %03d %s\r\n", code, http.StatusText(code))
-			buf.WriteString("\r\n")
-			buf.Flush()
-			return
-		}
-	}
-	err = hs.AcceptHandshake(buf.Writer)
-	if err != nil {
-		code = http.StatusBadRequest
-		fmt.Fprintf(buf, "HTTP/1.1 %03d %s\r\n", code, http.StatusText(code))
-		buf.WriteString("\r\n")
-		buf.Flush()
-		return
-	}
-	conn = hs.NewServerConn(buf, rwc, req)
-	return
-}
-
-// Server represents a server of a WebSocket.
-type Server struct {
-	// Config is a WebSocket configuration for new WebSocket connection.
-	Config
-
-	// Handshake is an optional function in WebSocket handshake.
-	// For example, you can check, or don't check Origin header.
-	// Another example, you can select config.Protocol.
-	Handshake func(*Config, *http.Request) error
-
-	// Handler handles a WebSocket connection.
-	Handler
-}
-
-// ServeHTTP implements the http.Handler interface for a WebSocket
-func (s Server) ServeHTTP(w http.ResponseWriter, req *http.Request) {
-	s.serveWebSocket(w, req)
-}
-
-func (s Server) serveWebSocket(w http.ResponseWriter, req *http.Request) {
-	rwc, buf, err := w.(http.Hijacker).Hijack()
-	if err != nil {
-		panic("Hijack failed: " + err.Error())
-		return
-	}
-	// The server should abort the WebSocket connection if it finds
-	// the client did not send a handshake that matches with protocol
-	// specification.
-	defer rwc.Close()
-	conn, err := newServerConn(rwc, buf, req, &s.Config, s.Handshake)
-	if err != nil {
-		return
-	}
-	if conn == nil {
-		panic("unexpected nil conn")
-	}
-	s.Handler(conn)
-}
-
-// Handler is a simple interface to a WebSocket browser client.
-// It checks if Origin header is valid URL by default.
-// You might want to verify websocket.Conn.Config().Origin in the func.
-// If you use Server instead of Handler, you could call websocket.Origin and
-// check the origin in your Handshake func. So, if you want to accept
-// non-browser client, which doesn't send Origin header, you could use Server
-//. that doesn't check origin in its Handshake.
-type Handler func(*Conn)
-
-func checkOrigin(config *Config, req *http.Request) (err error) {
-	config.Origin, err = Origin(config, req)
-	if err == nil && config.Origin == nil {
-		return fmt.Errorf("null origin")
-	}
-	return err
-}
-
-// ServeHTTP implements the http.Handler interface for a WebSocket
-func (h Handler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
-	s := Server{Handler: h, Handshake: checkOrigin}
-	s.serveWebSocket(w, req)
-}
diff --git a/Godeps/_workspace/src/code.google.com/p/go.net/websocket/websocket.go b/Godeps/_workspace/src/code.google.com/p/go.net/websocket/websocket.go
deleted file mode 100644
index 0f4917bf7..000000000
--- a/Godeps/_workspace/src/code.google.com/p/go.net/websocket/websocket.go
+++ /dev/null
@@ -1,411 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package websocket implements a client and server for the WebSocket protocol
-// as specified in RFC 6455.
-package websocket
-
-import (
-	"bufio"
-	"crypto/tls"
-	"encoding/json"
-	"errors"
-	"io"
-	"io/ioutil"
-	"net"
-	"net/http"
-	"net/url"
-	"sync"
-	"time"
-)
-
-const (
-	ProtocolVersionHybi13    = 13
-	ProtocolVersionHybi      = ProtocolVersionHybi13
-	SupportedProtocolVersion = "13"
-
-	ContinuationFrame = 0
-	TextFrame         = 1
-	BinaryFrame       = 2
-	CloseFrame        = 8
-	PingFrame         = 9
-	PongFrame         = 10
-	UnknownFrame      = 255
-)
-
-// ProtocolError represents WebSocket protocol errors.
-type ProtocolError struct {
-	ErrorString string
-}
-
-func (err *ProtocolError) Error() string { return err.ErrorString }
-
-var (
-	ErrBadProtocolVersion   = &ProtocolError{"bad protocol version"}
-	ErrBadScheme            = &ProtocolError{"bad scheme"}
-	ErrBadStatus            = &ProtocolError{"bad status"}
-	ErrBadUpgrade           = &ProtocolError{"missing or bad upgrade"}
-	ErrBadWebSocketOrigin   = &ProtocolError{"missing or bad WebSocket-Origin"}
-	ErrBadWebSocketLocation = &ProtocolError{"missing or bad WebSocket-Location"}
-	ErrBadWebSocketProtocol = &ProtocolError{"missing or bad WebSocket-Protocol"}
-	ErrBadWebSocketVersion  = &ProtocolError{"missing or bad WebSocket Version"}
-	ErrChallengeResponse    = &ProtocolError{"mismatch challenge/response"}
-	ErrBadFrame             = &ProtocolError{"bad frame"}
-	ErrBadFrameBoundary     = &ProtocolError{"not on frame boundary"}
-	ErrNotWebSocket         = &ProtocolError{"not websocket protocol"}
-	ErrBadRequestMethod     = &ProtocolError{"bad method"}
-	ErrNotSupported         = &ProtocolError{"not supported"}
-)
-
-// Addr is an implementation of net.Addr for WebSocket.
-type Addr struct {
-	*url.URL
-}
-
-// Network returns the network type for a WebSocket, "websocket".
-func (addr *Addr) Network() string { return "websocket" }
-
-// Config is a WebSocket configuration
-type Config struct {
-	// A WebSocket server address.
-	Location *url.URL
-
-	// A Websocket client origin.
-	Origin *url.URL
-
-	// WebSocket subprotocols.
-	Protocol []string
-
-	// WebSocket protocol version.
-	Version int
-
-	// TLS config for secure WebSocket (wss).
-	TlsConfig *tls.Config
-
-	// Additional header fields to be sent in WebSocket opening handshake.
-	Header http.Header
-
-	handshakeData map[string]string
-}
-
-// serverHandshaker is an interface to handle WebSocket server side handshake.
-type serverHandshaker interface {
-	// ReadHandshake reads handshake request message from client.
-	// Returns http response code and error if any.
-	ReadHandshake(buf *bufio.Reader, req *http.Request) (code int, err error)
-
-	// AcceptHandshake accepts the client handshake request and sends
-	// handshake response back to client.
-	AcceptHandshake(buf *bufio.Writer) (err error)
-
-	// NewServerConn creates a new WebSocket connection.
-	NewServerConn(buf *bufio.ReadWriter, rwc io.ReadWriteCloser, request *http.Request) (conn *Conn)
-}
-
-// frameReader is an interface to read a WebSocket frame.
-type frameReader interface {
-	// Reader is to read payload of the frame.
-	io.Reader
-
-	// PayloadType returns payload type.
-	PayloadType() byte
-
-	// HeaderReader returns a reader to read header of the frame.
-	HeaderReader() io.Reader
-
-	// TrailerReader returns a reader to read trailer of the frame.
-	// If it returns nil, there is no trailer in the frame.
-	TrailerReader() io.Reader
-
-	// Len returns total length of the frame, including header and trailer.
-	Len() int
-}
-
-// frameReaderFactory is an interface to creates new frame reader.
-type frameReaderFactory interface {
-	NewFrameReader() (r frameReader, err error)
-}
-
-// frameWriter is an interface to write a WebSocket frame.
-type frameWriter interface {
-	// Writer is to write payload of the frame.
-	io.WriteCloser
-}
-
-// frameWriterFactory is an interface to create new frame writer.
-type frameWriterFactory interface {
-	NewFrameWriter(payloadType byte) (w frameWriter, err error)
-}
-
-type frameHandler interface {
-	HandleFrame(frame frameReader) (r frameReader, err error)
-	WriteClose(status int) (err error)
-}
-
-// Conn represents a WebSocket connection.
-type Conn struct {
-	config  *Config
-	request *http.Request
-
-	buf *bufio.ReadWriter
-	rwc io.ReadWriteCloser
-
-	rio sync.Mutex
-	frameReaderFactory
-	frameReader
-
-	wio sync.Mutex
-	frameWriterFactory
-
-	frameHandler
-	PayloadType        byte
-	defaultCloseStatus int
-}
-
-// Read implements the io.Reader interface:
-// it reads data of a frame from the WebSocket connection.
-// if msg is not large enough for the frame data, it fills the msg and next Read
-// will read the rest of the frame data.
-// it reads Text frame or Binary frame.
-func (ws *Conn) Read(msg []byte) (n int, err error) {
-	ws.rio.Lock()
-	defer ws.rio.Unlock()
-again:
-	if ws.frameReader == nil {
-		frame, err := ws.frameReaderFactory.NewFrameReader()
-		if err != nil {
-			return 0, err
-		}
-		ws.frameReader, err = ws.frameHandler.HandleFrame(frame)
-		if err != nil {
-			return 0, err
-		}
-		if ws.frameReader == nil {
-			goto again
-		}
-	}
-	n, err = ws.frameReader.Read(msg)
-	if err == io.EOF {
-		if trailer := ws.frameReader.TrailerReader(); trailer != nil {
-			io.Copy(ioutil.Discard, trailer)
-		}
-		ws.frameReader = nil
-		goto again
-	}
-	return n, err
-}
-
-// Write implements the io.Writer interface:
-// it writes data as a frame to the WebSocket connection.
-func (ws *Conn) Write(msg []byte) (n int, err error) {
-	ws.wio.Lock()
-	defer ws.wio.Unlock()
-	w, err := ws.frameWriterFactory.NewFrameWriter(ws.PayloadType)
-	if err != nil {
-		return 0, err
-	}
-	n, err = w.Write(msg)
-	w.Close()
-	if err != nil {
-		return n, err
-	}
-	return n, err
-}
-
-// Close implements the io.Closer interface.
-func (ws *Conn) Close() error {
-	err := ws.frameHandler.WriteClose(ws.defaultCloseStatus)
-	if err != nil {
-		return err
-	}
-	return ws.rwc.Close()
-}
-
-func (ws *Conn) IsClientConn() bool { return ws.request == nil }
-func (ws *Conn) IsServerConn() bool { return ws.request != nil }
-
-// LocalAddr returns the WebSocket Origin for the connection for client, or
-// the WebSocket location for server.
-func (ws *Conn) LocalAddr() net.Addr {
-	if ws.IsClientConn() {
-		return &Addr{ws.config.Origin}
-	}
-	return &Addr{ws.config.Location}
-}
-
-// RemoteAddr returns the WebSocket location for the connection for client, or
-// the Websocket Origin for server.
-func (ws *Conn) RemoteAddr() net.Addr {
-	if ws.IsClientConn() {
-		return &Addr{ws.config.Location}
-	}
-	return &Addr{ws.config.Origin}
-}
-
-var errSetDeadline = errors.New("websocket: cannot set deadline: not using a net.Conn")
-
-// SetDeadline sets the connection's network read & write deadlines.
-func (ws *Conn) SetDeadline(t time.Time) error {
-	if conn, ok := ws.rwc.(net.Conn); ok {
-		return conn.SetDeadline(t)
-	}
-	return errSetDeadline
-}
-
-// SetReadDeadline sets the connection's network read deadline.
-func (ws *Conn) SetReadDeadline(t time.Time) error {
-	if conn, ok := ws.rwc.(net.Conn); ok {
-		return conn.SetReadDeadline(t)
-	}
-	return errSetDeadline
-}
-
-// SetWriteDeadline sets the connection's network write deadline.
-func (ws *Conn) SetWriteDeadline(t time.Time) error {
-	if conn, ok := ws.rwc.(net.Conn); ok {
-		return conn.SetWriteDeadline(t)
-	}
-	return errSetDeadline
-}
-
-// Config returns the WebSocket config.
-func (ws *Conn) Config() *Config { return ws.config }
-
-// Request returns the http request upgraded to the WebSocket.
-// It is nil for client side.
-func (ws *Conn) Request() *http.Request { return ws.request }
-
-// Codec represents a symmetric pair of functions that implement a codec.
-type Codec struct {
-	Marshal   func(v interface{}) (data []byte, payloadType byte, err error)
-	Unmarshal func(data []byte, payloadType byte, v interface{}) (err error)
-}
-
-// Send sends v marshaled by cd.Marshal as single frame to ws.
-func (cd Codec) Send(ws *Conn, v interface{}) (err error) {
-	data, payloadType, err := cd.Marshal(v)
-	if err != nil {
-		return err
-	}
-	ws.wio.Lock()
-	defer ws.wio.Unlock()
-	w, err := ws.frameWriterFactory.NewFrameWriter(payloadType)
-	if err != nil {
-		return err
-	}
-	_, err = w.Write(data)
-	w.Close()
-	return err
-}
-
-// Receive receives single frame from ws, unmarshaled by cd.Unmarshal and stores in v.
-func (cd Codec) Receive(ws *Conn, v interface{}) (err error) {
-	ws.rio.Lock()
-	defer ws.rio.Unlock()
-	if ws.frameReader != nil {
-		_, err = io.Copy(ioutil.Discard, ws.frameReader)
-		if err != nil {
-			return err
-		}
-		ws.frameReader = nil
-	}
-again:
-	frame, err := ws.frameReaderFactory.NewFrameReader()
-	if err != nil {
-		return err
-	}
-	frame, err = ws.frameHandler.HandleFrame(frame)
-	if err != nil {
-		return err
-	}
-	if frame == nil {
-		goto again
-	}
-	payloadType := frame.PayloadType()
-	data, err := ioutil.ReadAll(frame)
-	if err != nil {
-		return err
-	}
-	return cd.Unmarshal(data, payloadType, v)
-}
-
-func marshal(v interface{}) (msg []byte, payloadType byte, err error) {
-	switch data := v.(type) {
-	case string:
-		return []byte(data), TextFrame, nil
-	case []byte:
-		return data, BinaryFrame, nil
-	}
-	return nil, UnknownFrame, ErrNotSupported
-}
-
-func unmarshal(msg []byte, payloadType byte, v interface{}) (err error) {
-	switch data := v.(type) {
-	case *string:
-		*data = string(msg)
-		return nil
-	case *[]byte:
-		*data = msg
-		return nil
-	}
-	return ErrNotSupported
-}
-
-/*
-Message is a codec to send/receive text/binary data in a frame on WebSocket connection.
-To send/receive text frame, use string type.
-To send/receive binary frame, use []byte type.
-
-Trivial usage:
-
-	import "websocket"
-
-	// receive text frame
-	var message string
-	websocket.Message.Receive(ws, &message)
-
-	// send text frame
-	message = "hello"
-	websocket.Message.Send(ws, message)
-
-	// receive binary frame
-	var data []byte
-	websocket.Message.Receive(ws, &data)
-
-	// send binary frame
-	data = []byte{0, 1, 2}
-	websocket.Message.Send(ws, data)
-
-*/
-var Message = Codec{marshal, unmarshal}
-
-func jsonMarshal(v interface{}) (msg []byte, payloadType byte, err error) {
-	msg, err = json.Marshal(v)
-	return msg, TextFrame, err
-}
-
-func jsonUnmarshal(msg []byte, payloadType byte, v interface{}) (err error) {
-	return json.Unmarshal(msg, v)
-}
-
-/*
-JSON is a codec to send/receive JSON data in a frame from a WebSocket connection.
-
-Trivial usage:
-
-	import "websocket"
-
-	type T struct {
-		Msg string
-		Count int
-	}
-
-	// receive JSON type T
-	var data T
-	websocket.JSON.Receive(ws, &data)
-
-	// send JSON type T
-	websocket.JSON.Send(ws, data)
-*/
-var JSON = Codec{jsonMarshal, jsonUnmarshal}
diff --git a/Godeps/_workspace/src/code.google.com/p/go.net/websocket/websocket_test.go b/Godeps/_workspace/src/code.google.com/p/go.net/websocket/websocket_test.go
deleted file mode 100644
index 48f14b696..000000000
--- a/Godeps/_workspace/src/code.google.com/p/go.net/websocket/websocket_test.go
+++ /dev/null
@@ -1,341 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package websocket
-
-import (
-	"bytes"
-	"fmt"
-	"io"
-	"log"
-	"net"
-	"net/http"
-	"net/http/httptest"
-	"net/url"
-	"strings"
-	"sync"
-	"testing"
-)
-
-var serverAddr string
-var once sync.Once
-
-func echoServer(ws *Conn) { io.Copy(ws, ws) }
-
-type Count struct {
-	S string
-	N int
-}
-
-func countServer(ws *Conn) {
-	for {
-		var count Count
-		err := JSON.Receive(ws, &count)
-		if err != nil {
-			return
-		}
-		count.N++
-		count.S = strings.Repeat(count.S, count.N)
-		err = JSON.Send(ws, count)
-		if err != nil {
-			return
-		}
-	}
-}
-
-func subProtocolHandshake(config *Config, req *http.Request) error {
-	for _, proto := range config.Protocol {
-		if proto == "chat" {
-			config.Protocol = []string{proto}
-			return nil
-		}
-	}
-	return ErrBadWebSocketProtocol
-}
-
-func subProtoServer(ws *Conn) {
-	for _, proto := range ws.Config().Protocol {
-		io.WriteString(ws, proto)
-	}
-}
-
-func startServer() {
-	http.Handle("/echo", Handler(echoServer))
-	http.Handle("/count", Handler(countServer))
-	subproto := Server{
-		Handshake: subProtocolHandshake,
-		Handler:   Handler(subProtoServer),
-	}
-	http.Handle("/subproto", subproto)
-	server := httptest.NewServer(nil)
-	serverAddr = server.Listener.Addr().String()
-	log.Print("Test WebSocket server listening on ", serverAddr)
-}
-
-func newConfig(t *testing.T, path string) *Config {
-	config, _ := NewConfig(fmt.Sprintf("ws://%s%s", serverAddr, path), "http://localhost")
-	return config
-}
-
-func TestEcho(t *testing.T) {
-	once.Do(startServer)
-
-	// websocket.Dial()
-	client, err := net.Dial("tcp", serverAddr)
-	if err != nil {
-		t.Fatal("dialing", err)
-	}
-	conn, err := NewClient(newConfig(t, "/echo"), client)
-	if err != nil {
-		t.Errorf("WebSocket handshake error: %v", err)
-		return
-	}
-
-	msg := []byte("hello, world\n")
-	if _, err := conn.Write(msg); err != nil {
-		t.Errorf("Write: %v", err)
-	}
-	var actual_msg = make([]byte, 512)
-	n, err := conn.Read(actual_msg)
-	if err != nil {
-		t.Errorf("Read: %v", err)
-	}
-	actual_msg = actual_msg[0:n]
-	if !bytes.Equal(msg, actual_msg) {
-		t.Errorf("Echo: expected %q got %q", msg, actual_msg)
-	}
-	conn.Close()
-}
-
-func TestAddr(t *testing.T) {
-	once.Do(startServer)
-
-	// websocket.Dial()
-	client, err := net.Dial("tcp", serverAddr)
-	if err != nil {
-		t.Fatal("dialing", err)
-	}
-	conn, err := NewClient(newConfig(t, "/echo"), client)
-	if err != nil {
-		t.Errorf("WebSocket handshake error: %v", err)
-		return
-	}
-
-	ra := conn.RemoteAddr().String()
-	if !strings.HasPrefix(ra, "ws://") || !strings.HasSuffix(ra, "/echo") {
-		t.Errorf("Bad remote addr: %v", ra)
-	}
-	la := conn.LocalAddr().String()
-	if !strings.HasPrefix(la, "http://") {
-		t.Errorf("Bad local addr: %v", la)
-	}
-	conn.Close()
-}
-
-func TestCount(t *testing.T) {
-	once.Do(startServer)
-
-	// websocket.Dial()
-	client, err := net.Dial("tcp", serverAddr)
-	if err != nil {
-		t.Fatal("dialing", err)
-	}
-	conn, err := NewClient(newConfig(t, "/count"), client)
-	if err != nil {
-		t.Errorf("WebSocket handshake error: %v", err)
-		return
-	}
-
-	var count Count
-	count.S = "hello"
-	if err := JSON.Send(conn, count); err != nil {
-		t.Errorf("Write: %v", err)
-	}
-	if err := JSON.Receive(conn, &count); err != nil {
-		t.Errorf("Read: %v", err)
-	}
-	if count.N != 1 {
-		t.Errorf("count: expected %d got %d", 1, count.N)
-	}
-	if count.S != "hello" {
-		t.Errorf("count: expected %q got %q", "hello", count.S)
-	}
-	if err := JSON.Send(conn, count); err != nil {
-		t.Errorf("Write: %v", err)
-	}
-	if err := JSON.Receive(conn, &count); err != nil {
-		t.Errorf("Read: %v", err)
-	}
-	if count.N != 2 {
-		t.Errorf("count: expected %d got %d", 2, count.N)
-	}
-	if count.S != "hellohello" {
-		t.Errorf("count: expected %q got %q", "hellohello", count.S)
-	}
-	conn.Close()
-}
-
-func TestWithQuery(t *testing.T) {
-	once.Do(startServer)
-
-	client, err := net.Dial("tcp", serverAddr)
-	if err != nil {
-		t.Fatal("dialing", err)
-	}
-
-	config := newConfig(t, "/echo")
-	config.Location, err = url.ParseRequestURI(fmt.Sprintf("ws://%s/echo?q=v", serverAddr))
-	if err != nil {
-		t.Fatal("location url", err)
-	}
-
-	ws, err := NewClient(config, client)
-	if err != nil {
-		t.Errorf("WebSocket handshake: %v", err)
-		return
-	}
-	ws.Close()
-}
-
-func testWithProtocol(t *testing.T, subproto []string) (string, error) {
-	once.Do(startServer)
-
-	client, err := net.Dial("tcp", serverAddr)
-	if err != nil {
-		t.Fatal("dialing", err)
-	}
-
-	config := newConfig(t, "/subproto")
-	config.Protocol = subproto
-
-	ws, err := NewClient(config, client)
-	if err != nil {
-		return "", err
-	}
-	msg := make([]byte, 16)
-	n, err := ws.Read(msg)
-	if err != nil {
-		return "", err
-	}
-	ws.Close()
-	return string(msg[:n]), nil
-}
-
-func TestWithProtocol(t *testing.T) {
-	proto, err := testWithProtocol(t, []string{"chat"})
-	if err != nil {
-		t.Errorf("SubProto: unexpected error: %v", err)
-	}
-	if proto != "chat" {
-		t.Errorf("SubProto: expected %q, got %q", "chat", proto)
-	}
-}
-
-func TestWithTwoProtocol(t *testing.T) {
-	proto, err := testWithProtocol(t, []string{"test", "chat"})
-	if err != nil {
-		t.Errorf("SubProto: unexpected error: %v", err)
-	}
-	if proto != "chat" {
-		t.Errorf("SubProto: expected %q, got %q", "chat", proto)
-	}
-}
-
-func TestWithBadProtocol(t *testing.T) {
-	_, err := testWithProtocol(t, []string{"test"})
-	if err != ErrBadStatus {
-		t.Errorf("SubProto: expected %v, got %v", ErrBadStatus, err)
-	}
-}
-
-func TestHTTP(t *testing.T) {
-	once.Do(startServer)
-
-	// If the client did not send a handshake that matches the protocol
-	// specification, the server MUST return an HTTP response with an
-	// appropriate error code (such as 400 Bad Request)
-	resp, err := http.Get(fmt.Sprintf("http://%s/echo", serverAddr))
-	if err != nil {
-		t.Errorf("Get: error %#v", err)
-		return
-	}
-	if resp == nil {
-		t.Error("Get: resp is null")
-		return
-	}
-	if resp.StatusCode != http.StatusBadRequest {
-		t.Errorf("Get: expected %q got %q", http.StatusBadRequest, resp.StatusCode)
-	}
-}
-
-func TestTrailingSpaces(t *testing.T) {
-	// http://code.google.com/p/go/issues/detail?id=955
-	// The last runs of this create keys with trailing spaces that should not be
-	// generated by the client.
-	once.Do(startServer)
-	config := newConfig(t, "/echo")
-	for i := 0; i < 30; i++ {
-		// body
-		ws, err := DialConfig(config)
-		if err != nil {
-			t.Errorf("Dial #%d failed: %v", i, err)
-			break
-		}
-		ws.Close()
-	}
-}
-
-func TestDialConfigBadVersion(t *testing.T) {
-	once.Do(startServer)
-	config := newConfig(t, "/echo")
-	config.Version = 1234
-
-	_, err := DialConfig(config)
-
-	if dialerr, ok := err.(*DialError); ok {
-		if dialerr.Err != ErrBadProtocolVersion {
-			t.Errorf("dial expected err %q but got %q", ErrBadProtocolVersion, dialerr.Err)
-		}
-	}
-}
-
-func TestSmallBuffer(t *testing.T) {
-	// http://code.google.com/p/go/issues/detail?id=1145
-	// Read should be able to handle reading a fragment of a frame.
-	once.Do(startServer)
-
-	// websocket.Dial()
-	client, err := net.Dial("tcp", serverAddr)
-	if err != nil {
-		t.Fatal("dialing", err)
-	}
-	conn, err := NewClient(newConfig(t, "/echo"), client)
-	if err != nil {
-		t.Errorf("WebSocket handshake error: %v", err)
-		return
-	}
-
-	msg := []byte("hello, world\n")
-	if _, err := conn.Write(msg); err != nil {
-		t.Errorf("Write: %v", err)
-	}
-	var small_msg = make([]byte, 8)
-	n, err := conn.Read(small_msg)
-	if err != nil {
-		t.Errorf("Read: %v", err)
-	}
-	if !bytes.Equal(msg[:len(small_msg)], small_msg) {
-		t.Errorf("Echo: expected %q got %q", msg[:len(small_msg)], small_msg)
-	}
-	var second_msg = make([]byte, len(msg))
-	n, err = conn.Read(second_msg)
-	if err != nil {
-		t.Errorf("Read: %v", err)
-	}
-	second_msg = second_msg[0:n]
-	if !bytes.Equal(msg[len(small_msg):], second_msg) {
-		t.Errorf("Echo: expected %q got %q", msg[len(small_msg):], second_msg)
-	}
-	conn.Close()
-}
diff --git a/Godeps/_workspace/src/golang.org/x/net/websocket/client.go b/Godeps/_workspace/src/golang.org/x/net/websocket/client.go
new file mode 100644
index 000000000..ef11a51e4
--- /dev/null
+++ b/Godeps/_workspace/src/golang.org/x/net/websocket/client.go
@@ -0,0 +1,112 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package websocket
+
+import (
+	"bufio"
+	"crypto/tls"
+	"io"
+	"net"
+	"net/http"
+	"net/url"
+)
+
+// DialError is an error that occurs while dialling a websocket server.
+type DialError struct {
+	*Config
+	Err error
+}
+
+func (e *DialError) Error() string {
+	return "websocket.Dial " + e.Config.Location.String() + ": " + e.Err.Error()
+}
+
+// NewConfig creates a new WebSocket config for client connection.
+func NewConfig(server, origin string) (config *Config, err error) {
+	config = new(Config)
+	config.Version = ProtocolVersionHybi13
+	config.Location, err = url.ParseRequestURI(server)
+	if err != nil {
+		return
+	}
+	config.Origin, err = url.ParseRequestURI(origin)
+	if err != nil {
+		return
+	}
+	config.Header = http.Header(make(map[string][]string))
+	return
+}
+
+// NewClient creates a new WebSocket client connection over rwc.
+func NewClient(config *Config, rwc io.ReadWriteCloser) (ws *Conn, err error) {
+	br := bufio.NewReader(rwc)
+	bw := bufio.NewWriter(rwc)
+	err = hybiClientHandshake(config, br, bw)
+	if err != nil {
+		return
+	}
+	buf := bufio.NewReadWriter(br, bw)
+	ws = newHybiClientConn(config, buf, rwc)
+	return
+}
+
+// Dial opens a new client connection to a WebSocket.
+func Dial(url_, protocol, origin string) (ws *Conn, err error) {
+	config, err := NewConfig(url_, origin)
+	if err != nil {
+		return nil, err
+	}
+	if protocol != "" {
+		config.Protocol = []string{protocol}
+	}
+	return DialConfig(config)
+}
+
+var portMap = map[string]string{
+	"ws":  "80",
+	"wss": "443",
+}
+
+func parseAuthority(location *url.URL) string {
+	if _, ok := portMap[location.Scheme]; ok {
+		if _, _, err := net.SplitHostPort(location.Host); err != nil {
+			return net.JoinHostPort(location.Host, portMap[location.Scheme])
+		}
+	}
+	return location.Host
+}
+
+// DialConfig opens a new client connection to a WebSocket with a config.
+func DialConfig(config *Config) (ws *Conn, err error) {
+	var client net.Conn
+	if config.Location == nil {
+		return nil, &DialError{config, ErrBadWebSocketLocation}
+	}
+	if config.Origin == nil {
+		return nil, &DialError{config, ErrBadWebSocketOrigin}
+	}
+	switch config.Location.Scheme {
+	case "ws":
+		client, err = net.Dial("tcp", parseAuthority(config.Location))
+
+	case "wss":
+		client, err = tls.Dial("tcp", parseAuthority(config.Location), config.TlsConfig)
+
+	default:
+		err = ErrBadScheme
+	}
+	if err != nil {
+		goto Error
+	}
+
+	ws, err = NewClient(config, client)
+	if err != nil {
+		goto Error
+	}
+	return
+
+Error:
+	return nil, &DialError{config, err}
+}
diff --git a/Godeps/_workspace/src/golang.org/x/net/websocket/exampledial_test.go b/Godeps/_workspace/src/golang.org/x/net/websocket/exampledial_test.go
new file mode 100644
index 000000000..72bb9d48e
--- /dev/null
+++ b/Godeps/_workspace/src/golang.org/x/net/websocket/exampledial_test.go
@@ -0,0 +1,31 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package websocket_test
+
+import (
+	"fmt"
+	"log"
+
+	"golang.org/x/net/websocket"
+)
+
+// This example demonstrates a trivial client.
+func ExampleDial() {
+	origin := "http://localhost/"
+	url := "ws://localhost:12345/ws"
+	ws, err := websocket.Dial(url, "", origin)
+	if err != nil {
+		log.Fatal(err)
+	}
+	if _, err := ws.Write([]byte("hello, world!\n")); err != nil {
+		log.Fatal(err)
+	}
+	var msg = make([]byte, 512)
+	var n int
+	if n, err = ws.Read(msg); err != nil {
+		log.Fatal(err)
+	}
+	fmt.Printf("Received: %s.\n", msg[:n])
+}
diff --git a/Godeps/_workspace/src/golang.org/x/net/websocket/examplehandler_test.go b/Godeps/_workspace/src/golang.org/x/net/websocket/examplehandler_test.go
new file mode 100644
index 000000000..f22a98fcd
--- /dev/null
+++ b/Godeps/_workspace/src/golang.org/x/net/websocket/examplehandler_test.go
@@ -0,0 +1,26 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package websocket_test
+
+import (
+	"io"
+	"net/http"
+
+	"golang.org/x/net/websocket"
+)
+
+// Echo the data received on the WebSocket.
+func EchoServer(ws *websocket.Conn) {
+	io.Copy(ws, ws)
+}
+
+// This example demonstrates a trivial echo server.
+func ExampleHandler() {
+	http.Handle("/echo", websocket.Handler(EchoServer))
+	err := http.ListenAndServe(":12345", nil)
+	if err != nil {
+		panic("ListenAndServe: " + err.Error())
+	}
+}
diff --git a/Godeps/_workspace/src/golang.org/x/net/websocket/hybi.go b/Godeps/_workspace/src/golang.org/x/net/websocket/hybi.go
new file mode 100644
index 000000000..f8c0b2e29
--- /dev/null
+++ b/Godeps/_workspace/src/golang.org/x/net/websocket/hybi.go
@@ -0,0 +1,564 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package websocket
+
+// This file implements a protocol of hybi draft.
+// http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-17
+
+import (
+	"bufio"
+	"bytes"
+	"crypto/rand"
+	"crypto/sha1"
+	"encoding/base64"
+	"encoding/binary"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+	"strings"
+)
+
+const (
+	websocketGUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
+
+	closeStatusNormal            = 1000
+	closeStatusGoingAway         = 1001
+	closeStatusProtocolError     = 1002
+	closeStatusUnsupportedData   = 1003
+	closeStatusFrameTooLarge     = 1004
+	closeStatusNoStatusRcvd      = 1005
+	closeStatusAbnormalClosure   = 1006
+	closeStatusBadMessageData    = 1007
+	closeStatusPolicyViolation   = 1008
+	closeStatusTooBigData        = 1009
+	closeStatusExtensionMismatch = 1010
+
+	maxControlFramePayloadLength = 125
+)
+
+var (
+	ErrBadMaskingKey         = &ProtocolError{"bad masking key"}
+	ErrBadPongMessage        = &ProtocolError{"bad pong message"}
+	ErrBadClosingStatus      = &ProtocolError{"bad closing status"}
+	ErrUnsupportedExtensions = &ProtocolError{"unsupported extensions"}
+	ErrNotImplemented        = &ProtocolError{"not implemented"}
+
+	handshakeHeader = map[string]bool{
+		"Host":                   true,
+		"Upgrade":                true,
+		"Connection":             true,
+		"Sec-Websocket-Key":      true,
+		"Sec-Websocket-Origin":   true,
+		"Sec-Websocket-Version":  true,
+		"Sec-Websocket-Protocol": true,
+		"Sec-Websocket-Accept":   true,
+	}
+)
+
+// A hybiFrameHeader is a frame header as defined in hybi draft.
+type hybiFrameHeader struct {
+	Fin        bool
+	Rsv        [3]bool
+	OpCode     byte
+	Length     int64
+	MaskingKey []byte
+
+	data *bytes.Buffer
+}
+
+// A hybiFrameReader is a reader for hybi frame.
+type hybiFrameReader struct {
+	reader io.Reader
+
+	header hybiFrameHeader
+	pos    int64
+	length int
+}
+
+func (frame *hybiFrameReader) Read(msg []byte) (n int, err error) {
+	n, err = frame.reader.Read(msg)
+	if err != nil {
+		return 0, err
+	}
+	if frame.header.MaskingKey != nil {
+		for i := 0; i < n; i++ {
+			msg[i] = msg[i] ^ frame.header.MaskingKey[frame.pos%4]
+			frame.pos++
+		}
+	}
+	return n, err
+}
+
+func (frame *hybiFrameReader) PayloadType() byte { return frame.header.OpCode }
+
+func (frame *hybiFrameReader) HeaderReader() io.Reader {
+	if frame.header.data == nil {
+		return nil
+	}
+	if frame.header.data.Len() == 0 {
+		return nil
+	}
+	return frame.header.data
+}
+
+func (frame *hybiFrameReader) TrailerReader() io.Reader { return nil }
+
+func (frame *hybiFrameReader) Len() (n int) { return frame.length }
+
+// A hybiFrameReaderFactory creates new frame reader based on its frame type.
+type hybiFrameReaderFactory struct {
+	*bufio.Reader
+}
+
+// NewFrameReader reads a frame header from the connection, and creates new reader for the frame.
+// See Section 5.2 Base Framing protocol for detail.
+// http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-17#section-5.2
+func (buf hybiFrameReaderFactory) NewFrameReader() (frame frameReader, err error) {
+	hybiFrame := new(hybiFrameReader)
+	frame = hybiFrame
+	var header []byte
+	var b byte
+	// First byte. FIN/RSV1/RSV2/RSV3/OpCode(4bits)
+	b, err = buf.ReadByte()
+	if err != nil {
+		return
+	}
+	header = append(header, b)
+	hybiFrame.header.Fin = ((header[0] >> 7) & 1) != 0
+	for i := 0; i < 3; i++ {
+		j := uint(6 - i)
+		hybiFrame.header.Rsv[i] = ((header[0] >> j) & 1) != 0
+	}
+	hybiFrame.header.OpCode = header[0] & 0x0f
+
+	// Second byte. Mask/Payload len(7bits)
+	b, err = buf.ReadByte()
+	if err != nil {
+		return
+	}
+	header = append(header, b)
+	mask := (b & 0x80) != 0
+	b &= 0x7f
+	lengthFields := 0
+	switch {
+	case b <= 125: // Payload length 7bits.
+		hybiFrame.header.Length = int64(b)
+	case b == 126: // Payload length 7+16bits
+		lengthFields = 2
+	case b == 127: // Payload length 7+64bits
+		lengthFields = 8
+	}
+	for i := 0; i < lengthFields; i++ {
+		b, err = buf.ReadByte()
+		if err != nil {
+			return
+		}
+		header = append(header, b)
+		hybiFrame.header.Length = hybiFrame.header.Length*256 + int64(b)
+	}
+	if mask {
+		// Masking key. 4 bytes.
+		for i := 0; i < 4; i++ {
+			b, err = buf.ReadByte()
+			if err != nil {
+				return
+			}
+			header = append(header, b)
+			hybiFrame.header.MaskingKey = append(hybiFrame.header.MaskingKey, b)
+		}
+	}
+	hybiFrame.reader = io.LimitReader(buf.Reader, hybiFrame.header.Length)
+	hybiFrame.header.data = bytes.NewBuffer(header)
+	hybiFrame.length = len(header) + int(hybiFrame.header.Length)
+	return
+}
+
+// A HybiFrameWriter is a writer for hybi frame.
+type hybiFrameWriter struct {
+	writer *bufio.Writer
+
+	header *hybiFrameHeader
+}
+
+func (frame *hybiFrameWriter) Write(msg []byte) (n int, err error) {
+	var header []byte
+	var b byte
+	if frame.header.Fin {
+		b |= 0x80
+	}
+	for i := 0; i < 3; i++ {
+		if frame.header.Rsv[i] {
+			j := uint(6 - i)
+			b |= 1 << j
+		}
+	}
+	b |= frame.header.OpCode
+	header = append(header, b)
+	if frame.header.MaskingKey != nil {
+		b = 0x80
+	} else {
+		b = 0
+	}
+	lengthFields := 0
+	length := len(msg)
+	switch {
+	case length <= 125:
+		b |= byte(length)
+	case length < 65536:
+		b |= 126
+		lengthFields = 2
+	default:
+		b |= 127
+		lengthFields = 8
+	}
+	header = append(header, b)
+	for i := 0; i < lengthFields; i++ {
+		j := uint((lengthFields - i - 1) * 8)
+		b = byte((length >> j) & 0xff)
+		header = append(header, b)
+	}
+	if frame.header.MaskingKey != nil {
+		if len(frame.header.MaskingKey) != 4 {
+			return 0, ErrBadMaskingKey
+		}
+		header = append(header, frame.header.MaskingKey...)
+		frame.writer.Write(header)
+		data := make([]byte, length)
+		for i := range data {
+			data[i] = msg[i] ^ frame.header.MaskingKey[i%4]
+		}
+		frame.writer.Write(data)
+		err = frame.writer.Flush()
+		return length, err
+	}
+	frame.writer.Write(header)
+	frame.writer.Write(msg)
+	err = frame.writer.Flush()
+	return length, err
+}
+
+func (frame *hybiFrameWriter) Close() error { return nil }
+
+type hybiFrameWriterFactory struct {
+	*bufio.Writer
+	needMaskingKey bool
+}
+
+func (buf hybiFrameWriterFactory) NewFrameWriter(payloadType byte) (frame frameWriter, err error) {
+	frameHeader := &hybiFrameHeader{Fin: true, OpCode: payloadType}
+	if buf.needMaskingKey {
+		frameHeader.MaskingKey, err = generateMaskingKey()
+		if err != nil {
+			return nil, err
+		}
+	}
+	return &hybiFrameWriter{writer: buf.Writer, header: frameHeader}, nil
+}
+
+type hybiFrameHandler struct {
+	conn        *Conn
+	payloadType byte
+}
+
+func (handler *hybiFrameHandler) HandleFrame(frame frameReader) (r frameReader, err error) {
+	if handler.conn.IsServerConn() {
+		// The client MUST mask all frames sent to the server.
+		if frame.(*hybiFrameReader).header.MaskingKey == nil {
+			handler.WriteClose(closeStatusProtocolError)
+			return nil, io.EOF
+		}
+	} else {
+		// The server MUST NOT mask all frames.
+		if frame.(*hybiFrameReader).header.MaskingKey != nil {
+			handler.WriteClose(closeStatusProtocolError)
+			return nil, io.EOF
+		}
+	}
+	if header := frame.HeaderReader(); header != nil {
+		io.Copy(ioutil.Discard, header)
+	}
+	switch frame.PayloadType() {
+	case ContinuationFrame:
+		frame.(*hybiFrameReader).header.OpCode = handler.payloadType
+	case TextFrame, BinaryFrame:
+		handler.payloadType = frame.PayloadType()
+	case CloseFrame:
+		return nil, io.EOF
+	case PingFrame:
+		pingMsg := make([]byte, maxControlFramePayloadLength)
+		n, err := io.ReadFull(frame, pingMsg)
+		if err != nil && err != io.ErrUnexpectedEOF {
+			return nil, err
+		}
+		io.Copy(ioutil.Discard, frame)
+		n, err = handler.WritePong(pingMsg[:n])
+		if err != nil {
+			return nil, err
+		}
+		return nil, nil
+	case PongFrame:
+		return nil, ErrNotImplemented
+	}
+	return frame, nil
+}
+
+func (handler *hybiFrameHandler) WriteClose(status int) (err error) {
+	handler.conn.wio.Lock()
+	defer handler.conn.wio.Unlock()
+	w, err := handler.conn.frameWriterFactory.NewFrameWriter(CloseFrame)
+	if err != nil {
+		return err
+	}
+	msg := make([]byte, 2)
+	binary.BigEndian.PutUint16(msg, uint16(status))
+	_, err = w.Write(msg)
+	w.Close()
+	return err
+}
+
+func (handler *hybiFrameHandler) WritePong(msg []byte) (n int, err error) {
+	handler.conn.wio.Lock()
+	defer handler.conn.wio.Unlock()
+	w, err := handler.conn.frameWriterFactory.NewFrameWriter(PongFrame)
+	if err != nil {
+		return 0, err
+	}
+	n, err = w.Write(msg)
+	w.Close()
+	return n, err
+}
+
+// newHybiConn creates a new WebSocket connection speaking hybi draft protocol.
+func newHybiConn(config *Config, buf *bufio.ReadWriter, rwc io.ReadWriteCloser, request *http.Request) *Conn {
+	if buf == nil {
+		br := bufio.NewReader(rwc)
+		bw := bufio.NewWriter(rwc)
+		buf = bufio.NewReadWriter(br, bw)
+	}
+	ws := &Conn{config: config, request: request, buf: buf, rwc: rwc,
+		frameReaderFactory: hybiFrameReaderFactory{buf.Reader},
+		frameWriterFactory: hybiFrameWriterFactory{
+			buf.Writer, request == nil},
+		PayloadType:        TextFrame,
+		defaultCloseStatus: closeStatusNormal}
+	ws.frameHandler = &hybiFrameHandler{conn: ws}
+	return ws
+}
+
+// generateMaskingKey generates a masking key for a frame.
+func generateMaskingKey() (maskingKey []byte, err error) {
+	maskingKey = make([]byte, 4)
+	if _, err = io.ReadFull(rand.Reader, maskingKey); err != nil {
+		return
+	}
+	return
+}
+
+// generateNonce generates a nonce consisting of a randomly selected 16-byte
+// value that has been base64-encoded.
+func generateNonce() (nonce []byte) {
+	key := make([]byte, 16)
+	if _, err := io.ReadFull(rand.Reader, key); err != nil {
+		panic(err)
+	}
+	nonce = make([]byte, 24)
+	base64.StdEncoding.Encode(nonce, key)
+	return
+}
+
+// getNonceAccept computes the base64-encoded SHA-1 of the concatenation of
+// the nonce ("Sec-WebSocket-Key" value) with the websocket GUID string.
+func getNonceAccept(nonce []byte) (expected []byte, err error) {
+	h := sha1.New()
+	if _, err = h.Write(nonce); err != nil {
+		return
+	}
+	if _, err = h.Write([]byte(websocketGUID)); err != nil {
+		return
+	}
+	expected = make([]byte, 28)
+	base64.StdEncoding.Encode(expected, h.Sum(nil))
+	return
+}
+
+// Client handshake described in draft-ietf-hybi-thewebsocket-protocol-17
+func hybiClientHandshake(config *Config, br *bufio.Reader, bw *bufio.Writer) (err error) {
+	bw.WriteString("GET " + config.Location.RequestURI() + " HTTP/1.1\r\n")
+
+	bw.WriteString("Host: " + config.Location.Host + "\r\n")
+	bw.WriteString("Upgrade: websocket\r\n")
+	bw.WriteString("Connection: Upgrade\r\n")
+	nonce := generateNonce()
+	if config.handshakeData != nil {
+		nonce = []byte(config.handshakeData["key"])
+	}
+	bw.WriteString("Sec-WebSocket-Key: " + string(nonce) + "\r\n")
+	bw.WriteString("Origin: " + strings.ToLower(config.Origin.String()) + "\r\n")
+
+	if config.Version != ProtocolVersionHybi13 {
+		return ErrBadProtocolVersion
+	}
+
+	bw.WriteString("Sec-WebSocket-Version: " + fmt.Sprintf("%d", config.Version) + "\r\n")
+	if len(config.Protocol) > 0 {
+		bw.WriteString("Sec-WebSocket-Protocol: " + strings.Join(config.Protocol, ", ") + "\r\n")
+	}
+	// TODO(ukai): send Sec-WebSocket-Extensions.
+	err = config.Header.WriteSubset(bw, handshakeHeader)
+	if err != nil {
+		return err
+	}
+
+	bw.WriteString("\r\n")
+	if err = bw.Flush(); err != nil {
+		return err
+	}
+
+	resp, err := http.ReadResponse(br, &http.Request{Method: "GET"})
+	if err != nil {
+		return err
+	}
+	if resp.StatusCode != 101 {
+		return ErrBadStatus
+	}
+	if strings.ToLower(resp.Header.Get("Upgrade")) != "websocket" ||
+		strings.ToLower(resp.Header.Get("Connection")) != "upgrade" {
+		return ErrBadUpgrade
+	}
+	expectedAccept, err := getNonceAccept(nonce)
+	if err != nil {
+		return err
+	}
+	if resp.Header.Get("Sec-WebSocket-Accept") != string(expectedAccept) {
+		return ErrChallengeResponse
+	}
+	if resp.Header.Get("Sec-WebSocket-Extensions") != "" {
+		return ErrUnsupportedExtensions
+	}
+	offeredProtocol := resp.Header.Get("Sec-WebSocket-Protocol")
+	if offeredProtocol != "" {
+		protocolMatched := false
+		for i := 0; i < len(config.Protocol); i++ {
+			if config.Protocol[i] == offeredProtocol {
+				protocolMatched = true
+				break
+			}
+		}
+		if !protocolMatched {
+			return ErrBadWebSocketProtocol
+		}
+		config.Protocol = []string{offeredProtocol}
+	}
+
+	return nil
+}
+
+// newHybiClientConn creates a client WebSocket connection after handshake.
+func newHybiClientConn(config *Config, buf *bufio.ReadWriter, rwc io.ReadWriteCloser) *Conn {
+	return newHybiConn(config, buf, rwc, nil)
+}
+
+// A HybiServerHandshaker performs a server handshake using hybi draft protocol.
+type hybiServerHandshaker struct {
+	*Config
+	accept []byte
+}
+
+func (c *hybiServerHandshaker) ReadHandshake(buf *bufio.Reader, req *http.Request) (code int, err error) {
+	c.Version = ProtocolVersionHybi13
+	if req.Method != "GET" {
+		return http.StatusMethodNotAllowed, ErrBadRequestMethod
+	}
+	// HTTP version can be safely ignored.
+
+	if strings.ToLower(req.Header.Get("Upgrade")) != "websocket" ||
+		!strings.Contains(strings.ToLower(req.Header.Get("Connection")), "upgrade") {
+		return http.StatusBadRequest, ErrNotWebSocket
+	}
+
+	key := req.Header.Get("Sec-Websocket-Key")
+	if key == "" {
+		return http.StatusBadRequest, ErrChallengeResponse
+	}
+	version := req.Header.Get("Sec-Websocket-Version")
+	switch version {
+	case "13":
+		c.Version = ProtocolVersionHybi13
+	default:
+		return http.StatusBadRequest, ErrBadWebSocketVersion
+	}
+	var scheme string
+	if req.TLS != nil {
+		scheme = "wss"
+	} else {
+		scheme = "ws"
+	}
+	c.Location, err = url.ParseRequestURI(scheme + "://" + req.Host + req.URL.RequestURI())
+	if err != nil {
+		return http.StatusBadRequest, err
+	}
+	protocol := strings.TrimSpace(req.Header.Get("Sec-Websocket-Protocol"))
+	if protocol != "" {
+		protocols := strings.Split(protocol, ",")
+		for i := 0; i < len(protocols); i++ {
+			c.Protocol = append(c.Protocol, strings.TrimSpace(protocols[i]))
+		}
+	}
+	c.accept, err = getNonceAccept([]byte(key))
+	if err != nil {
+		return http.StatusInternalServerError, err
+	}
+	return http.StatusSwitchingProtocols, nil
+}
+
+// Origin parses Origin header in "req".
+// If origin is "null", returns (nil, nil).
+func Origin(config *Config, req *http.Request) (*url.URL, error) {
+	var origin string
+	switch config.Version {
+	case ProtocolVersionHybi13:
+		origin = req.Header.Get("Origin")
+	}
+	if origin == "null" {
+		return nil, nil
+	}
+	return url.ParseRequestURI(origin)
+}
+
+func (c *hybiServerHandshaker) AcceptHandshake(buf *bufio.Writer) (err error) {
+	if len(c.Protocol) > 0 {
+		if len(c.Protocol) != 1 {
+			// You need choose a Protocol in Handshake func in Server.
+			return ErrBadWebSocketProtocol
+		}
+	}
+	buf.WriteString("HTTP/1.1 101 Switching Protocols\r\n")
+	buf.WriteString("Upgrade: websocket\r\n")
+	buf.WriteString("Connection: Upgrade\r\n")
+	buf.WriteString("Sec-WebSocket-Accept: " + string(c.accept) + "\r\n")
+	if len(c.Protocol) > 0 {
+		buf.WriteString("Sec-WebSocket-Protocol: " + c.Protocol[0] + "\r\n")
+	}
+	// TODO(ukai): send Sec-WebSocket-Extensions.
+	if c.Header != nil {
+		err := c.Header.WriteSubset(buf, handshakeHeader)
+		if err != nil {
+			return err
+		}
+	}
+	buf.WriteString("\r\n")
+	return buf.Flush()
+}
+
+func (c *hybiServerHandshaker) NewServerConn(buf *bufio.ReadWriter, rwc io.ReadWriteCloser, request *http.Request) *Conn {
+	return newHybiServerConn(c.Config, buf, rwc, request)
+}
+
+// newHybiServerConn returns a new WebSocket connection speaking hybi draft protocol.
+func newHybiServerConn(config *Config, buf *bufio.ReadWriter, rwc io.ReadWriteCloser, request *http.Request) *Conn {
+	return newHybiConn(config, buf, rwc, request)
+}
diff --git a/Godeps/_workspace/src/golang.org/x/net/websocket/hybi_test.go b/Godeps/_workspace/src/golang.org/x/net/websocket/hybi_test.go
new file mode 100644
index 000000000..d6a19108a
--- /dev/null
+++ b/Godeps/_workspace/src/golang.org/x/net/websocket/hybi_test.go
@@ -0,0 +1,590 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package websocket
+
+import (
+	"bufio"
+	"bytes"
+	"fmt"
+	"io"
+	"net/http"
+	"net/url"
+	"strings"
+	"testing"
+)
+
+// Test the getNonceAccept function with values in
+// http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-17
+func TestSecWebSocketAccept(t *testing.T) {
+	nonce := []byte("dGhlIHNhbXBsZSBub25jZQ==")
+	expected := []byte("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=")
+	accept, err := getNonceAccept(nonce)
+	if err != nil {
+		t.Errorf("getNonceAccept: returned error %v", err)
+		return
+	}
+	if !bytes.Equal(expected, accept) {
+		t.Errorf("getNonceAccept: expected %q got %q", expected, accept)
+	}
+}
+
+func TestHybiClientHandshake(t *testing.T) {
+	b := bytes.NewBuffer([]byte{})
+	bw := bufio.NewWriter(b)
+	br := bufio.NewReader(strings.NewReader(`HTTP/1.1 101 Switching Protocols
+Upgrade: websocket
+Connection: Upgrade
+Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
+Sec-WebSocket-Protocol: chat
+
+`))
+	var err error
+	config := new(Config)
+	config.Location, err = url.ParseRequestURI("ws://server.example.com/chat")
+	if err != nil {
+		t.Fatal("location url", err)
+	}
+	config.Origin, err = url.ParseRequestURI("http://example.com")
+	if err != nil {
+		t.Fatal("origin url", err)
+	}
+	config.Protocol = append(config.Protocol, "chat")
+	config.Protocol = append(config.Protocol, "superchat")
+	config.Version = ProtocolVersionHybi13
+
+	config.handshakeData = map[string]string{
+		"key": "dGhlIHNhbXBsZSBub25jZQ==",
+	}
+	err = hybiClientHandshake(config, br, bw)
+	if err != nil {
+		t.Errorf("handshake failed: %v", err)
+	}
+	req, err := http.ReadRequest(bufio.NewReader(b))
+	if err != nil {
+		t.Fatalf("read request: %v", err)
+	}
+	if req.Method != "GET" {
+		t.Errorf("request method expected GET, but got %q", req.Method)
+	}
+	if req.URL.Path != "/chat" {
+		t.Errorf("request path expected /chat, but got %q", req.URL.Path)
+	}
+	if req.Proto != "HTTP/1.1" {
+		t.Errorf("request proto expected HTTP/1.1, but got %q", req.Proto)
+	}
+	if req.Host != "server.example.com" {
+		t.Errorf("request Host expected server.example.com, but got %v", req.Host)
+	}
+	var expectedHeader = map[string]string{
+		"Connection":             "Upgrade",
+		"Upgrade":                "websocket",
+		"Sec-Websocket-Key":      config.handshakeData["key"],
+		"Origin":                 config.Origin.String(),
+		"Sec-Websocket-Protocol": "chat, superchat",
+		"Sec-Websocket-Version":  fmt.Sprintf("%d", ProtocolVersionHybi13),
+	}
+	for k, v := range expectedHeader {
+		if req.Header.Get(k) != v {
+			t.Errorf(fmt.Sprintf("%s expected %q but got %q", k, v, req.Header.Get(k)))
+		}
+	}
+}
+
+func TestHybiClientHandshakeWithHeader(t *testing.T) {
+	b := bytes.NewBuffer([]byte{})
+	bw := bufio.NewWriter(b)
+	br := bufio.NewReader(strings.NewReader(`HTTP/1.1 101 Switching Protocols
+Upgrade: websocket
+Connection: Upgrade
+Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
+Sec-WebSocket-Protocol: chat
+
+`))
+	var err error
+	config := new(Config)
+	config.Location, err = url.ParseRequestURI("ws://server.example.com/chat")
+	if err != nil {
+		t.Fatal("location url", err)
+	}
+	config.Origin, err = url.ParseRequestURI("http://example.com")
+	if err != nil {
+		t.Fatal("origin url", err)
+	}
+	config.Protocol = append(config.Protocol, "chat")
+	config.Protocol = append(config.Protocol, "superchat")
+	config.Version = ProtocolVersionHybi13
+	config.Header = http.Header(make(map[string][]string))
+	config.Header.Add("User-Agent", "test")
+
+	config.handshakeData = map[string]string{
+		"key": "dGhlIHNhbXBsZSBub25jZQ==",
+	}
+	err = hybiClientHandshake(config, br, bw)
+	if err != nil {
+		t.Errorf("handshake failed: %v", err)
+	}
+	req, err := http.ReadRequest(bufio.NewReader(b))
+	if err != nil {
+		t.Fatalf("read request: %v", err)
+	}
+	if req.Method != "GET" {
+		t.Errorf("request method expected GET, but got %q", req.Method)
+	}
+	if req.URL.Path != "/chat" {
+		t.Errorf("request path expected /chat, but got %q", req.URL.Path)
+	}
+	if req.Proto != "HTTP/1.1" {
+		t.Errorf("request proto expected HTTP/1.1, but got %q", req.Proto)
+	}
+	if req.Host != "server.example.com" {
+		t.Errorf("request Host expected server.example.com, but got %v", req.Host)
+	}
+	var expectedHeader = map[string]string{
+		"Connection":             "Upgrade",
+		"Upgrade":                "websocket",
+		"Sec-Websocket-Key":      config.handshakeData["key"],
+		"Origin":                 config.Origin.String(),
+		"Sec-Websocket-Protocol": "chat, superchat",
+		"Sec-Websocket-Version":  fmt.Sprintf("%d", ProtocolVersionHybi13),
+		"User-Agent":             "test",
+	}
+	for k, v := range expectedHeader {
+		if req.Header.Get(k) != v {
+			t.Errorf(fmt.Sprintf("%s expected %q but got %q", k, v, req.Header.Get(k)))
+		}
+	}
+}
+
+func TestHybiServerHandshake(t *testing.T) {
+	config := new(Config)
+	handshaker := &hybiServerHandshaker{Config: config}
+	br := bufio.NewReader(strings.NewReader(`GET /chat HTTP/1.1
+Host: server.example.com
+Upgrade: websocket
+Connection: Upgrade
+Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
+Origin: http://example.com
+Sec-WebSocket-Protocol: chat, superchat
+Sec-WebSocket-Version: 13
+
+`))
+	req, err := http.ReadRequest(br)
+	if err != nil {
+		t.Fatal("request", err)
+	}
+	code, err := handshaker.ReadHandshake(br, req)
+	if err != nil {
+		t.Errorf("handshake failed: %v", err)
+	}
+	if code != http.StatusSwitchingProtocols {
+		t.Errorf("status expected %q but got %q", http.StatusSwitchingProtocols, code)
+	}
+	expectedProtocols := []string{"chat", "superchat"}
+	if fmt.Sprintf("%v", config.Protocol) != fmt.Sprintf("%v", expectedProtocols) {
+		t.Errorf("protocol expected %q but got %q", expectedProtocols, config.Protocol)
+	}
+	b := bytes.NewBuffer([]byte{})
+	bw := bufio.NewWriter(b)
+
+	config.Protocol = config.Protocol[:1]
+
+	err = handshaker.AcceptHandshake(bw)
+	if err != nil {
+		t.Errorf("handshake response failed: %v", err)
+	}
+	expectedResponse := strings.Join([]string{
+		"HTTP/1.1 101 Switching Protocols",
+		"Upgrade: websocket",
+		"Connection: Upgrade",
+		"Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",
+		"Sec-WebSocket-Protocol: chat",
+		"", ""}, "\r\n")
+
+	if b.String() != expectedResponse {
+		t.Errorf("handshake expected %q but got %q", expectedResponse, b.String())
+	}
+}
+
+func TestHybiServerHandshakeNoSubProtocol(t *testing.T) {
+	config := new(Config)
+	handshaker := &hybiServerHandshaker{Config: config}
+	br := bufio.NewReader(strings.NewReader(`GET /chat HTTP/1.1
+Host: server.example.com
+Upgrade: websocket
+Connection: Upgrade
+Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
+Origin: http://example.com
+Sec-WebSocket-Version: 13
+
+`))
+	req, err := http.ReadRequest(br)
+	if err != nil {
+		t.Fatal("request", err)
+	}
+	code, err := handshaker.ReadHandshake(br, req)
+	if err != nil {
+		t.Errorf("handshake failed: %v", err)
+	}
+	if code != http.StatusSwitchingProtocols {
+		t.Errorf("status expected %q but got %q", http.StatusSwitchingProtocols, code)
+	}
+	if len(config.Protocol) != 0 {
+		t.Errorf("len(config.Protocol) expected 0, but got %q", len(config.Protocol))
+	}
+	b := bytes.NewBuffer([]byte{})
+	bw := bufio.NewWriter(b)
+
+	err = handshaker.AcceptHandshake(bw)
+	if err != nil {
+		t.Errorf("handshake response failed: %v", err)
+	}
+	expectedResponse := strings.Join([]string{
+		"HTTP/1.1 101 Switching Protocols",
+		"Upgrade: websocket",
+		"Connection: Upgrade",
+		"Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",
+		"", ""}, "\r\n")
+
+	if b.String() != expectedResponse {
+		t.Errorf("handshake expected %q but got %q", expectedResponse, b.String())
+	}
+}
+
+func TestHybiServerHandshakeHybiBadVersion(t *testing.T) {
+	config := new(Config)
+	handshaker := &hybiServerHandshaker{Config: config}
+	br := bufio.NewReader(strings.NewReader(`GET /chat HTTP/1.1
+Host: server.example.com
+Upgrade: websocket
+Connection: Upgrade
+Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
+Sec-WebSocket-Origin: http://example.com
+Sec-WebSocket-Protocol: chat, superchat
+Sec-WebSocket-Version: 9
+
+`))
+	req, err := http.ReadRequest(br)
+	if err != nil {
+		t.Fatal("request", err)
+	}
+	code, err := handshaker.ReadHandshake(br, req)
+	if err != ErrBadWebSocketVersion {
+		t.Errorf("handshake expected err %q but got %q", ErrBadWebSocketVersion, err)
+	}
+	if code != http.StatusBadRequest {
+		t.Errorf("status expected %q but got %q", http.StatusBadRequest, code)
+	}
+}
+
+func testHybiFrame(t *testing.T, testHeader, testPayload, testMaskedPayload []byte, frameHeader *hybiFrameHeader) {
+	b := bytes.NewBuffer([]byte{})
+	frameWriterFactory := &hybiFrameWriterFactory{bufio.NewWriter(b), false}
+	w, _ := frameWriterFactory.NewFrameWriter(TextFrame)
+	w.(*hybiFrameWriter).header = frameHeader
+	_, err := w.Write(testPayload)
+	w.Close()
+	if err != nil {
+		t.Errorf("Write error %q", err)
+	}
+	var expectedFrame []byte
+	expectedFrame = append(expectedFrame, testHeader...)
+	expectedFrame = append(expectedFrame, testMaskedPayload...)
+	if !bytes.Equal(expectedFrame, b.Bytes()) {
+		t.Errorf("frame expected %q got %q", expectedFrame, b.Bytes())
+	}
+	frameReaderFactory := &hybiFrameReaderFactory{bufio.NewReader(b)}
+	r, err := frameReaderFactory.NewFrameReader()
+	if err != nil {
+		t.Errorf("Read error %q", err)
+	}
+	if header := r.HeaderReader(); header == nil {
+		t.Errorf("no header")
+	} else {
+		actualHeader := make([]byte, r.Len())
+		n, err := header.Read(actualHeader)
+		if err != nil {
+			t.Errorf("Read header error %q", err)
+		} else {
+			if n < len(testHeader) {
+				t.Errorf("header too short %q got %q", testHeader, actualHeader[:n])
+			}
+			if !bytes.Equal(testHeader, actualHeader[:n]) {
+				t.Errorf("header expected %q got %q", testHeader, actualHeader[:n])
+			}
+		}
+	}
+	if trailer := r.TrailerReader(); trailer != nil {
+		t.Errorf("unexpected trailer %q", trailer)
+	}
+	frame := r.(*hybiFrameReader)
+	if frameHeader.Fin != frame.header.Fin ||
+		frameHeader.OpCode != frame.header.OpCode ||
+		len(testPayload) != int(frame.header.Length) {
+		t.Errorf("mismatch %v (%d) vs %v", frameHeader, len(testPayload), frame)
+	}
+	payload := make([]byte, len(testPayload))
+	_, err = r.Read(payload)
+	if err != nil {
+		t.Errorf("read %v", err)
+	}
+	if !bytes.Equal(testPayload, payload) {
+		t.Errorf("payload %q vs %q", testPayload, payload)
+	}
+}
+
+func TestHybiShortTextFrame(t *testing.T) {
+	frameHeader := &hybiFrameHeader{Fin: true, OpCode: TextFrame}
+	payload := []byte("hello")
+	testHybiFrame(t, []byte{0x81, 0x05}, payload, payload, frameHeader)
+
+	payload = make([]byte, 125)
+	testHybiFrame(t, []byte{0x81, 125}, payload, payload, frameHeader)
+}
+
+func TestHybiShortMaskedTextFrame(t *testing.T) {
+	frameHeader := &hybiFrameHeader{Fin: true, OpCode: TextFrame,
+		MaskingKey: []byte{0xcc, 0x55, 0x80, 0x20}}
+	payload := []byte("hello")
+	maskedPayload := []byte{0xa4, 0x30, 0xec, 0x4c, 0xa3}
+	header := []byte{0x81, 0x85}
+	header = append(header, frameHeader.MaskingKey...)
+	testHybiFrame(t, header, payload, maskedPayload, frameHeader)
+}
+
+func TestHybiShortBinaryFrame(t *testing.T) {
+	frameHeader := &hybiFrameHeader{Fin: true, OpCode: BinaryFrame}
+	payload := []byte("hello")
+	testHybiFrame(t, []byte{0x82, 0x05}, payload, payload, frameHeader)
+
+	payload = make([]byte, 125)
+	testHybiFrame(t, []byte{0x82, 125}, payload, payload, frameHeader)
+}
+
+func TestHybiControlFrame(t *testing.T) {
+	frameHeader := &hybiFrameHeader{Fin: true, OpCode: PingFrame}
+	payload := []byte("hello")
+	testHybiFrame(t, []byte{0x89, 0x05}, payload, payload, frameHeader)
+
+	frameHeader = &hybiFrameHeader{Fin: true, OpCode: PongFrame}
+	testHybiFrame(t, []byte{0x8A, 0x05}, payload, payload, frameHeader)
+
+	frameHeader = &hybiFrameHeader{Fin: true, OpCode: CloseFrame}
+	payload = []byte{0x03, 0xe8} // 1000
+	testHybiFrame(t, []byte{0x88, 0x02}, payload, payload, frameHeader)
+}
+
+func TestHybiLongFrame(t *testing.T) {
+	frameHeader := &hybiFrameHeader{Fin: true, OpCode: TextFrame}
+	payload := make([]byte, 126)
+	testHybiFrame(t, []byte{0x81, 126, 0x00, 126}, payload, payload, frameHeader)
+
+	payload = make([]byte, 65535)
+	testHybiFrame(t, []byte{0x81, 126, 0xff, 0xff}, payload, payload, frameHeader)
+
+	payload = make([]byte, 65536)
+	testHybiFrame(t, []byte{0x81, 127, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00}, payload, payload, frameHeader)
+}
+
+func TestHybiClientRead(t *testing.T) {
+	wireData := []byte{0x81, 0x05, 'h', 'e', 'l', 'l', 'o',
+		0x89, 0x05, 'h', 'e', 'l', 'l', 'o', // ping
+		0x81, 0x05, 'w', 'o', 'r', 'l', 'd'}
+	br := bufio.NewReader(bytes.NewBuffer(wireData))
+	bw := bufio.NewWriter(bytes.NewBuffer([]byte{}))
+	conn := newHybiConn(newConfig(t, "/"), bufio.NewReadWriter(br, bw), nil, nil)
+
+	msg := make([]byte, 512)
+	n, err := conn.Read(msg)
+	if err != nil {
+		t.Errorf("read 1st frame, error %q", err)
+	}
+	if n != 5 {
+		t.Errorf("read 1st frame, expect 5, got %d", n)
+	}
+	if !bytes.Equal(wireData[2:7], msg[:n]) {
+		t.Errorf("read 1st frame %v, got %v", wireData[2:7], msg[:n])
+	}
+	n, err = conn.Read(msg)
+	if err != nil {
+		t.Errorf("read 2nd frame, error %q", err)
+	}
+	if n != 5 {
+		t.Errorf("read 2nd frame, expect 5, got %d", n)
+	}
+	if !bytes.Equal(wireData[16:21], msg[:n]) {
+		t.Errorf("read 2nd frame %v, got %v", wireData[16:21], msg[:n])
+	}
+	n, err = conn.Read(msg)
+	if err == nil {
+		t.Errorf("read not EOF")
+	}
+	if n != 0 {
+		t.Errorf("expect read 0, got %d", n)
+	}
+}
+
+func TestHybiShortRead(t *testing.T) {
+	wireData := []byte{0x81, 0x05, 'h', 'e', 'l', 'l', 'o',
+		0x89, 0x05, 'h', 'e', 'l', 'l', 'o', // ping
+		0x81, 0x05, 'w', 'o', 'r', 'l', 'd'}
+	br := bufio.NewReader(bytes.NewBuffer(wireData))
+	bw := bufio.NewWriter(bytes.NewBuffer([]byte{}))
+	conn := newHybiConn(newConfig(t, "/"), bufio.NewReadWriter(br, bw), nil, nil)
+
+	step := 0
+	pos := 0
+	expectedPos := []int{2, 5, 16, 19}
+	expectedLen := []int{3, 2, 3, 2}
+	for {
+		msg := make([]byte, 3)
+		n, err := conn.Read(msg)
+		if step >= len(expectedPos) {
+			if err == nil {
+				t.Errorf("read not EOF")
+			}
+			if n != 0 {
+				t.Errorf("expect read 0, got %d", n)
+			}
+			return
+		}
+		pos = expectedPos[step]
+		endPos := pos + expectedLen[step]
+		if err != nil {
+			t.Errorf("read from %d, got error %q", pos, err)
+			return
+		}
+		if n != endPos-pos {
+			t.Errorf("read from %d, expect %d, got %d", pos, endPos-pos, n)
+		}
+		if !bytes.Equal(wireData[pos:endPos], msg[:n]) {
+			t.Errorf("read from %d, frame %v, got %v", pos, wireData[pos:endPos], msg[:n])
+		}
+		step++
+	}
+}
+
+func TestHybiServerRead(t *testing.T) {
+	wireData := []byte{0x81, 0x85, 0xcc, 0x55, 0x80, 0x20,
+		0xa4, 0x30, 0xec, 0x4c, 0xa3, // hello
+		0x89, 0x85, 0xcc, 0x55, 0x80, 0x20,
+		0xa4, 0x30, 0xec, 0x4c, 0xa3, // ping: hello
+		0x81, 0x85, 0xed, 0x83, 0xb4, 0x24,
+		0x9a, 0xec, 0xc6, 0x48, 0x89, // world
+	}
+	br := bufio.NewReader(bytes.NewBuffer(wireData))
+	bw := bufio.NewWriter(bytes.NewBuffer([]byte{}))
+	conn := newHybiConn(newConfig(t, "/"), bufio.NewReadWriter(br, bw), nil, new(http.Request))
+
+	expected := [][]byte{[]byte("hello"), []byte("world")}
+
+	msg := make([]byte, 512)
+	n, err := conn.Read(msg)
+	if err != nil {
+		t.Errorf("read 1st frame, error %q", err)
+	}
+	if n != 5 {
+		t.Errorf("read 1st frame, expect 5, got %d", n)
+	}
+	if !bytes.Equal(expected[0], msg[:n]) {
+		t.Errorf("read 1st frame %q, got %q", expected[0], msg[:n])
+	}
+
+	n, err = conn.Read(msg)
+	if err != nil {
+		t.Errorf("read 2nd frame, error %q", err)
+	}
+	if n != 5 {
+		t.Errorf("read 2nd frame, expect 5, got %d", n)
+	}
+	if !bytes.Equal(expected[1], msg[:n]) {
+		t.Errorf("read 2nd frame %q, got %q", expected[1], msg[:n])
+	}
+
+	n, err = conn.Read(msg)
+	if err == nil {
+		t.Errorf("read not EOF")
+	}
+	if n != 0 {
+		t.Errorf("expect read 0, got %d", n)
+	}
+}
+
+func TestHybiServerReadWithoutMasking(t *testing.T) {
+	wireData := []byte{0x81, 0x05, 'h', 'e', 'l', 'l', 'o'}
+	br := bufio.NewReader(bytes.NewBuffer(wireData))
+	bw := bufio.NewWriter(bytes.NewBuffer([]byte{}))
+	conn := newHybiConn(newConfig(t, "/"), bufio.NewReadWriter(br, bw), nil, new(http.Request))
+	// server MUST close the connection upon receiving a non-masked frame.
+	msg := make([]byte, 512)
+	_, err := conn.Read(msg)
+	if err != io.EOF {
+		t.Errorf("read 1st frame, expect %q, but got %q", io.EOF, err)
+	}
+}
+
+func TestHybiClientReadWithMasking(t *testing.T) {
+	wireData := []byte{0x81, 0x85, 0xcc, 0x55, 0x80, 0x20,
+		0xa4, 0x30, 0xec, 0x4c, 0xa3, // hello
+	}
+	br := bufio.NewReader(bytes.NewBuffer(wireData))
+	bw := bufio.NewWriter(bytes.NewBuffer([]byte{}))
+	conn := newHybiConn(newConfig(t, "/"), bufio.NewReadWriter(br, bw), nil, nil)
+
+	// client MUST close the connection upon receiving a masked frame.
+	msg := make([]byte, 512)
+	_, err := conn.Read(msg)
+	if err != io.EOF {
+		t.Errorf("read 1st frame, expect %q, but got %q", io.EOF, err)
+	}
+}
+
+// Test the hybiServerHandshaker supports firefox implementation and
+// checks Connection request header include (but it's not necessary
+// equal to) "upgrade"
+func TestHybiServerFirefoxHandshake(t *testing.T) {
+	config := new(Config)
+	handshaker := &hybiServerHandshaker{Config: config}
+	br := bufio.NewReader(strings.NewReader(`GET /chat HTTP/1.1
+Host: server.example.com
+Upgrade: websocket
+Connection: keep-alive, upgrade
+Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
+Origin: http://example.com
+Sec-WebSocket-Protocol: chat, superchat
+Sec-WebSocket-Version: 13
+
+`))
+	req, err := http.ReadRequest(br)
+	if err != nil {
+		t.Fatal("request", err)
+	}
+	code, err := handshaker.ReadHandshake(br, req)
+	if err != nil {
+		t.Errorf("handshake failed: %v", err)
+	}
+	if code != http.StatusSwitchingProtocols {
+		t.Errorf("status expected %q but got %q", http.StatusSwitchingProtocols, code)
+	}
+	b := bytes.NewBuffer([]byte{})
+	bw := bufio.NewWriter(b)
+
+	config.Protocol = []string{"chat"}
+
+	err = handshaker.AcceptHandshake(bw)
+	if err != nil {
+		t.Errorf("handshake response failed: %v", err)
+	}
+	expectedResponse := strings.Join([]string{
+		"HTTP/1.1 101 Switching Protocols",
+		"Upgrade: websocket",
+		"Connection: Upgrade",
+		"Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",
+		"Sec-WebSocket-Protocol: chat",
+		"", ""}, "\r\n")
+
+	if b.String() != expectedResponse {
+		t.Errorf("handshake expected %q but got %q", expectedResponse, b.String())
+	}
+}
diff --git a/Godeps/_workspace/src/golang.org/x/net/websocket/server.go b/Godeps/_workspace/src/golang.org/x/net/websocket/server.go
new file mode 100644
index 000000000..70322133c
--- /dev/null
+++ b/Godeps/_workspace/src/golang.org/x/net/websocket/server.go
@@ -0,0 +1,114 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package websocket
+
+import (
+	"bufio"
+	"fmt"
+	"io"
+	"net/http"
+)
+
+func newServerConn(rwc io.ReadWriteCloser, buf *bufio.ReadWriter, req *http.Request, config *Config, handshake func(*Config, *http.Request) error) (conn *Conn, err error) {
+	var hs serverHandshaker = &hybiServerHandshaker{Config: config}
+	code, err := hs.ReadHandshake(buf.Reader, req)
+	if err == ErrBadWebSocketVersion {
+		fmt.Fprintf(buf, "HTTP/1.1 %03d %s\r\n", code, http.StatusText(code))
+		fmt.Fprintf(buf, "Sec-WebSocket-Version: %s\r\n", SupportedProtocolVersion)
+		buf.WriteString("\r\n")
+		buf.WriteString(err.Error())
+		buf.Flush()
+		return
+	}
+	if err != nil {
+		fmt.Fprintf(buf, "HTTP/1.1 %03d %s\r\n", code, http.StatusText(code))
+		buf.WriteString("\r\n")
+		buf.WriteString(err.Error())
+		buf.Flush()
+		return
+	}
+	if handshake != nil {
+		err = handshake(config, req)
+		if err != nil {
+			code = http.StatusForbidden
+			fmt.Fprintf(buf, "HTTP/1.1 %03d %s\r\n", code, http.StatusText(code))
+			buf.WriteString("\r\n")
+			buf.Flush()
+			return
+		}
+	}
+	err = hs.AcceptHandshake(buf.Writer)
+	if err != nil {
+		code = http.StatusBadRequest
+		fmt.Fprintf(buf, "HTTP/1.1 %03d %s\r\n", code, http.StatusText(code))
+		buf.WriteString("\r\n")
+		buf.Flush()
+		return
+	}
+	conn = hs.NewServerConn(buf, rwc, req)
+	return
+}
+
+// Server represents a server of a WebSocket.
+type Server struct {
+	// Config is a WebSocket configuration for new WebSocket connection.
+	Config
+
+	// Handshake is an optional function in WebSocket handshake.
+	// For example, you can check, or don't check Origin header.
+	// Another example, you can select config.Protocol.
+	Handshake func(*Config, *http.Request) error
+
+	// Handler handles a WebSocket connection.
+	Handler
+}
+
+// ServeHTTP implements the http.Handler interface for a WebSocket
+func (s Server) ServeHTTP(w http.ResponseWriter, req *http.Request) {
+	s.serveWebSocket(w, req)
+}
+
+func (s Server) serveWebSocket(w http.ResponseWriter, req *http.Request) {
+	rwc, buf, err := w.(http.Hijacker).Hijack()
+	if err != nil {
+		panic("Hijack failed: " + err.Error())
+		return
+	}
+	// The server should abort the WebSocket connection if it finds
+	// the client did not send a handshake that matches with protocol
+	// specification.
+	defer rwc.Close()
+	conn, err := newServerConn(rwc, buf, req, &s.Config, s.Handshake)
+	if err != nil {
+		return
+	}
+	if conn == nil {
+		panic("unexpected nil conn")
+	}
+	s.Handler(conn)
+}
+
+// Handler is a simple interface to a WebSocket browser client.
+// It checks if Origin header is valid URL by default.
+// You might want to verify websocket.Conn.Config().Origin in the func.
+// If you use Server instead of Handler, you could call websocket.Origin and
+// check the origin in your Handshake func. So, if you want to accept
+// non-browser client, which doesn't send Origin header, you could use Server
+//. that doesn't check origin in its Handshake.
+type Handler func(*Conn)
+
+func checkOrigin(config *Config, req *http.Request) (err error) {
+	config.Origin, err = Origin(config, req)
+	if err == nil && config.Origin == nil {
+		return fmt.Errorf("null origin")
+	}
+	return err
+}
+
+// ServeHTTP implements the http.Handler interface for a WebSocket
+func (h Handler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
+	s := Server{Handler: h, Handshake: checkOrigin}
+	s.serveWebSocket(w, req)
+}
diff --git a/Godeps/_workspace/src/golang.org/x/net/websocket/websocket.go b/Godeps/_workspace/src/golang.org/x/net/websocket/websocket.go
new file mode 100644
index 000000000..0f4917bf7
--- /dev/null
+++ b/Godeps/_workspace/src/golang.org/x/net/websocket/websocket.go
@@ -0,0 +1,411 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package websocket implements a client and server for the WebSocket protocol
+// as specified in RFC 6455.
+package websocket
+
+import (
+	"bufio"
+	"crypto/tls"
+	"encoding/json"
+	"errors"
+	"io"
+	"io/ioutil"
+	"net"
+	"net/http"
+	"net/url"
+	"sync"
+	"time"
+)
+
+const (
+	ProtocolVersionHybi13    = 13
+	ProtocolVersionHybi      = ProtocolVersionHybi13
+	SupportedProtocolVersion = "13"
+
+	ContinuationFrame = 0
+	TextFrame         = 1
+	BinaryFrame       = 2
+	CloseFrame        = 8
+	PingFrame         = 9
+	PongFrame         = 10
+	UnknownFrame      = 255
+)
+
+// ProtocolError represents WebSocket protocol errors.
+type ProtocolError struct {
+	ErrorString string
+}
+
+func (err *ProtocolError) Error() string { return err.ErrorString }
+
+var (
+	ErrBadProtocolVersion   = &ProtocolError{"bad protocol version"}
+	ErrBadScheme            = &ProtocolError{"bad scheme"}
+	ErrBadStatus            = &ProtocolError{"bad status"}
+	ErrBadUpgrade           = &ProtocolError{"missing or bad upgrade"}
+	ErrBadWebSocketOrigin   = &ProtocolError{"missing or bad WebSocket-Origin"}
+	ErrBadWebSocketLocation = &ProtocolError{"missing or bad WebSocket-Location"}
+	ErrBadWebSocketProtocol = &ProtocolError{"missing or bad WebSocket-Protocol"}
+	ErrBadWebSocketVersion  = &ProtocolError{"missing or bad WebSocket Version"}
+	ErrChallengeResponse    = &ProtocolError{"mismatch challenge/response"}
+	ErrBadFrame             = &ProtocolError{"bad frame"}
+	ErrBadFrameBoundary     = &ProtocolError{"not on frame boundary"}
+	ErrNotWebSocket         = &ProtocolError{"not websocket protocol"}
+	ErrBadRequestMethod     = &ProtocolError{"bad method"}
+	ErrNotSupported         = &ProtocolError{"not supported"}
+)
+
+// Addr is an implementation of net.Addr for WebSocket.
+type Addr struct {
+	*url.URL
+}
+
+// Network returns the network type for a WebSocket, "websocket".
+func (addr *Addr) Network() string { return "websocket" }
+
+// Config is a WebSocket configuration
+type Config struct {
+	// A WebSocket server address.
+	Location *url.URL
+
+	// A Websocket client origin.
+	Origin *url.URL
+
+	// WebSocket subprotocols.
+	Protocol []string
+
+	// WebSocket protocol version.
+	Version int
+
+	// TLS config for secure WebSocket (wss).
+	TlsConfig *tls.Config
+
+	// Additional header fields to be sent in WebSocket opening handshake.
+	Header http.Header
+
+	handshakeData map[string]string
+}
+
+// serverHandshaker is an interface to handle WebSocket server side handshake.
+type serverHandshaker interface {
+	// ReadHandshake reads handshake request message from client.
+	// Returns http response code and error if any.
+	ReadHandshake(buf *bufio.Reader, req *http.Request) (code int, err error)
+
+	// AcceptHandshake accepts the client handshake request and sends
+	// handshake response back to client.
+	AcceptHandshake(buf *bufio.Writer) (err error)
+
+	// NewServerConn creates a new WebSocket connection.
+	NewServerConn(buf *bufio.ReadWriter, rwc io.ReadWriteCloser, request *http.Request) (conn *Conn)
+}
+
+// frameReader is an interface to read a WebSocket frame.
+type frameReader interface {
+	// Reader is to read payload of the frame.
+	io.Reader
+
+	// PayloadType returns payload type.
+	PayloadType() byte
+
+	// HeaderReader returns a reader to read header of the frame.
+	HeaderReader() io.Reader
+
+	// TrailerReader returns a reader to read trailer of the frame.
+	// If it returns nil, there is no trailer in the frame.
+	TrailerReader() io.Reader
+
+	// Len returns total length of the frame, including header and trailer.
+	Len() int
+}
+
+// frameReaderFactory is an interface to creates new frame reader.
+type frameReaderFactory interface {
+	NewFrameReader() (r frameReader, err error)
+}
+
+// frameWriter is an interface to write a WebSocket frame.
+type frameWriter interface {
+	// Writer is to write payload of the frame.
+	io.WriteCloser
+}
+
+// frameWriterFactory is an interface to create new frame writer.
+type frameWriterFactory interface {
+	NewFrameWriter(payloadType byte) (w frameWriter, err error)
+}
+
+type frameHandler interface {
+	HandleFrame(frame frameReader) (r frameReader, err error)
+	WriteClose(status int) (err error)
+}
+
+// Conn represents a WebSocket connection.
+type Conn struct {
+	config  *Config
+	request *http.Request
+
+	buf *bufio.ReadWriter
+	rwc io.ReadWriteCloser
+
+	rio sync.Mutex
+	frameReaderFactory
+	frameReader
+
+	wio sync.Mutex
+	frameWriterFactory
+
+	frameHandler
+	PayloadType        byte
+	defaultCloseStatus int
+}
+
+// Read implements the io.Reader interface:
+// it reads data of a frame from the WebSocket connection.
+// if msg is not large enough for the frame data, it fills the msg and next Read
+// will read the rest of the frame data.
+// it reads Text frame or Binary frame.
+func (ws *Conn) Read(msg []byte) (n int, err error) {
+	ws.rio.Lock()
+	defer ws.rio.Unlock()
+again:
+	if ws.frameReader == nil {
+		frame, err := ws.frameReaderFactory.NewFrameReader()
+		if err != nil {
+			return 0, err
+		}
+		ws.frameReader, err = ws.frameHandler.HandleFrame(frame)
+		if err != nil {
+			return 0, err
+		}
+		if ws.frameReader == nil {
+			goto again
+		}
+	}
+	n, err = ws.frameReader.Read(msg)
+	if err == io.EOF {
+		if trailer := ws.frameReader.TrailerReader(); trailer != nil {
+			io.Copy(ioutil.Discard, trailer)
+		}
+		ws.frameReader = nil
+		goto again
+	}
+	return n, err
+}
+
+// Write implements the io.Writer interface:
+// it writes data as a frame to the WebSocket connection.
+func (ws *Conn) Write(msg []byte) (n int, err error) {
+	ws.wio.Lock()
+	defer ws.wio.Unlock()
+	w, err := ws.frameWriterFactory.NewFrameWriter(ws.PayloadType)
+	if err != nil {
+		return 0, err
+	}
+	n, err = w.Write(msg)
+	w.Close()
+	if err != nil {
+		return n, err
+	}
+	return n, err
+}
+
+// Close implements the io.Closer interface.
+func (ws *Conn) Close() error {
+	err := ws.frameHandler.WriteClose(ws.defaultCloseStatus)
+	if err != nil {
+		return err
+	}
+	return ws.rwc.Close()
+}
+
+func (ws *Conn) IsClientConn() bool { return ws.request == nil }
+func (ws *Conn) IsServerConn() bool { return ws.request != nil }
+
+// LocalAddr returns the WebSocket Origin for the connection for client, or
+// the WebSocket location for server.
+func (ws *Conn) LocalAddr() net.Addr {
+	if ws.IsClientConn() {
+		return &Addr{ws.config.Origin}
+	}
+	return &Addr{ws.config.Location}
+}
+
+// RemoteAddr returns the WebSocket location for the connection for client, or
+// the Websocket Origin for server.
+func (ws *Conn) RemoteAddr() net.Addr {
+	if ws.IsClientConn() {
+		return &Addr{ws.config.Location}
+	}
+	return &Addr{ws.config.Origin}
+}
+
+var errSetDeadline = errors.New("websocket: cannot set deadline: not using a net.Conn")
+
+// SetDeadline sets the connection's network read & write deadlines.
+func (ws *Conn) SetDeadline(t time.Time) error {
+	if conn, ok := ws.rwc.(net.Conn); ok {
+		return conn.SetDeadline(t)
+	}
+	return errSetDeadline
+}
+
+// SetReadDeadline sets the connection's network read deadline.
+func (ws *Conn) SetReadDeadline(t time.Time) error {
+	if conn, ok := ws.rwc.(net.Conn); ok {
+		return conn.SetReadDeadline(t)
+	}
+	return errSetDeadline
+}
+
+// SetWriteDeadline sets the connection's network write deadline.
+func (ws *Conn) SetWriteDeadline(t time.Time) error {
+	if conn, ok := ws.rwc.(net.Conn); ok {
+		return conn.SetWriteDeadline(t)
+	}
+	return errSetDeadline
+}
+
+// Config returns the WebSocket config.
+func (ws *Conn) Config() *Config { return ws.config }
+
+// Request returns the http request upgraded to the WebSocket.
+// It is nil for client side.
+func (ws *Conn) Request() *http.Request { return ws.request }
+
+// Codec represents a symmetric pair of functions that implement a codec.
+type Codec struct {
+	Marshal   func(v interface{}) (data []byte, payloadType byte, err error)
+	Unmarshal func(data []byte, payloadType byte, v interface{}) (err error)
+}
+
+// Send sends v marshaled by cd.Marshal as single frame to ws.
+func (cd Codec) Send(ws *Conn, v interface{}) (err error) {
+	data, payloadType, err := cd.Marshal(v)
+	if err != nil {
+		return err
+	}
+	ws.wio.Lock()
+	defer ws.wio.Unlock()
+	w, err := ws.frameWriterFactory.NewFrameWriter(payloadType)
+	if err != nil {
+		return err
+	}
+	_, err = w.Write(data)
+	w.Close()
+	return err
+}
+
+// Receive receives single frame from ws, unmarshaled by cd.Unmarshal and stores in v.
+func (cd Codec) Receive(ws *Conn, v interface{}) (err error) {
+	ws.rio.Lock()
+	defer ws.rio.Unlock()
+	if ws.frameReader != nil {
+		_, err = io.Copy(ioutil.Discard, ws.frameReader)
+		if err != nil {
+			return err
+		}
+		ws.frameReader = nil
+	}
+again:
+	frame, err := ws.frameReaderFactory.NewFrameReader()
+	if err != nil {
+		return err
+	}
+	frame, err = ws.frameHandler.HandleFrame(frame)
+	if err != nil {
+		return err
+	}
+	if frame == nil {
+		goto again
+	}
+	payloadType := frame.PayloadType()
+	data, err := ioutil.ReadAll(frame)
+	if err != nil {
+		return err
+	}
+	return cd.Unmarshal(data, payloadType, v)
+}
+
+func marshal(v interface{}) (msg []byte, payloadType byte, err error) {
+	switch data := v.(type) {
+	case string:
+		return []byte(data), TextFrame, nil
+	case []byte:
+		return data, BinaryFrame, nil
+	}
+	return nil, UnknownFrame, ErrNotSupported
+}
+
+func unmarshal(msg []byte, payloadType byte, v interface{}) (err error) {
+	switch data := v.(type) {
+	case *string:
+		*data = string(msg)
+		return nil
+	case *[]byte:
+		*data = msg
+		return nil
+	}
+	return ErrNotSupported
+}
+
+/*
+Message is a codec to send/receive text/binary data in a frame on WebSocket connection.
+To send/receive text frame, use string type.
+To send/receive binary frame, use []byte type.
+
+Trivial usage:
+
+	import "websocket"
+
+	// receive text frame
+	var message string
+	websocket.Message.Receive(ws, &message)
+
+	// send text frame
+	message = "hello"
+	websocket.Message.Send(ws, message)
+
+	// receive binary frame
+	var data []byte
+	websocket.Message.Receive(ws, &data)
+
+	// send binary frame
+	data = []byte{0, 1, 2}
+	websocket.Message.Send(ws, data)
+
+*/
+var Message = Codec{marshal, unmarshal}
+
+func jsonMarshal(v interface{}) (msg []byte, payloadType byte, err error) {
+	msg, err = json.Marshal(v)
+	return msg, TextFrame, err
+}
+
+func jsonUnmarshal(msg []byte, payloadType byte, v interface{}) (err error) {
+	return json.Unmarshal(msg, v)
+}
+
+/*
+JSON is a codec to send/receive JSON data in a frame from a WebSocket connection.
+
+Trivial usage:
+
+	import "websocket"
+
+	type T struct {
+		Msg string
+		Count int
+	}
+
+	// receive JSON type T
+	var data T
+	websocket.JSON.Receive(ws, &data)
+
+	// send JSON type T
+	websocket.JSON.Send(ws, data)
+*/
+var JSON = Codec{jsonMarshal, jsonUnmarshal}
diff --git a/Godeps/_workspace/src/golang.org/x/net/websocket/websocket_test.go b/Godeps/_workspace/src/golang.org/x/net/websocket/websocket_test.go
new file mode 100644
index 000000000..a376abacf
--- /dev/null
+++ b/Godeps/_workspace/src/golang.org/x/net/websocket/websocket_test.go
@@ -0,0 +1,414 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package websocket
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"log"
+	"net"
+	"net/http"
+	"net/http/httptest"
+	"net/url"
+	"strings"
+	"sync"
+	"testing"
+)
+
+var serverAddr string
+var once sync.Once
+
+func echoServer(ws *Conn) { io.Copy(ws, ws) }
+
+type Count struct {
+	S string
+	N int
+}
+
+func countServer(ws *Conn) {
+	for {
+		var count Count
+		err := JSON.Receive(ws, &count)
+		if err != nil {
+			return
+		}
+		count.N++
+		count.S = strings.Repeat(count.S, count.N)
+		err = JSON.Send(ws, count)
+		if err != nil {
+			return
+		}
+	}
+}
+
+func subProtocolHandshake(config *Config, req *http.Request) error {
+	for _, proto := range config.Protocol {
+		if proto == "chat" {
+			config.Protocol = []string{proto}
+			return nil
+		}
+	}
+	return ErrBadWebSocketProtocol
+}
+
+func subProtoServer(ws *Conn) {
+	for _, proto := range ws.Config().Protocol {
+		io.WriteString(ws, proto)
+	}
+}
+
+func startServer() {
+	http.Handle("/echo", Handler(echoServer))
+	http.Handle("/count", Handler(countServer))
+	subproto := Server{
+		Handshake: subProtocolHandshake,
+		Handler:   Handler(subProtoServer),
+	}
+	http.Handle("/subproto", subproto)
+	server := httptest.NewServer(nil)
+	serverAddr = server.Listener.Addr().String()
+	log.Print("Test WebSocket server listening on ", serverAddr)
+}
+
+func newConfig(t *testing.T, path string) *Config {
+	config, _ := NewConfig(fmt.Sprintf("ws://%s%s", serverAddr, path), "http://localhost")
+	return config
+}
+
+func TestEcho(t *testing.T) {
+	once.Do(startServer)
+
+	// websocket.Dial()
+	client, err := net.Dial("tcp", serverAddr)
+	if err != nil {
+		t.Fatal("dialing", err)
+	}
+	conn, err := NewClient(newConfig(t, "/echo"), client)
+	if err != nil {
+		t.Errorf("WebSocket handshake error: %v", err)
+		return
+	}
+
+	msg := []byte("hello, world\n")
+	if _, err := conn.Write(msg); err != nil {
+		t.Errorf("Write: %v", err)
+	}
+	var actual_msg = make([]byte, 512)
+	n, err := conn.Read(actual_msg)
+	if err != nil {
+		t.Errorf("Read: %v", err)
+	}
+	actual_msg = actual_msg[0:n]
+	if !bytes.Equal(msg, actual_msg) {
+		t.Errorf("Echo: expected %q got %q", msg, actual_msg)
+	}
+	conn.Close()
+}
+
+func TestAddr(t *testing.T) {
+	once.Do(startServer)
+
+	// websocket.Dial()
+	client, err := net.Dial("tcp", serverAddr)
+	if err != nil {
+		t.Fatal("dialing", err)
+	}
+	conn, err := NewClient(newConfig(t, "/echo"), client)
+	if err != nil {
+		t.Errorf("WebSocket handshake error: %v", err)
+		return
+	}
+
+	ra := conn.RemoteAddr().String()
+	if !strings.HasPrefix(ra, "ws://") || !strings.HasSuffix(ra, "/echo") {
+		t.Errorf("Bad remote addr: %v", ra)
+	}
+	la := conn.LocalAddr().String()
+	if !strings.HasPrefix(la, "http://") {
+		t.Errorf("Bad local addr: %v", la)
+	}
+	conn.Close()
+}
+
+func TestCount(t *testing.T) {
+	once.Do(startServer)
+
+	// websocket.Dial()
+	client, err := net.Dial("tcp", serverAddr)
+	if err != nil {
+		t.Fatal("dialing", err)
+	}
+	conn, err := NewClient(newConfig(t, "/count"), client)
+	if err != nil {
+		t.Errorf("WebSocket handshake error: %v", err)
+		return
+	}
+
+	var count Count
+	count.S = "hello"
+	if err := JSON.Send(conn, count); err != nil {
+		t.Errorf("Write: %v", err)
+	}
+	if err := JSON.Receive(conn, &count); err != nil {
+		t.Errorf("Read: %v", err)
+	}
+	if count.N != 1 {
+		t.Errorf("count: expected %d got %d", 1, count.N)
+	}
+	if count.S != "hello" {
+		t.Errorf("count: expected %q got %q", "hello", count.S)
+	}
+	if err := JSON.Send(conn, count); err != nil {
+		t.Errorf("Write: %v", err)
+	}
+	if err := JSON.Receive(conn, &count); err != nil {
+		t.Errorf("Read: %v", err)
+	}
+	if count.N != 2 {
+		t.Errorf("count: expected %d got %d", 2, count.N)
+	}
+	if count.S != "hellohello" {
+		t.Errorf("count: expected %q got %q", "hellohello", count.S)
+	}
+	conn.Close()
+}
+
+func TestWithQuery(t *testing.T) {
+	once.Do(startServer)
+
+	client, err := net.Dial("tcp", serverAddr)
+	if err != nil {
+		t.Fatal("dialing", err)
+	}
+
+	config := newConfig(t, "/echo")
+	config.Location, err = url.ParseRequestURI(fmt.Sprintf("ws://%s/echo?q=v", serverAddr))
+	if err != nil {
+		t.Fatal("location url", err)
+	}
+
+	ws, err := NewClient(config, client)
+	if err != nil {
+		t.Errorf("WebSocket handshake: %v", err)
+		return
+	}
+	ws.Close()
+}
+
+func testWithProtocol(t *testing.T, subproto []string) (string, error) {
+	once.Do(startServer)
+
+	client, err := net.Dial("tcp", serverAddr)
+	if err != nil {
+		t.Fatal("dialing", err)
+	}
+
+	config := newConfig(t, "/subproto")
+	config.Protocol = subproto
+
+	ws, err := NewClient(config, client)
+	if err != nil {
+		return "", err
+	}
+	msg := make([]byte, 16)
+	n, err := ws.Read(msg)
+	if err != nil {
+		return "", err
+	}
+	ws.Close()
+	return string(msg[:n]), nil
+}
+
+func TestWithProtocol(t *testing.T) {
+	proto, err := testWithProtocol(t, []string{"chat"})
+	if err != nil {
+		t.Errorf("SubProto: unexpected error: %v", err)
+	}
+	if proto != "chat" {
+		t.Errorf("SubProto: expected %q, got %q", "chat", proto)
+	}
+}
+
+func TestWithTwoProtocol(t *testing.T) {
+	proto, err := testWithProtocol(t, []string{"test", "chat"})
+	if err != nil {
+		t.Errorf("SubProto: unexpected error: %v", err)
+	}
+	if proto != "chat" {
+		t.Errorf("SubProto: expected %q, got %q", "chat", proto)
+	}
+}
+
+func TestWithBadProtocol(t *testing.T) {
+	_, err := testWithProtocol(t, []string{"test"})
+	if err != ErrBadStatus {
+		t.Errorf("SubProto: expected %v, got %v", ErrBadStatus, err)
+	}
+}
+
+func TestHTTP(t *testing.T) {
+	once.Do(startServer)
+
+	// If the client did not send a handshake that matches the protocol
+	// specification, the server MUST return an HTTP response with an
+	// appropriate error code (such as 400 Bad Request)
+	resp, err := http.Get(fmt.Sprintf("http://%s/echo", serverAddr))
+	if err != nil {
+		t.Errorf("Get: error %#v", err)
+		return
+	}
+	if resp == nil {
+		t.Error("Get: resp is null")
+		return
+	}
+	if resp.StatusCode != http.StatusBadRequest {
+		t.Errorf("Get: expected %q got %q", http.StatusBadRequest, resp.StatusCode)
+	}
+}
+
+func TestTrailingSpaces(t *testing.T) {
+	// http://code.google.com/p/go/issues/detail?id=955
+	// The last runs of this create keys with trailing spaces that should not be
+	// generated by the client.
+	once.Do(startServer)
+	config := newConfig(t, "/echo")
+	for i := 0; i < 30; i++ {
+		// body
+		ws, err := DialConfig(config)
+		if err != nil {
+			t.Errorf("Dial #%d failed: %v", i, err)
+			break
+		}
+		ws.Close()
+	}
+}
+
+func TestDialConfigBadVersion(t *testing.T) {
+	once.Do(startServer)
+	config := newConfig(t, "/echo")
+	config.Version = 1234
+
+	_, err := DialConfig(config)
+
+	if dialerr, ok := err.(*DialError); ok {
+		if dialerr.Err != ErrBadProtocolVersion {
+			t.Errorf("dial expected err %q but got %q", ErrBadProtocolVersion, dialerr.Err)
+		}
+	}
+}
+
+func TestSmallBuffer(t *testing.T) {
+	// http://code.google.com/p/go/issues/detail?id=1145
+	// Read should be able to handle reading a fragment of a frame.
+	once.Do(startServer)
+
+	// websocket.Dial()
+	client, err := net.Dial("tcp", serverAddr)
+	if err != nil {
+		t.Fatal("dialing", err)
+	}
+	conn, err := NewClient(newConfig(t, "/echo"), client)
+	if err != nil {
+		t.Errorf("WebSocket handshake error: %v", err)
+		return
+	}
+
+	msg := []byte("hello, world\n")
+	if _, err := conn.Write(msg); err != nil {
+		t.Errorf("Write: %v", err)
+	}
+	var small_msg = make([]byte, 8)
+	n, err := conn.Read(small_msg)
+	if err != nil {
+		t.Errorf("Read: %v", err)
+	}
+	if !bytes.Equal(msg[:len(small_msg)], small_msg) {
+		t.Errorf("Echo: expected %q got %q", msg[:len(small_msg)], small_msg)
+	}
+	var second_msg = make([]byte, len(msg))
+	n, err = conn.Read(second_msg)
+	if err != nil {
+		t.Errorf("Read: %v", err)
+	}
+	second_msg = second_msg[0:n]
+	if !bytes.Equal(msg[len(small_msg):], second_msg) {
+		t.Errorf("Echo: expected %q got %q", msg[len(small_msg):], second_msg)
+	}
+	conn.Close()
+}
+
+var parseAuthorityTests = []struct {
+	in  *url.URL
+	out string
+}{
+	{
+		&url.URL{
+			Scheme: "ws",
+			Host:   "www.google.com",
+		},
+		"www.google.com:80",
+	},
+	{
+		&url.URL{
+			Scheme: "wss",
+			Host:   "www.google.com",
+		},
+		"www.google.com:443",
+	},
+	{
+		&url.URL{
+			Scheme: "ws",
+			Host:   "www.google.com:80",
+		},
+		"www.google.com:80",
+	},
+	{
+		&url.URL{
+			Scheme: "wss",
+			Host:   "www.google.com:443",
+		},
+		"www.google.com:443",
+	},
+	// some invalid ones for parseAuthority. parseAuthority doesn't
+	// concern itself with the scheme unless it actually knows about it
+	{
+		&url.URL{
+			Scheme: "http",
+			Host:   "www.google.com",
+		},
+		"www.google.com",
+	},
+	{
+		&url.URL{
+			Scheme: "http",
+			Host:   "www.google.com:80",
+		},
+		"www.google.com:80",
+	},
+	{
+		&url.URL{
+			Scheme: "asdf",
+			Host:   "127.0.0.1",
+		},
+		"127.0.0.1",
+	},
+	{
+		&url.URL{
+			Scheme: "asdf",
+			Host:   "www.google.com",
+		},
+		"www.google.com",
+	},
+}
+
+func TestParseAuthority(t *testing.T) {
+	for _, tt := range parseAuthorityTests {
+		out := parseAuthority(tt.in)
+		if out != tt.out {
+			t.Errorf("got %v; want %v", out, tt.out)
+		}
+	}
+}
-- 
cgit v1.2.3