mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
Add WebSocket server framework hooked into http.
R=r, rsc https://golang.org/cl/156071
This commit is contained in:
parent
6e6125ffa4
commit
f9f0184e13
6 changed files with 418 additions and 0 deletions
73
src/pkg/websocket/server.go
Normal file
73
src/pkg/websocket/server.go
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
// 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 (
|
||||
"http";
|
||||
"io";
|
||||
)
|
||||
|
||||
// Handler is a interface that use a WebSocket.
|
||||
//
|
||||
// A trivial example server is:
|
||||
//
|
||||
// package main
|
||||
//
|
||||
// import (
|
||||
// "http"
|
||||
// "io"
|
||||
// "websocket"
|
||||
// )
|
||||
//
|
||||
// // echo back the websocket.
|
||||
// func EchoServer(ws *websocket.Conn) {
|
||||
// io.Copy(ws, ws);
|
||||
// }
|
||||
//
|
||||
// func main() {
|
||||
// http.Handle("/echo", websocket.Handler(EchoServer));
|
||||
// err := http.ListenAndServe(":12345", nil);
|
||||
// if err != nil {
|
||||
// panic("ListenAndServe: ", err.String())
|
||||
// }
|
||||
// }
|
||||
type Handler func(*Conn)
|
||||
|
||||
func (f Handler) ServeHTTP(c *http.Conn, req *http.Request) {
|
||||
if req.Method != "GET" || req.Proto != "HTTP/1.1" ||
|
||||
req.Header["Upgrade"] != "WebSocket" ||
|
||||
req.Header["Connection"] != "Upgrade" {
|
||||
c.WriteHeader(http.StatusNotFound);
|
||||
io.WriteString(c, "must use websocket to connect here");
|
||||
return;
|
||||
}
|
||||
rwc, buf, err := c.Hijack();
|
||||
if err != nil {
|
||||
panic("Hijack failed: ", err.String());
|
||||
return;
|
||||
}
|
||||
defer rwc.Close();
|
||||
origin := req.Header["Origin"];
|
||||
location := "ws://" + req.Host + req.URL.Path;
|
||||
|
||||
// TODO(ukai): verify origin,location,protocol.
|
||||
|
||||
buf.WriteString("HTTP/1.1 101 Web Socket Protocol Handshake\r\n");
|
||||
buf.WriteString("Upgrade: WebSocket\r\n");
|
||||
buf.WriteString("Connection: Upgrade\r\n");
|
||||
buf.WriteString("WebSocket-Origin: " + origin + "\r\n");
|
||||
buf.WriteString("WebSocket-Location: " + location + "\r\n");
|
||||
protocol := "";
|
||||
// canonical header key of WebSocket-Protocol.
|
||||
if protocol, found := req.Header["Websocket-Protocol"]; found {
|
||||
buf.WriteString("WebSocket-Protocol: " + protocol + "\r\n")
|
||||
}
|
||||
buf.WriteString("\r\n");
|
||||
if err := buf.Flush(); err != nil {
|
||||
return
|
||||
}
|
||||
ws := newConn(origin, location, protocol, buf, rwc);
|
||||
f(ws);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue