Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(899)

Side by Side Diff: net/server/http_server.cc

Issue 7482041: DevTools: no way to remote debug using ToT build. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: web_socket class was extracted. Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/http_server.h" 5 #include "net/server/http_server.h"
6 6
7 #include "base/compiler_specific.h" 7 #include "base/compiler_specific.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/md5.h"
10 #include "base/string_number_conversions.h"
11 #include "base/string_util.h" 9 #include "base/string_util.h"
12 #include "base/stringprintf.h" 10 #include "base/stringprintf.h"
13 #include "build/build_config.h" 11 #include "build/build_config.h"
14 #include "net/server/http_server_request_info.h" 12 #include "net/server/http_server_request_info.h"
13 #include "net/server/web_socket.h"
15 14
16 #if defined(OS_WIN) 15 #if defined(OS_WIN)
17 #include <winsock2.h> 16 #include <winsock2.h>
18 #else 17 #else
19 #include <arpa/inet.h> 18 #include <arpa/inet.h>
20 #endif 19 #endif
21 20
22 namespace net { 21 namespace net {
23 22
24 int HttpServer::Connection::lastId_ = 0; 23 int Connection::lastId_ = 0;
25 24
26 HttpServer::HttpServer(const std::string& host, 25 HttpServer::HttpServer(const std::string& host,
27 int port, 26 int port,
28 HttpServer::Delegate* del) 27 HttpServer::Delegate* del)
29 : delegate_(del) { 28 : delegate_(del) {
30 server_ = ListenSocket::Listen(host, port, this); 29 server_ = ListenSocket::Listen(host, port, this);
31 } 30 }
32 31
33 HttpServer::~HttpServer() { 32 HttpServer::~HttpServer() {
34 IdToConnectionMap copy = id_to_connection_; 33 IdToConnectionMap copy = id_to_connection_;
35 for (IdToConnectionMap::iterator it = copy.begin(); it != copy.end(); ++it) 34 for (IdToConnectionMap::iterator it = copy.begin(); it != copy.end(); ++it)
36 delete it->second; 35 delete it->second;
37 36
38 server_ = NULL; 37 server_ = NULL;
39 } 38 }
40 39
41 std::string GetHeaderValue( 40 static std::string GetHeaderValue(
42 const HttpServerRequestInfo& request, 41 const HttpServerRequestInfo& request,
43 const std::string& header_name) { 42 const std::string& header_name) {
44 HttpServerRequestInfo::HeadersMap::iterator it = 43 HttpServerRequestInfo::HeadersMap::iterator it =
45 request.headers.find(header_name); 44 request.headers.find(header_name);
46 if (it != request.headers.end()) 45 if (it != request.headers.end())
47 return it->second; 46 return it->second;
48 return ""; 47 return "";
49 } 48 }
50 49
51 uint32 WebSocketKeyFingerprint(const std::string& str) {
52 std::string result;
53 const char* pChar = str.c_str();
54 int length = str.length();
55 int spaces = 0;
56 for (int i = 0; i < length; ++i) {
57 if (pChar[i] >= '0' && pChar[i] <= '9')
58 result.append(&pChar[i], 1);
59 else if (pChar[i] == ' ')
60 spaces++;
61 }
62 if (spaces == 0)
63 return 0;
64 int64 number = 0;
65 if (!base::StringToInt64(result, &number))
66 return 0;
67 return htonl(static_cast<uint32>(number / spaces));
68 }
69
70 void HttpServer::AcceptWebSocket(
71 int connection_id,
72 const HttpServerRequestInfo& request) {
73 Connection* connection = FindConnection(connection_id);
74 if (connection == NULL)
75 return;
76
77 std::string key1 = GetHeaderValue(request, "Sec-WebSocket-Key1");
78 std::string key2 = GetHeaderValue(request, "Sec-WebSocket-Key2");
79
80 uint32 fp1 = WebSocketKeyFingerprint(key1);
81 uint32 fp2 = WebSocketKeyFingerprint(key2);
82
83 char data[16];
84 memcpy(data, &fp1, 4);
85 memcpy(data + 4, &fp2, 4);
86 memcpy(data + 8, &request.data[0], 8);
87
88 base::MD5Digest digest;
89 base::MD5Sum(data, 16, &digest);
90
91 std::string origin = GetHeaderValue(request, "Origin");
92 std::string host = GetHeaderValue(request, "Host");
93 std::string location = "ws://" + host + request.path;
94 connection->is_web_socket_ = true;
95 connection->socket_->Send(base::StringPrintf(
96 "HTTP/1.1 101 WebSocket Protocol Handshake\r\n"
97 "Upgrade: WebSocket\r\n"
98 "Connection: Upgrade\r\n"
99 "Sec-WebSocket-Origin: %s\r\n"
100 "Sec-WebSocket-Location: %s\r\n"
101 "\r\n",
102 origin.c_str(),
103 location.c_str()));
104 connection->socket_->Send(reinterpret_cast<char*>(digest.a), 16);
105 }
106
107 void HttpServer::SendOverWebSocket(int connection_id,
108 const std::string& data) {
109 Connection* connection = FindConnection(connection_id);
110 if (connection == NULL)
111 return;
112
113 DCHECK(connection->is_web_socket_);
114 char message_start = 0;
115 char message_end = -1;
116 connection->socket_->Send(&message_start, 1);
117 connection->socket_->Send(data);
118 connection->socket_->Send(&message_end, 1);
119 }
120
121 void HttpServer::Send(int connection_id, const std::string& data) { 50 void HttpServer::Send(int connection_id, const std::string& data) {
122 Connection* connection = FindConnection(connection_id); 51 Connection* connection = FindConnection(connection_id);
123 if (connection == NULL) 52 if (connection == NULL)
124 return; 53 return;
54 connection->Send(data);
55 }
125 56
126 connection->socket_->Send(data); 57 void Connection::Send(const std::string& data) {
58 if (!socket_)
59 return;
60 socket_->Send(data);
127 } 61 }
128 62
129 void HttpServer::Send(int connection_id, const char* bytes, int len) { 63 void HttpServer::Send(int connection_id, const char* bytes, int len) {
130 Connection* connection = FindConnection(connection_id); 64 Connection* connection = FindConnection(connection_id);
131 if (connection == NULL) 65 if (connection == NULL)
132 return; 66 return;
133 67
134 connection->socket_->Send(bytes, len); 68 connection->Send(bytes, len);
69 }
70
71 void Connection::Send(const char* bytes, int len) {
72 if (!socket_)
73 return;
74 socket_->Send(bytes, len);
135 } 75 }
136 76
137 void HttpServer::Send200(int connection_id, 77 void HttpServer::Send200(int connection_id,
138 const std::string& data, 78 const std::string& data,
139 const std::string& content_type) { 79 const std::string& content_type) {
140 Connection* connection = FindConnection(connection_id); 80 Connection* connection = FindConnection(connection_id);
141 if (connection == NULL) 81 if (connection == NULL)
142 return; 82 return;
83 connection->Send200(data, content_type);
84 }
143 85
144 connection->socket_->Send(base::StringPrintf( 86 void Connection::Send200(const std::string& data,
87 const std::string& content_type) {
88 if (!socket_)
89 return;
90 socket_->Send(base::StringPrintf(
145 "HTTP/1.1 200 OK\r\n" 91 "HTTP/1.1 200 OK\r\n"
146 "Content-Type:%s\r\n" 92 "Content-Type:%s\r\n"
147 "Content-Length:%d\r\n" 93 "Content-Length:%d\r\n"
148 "\r\n", 94 "\r\n",
149 content_type.c_str(), 95 content_type.c_str(),
150 static_cast<int>(data.length()))); 96 static_cast<int>(data.length())));
151 connection->socket_->Send(data); 97 socket_->Send(data);
152 } 98 }
153 99
154 void HttpServer::Send404(int connection_id) { 100 void HttpServer::Send404(int connection_id) {
155 Connection* connection = FindConnection(connection_id); 101 Connection* connection = FindConnection(connection_id);
156 if (connection == NULL) 102 if (connection == NULL)
157 return; 103 return;
104 connection->Send404();
105 }
158 106
159 connection->socket_->Send( 107 void Connection::Send404() {
108 if (!socket_)
109 return;
110 socket_->Send(
160 "HTTP/1.1 404 Not Found\r\n" 111 "HTTP/1.1 404 Not Found\r\n"
161 "Content-Length: 0\r\n" 112 "Content-Length: 0\r\n"
162 "\r\n"); 113 "\r\n");
163 } 114 }
164 115
165 void HttpServer::Send500(int connection_id, const std::string& message) { 116 void HttpServer::Send500(int connection_id, const std::string& message) {
166 Connection* connection = FindConnection(connection_id); 117 Connection* connection = FindConnection(connection_id);
167 if (connection == NULL) 118 if (connection == NULL)
168 return; 119 return;
120 connection->Send500(message);
121 }
169 122
170 connection->socket_->Send(base::StringPrintf( 123 void Connection::Send500(const std::string& message) {
124 if (!socket_)
125 return;
126 socket_->Send(base::StringPrintf(
171 "HTTP/1.1 500 Internal Error\r\n" 127 "HTTP/1.1 500 Internal Error\r\n"
172 "Content-Type:text/html\r\n" 128 "Content-Type:text/html\r\n"
173 "Content-Length:%d\r\n" 129 "Content-Length:%d\r\n"
174 "\r\n" 130 "\r\n"
175 "%s", 131 "%s",
176 static_cast<int>(message.length()), 132 static_cast<int>(message.length()),
177 message.c_str())); 133 message.c_str()));
178 } 134 }
179 135
180 void HttpServer::Close(int connection_id) 136 void HttpServer::Close(int connection_id)
181 { 137 {
182 Connection* connection = FindConnection(connection_id); 138 Connection* connection = FindConnection(connection_id);
183 if (connection == NULL) 139 if (connection == NULL)
184 return; 140 return;
185 141
186 connection->DetachSocket(); 142 connection->DetachSocket();
187 } 143 }
188 144
189 HttpServer::Connection::Connection(HttpServer* server, ListenSocket* sock) 145 Connection::Connection(HttpServer* server, ListenSocket* sock)
190 : server_(server), 146 : server_(server),
191 socket_(sock), 147 socket_(sock) {
192 is_web_socket_(false) {
193 id_ = lastId_++; 148 id_ = lastId_++;
194 } 149 }
195 150
196 HttpServer::Connection::~Connection() { 151 Connection::~Connection() {
197 DetachSocket(); 152 DetachSocket();
198 server_->delegate_->OnClose(id_); 153 server_->delegate_->OnClose(id_);
199 } 154 }
200 155
201 void HttpServer::Connection::DetachSocket() { 156 void Connection::DetachSocket() {
202 socket_ = NULL; 157 socket_ = NULL;
203 } 158 }
204 159
205 void HttpServer::Connection::Shift(int num_bytes) { 160 void Connection::Shift(int num_bytes) {
206 recv_data_ = recv_data_.substr(num_bytes); 161 recv_data_ = recv_data_.substr(num_bytes);
207 } 162 }
208 163
209 // 164 //
210 // HTTP Request Parser 165 // HTTP Request Parser
211 // This HTTP request parser uses a simple state machine to quickly parse 166 // This HTTP request parser uses a simple state machine to quickly parse
212 // through the headers. The parser is not 100% complete, as it is designed 167 // through the headers. The parser is not 100% complete, as it is designed
213 // for use in this simple test driver. 168 // for use in this simple test driver.
214 // 169 //
215 // Known issues: 170 // Known issues:
216 // - does not handle whitespace on first HTTP line correctly. Expects 171 // - does not handle whitespace on first HTTP line correctly. Expects
217 // a single space between the method/url and url/protocol. 172 // a single space between the method/url and url/protocol.
218 173
219 // Input character types. 174 // Input character types.
220 enum header_parse_inputs { 175 enum header_parse_inputs {
221 INPUT_SPACE, 176 INPUT_SPACE,
222 INPUT_CR, 177 INPUT_CR,
223 INPUT_LF, 178 INPUT_LF,
224 INPUT_COLON, 179 INPUT_COLON,
225 INPUT_00,
226 INPUT_FF,
227 INPUT_DEFAULT, 180 INPUT_DEFAULT,
228 MAX_INPUTS, 181 MAX_INPUTS,
229 }; 182 };
230 183
231 // Parser states. 184 // Parser states.
232 enum header_parse_states { 185 enum header_parse_states {
233 ST_METHOD, // Receiving the method 186 ST_METHOD, // Receiving the method
234 ST_URL, // Receiving the URL 187 ST_URL, // Receiving the URL
235 ST_PROTO, // Receiving the protocol 188 ST_PROTO, // Receiving the protocol
236 ST_HEADER, // Starting a Request Header 189 ST_HEADER, // Starting a Request Header
237 ST_NAME, // Receiving a request header name 190 ST_NAME, // Receiving a request header name
238 ST_SEPARATOR, // Receiving the separator between header name and value 191 ST_SEPARATOR, // Receiving the separator between header name and value
239 ST_VALUE, // Receiving a request header value 192 ST_VALUE, // Receiving a request header value
240 ST_WS_READY, // Ready to receive web socket frame
241 ST_WS_FRAME, // Receiving WebSocket frame
242 ST_WS_CLOSE, // Closing the connection WebSocket connection
243 ST_DONE, // Parsing is complete and successful 193 ST_DONE, // Parsing is complete and successful
244 ST_ERR, // Parsing encountered invalid syntax. 194 ST_ERR, // Parsing encountered invalid syntax.
245 MAX_STATES 195 MAX_STATES
246 }; 196 };
247 197
248 // State transition table 198 // State transition table
249 int parser_state[MAX_STATES][MAX_INPUTS] = { 199 int parser_state[MAX_STATES][MAX_INPUTS] = {
250 /* METHOD */ { ST_URL, ST_ERR, ST_ERR, ST_ERR, ST_ERR, ST_ERR, ST_METHOD }, 200 /* METHOD */ { ST_URL, ST_ERR, ST_ERR, ST_ERR, ST_METHO D },
251 /* URL */ { ST_PROTO, ST_ERR, ST_ERR, ST_URL, ST_ERR, ST_ERR, ST_URL }, 201 /* URL */ { ST_PROTO, ST_ERR, ST_ERR, ST_URL, ST_URL } ,
252 /* PROTOCOL */ { ST_ERR, ST_HEADER, ST_NAME, ST_ERR, ST_ERR, ST_ERR, ST_PROTO }, 202 /* PROTOCOL */ { ST_ERR, ST_HEADER, ST_NAME, ST_ERR, ST_PROTO },
253 /* HEADER */ { ST_ERR, ST_ERR, ST_NAME, ST_ERR, ST_ERR, ST_ERR, ST_ERR }, 203 /* HEADER */ { ST_ERR, ST_ERR, ST_NAME, ST_ERR, ST_ERR } ,
254 /* NAME */ { ST_SEPARATOR, ST_DONE, ST_ERR, ST_SEPARATOR, ST_ERR, ST_ERR, ST_NAME }, 204 /* NAME */ { ST_SEPARATOR, ST_DONE, ST_ERR, ST_SEPARATOR, ST_NAME },
255 /* SEPARATOR */ { ST_SEPARATOR, ST_ERR, ST_ERR, ST_SEPARATOR, ST_ERR, ST_ERR, ST_VALUE }, 205 /* SEPARATOR */ { ST_SEPARATOR, ST_ERR, ST_ERR, ST_SEPARATOR, ST_VALUE },
256 /* VALUE */ { ST_VALUE, ST_HEADER, ST_NAME, ST_VALUE, ST_ERR, ST_ERR, ST_VALUE }, 206 /* VALUE */ { ST_VALUE, ST_HEADER, ST_NAME, ST_VALUE, ST_VALUE },
257 /* WS_READY */ { ST_ERR, ST_ERR, ST_ERR, ST_ERR, ST_WS_FR AME, ST_WS_CLOSE, ST_ERR}, 207 /* DONE */ { ST_DONE, ST_DONE, ST_DONE, ST_DONE, ST_DONE },
258 /* WS_FRAME */ { ST_WS_FRAME, ST_WS_FRAME, ST_WS_FRAME, ST_WS_FRAME, ST_ERR, ST_WS_READY, ST_WS_FRAME }, 208 /* ERR */ { ST_ERR, ST_ERR, ST_ERR, ST_ERR, ST_ERR }
259 /* WS_CLOSE */ { ST_ERR, ST_ERR, ST_ERR, ST_ERR, ST_WS_CL OSE, ST_ERR, ST_ERR },
260 /* DONE */ { ST_DONE, ST_DONE, ST_DONE, ST_DONE, ST_DONE, ST_DONE, ST_DONE },
261 /* ERR */ { ST_ERR, ST_ERR, ST_ERR, ST_ERR, ST_ERR, ST_ERR, ST_ERR }
262 }; 209 };
263 210
264 // Convert an input character to the parser's input token. 211 // Convert an input character to the parser's input token.
265 int charToInput(char ch) { 212 int charToInput(char ch) {
266 switch(ch) { 213 switch(ch) {
267 case ' ': 214 case ' ':
268 return INPUT_SPACE; 215 return INPUT_SPACE;
269 case '\r': 216 case '\r':
270 return INPUT_CR; 217 return INPUT_CR;
271 case '\n': 218 case '\n':
272 return INPUT_LF; 219 return INPUT_LF;
273 case ':': 220 case ':':
274 return INPUT_COLON; 221 return INPUT_COLON;
275 case 0x0:
276 return INPUT_00;
277 case static_cast<char>(-1):
278 return INPUT_FF;
279 } 222 }
280 return INPUT_DEFAULT; 223 return INPUT_DEFAULT;
281 } 224 }
282 225
283 bool HttpServer::ParseHeaders(Connection* connection, 226 bool HttpServer::ParseHeaders(Connection* connection,
284 HttpServerRequestInfo* info, 227 HttpServerRequestInfo* info,
285 int* ppos) { 228 size_t* ppos) {
286 int& pos = *ppos; 229 size_t& pos = *ppos;
287 int data_len = connection->recv_data_.length(); 230 size_t data_len = connection->recv_data_.length();
288 int state = connection->is_web_socket_ ? ST_WS_READY : ST_METHOD; 231 int state = ST_METHOD;
289 std::string buffer; 232 std::string buffer;
290 std::string header_name; 233 std::string header_name;
291 std::string header_value; 234 std::string header_value;
292 while (pos < data_len) { 235 while (pos < data_len) {
293 char ch = connection->recv_data_[pos++]; 236 char ch = connection->recv_data_[pos++];
294 int input = charToInput(ch); 237 int input = charToInput(ch);
295 int next_state = parser_state[state][input]; 238 int next_state = parser_state[state][input];
296 239
297 bool transition = (next_state != state); 240 bool transition = (next_state != state);
298 if (transition) { 241 if (transition) {
(...skipping 19 matching lines...) Expand all
318 case ST_VALUE: 261 case ST_VALUE:
319 header_value = buffer; 262 header_value = buffer;
320 // TODO(mbelshe): Deal better with duplicate headers 263 // TODO(mbelshe): Deal better with duplicate headers
321 DCHECK(info->headers.find(header_name) == info->headers.end()); 264 DCHECK(info->headers.find(header_name) == info->headers.end());
322 info->headers[header_name] = header_value; 265 info->headers[header_name] = header_value;
323 buffer.clear(); 266 buffer.clear();
324 break; 267 break;
325 case ST_SEPARATOR: 268 case ST_SEPARATOR:
326 buffer.append(&ch, 1); 269 buffer.append(&ch, 1);
327 break; 270 break;
328 case ST_WS_FRAME:
329 info->data = buffer;
330 buffer.clear();
331 return true;
332 break;
333 } 271 }
334 state = next_state; 272 state = next_state;
335 } else { 273 } else {
336 // Do any actions based on current state 274 // Do any actions based on current state
337 switch (state) { 275 switch (state) {
338 case ST_METHOD: 276 case ST_METHOD:
339 case ST_URL: 277 case ST_URL:
340 case ST_PROTO: 278 case ST_PROTO:
341 case ST_VALUE: 279 case ST_VALUE:
342 case ST_NAME: 280 case ST_NAME:
343 case ST_WS_FRAME:
344 buffer.append(&ch, 1); 281 buffer.append(&ch, 1);
345 break; 282 break;
346 case ST_DONE: 283 case ST_DONE:
347 DCHECK(input == INPUT_LF); 284 DCHECK(input == INPUT_LF);
348 return true; 285 return true;
349 case ST_WS_CLOSE:
350 connection->is_web_socket_ = false;
351 return false;
352 case ST_ERR: 286 case ST_ERR:
353 return false; 287 return false;
354 } 288 }
355 } 289 }
356 } 290 }
357 // No more characters, but we haven't finished parsing yet. 291 // No more characters, but we haven't finished parsing yet.
358 return false; 292 return false;
359 } 293 }
360 294
361 void HttpServer::DidAccept(ListenSocket* server, 295 void HttpServer::DidAccept(ListenSocket* server,
362 ListenSocket* socket) { 296 ListenSocket* socket) {
363 Connection* connection = new Connection(this, socket); 297 Connection* connection = new Connection(this, socket);
364 id_to_connection_[connection->id_] = connection; 298 id_to_connection_[connection->Id()] = connection;
365 socket_to_connection_[socket] = connection; 299 socket_to_connection_[socket] = connection;
366 } 300 }
367 301
368 void HttpServer::DidRead(ListenSocket* socket, 302 void HttpServer::DidRead(ListenSocket* socket,
369 const char* data, 303 const char* data,
370 int len) { 304 int len) {
371 Connection* connection = FindConnection(socket); 305 Connection* connection = FindConnection(socket);
372 DCHECK(connection != NULL); 306 DCHECK(connection != NULL);
373 if (connection == NULL) 307 if (connection == NULL)
374 return; 308 return;
375 309
376 connection->recv_data_.append(data, len); 310 connection->recv_data_.append(data, len);
377 while (connection->recv_data_.length()) { 311 while (connection->recv_data_.length()) {
378 int pos = 0; 312 if (connection->web_socket_.get()) {
313 std::string message;
314 WebSocket::ParseResult result = connection->web_socket_->Read(&message);
315 if (result == WebSocket::FrameIncomplete)
316 break;
317
318 if (result == WebSocket::FrameError) {
319 Close(connection->Id());
320 break;
321 }
322 delegate_->OnWebSocketMessage(connection->Id(), message);
323 continue;
324 }
325
379 HttpServerRequestInfo request; 326 HttpServerRequestInfo request;
327 size_t pos = 0;
380 if (!ParseHeaders(connection, &request, &pos)) 328 if (!ParseHeaders(connection, &request, &pos))
381 break; 329 break;
382 330
383 if (connection->is_web_socket_) { 331 std::string connection_header = GetHeaderValue(request, "Connection");
384 delegate_->OnWebSocketMessage(connection->id_, request.data); 332 if (connection_header == "Upgrade") {
333 connection->web_socket_.reset(WebSocket::createWebSocket(
334 connection, request, &pos));
335 if (!connection->web_socket_.get()) // Not enought data was received.
336 break;
337 delegate_->OnWebSocketRequest(connection->Id(), request);
385 connection->Shift(pos); 338 connection->Shift(pos);
386 continue; 339 continue;
387 } 340 }
388
389 std::string connection_header = GetHeaderValue(request, "Connection");
390 if (connection_header == "Upgrade") {
391 // Is this WebSocket and if yes, upgrade the connection.
392 std::string key1 = GetHeaderValue(request, "Sec-WebSocket-Key1");
393 std::string key2 = GetHeaderValue(request, "Sec-WebSocket-Key2");
394
395 const int websocket_handshake_body_len = 8;
396 if (pos + websocket_handshake_body_len >
397 static_cast<int>(connection->recv_data_.length())) {
398 // We haven't received websocket handshake body yet. Wait.
399 break;
400 }
401
402 if (!key1.empty() && !key2.empty()) {
403 request.data = connection->recv_data_.substr(
404 pos,
405 pos + websocket_handshake_body_len);
406 pos += websocket_handshake_body_len;
407 delegate_->OnWebSocketRequest(connection->id_, request);
408 connection->Shift(pos);
409 continue;
410 }
411 }
412 // Request body is not supported. It is always empty. 341 // Request body is not supported. It is always empty.
413 delegate_->OnHttpRequest(connection->id_, request); 342 delegate_->OnHttpRequest(connection->Id(), request);
414 connection->Shift(pos); 343 connection->Shift(pos);
415 } 344 }
416 } 345 }
417 346
418 void HttpServer::DidClose(ListenSocket* socket) { 347 void HttpServer::DidClose(ListenSocket* socket) {
419 Connection* connection = FindConnection(socket); 348 Connection* connection = FindConnection(socket);
420 DCHECK(connection != NULL); 349 DCHECK(connection != NULL);
421 id_to_connection_.erase(connection->id_); 350 id_to_connection_.erase(connection->Id());
422 socket_to_connection_.erase(connection->socket_); 351 socket_to_connection_.erase(connection->socket_);
423 delete connection; 352 delete connection;
424 } 353 }
425 354
426 HttpServer::Connection* HttpServer::FindConnection(int connection_id) { 355 Connection* HttpServer::FindConnection(int connection_id) {
427 IdToConnectionMap::iterator it = id_to_connection_.find(connection_id); 356 IdToConnectionMap::iterator it = id_to_connection_.find(connection_id);
428 if (it == id_to_connection_.end()) 357 if (it == id_to_connection_.end())
429 return NULL; 358 return NULL;
430 return it->second; 359 return it->second;
431 } 360 }
432 361
433 HttpServer::Connection* HttpServer::FindConnection(ListenSocket* socket) { 362 Connection* HttpServer::FindConnection(ListenSocket* socket) {
434 SocketToConnectionMap::iterator it = socket_to_connection_.find(socket); 363 SocketToConnectionMap::iterator it = socket_to_connection_.find(socket);
435 if (it == socket_to_connection_.end()) 364 if (it == socket_to_connection_.end())
436 return NULL; 365 return NULL;
437 return it->second; 366 return it->second;
438 } 367 }
439 368
369 void HttpServer::AcceptWebSocket(
370 int connection_id,
371 const HttpServerRequestInfo& request) {
372 Connection* connection = FindConnection(connection_id);
373 if (connection == NULL)
374 return;
375
376 DCHECK(connection->web_socket_.get());
377 connection->web_socket_->Accept(request);
378 }
379
380 void HttpServer::SendOverWebSocket(int connection_id,
381 const std::string& data) {
382 Connection* connection = FindConnection(connection_id);
383 if (connection == NULL)
384 return;
385 DCHECK(connection->web_socket_.get());
386 connection->web_socket_->Send(data);
387 }
388
440 } // namespace net 389 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698