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::CreateFor500( |
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::CreateFor500( |
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::CreateFor500( |
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 |