OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/server/web_socket.h" | 5 #include "net/server/web_socket.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 | 8 |
9 #include "base/base64.h" | 9 #include "base/base64.h" |
10 #include "base/rand_util.h" | 10 #include "base/rand_util.h" |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
47 static net::WebSocket* Create(HttpServer* server, | 47 static net::WebSocket* Create(HttpServer* server, |
48 HttpConnection* connection, | 48 HttpConnection* connection, |
49 const HttpServerRequestInfo& request, | 49 const HttpServerRequestInfo& request, |
50 size_t* pos) { | 50 size_t* pos) { |
51 if (connection->read_buf()->GetSize() < | 51 if (connection->read_buf()->GetSize() < |
52 static_cast<int>(*pos + kWebSocketHandshakeBodyLen)) | 52 static_cast<int>(*pos + kWebSocketHandshakeBodyLen)) |
53 return NULL; | 53 return NULL; |
54 return new WebSocketHixie76(server, connection, request, pos); | 54 return new WebSocketHixie76(server, connection, request, pos); |
55 } | 55 } |
56 | 56 |
57 virtual void Accept(const HttpServerRequestInfo& request) OVERRIDE { | 57 virtual void Accept(const HttpServerRequestInfo& request) override { |
58 std::string key1 = request.GetHeaderValue("sec-websocket-key1"); | 58 std::string key1 = request.GetHeaderValue("sec-websocket-key1"); |
59 std::string key2 = request.GetHeaderValue("sec-websocket-key2"); | 59 std::string key2 = request.GetHeaderValue("sec-websocket-key2"); |
60 | 60 |
61 uint32 fp1 = WebSocketKeyFingerprint(key1); | 61 uint32 fp1 = WebSocketKeyFingerprint(key1); |
62 uint32 fp2 = WebSocketKeyFingerprint(key2); | 62 uint32 fp2 = WebSocketKeyFingerprint(key2); |
63 | 63 |
64 char data[16]; | 64 char data[16]; |
65 memcpy(data, &fp1, 4); | 65 memcpy(data, &fp1, 4); |
66 memcpy(data + 4, &fp2, 4); | 66 memcpy(data + 4, &fp2, 4); |
67 memcpy(data + 8, &key3_[0], 8); | 67 memcpy(data + 8, &key3_[0], 8); |
(...skipping 11 matching lines...) Expand all Loading... |
79 "Connection: Upgrade\r\n" | 79 "Connection: Upgrade\r\n" |
80 "Sec-WebSocket-Origin: %s\r\n" | 80 "Sec-WebSocket-Origin: %s\r\n" |
81 "Sec-WebSocket-Location: %s\r\n" | 81 "Sec-WebSocket-Location: %s\r\n" |
82 "\r\n", | 82 "\r\n", |
83 origin.c_str(), | 83 origin.c_str(), |
84 location.c_str())); | 84 location.c_str())); |
85 server_->SendRaw(connection_->id(), | 85 server_->SendRaw(connection_->id(), |
86 std::string(reinterpret_cast<char*>(digest.a), 16)); | 86 std::string(reinterpret_cast<char*>(digest.a), 16)); |
87 } | 87 } |
88 | 88 |
89 virtual ParseResult Read(std::string* message) OVERRIDE { | 89 virtual ParseResult Read(std::string* message) override { |
90 DCHECK(message); | 90 DCHECK(message); |
91 HttpConnection::ReadIOBuffer* read_buf = connection_->read_buf(); | 91 HttpConnection::ReadIOBuffer* read_buf = connection_->read_buf(); |
92 if (read_buf->StartOfBuffer()[0]) | 92 if (read_buf->StartOfBuffer()[0]) |
93 return FRAME_ERROR; | 93 return FRAME_ERROR; |
94 | 94 |
95 base::StringPiece data(read_buf->StartOfBuffer(), read_buf->GetSize()); | 95 base::StringPiece data(read_buf->StartOfBuffer(), read_buf->GetSize()); |
96 size_t pos = data.find('\377', 1); | 96 size_t pos = data.find('\377', 1); |
97 if (pos == base::StringPiece::npos) | 97 if (pos == base::StringPiece::npos) |
98 return FRAME_INCOMPLETE; | 98 return FRAME_INCOMPLETE; |
99 | 99 |
100 message->assign(data.data() + 1, pos - 1); | 100 message->assign(data.data() + 1, pos - 1); |
101 read_buf->DidConsume(pos + 1); | 101 read_buf->DidConsume(pos + 1); |
102 | 102 |
103 return FRAME_OK; | 103 return FRAME_OK; |
104 } | 104 } |
105 | 105 |
106 virtual void Send(const std::string& message) OVERRIDE { | 106 virtual void Send(const std::string& message) override { |
107 char message_start = 0; | 107 char message_start = 0; |
108 char message_end = -1; | 108 char message_end = -1; |
109 server_->SendRaw(connection_->id(), std::string(1, message_start)); | 109 server_->SendRaw(connection_->id(), std::string(1, message_start)); |
110 server_->SendRaw(connection_->id(), message); | 110 server_->SendRaw(connection_->id(), message); |
111 server_->SendRaw(connection_->id(), std::string(1, message_end)); | 111 server_->SendRaw(connection_->id(), std::string(1, message_end)); |
112 } | 112 } |
113 | 113 |
114 private: | 114 private: |
115 static const int kWebSocketHandshakeBodyLen; | 115 static const int kWebSocketHandshakeBodyLen; |
116 | 116 |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
192 server->SendResponse( | 192 server->SendResponse( |
193 connection->id(), | 193 connection->id(), |
194 HttpServerResponseInfo::CreateFor500( | 194 HttpServerResponseInfo::CreateFor500( |
195 "Invalid request format. Sec-WebSocket-Key is empty or isn't " | 195 "Invalid request format. Sec-WebSocket-Key is empty or isn't " |
196 "specified.")); | 196 "specified.")); |
197 return NULL; | 197 return NULL; |
198 } | 198 } |
199 return new WebSocketHybi17(server, connection, request, pos); | 199 return new WebSocketHybi17(server, connection, request, pos); |
200 } | 200 } |
201 | 201 |
202 virtual void Accept(const HttpServerRequestInfo& request) OVERRIDE { | 202 virtual void Accept(const HttpServerRequestInfo& request) override { |
203 static const char* const kWebSocketGuid = | 203 static const char* const kWebSocketGuid = |
204 "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; | 204 "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; |
205 std::string key = request.GetHeaderValue("sec-websocket-key"); | 205 std::string key = request.GetHeaderValue("sec-websocket-key"); |
206 std::string data = base::StringPrintf("%s%s", key.c_str(), kWebSocketGuid); | 206 std::string data = base::StringPrintf("%s%s", key.c_str(), kWebSocketGuid); |
207 std::string encoded_hash; | 207 std::string encoded_hash; |
208 base::Base64Encode(base::SHA1HashString(data), &encoded_hash); | 208 base::Base64Encode(base::SHA1HashString(data), &encoded_hash); |
209 | 209 |
210 server_->SendRaw( | 210 server_->SendRaw( |
211 connection_->id(), | 211 connection_->id(), |
212 base::StringPrintf("HTTP/1.1 101 WebSocket Protocol Handshake\r\n" | 212 base::StringPrintf("HTTP/1.1 101 WebSocket Protocol Handshake\r\n" |
213 "Upgrade: WebSocket\r\n" | 213 "Upgrade: WebSocket\r\n" |
214 "Connection: Upgrade\r\n" | 214 "Connection: Upgrade\r\n" |
215 "Sec-WebSocket-Accept: %s\r\n" | 215 "Sec-WebSocket-Accept: %s\r\n" |
216 "\r\n", | 216 "\r\n", |
217 encoded_hash.c_str())); | 217 encoded_hash.c_str())); |
218 } | 218 } |
219 | 219 |
220 virtual ParseResult Read(std::string* message) OVERRIDE { | 220 virtual ParseResult Read(std::string* message) override { |
221 HttpConnection::ReadIOBuffer* read_buf = connection_->read_buf(); | 221 HttpConnection::ReadIOBuffer* read_buf = connection_->read_buf(); |
222 base::StringPiece frame(read_buf->StartOfBuffer(), read_buf->GetSize()); | 222 base::StringPiece frame(read_buf->StartOfBuffer(), read_buf->GetSize()); |
223 int bytes_consumed = 0; | 223 int bytes_consumed = 0; |
224 ParseResult result = | 224 ParseResult result = |
225 WebSocket::DecodeFrameHybi17(frame, true, &bytes_consumed, message); | 225 WebSocket::DecodeFrameHybi17(frame, true, &bytes_consumed, message); |
226 if (result == FRAME_OK) | 226 if (result == FRAME_OK) |
227 read_buf->DidConsume(bytes_consumed); | 227 read_buf->DidConsume(bytes_consumed); |
228 if (result == FRAME_CLOSE) | 228 if (result == FRAME_CLOSE) |
229 closed_ = true; | 229 closed_ = true; |
230 return result; | 230 return result; |
231 } | 231 } |
232 | 232 |
233 virtual void Send(const std::string& message) OVERRIDE { | 233 virtual void Send(const std::string& message) override { |
234 if (closed_) | 234 if (closed_) |
235 return; | 235 return; |
236 server_->SendRaw(connection_->id(), | 236 server_->SendRaw(connection_->id(), |
237 WebSocket::EncodeFrameHybi17(message, 0)); | 237 WebSocket::EncodeFrameHybi17(message, 0)); |
238 } | 238 } |
239 | 239 |
240 private: | 240 private: |
241 WebSocketHybi17(HttpServer* server, | 241 WebSocketHybi17(HttpServer* server, |
242 HttpConnection* connection, | 242 HttpConnection* connection, |
243 const HttpServerRequestInfo& request, | 243 const HttpServerRequestInfo& request, |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
414 } | 414 } |
415 return std::string(&frame[0], frame.size()); | 415 return std::string(&frame[0], frame.size()); |
416 } | 416 } |
417 | 417 |
418 WebSocket::WebSocket(HttpServer* server, HttpConnection* connection) | 418 WebSocket::WebSocket(HttpServer* server, HttpConnection* connection) |
419 : server_(server), | 419 : server_(server), |
420 connection_(connection) { | 420 connection_(connection) { |
421 } | 421 } |
422 | 422 |
423 } // namespace net | 423 } // namespace net |
OLD | NEW |