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

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

Issue 2870062: DevTools: implement basic handshake for remote debugging. (Closed)
Patch Set: utf16 conversion Created 10 years, 5 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
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 #ifdef _WIN32 5 #ifdef _WIN32
6 #include <winsock2.h> 6 #include <winsock2.h>
7 #else 7 #else
8 #include <arpa/inet.h> 8 #include <arpa/inet.h>
9 #endif 9 #endif
10 10
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 // TODO (ibrar): error handling 51 // TODO (ibrar): error handling
52 } else { 52 } else {
53 HttpListenSocket *serv = new HttpListenSocket(s, delegate); 53 HttpListenSocket *serv = new HttpListenSocket(s, delegate);
54 serv->Listen(); 54 serv->Listen();
55 return serv; 55 return serv;
56 } 56 }
57 return NULL; 57 return NULL;
58 } 58 }
59 59
60 std::string GetHeaderValue( 60 std::string GetHeaderValue(
61 HttpServerRequestInfo* request, 61 const HttpServerRequestInfo& request,
62 const std::string& header_name) { 62 const std::string& header_name) {
63 HttpServerRequestInfo::HeadersMap::iterator it = 63 HttpServerRequestInfo::HeadersMap::iterator it =
64 request->headers.find(header_name); 64 request.headers.find(header_name);
65 if (it != request->headers.end()) 65 if (it != request.headers.end())
66 return it->second; 66 return it->second;
67 return ""; 67 return "";
68 } 68 }
69 69
70 uint32 WebSocketKeyFingerprint(const std::string& str) { 70 uint32 WebSocketKeyFingerprint(const std::string& str) {
71 std::string result; 71 std::string result;
72 const char* pChar = str.c_str(); 72 const char* pChar = str.c_str();
73 int length = str.length(); 73 int length = str.length();
74 int spaces = 0; 74 int spaces = 0;
75 for (int i = 0; i < length; ++i) { 75 for (int i = 0; i < length; ++i) {
76 if (pChar[i] >= '0' && pChar[i] <= '9') 76 if (pChar[i] >= '0' && pChar[i] <= '9')
77 result.append(&pChar[i], 1); 77 result.append(&pChar[i], 1);
78 else if (pChar[i] == ' ') 78 else if (pChar[i] == ' ')
79 spaces++; 79 spaces++;
80 } 80 }
81 if (spaces == 0) 81 if (spaces == 0)
82 return 0; 82 return 0;
83 int64 number = 0; 83 int64 number = 0;
84 if (!StringToInt64(result, &number)) 84 if (!StringToInt64(result, &number))
85 return 0; 85 return 0;
86 return htonl(static_cast<uint32>(number / spaces)); 86 return htonl(static_cast<uint32>(number / spaces));
87 } 87 }
88 88
89 void HttpListenSocket::AcceptWebSocket(HttpServerRequestInfo* request) { 89 void HttpListenSocket::AcceptWebSocket(const HttpServerRequestInfo& request) {
90 std::string key1 = GetHeaderValue(request, "Sec-WebSocket-Key1"); 90 std::string key1 = GetHeaderValue(request, "Sec-WebSocket-Key1");
91 std::string key2 = GetHeaderValue(request, "Sec-WebSocket-Key2"); 91 std::string key2 = GetHeaderValue(request, "Sec-WebSocket-Key2");
92 92
93 uint32 fp1 = WebSocketKeyFingerprint(key1); 93 uint32 fp1 = WebSocketKeyFingerprint(key1);
94 uint32 fp2 = WebSocketKeyFingerprint(key2); 94 uint32 fp2 = WebSocketKeyFingerprint(key2);
95 95
96 char data[16]; 96 char data[16];
97 memcpy(data, &fp1, 4); 97 memcpy(data, &fp1, 4);
98 memcpy(data + 4, &fp2, 4); 98 memcpy(data + 4, &fp2, 4);
99 memcpy(data + 8, &request->data[0], 8); 99 memcpy(data + 8, &request.data[0], 8);
100 100
101 MD5Digest digest; 101 MD5Digest digest;
102 MD5Sum(data, 16, &digest); 102 MD5Sum(data, 16, &digest);
103 103
104 std::string origin = GetHeaderValue(request, "Origin"); 104 std::string origin = GetHeaderValue(request, "Origin");
105 std::string host = GetHeaderValue(request, "Host"); 105 std::string host = GetHeaderValue(request, "Host");
106 std::string location = "ws://" + host + request->path; 106 std::string location = "ws://" + host + request.path;
107 is_web_socket_ = true; 107 is_web_socket_ = true;
108 Send(StringPrintf("HTTP/1.1 101 WebSocket Protocol Handshake\r\n" 108 Send(StringPrintf("HTTP/1.1 101 WebSocket Protocol Handshake\r\n"
109 "Upgrade: WebSocket\r\n" 109 "Upgrade: WebSocket\r\n"
110 "Connection: Upgrade\r\n" 110 "Connection: Upgrade\r\n"
111 "Sec-WebSocket-Origin: %s\r\n" 111 "Sec-WebSocket-Origin: %s\r\n"
112 "Sec-WebSocket-Location: %s\r\n" 112 "Sec-WebSocket-Location: %s\r\n"
113 "\r\n", 113 "\r\n",
114 origin.c_str(), 114 origin.c_str(),
115 location.c_str())); 115 location.c_str()));
116 Send(reinterpret_cast<char*>(digest.a), 16); 116 Send(reinterpret_cast<char*>(digest.a), 16);
117 } 117 }
118 118
119 void HttpListenSocket::SendOverWebSocket(const std::string& data) { 119 void HttpListenSocket::SendOverWebSocket(const std::string& data) {
120 DCHECK(is_web_socket_); 120 DCHECK(is_web_socket_);
121 char message_start = 0; 121 char message_start = 0;
122 char message_end = -1; 122 char message_end = -1;
123 Send(&message_start, 1); 123 Send(&message_start, 1);
124 Send(data); 124 Send(data);
125 Send(&message_end, 1); 125 Send(&message_end, 1);
126 } 126 }
127 127
128 void HttpListenSocket::Send200(const std::string& data,
129 const std::string& content_type) {
130 Send(StringPrintf("HTTP/1.1 200 OK\r\n"
131 "Content-Type:%s\r\n"
132 "Content-Length:%d\r\n"
133 "\r\n",
134 content_type.c_str(),
135 data.length()));
136 Send(data);
137 }
138
139 void HttpListenSocket::Send404() {
140 Send("HTTP/1.1 404 Not Found\r\n"
141 "Content-Length: 0\r\n"
142 "\r\n");
143 }
144
145 void HttpListenSocket::Send500(const std::string& message) {
146 Send(StringPrintf("HTTP/1.1 500 Internal Error\r\n"
147 "Content-Type:text/html\r\n"
148 "Content-Length:%d\r\n"
149 "\r\n"
150 "%s",
151 message.length(),
152 message.c_str()));
153 }
154
128 // 155 //
129 // HTTP Request Parser 156 // HTTP Request Parser
130 // This HTTP request parser uses a simple state machine to quickly parse 157 // This HTTP request parser uses a simple state machine to quickly parse
131 // through the headers. The parser is not 100% complete, as it is designed 158 // through the headers. The parser is not 100% complete, as it is designed
132 // for use in this simple test driver. 159 // for use in this simple test driver.
133 // 160 //
134 // Known issues: 161 // Known issues:
135 // - does not handle whitespace on first HTTP line correctly. Expects 162 // - does not handle whitespace on first HTTP line correctly. Expects
136 // a single space between the method/url and url/protocol. 163 // a single space between the method/url and url/protocol.
137 164
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 case ':': 219 case ':':
193 return INPUT_COLON; 220 return INPUT_COLON;
194 case 0x0: 221 case 0x0:
195 return INPUT_00; 222 return INPUT_00;
196 case static_cast<char>(-1): 223 case static_cast<char>(-1):
197 return INPUT_FF; 224 return INPUT_FF;
198 } 225 }
199 return INPUT_DEFAULT; 226 return INPUT_DEFAULT;
200 } 227 }
201 228
202 HttpServerRequestInfo* HttpListenSocket::ParseHeaders() { 229 bool HttpListenSocket::ParseHeaders(HttpServerRequestInfo* info) {
203 int pos = 0; 230 int pos = 0;
204 int data_len = recv_data_.length(); 231 int data_len = recv_data_.length();
205 int state = is_web_socket_ ? ST_WS_READY : ST_METHOD; 232 int state = is_web_socket_ ? ST_WS_READY : ST_METHOD;
206 scoped_ptr<HttpServerRequestInfo> info(new HttpServerRequestInfo());
207 std::string buffer; 233 std::string buffer;
208 std::string header_name; 234 std::string header_name;
209 std::string header_value; 235 std::string header_value;
210 while (pos < data_len) { 236 while (pos < data_len) {
211 char ch = recv_data_[pos++]; 237 char ch = recv_data_[pos++];
212 int input = charToInput(ch); 238 int input = charToInput(ch);
213 int next_state = parser_state[state][input]; 239 int next_state = parser_state[state][input];
214 240
215 bool transition = (next_state != state); 241 bool transition = (next_state != state);
216 if (transition) { 242 if (transition) {
(...skipping 23 matching lines...) Expand all
240 info->headers[header_name] = header_value; 266 info->headers[header_name] = header_value;
241 buffer.clear(); 267 buffer.clear();
242 break; 268 break;
243 case ST_SEPARATOR: 269 case ST_SEPARATOR:
244 buffer.append(&ch, 1); 270 buffer.append(&ch, 1);
245 break; 271 break;
246 case ST_WS_FRAME: 272 case ST_WS_FRAME:
247 recv_data_ = recv_data_.substr(pos); 273 recv_data_ = recv_data_.substr(pos);
248 info->data = buffer; 274 info->data = buffer;
249 buffer.clear(); 275 buffer.clear();
250 return info.release(); 276 return true;
251 break; 277 break;
252 } 278 }
253 state = next_state; 279 state = next_state;
254 } else { 280 } else {
255 // Do any actions based on current state 281 // Do any actions based on current state
256 switch (state) { 282 switch (state) {
257 case ST_METHOD: 283 case ST_METHOD:
258 case ST_URL: 284 case ST_URL:
259 case ST_PROTO: 285 case ST_PROTO:
260 case ST_VALUE: 286 case ST_VALUE:
261 case ST_NAME: 287 case ST_NAME:
262 case ST_WS_FRAME: 288 case ST_WS_FRAME:
263 buffer.append(&ch, 1); 289 buffer.append(&ch, 1);
264 break; 290 break;
265 case ST_DONE: 291 case ST_DONE:
266 recv_data_ = recv_data_.substr(pos); 292 recv_data_ = recv_data_.substr(pos);
267 info->data = recv_data_; 293 info->data = recv_data_;
268 recv_data_.clear(); 294 recv_data_.clear();
269 return info.release(); 295 return true;
270 case ST_WS_CLOSE: 296 case ST_WS_CLOSE:
271 is_web_socket_ = false; 297 is_web_socket_ = false;
272 return NULL; 298 return false;
273 case ST_ERR: 299 case ST_ERR:
274 return NULL; 300 return false;
275 } 301 }
276 } 302 }
277 } 303 }
278 // No more characters, but we haven't finished parsing yet. 304 // No more characters, but we haven't finished parsing yet.
279 return NULL; 305 return false;
280 } 306 }
281 307
282 void HttpListenSocket::DidAccept(ListenSocket* server, 308 void HttpListenSocket::DidAccept(ListenSocket* server,
283 ListenSocket* connection) { 309 ListenSocket* connection) {
284 connection->AddRef(); 310 connection->AddRef();
285 } 311 }
286 312
287 void HttpListenSocket::DidRead(ListenSocket*, 313 void HttpListenSocket::DidRead(ListenSocket*,
288 const char* data, 314 const char* data,
289 int len) { 315 int len) {
290 recv_data_.append(data, len); 316 recv_data_.append(data, len);
291 while (recv_data_.length()) { 317 while (recv_data_.length()) {
292 scoped_ptr<HttpServerRequestInfo> request(ParseHeaders()); 318 HttpServerRequestInfo request;
293 if (!request.get()) 319 if (!ParseHeaders(&request))
294 break; 320 break;
295 321
296 if (is_web_socket_) { 322 if (is_web_socket_) {
297 delegate_->OnWebSocketMessage(this, request->data); 323 delegate_->OnWebSocketMessage(this, request.data);
298 continue; 324 continue;
299 } 325 }
300 326
301 std::string connection = GetHeaderValue(request.get(), "Connection"); 327 std::string connection = GetHeaderValue(request, "Connection");
302 if (connection == "Upgrade") { 328 if (connection == "Upgrade") {
303 // Is this WebSocket and if yes, upgrade the connection. 329 // Is this WebSocket and if yes, upgrade the connection.
304 std::string key1 = GetHeaderValue(request.get(), "Sec-WebSocket-Key1"); 330 std::string key1 = GetHeaderValue(request, "Sec-WebSocket-Key1");
305 std::string key2 = GetHeaderValue(request.get(), "Sec-WebSocket-Key2"); 331 std::string key2 = GetHeaderValue(request, "Sec-WebSocket-Key2");
306 if (!key1.empty() && !key2.empty()) { 332 if (!key1.empty() && !key2.empty()) {
307 delegate_->OnWebSocketRequest(this, request.get()); 333 delegate_->OnWebSocketRequest(this, request);
308 continue; 334 continue;
309 } 335 }
310 } 336 }
311 delegate_->OnHttpRequest(this, request.get()); 337 delegate_->OnHttpRequest(this, request);
312 } 338 }
313 } 339 }
314 340
315 void HttpListenSocket::DidClose(ListenSocket* sock) { 341 void HttpListenSocket::DidClose(ListenSocket* sock) {
316 sock->Release(); 342 sock->Release();
317 delegate_->OnClose(this); 343 delegate_->OnClose(this);
318 } 344 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698