| 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" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/md5.h" | 12 #include "base/md5.h" |
| 13 #include "base/sha1.h" | 13 #include "base/sha1.h" |
| 14 #include "base/strings/string_number_conversions.h" | 14 #include "base/strings/string_number_conversions.h" |
| 15 #include "base/strings/stringprintf.h" | 15 #include "base/strings/stringprintf.h" |
| 16 #include "base/sys_byteorder.h" | 16 #include "base/sys_byteorder.h" |
| 17 #include "net/server/http_connection.h" | 17 #include "net/server/http_connection.h" |
| 18 #include "net/server/http_server_request_info.h" | 18 #include "net/server/http_server_request_info.h" |
| 19 #include "net/server/http_server_response_info.h" |
| 19 | 20 |
| 20 namespace net { | 21 namespace net { |
| 21 | 22 |
| 22 namespace { | 23 namespace { |
| 23 | 24 |
| 24 static uint32 WebSocketKeyFingerprint(const std::string& str) { | 25 static uint32 WebSocketKeyFingerprint(const std::string& str) { |
| 25 std::string result; | 26 std::string result; |
| 26 const char* p_char = str.c_str(); | 27 const char* p_char = str.c_str(); |
| 27 int length = str.length(); | 28 int length = str.length(); |
| 28 int spaces = 0; | 29 int spaces = 0; |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 108 private: | 109 private: |
| 109 static const int kWebSocketHandshakeBodyLen; | 110 static const int kWebSocketHandshakeBodyLen; |
| 110 | 111 |
| 111 WebSocketHixie76(HttpConnection* connection, | 112 WebSocketHixie76(HttpConnection* connection, |
| 112 const HttpServerRequestInfo& request, | 113 const HttpServerRequestInfo& request, |
| 113 size_t* pos) : WebSocket(connection) { | 114 size_t* pos) : WebSocket(connection) { |
| 114 std::string key1 = request.GetHeaderValue("Sec-WebSocket-Key1"); | 115 std::string key1 = request.GetHeaderValue("Sec-WebSocket-Key1"); |
| 115 std::string key2 = request.GetHeaderValue("Sec-WebSocket-Key2"); | 116 std::string key2 = request.GetHeaderValue("Sec-WebSocket-Key2"); |
| 116 | 117 |
| 117 if (key1.empty()) { | 118 if (key1.empty()) { |
| 118 connection->Send(net::HTTP_INTERNAL_SERVER_ERROR, | 119 connection->Send(HttpServerResponseInfo::For500( |
| 119 "Invalid request format. " | 120 "Invalid request format. Sec-WebSocket-Key1 is empty or isn't " |
| 120 "Sec-WebSocket-Key1 is empty or isn't specified.", | 121 "specified.")); |
| 121 "text/html"); | |
| 122 return; | 122 return; |
| 123 } | 123 } |
| 124 | 124 |
| 125 if (key2.empty()) { | 125 if (key2.empty()) { |
| 126 connection->Send(net::HTTP_INTERNAL_SERVER_ERROR, | 126 connection->Send(HttpServerResponseInfo::For500( |
| 127 "Invalid request format. " | 127 "Invalid request format. Sec-WebSocket-Key2 is empty or isn't " |
| 128 "Sec-WebSocket-Key2 is empty or isn't specified.", | 128 "specified.")); |
| 129 "text/html"); | |
| 130 return; | 129 return; |
| 131 } | 130 } |
| 132 | 131 |
| 133 key3_ = connection->recv_data().substr( | 132 key3_ = connection->recv_data().substr( |
| 134 *pos, | 133 *pos, |
| 135 *pos + kWebSocketHandshakeBodyLen); | 134 *pos + kWebSocketHandshakeBodyLen); |
| 136 *pos += kWebSocketHandshakeBodyLen; | 135 *pos += kWebSocketHandshakeBodyLen; |
| 137 } | 136 } |
| 138 | 137 |
| 139 std::string key3_; | 138 std::string key3_; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 172 public: | 171 public: |
| 173 static WebSocket* Create(HttpConnection* connection, | 172 static WebSocket* Create(HttpConnection* connection, |
| 174 const HttpServerRequestInfo& request, | 173 const HttpServerRequestInfo& request, |
| 175 size_t* pos) { | 174 size_t* pos) { |
| 176 std::string version = request.GetHeaderValue("Sec-WebSocket-Version"); | 175 std::string version = request.GetHeaderValue("Sec-WebSocket-Version"); |
| 177 if (version != "8" && version != "13") | 176 if (version != "8" && version != "13") |
| 178 return NULL; | 177 return NULL; |
| 179 | 178 |
| 180 std::string key = request.GetHeaderValue("Sec-WebSocket-Key"); | 179 std::string key = request.GetHeaderValue("Sec-WebSocket-Key"); |
| 181 if (key.empty()) { | 180 if (key.empty()) { |
| 182 connection->Send(net::HTTP_INTERNAL_SERVER_ERROR, | 181 connection->Send(HttpServerResponseInfo::For500( |
| 183 "Invalid request format. " | 182 "Invalid request format. Sec-WebSocket-Key is empty or isn't " |
| 184 "Sec-WebSocket-Key is empty or isn't specified.", | 183 "specified.")); |
| 185 "text/html"); | |
| 186 return NULL; | 184 return NULL; |
| 187 } | 185 } |
| 188 return new WebSocketHybi17(connection, request, pos); | 186 return new WebSocketHybi17(connection, request, pos); |
| 189 } | 187 } |
| 190 | 188 |
| 191 virtual void Accept(const HttpServerRequestInfo& request) OVERRIDE { | 189 virtual void Accept(const HttpServerRequestInfo& request) OVERRIDE { |
| 192 static const char* const kWebSocketGuid = | 190 static const char* const kWebSocketGuid = |
| 193 "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; | 191 "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; |
| 194 std::string key = request.GetHeaderValue("Sec-WebSocket-Key"); | 192 std::string key = request.GetHeaderValue("Sec-WebSocket-Key"); |
| 195 std::string data = base::StringPrintf("%s%s", key.c_str(), kWebSocketGuid); | 193 std::string data = base::StringPrintf("%s%s", key.c_str(), kWebSocketGuid); |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 399 } else { | 397 } else { |
| 400 frame.insert(frame.end(), data, data + data_length); | 398 frame.insert(frame.end(), data, data + data_length); |
| 401 } | 399 } |
| 402 return std::string(&frame[0], frame.size()); | 400 return std::string(&frame[0], frame.size()); |
| 403 } | 401 } |
| 404 | 402 |
| 405 WebSocket::WebSocket(HttpConnection* connection) : connection_(connection) { | 403 WebSocket::WebSocket(HttpConnection* connection) : connection_(connection) { |
| 406 } | 404 } |
| 407 | 405 |
| 408 } // namespace net | 406 } // namespace net |
| OLD | NEW |