LEFT | RIGHT |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 package websocket | 5 package websocket |
6 | 6 |
7 import ( | 7 import ( |
8 "bytes" | |
9 "crypto/md5" | |
10 "encoding/binary" | |
11 "http" | 8 "http" |
12 "io" | 9 "io" |
13 "strings" | 10 "strings" |
14 ) | 11 ) |
15 | 12 |
16 /* | 13 /* |
17 Handler is an interface to a WebSocket. | 14 Handler is an interface to a WebSocket. |
18 | 15 |
19 A trivial example server: | 16 A trivial example server: |
20 | 17 |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
116 // Step 6. key number must be an integral multiple of spaces. | 113 // Step 6. key number must be an integral multiple of spaces. |
117 if keyNumber1%space1 != 0 || keyNumber2%space2 != 0 { | 114 if keyNumber1%space1 != 0 || keyNumber2%space2 != 0 { |
118 return | 115 return |
119 } | 116 } |
120 | 117 |
121 // Step 7. let part be key number divided by spaces. | 118 // Step 7. let part be key number divided by spaces. |
122 part1 := keyNumber1 / space1 | 119 part1 := keyNumber1 / space1 |
123 part2 := keyNumber2 / space2 | 120 part2 := keyNumber2 / space2 |
124 | 121 |
125 // Step 8. let challenge to be concatination of part1, part2 and key3. | 122 // Step 8. let challenge to be concatination of part1, part2 and key3. |
126 » challengeBuf := new(bytes.Buffer) | 123 » // Step 9. get MD5 fingerprint of challenge. |
127 » err = binary.Write(challengeBuf, binary.BigEndian, part1) | 124 » response, err := getChallengeResponse(part1, part2, key3) |
128 if err != nil { | 125 if err != nil { |
129 return | 126 return |
130 } | 127 } |
131 err = binary.Write(challengeBuf, binary.BigEndian, part2) | |
132 if err != nil { | |
133 return | |
134 } | |
135 if n, err := challengeBuf.Write(key3); n != 8 || err != nil { | |
136 return | |
137 } | |
138 challenge := challengeBuf.Bytes() | |
139 // Step 9. get MD5 fingerprint of challenge. | |
140 h := md5.New() | |
141 if _, err = h.Write(challenge); err != nil { | |
142 return | |
143 } | |
144 response := h.Sum() | |
145 | 128 |
146 // Step 10. send response status line. | 129 // Step 10. send response status line. |
147 buf.WriteString("HTTP/1.1 101 WebSocket Protocol Handshake\r\n") | 130 buf.WriteString("HTTP/1.1 101 WebSocket Protocol Handshake\r\n") |
148 // Step 11. send response headers. | 131 // Step 11. send response headers. |
149 buf.WriteString("Upgrade: WebSocket\r\n") | 132 buf.WriteString("Upgrade: WebSocket\r\n") |
150 buf.WriteString("Connection: Upgrade\r\n") | 133 buf.WriteString("Connection: Upgrade\r\n") |
151 buf.WriteString("Sec-WebSocket-Location: " + location + "\r\n") | 134 buf.WriteString("Sec-WebSocket-Location: " + location + "\r\n") |
152 buf.WriteString("Sec-WebSocket-Origin: " + origin + "\r\n") | 135 buf.WriteString("Sec-WebSocket-Origin: " + origin + "\r\n") |
153 protocol, found := req.Header["Sec-WebSocket-Protocol"] | 136 protocol, found := req.Header["Sec-WebSocket-Protocol"] |
154 if found { | 137 if found { |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
216 if found { | 199 if found { |
217 buf.WriteString("WebSocket-Protocol: " + protocol + "\r\n") | 200 buf.WriteString("WebSocket-Protocol: " + protocol + "\r\n") |
218 } | 201 } |
219 buf.WriteString("\r\n") | 202 buf.WriteString("\r\n") |
220 if err := buf.Flush(); err != nil { | 203 if err := buf.Flush(); err != nil { |
221 return | 204 return |
222 } | 205 } |
223 ws := newConn(origin, location, protocol, buf, rwc) | 206 ws := newConn(origin, location, protocol, buf, rwc) |
224 f(ws) | 207 f(ws) |
225 } | 208 } |
LEFT | RIGHT |