OSDN Git Service

libgo: Update to weekly.2011-12-22.
[pf3gnuchains/gcc-fork.git] / libgo / go / websocket / server.go
1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package websocket
6
7 import (
8         "bufio"
9         "fmt"
10         "io"
11         "net/http"
12 )
13
14 func newServerConn(rwc io.ReadWriteCloser, buf *bufio.ReadWriter, req *http.Request) (conn *Conn, err error) {
15         config := new(Config)
16         var hs serverHandshaker = &hybiServerHandshaker{Config: config}
17         code, err := hs.ReadHandshake(buf.Reader, req)
18         if err == ErrBadWebSocketVersion {
19                 fmt.Fprintf(buf, "HTTP/1.1 %03d %s\r\n", code, http.StatusText(code))
20                 fmt.Fprintf(buf, "Sec-WebSocket-Version: %s\r\n", SupportedProtocolVersion)
21                 buf.WriteString("\r\n")
22                 buf.WriteString(err.Error())
23                 buf.Flush()
24                 return
25         }
26         if err != nil {
27                 hs = &hixie76ServerHandshaker{Config: config}
28                 code, err = hs.ReadHandshake(buf.Reader, req)
29         }
30         if err != nil {
31                 hs = &hixie75ServerHandshaker{Config: config}
32                 code, err = hs.ReadHandshake(buf.Reader, req)
33         }
34         if err != nil {
35                 fmt.Fprintf(buf, "HTTP/1.1 %03d %s\r\n", code, http.StatusText(code))
36                 buf.WriteString("\r\n")
37                 buf.WriteString(err.Error())
38                 buf.Flush()
39                 return
40         }
41         config.Protocol = nil
42
43         err = hs.AcceptHandshake(buf.Writer)
44         if err != nil {
45                 code = http.StatusBadRequest
46                 fmt.Fprintf(buf, "HTTP/1.1 %03d %s\r\n", code, http.StatusText(code))
47                 buf.WriteString("\r\n")
48                 buf.Flush()
49                 return
50         }
51         conn = hs.NewServerConn(buf, rwc, req)
52         return
53 }
54
55 /*
56 Handler is an interface to a WebSocket.
57
58 A trivial example server:
59
60         package main
61
62         import (
63                 "io"
64                 "net/http"
65                 "websocket"
66         )
67
68         // Echo the data received on the WebSocket.
69         func EchoServer(ws *websocket.Conn) {
70                 io.Copy(ws, ws);
71         }
72
73         func main() {
74                 http.Handle("/echo", websocket.Handler(EchoServer));
75                 err := http.ListenAndServe(":12345", nil);
76                 if err != nil {
77                         panic("ListenAndServe: " + err.Error())
78                 }
79         }
80 */
81 type Handler func(*Conn)
82
83 // ServeHTTP implements the http.Handler interface for a Web Socket
84 func (h Handler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
85         rwc, buf, err := w.(http.Hijacker).Hijack()
86         if err != nil {
87                 panic("Hijack failed: " + err.Error())
88                 return
89         }
90         // The server should abort the WebSocket connection if it finds
91         // the client did not send a handshake that matches with protocol
92         // specification.
93         defer rwc.Close()
94         conn, err := newServerConn(rwc, buf, req)
95         if err != nil {
96                 return
97         }
98         if conn == nil {
99                 panic("unepxected nil conn")
100         }
101         h(conn)
102 }