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

Side by Side Diff: net/websockets/websocket_handshake_handler.cc

Issue 6823075: Accept new WebSocket handshake format (hybi-04 and later). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Replace DCHECKs with DVLOG. Created 9 years, 7 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) 2010 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/websockets/websocket_handshake_handler.h" 5 #include "net/websockets/websocket_handshake_handler.h"
6 6
7 #include "base/base64.h"
7 #include "base/md5.h" 8 #include "base/md5.h"
9 #include "base/sha1.h"
10 #include "base/string_number_conversions.h"
8 #include "base/string_piece.h" 11 #include "base/string_piece.h"
9 #include "base/string_util.h" 12 #include "base/string_util.h"
10 #include "googleurl/src/gurl.h" 13 #include "googleurl/src/gurl.h"
11 #include "net/http/http_response_headers.h" 14 #include "net/http/http_response_headers.h"
12 #include "net/http/http_util.h" 15 #include "net/http/http_util.h"
13 16
14 namespace { 17 namespace {
15 18
16 const size_t kRequestKey3Size = 8U; 19 const size_t kRequestKey3Size = 8U;
17 const size_t kResponseKeySize = 16U; 20 const size_t kResponseKeySize = 16U;
18 21
22 // First version that introduced new WebSocket handshake which does not
23 // require sending "key3" or "response key" data after headers.
24 const int kMinVersionOfHybiNewHandshake = 4;
25
26 // Used when we calculate the value of Sec-WebSocket-Accept.
27 const char* const kWebSocketGuid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
28
19 void ParseHandshakeHeader( 29 void ParseHandshakeHeader(
20 const char* handshake_message, int len, 30 const char* handshake_message, int len,
21 std::string* status_line, 31 std::string* status_line,
22 std::string* headers) { 32 std::string* headers) {
23 size_t i = base::StringPiece(handshake_message, len).find_first_of("\r\n"); 33 size_t i = base::StringPiece(handshake_message, len).find_first_of("\r\n");
24 if (i == base::StringPiece::npos) { 34 if (i == base::StringPiece::npos) {
25 *status_line = std::string(handshake_message, len); 35 *status_line = std::string(handshake_message, len);
26 *headers = ""; 36 *headers = "";
27 return; 37 return;
28 } 38 }
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 key_number /= spaces; 133 key_number /= spaces;
124 134
125 char part[4]; 135 char part[4];
126 for (int i = 0; i < 4; i++) { 136 for (int i = 0; i < 4; i++) {
127 part[3 - i] = key_number & 0xFF; 137 part[3 - i] = key_number & 0xFF;
128 key_number >>= 8; 138 key_number >>= 8;
129 } 139 }
130 challenge->append(part, 4); 140 challenge->append(part, 4);
131 } 141 }
132 142
143 int GetVersionFromRequest(const std::string& request_headers) {
144 std::vector<std::string> values;
145 const char* const headers_to_get[2] = { "sec-websocket-version",
146 "sec-websocket-draft" };
147 FetchHeaders(request_headers, headers_to_get, 2, &values);
148 DCHECK_LE(values.size(), 1U);
149 if (values.empty())
150 return 0;
151 int version;
152 bool conversion_success = base::StringToInt(values[0], &version);
153 DCHECK(conversion_success);
154 DCHECK_GE(version, 1);
155 return version;
156 }
157
133 } // anonymous namespace 158 } // anonymous namespace
134 159
135 namespace net { 160 namespace net {
136 161
137 WebSocketHandshakeRequestHandler::WebSocketHandshakeRequestHandler() 162 WebSocketHandshakeRequestHandler::WebSocketHandshakeRequestHandler()
138 : original_length_(0), 163 : original_length_(0),
139 raw_length_(0) {} 164 raw_length_(0),
165 protocol_version_(-1) {}
140 166
141 bool WebSocketHandshakeRequestHandler::ParseRequest( 167 bool WebSocketHandshakeRequestHandler::ParseRequest(
142 const char* data, int length) { 168 const char* data, int length) {
143 DCHECK_GT(length, 0); 169 DCHECK_GT(length, 0);
144 std::string input(data, length); 170 std::string input(data, length);
145 int input_header_length = 171 int input_header_length =
146 HttpUtil::LocateEndOfHeaders(input.data(), input.size(), 0); 172 HttpUtil::LocateEndOfHeaders(input.data(), input.size(), 0);
147 if (input_header_length <= 0 || 173 if (input_header_length <= 0)
148 input_header_length + kRequestKey3Size > input.size())
149 return false; 174 return false;
150 175
151 ParseHandshakeHeader(input.data(), 176 ParseHandshakeHeader(input.data(),
152 input_header_length, 177 input_header_length,
153 &status_line_, 178 &status_line_,
154 &headers_); 179 &headers_);
155 180
156 // draft-hixie-thewebsocketprotocol-76 or later will send /key3/ 181 // WebSocket protocol drafts hixie-76 (hybi-00), hybi-01, 02 and 03 require
157 // after handshake request header. 182 // the clients to send key3 after the handshake request header fields.
183 // Hybi-04 and later drafts, on the other hand, no longer have key3
184 // in the handshake format.
185 protocol_version_ = GetVersionFromRequest(headers_);
186 DCHECK_GE(protocol_version_, 0);
187 if (protocol_version_ >= kMinVersionOfHybiNewHandshake) {
188 key3_ = "";
189 original_length_ = input_header_length;
190 return true;
191 }
192
193 if (input_header_length + kRequestKey3Size > input.size())
194 return false;
195
158 // Assumes WebKit doesn't send any data after handshake request message 196 // Assumes WebKit doesn't send any data after handshake request message
159 // until handshake is finished. 197 // until handshake is finished.
160 // Thus, |key3_| is part of handshake message, and not in part 198 // Thus, |key3_| is part of handshake message, and not in part
161 // of WebSocket frame stream. 199 // of WebSocket frame stream.
162 DCHECK_EQ(kRequestKey3Size, 200 DCHECK_EQ(kRequestKey3Size, input.size() - input_header_length);
163 input.size() -
164 input_header_length);
165 key3_ = std::string(input.data() + input_header_length, 201 key3_ = std::string(input.data() + input_header_length,
166 input.size() - input_header_length); 202 input.size() - input_header_length);
167 original_length_ = input.size(); 203 original_length_ = input.size();
168 return true; 204 return true;
169 } 205 }
170 206
171 size_t WebSocketHandshakeRequestHandler::original_length() const { 207 size_t WebSocketHandshakeRequestHandler::original_length() const {
172 return original_length_; 208 return original_length_;
173 } 209 }
174 210
(...skipping 20 matching lines...) Expand all
195 status_line_.data(), status_line_.size()).find_first_of(" "); 231 status_line_.data(), status_line_.size()).find_first_of(" ");
196 if (method_end != base::StringPiece::npos) 232 if (method_end != base::StringPiece::npos)
197 request_info.method = std::string(status_line_.data(), method_end); 233 request_info.method = std::string(status_line_.data(), method_end);
198 234
199 request_info.extra_headers.Clear(); 235 request_info.extra_headers.Clear();
200 request_info.extra_headers.AddHeadersFromString(headers_); 236 request_info.extra_headers.AddHeadersFromString(headers_);
201 237
202 request_info.extra_headers.RemoveHeader("Upgrade"); 238 request_info.extra_headers.RemoveHeader("Upgrade");
203 request_info.extra_headers.RemoveHeader("Connection"); 239 request_info.extra_headers.RemoveHeader("Connection");
204 240
205 challenge->clear(); 241 if (protocol_version_ >= kMinVersionOfHybiNewHandshake) {
206 std::string key; 242 std::string key;
207 request_info.extra_headers.GetHeader("Sec-WebSocket-Key1", &key); 243 bool header_present =
208 request_info.extra_headers.RemoveHeader("Sec-WebSocket-Key1"); 244 request_info.extra_headers.GetHeader("Sec-WebSocket-Key", &key);
209 GetKeyNumber(key, challenge); 245 DCHECK(header_present);
246 request_info.extra_headers.RemoveHeader("Sec-WebSocket-Key");
247 *challenge = key;
248 } else {
249 challenge->clear();
250 std::string key;
251 bool header_present =
252 request_info.extra_headers.GetHeader("Sec-WebSocket-Key1", &key);
253 DCHECK(header_present);
254 request_info.extra_headers.RemoveHeader("Sec-WebSocket-Key1");
255 GetKeyNumber(key, challenge);
210 256
211 request_info.extra_headers.GetHeader("Sec-WebSocket-Key2", &key); 257 header_present =
212 request_info.extra_headers.RemoveHeader("Sec-WebSocket-Key2"); 258 request_info.extra_headers.GetHeader("Sec-WebSocket-Key2", &key);
213 GetKeyNumber(key, challenge); 259 DCHECK(header_present);
260 request_info.extra_headers.RemoveHeader("Sec-WebSocket-Key2");
261 GetKeyNumber(key, challenge);
214 262
215 challenge->append(key3_); 263 challenge->append(key3_);
264 }
216 265
217 return request_info; 266 return request_info;
218 } 267 }
219 268
220 bool WebSocketHandshakeRequestHandler::GetRequestHeaderBlock( 269 bool WebSocketHandshakeRequestHandler::GetRequestHeaderBlock(
221 const GURL& url, spdy::SpdyHeaderBlock* headers, std::string* challenge) { 270 const GURL& url, spdy::SpdyHeaderBlock* headers, std::string* challenge) {
222 // We don't set "method" and "version". These are fixed value in WebSocket 271 // We don't set "method" and "version". These are fixed value in WebSocket
223 // protocol. 272 // protocol.
224 (*headers)["url"] = url.spec(); 273 (*headers)["url"] = url.spec();
225 274
226 std::string key1; 275 std::string new_key; // For protocols hybi-04 and newer.
227 std::string key2; 276 std::string old_key1; // For protocols hybi-03 and older.
277 std::string old_key2; // Ditto.
228 HttpUtil::HeadersIterator iter(headers_.begin(), headers_.end(), "\r\n"); 278 HttpUtil::HeadersIterator iter(headers_.begin(), headers_.end(), "\r\n");
229 while (iter.GetNext()) { 279 while (iter.GetNext()) {
230 if (LowerCaseEqualsASCII(iter.name_begin(), iter.name_end(), 280 if (LowerCaseEqualsASCII(iter.name_begin(), iter.name_end(),
231 "connection")) { 281 "connection")) {
232 // Ignore "Connection" header. 282 // Ignore "Connection" header.
233 continue; 283 continue;
234 } else if (LowerCaseEqualsASCII(iter.name_begin(), iter.name_end(), 284 } else if (LowerCaseEqualsASCII(iter.name_begin(), iter.name_end(),
235 "upgrade")) { 285 "upgrade")) {
236 // Ignore "Upgrade" header. 286 // Ignore "Upgrade" header.
237 continue; 287 continue;
238 } else if (LowerCaseEqualsASCII(iter.name_begin(), iter.name_end(), 288 } else if (LowerCaseEqualsASCII(iter.name_begin(), iter.name_end(),
239 "sec-websocket-key1")) { 289 "sec-websocket-key1")) {
240 // Use only for generating challenge. 290 // Only used for generating challenge.
241 key1 = iter.values(); 291 old_key1 = iter.values();
242 continue; 292 continue;
243 } else if (LowerCaseEqualsASCII(iter.name_begin(), iter.name_end(), 293 } else if (LowerCaseEqualsASCII(iter.name_begin(), iter.name_end(),
244 "sec-websocket-key2")) { 294 "sec-websocket-key2")) {
245 // Use only for generating challenge. 295 // Only used for generating challenge.
246 key2 = iter.values(); 296 old_key2 = iter.values();
297 continue;
298 } else if (LowerCaseEqualsASCII(iter.name_begin(), iter.name_end(),
299 "sec-websocket-key")) {
300 // Only used for generating challenge.
301 new_key = iter.values();
247 continue; 302 continue;
248 } 303 }
249 // Others should be sent out to |headers|. 304 // Others should be sent out to |headers|.
250 std::string name = StringToLowerASCII(iter.name()); 305 std::string name = StringToLowerASCII(iter.name());
251 spdy::SpdyHeaderBlock::iterator found = headers->find(name); 306 spdy::SpdyHeaderBlock::iterator found = headers->find(name);
252 if (found == headers->end()) { 307 if (found == headers->end()) {
253 (*headers)[name] = iter.values(); 308 (*headers)[name] = iter.values();
254 } else { 309 } else {
255 // For now, websocket doesn't use multiple headers, but follows to http. 310 // For now, websocket doesn't use multiple headers, but follows to http.
256 found->second.append(1, '\0'); // +=() doesn't append 0's 311 found->second.append(1, '\0'); // +=() doesn't append 0's
257 found->second.append(iter.values()); 312 found->second.append(iter.values());
258 } 313 }
259 } 314 }
260 315
261 challenge->clear(); 316 if (protocol_version_ >= kMinVersionOfHybiNewHandshake) {
262 GetKeyNumber(key1, challenge); 317 DVLOG_IF(1, !old_key1.empty())
263 GetKeyNumber(key2, challenge); 318 << "Server sent unexpected Sec-WebSocket-Key1 header.";
264 challenge->append(key3_); 319 DVLOG_IF(1, !old_key2.empty())
320 << "Server sent unexpected Sec-WebSocket-Key2 header.";
321 *challenge = new_key;
322 } else {
323 DVLOG_IF(1, !new_key.empty())
324 << "Server sent unexpected Sec-WebSocket-Key header.";
325 challenge->clear();
326 GetKeyNumber(old_key1, challenge);
327 GetKeyNumber(old_key2, challenge);
328 challenge->append(key3_);
329 }
265 330
266 return true; 331 return true;
267 } 332 }
268 333
269 std::string WebSocketHandshakeRequestHandler::GetRawRequest() { 334 std::string WebSocketHandshakeRequestHandler::GetRawRequest() {
270 DCHECK(!status_line_.empty()); 335 DCHECK(!status_line_.empty());
271 DCHECK(!headers_.empty()); 336 DCHECK(!headers_.empty());
272 DCHECK_EQ(kRequestKey3Size, key3_.size()); 337 // The following works on both hybi-04 and older handshake,
338 // because |key3_| is guaranteed to be empty if the handshake was hybi-04's.
273 std::string raw_request = status_line_ + headers_ + "\r\n" + key3_; 339 std::string raw_request = status_line_ + headers_ + "\r\n" + key3_;
274 raw_length_ = raw_request.size(); 340 raw_length_ = raw_request.size();
275 return raw_request; 341 return raw_request;
276 } 342 }
277 343
278 size_t WebSocketHandshakeRequestHandler::raw_length() const { 344 size_t WebSocketHandshakeRequestHandler::raw_length() const {
279 DCHECK_GT(raw_length_, 0); 345 DCHECK_GT(raw_length_, 0);
280 return raw_length_; 346 return raw_length_;
281 } 347 }
282 348
283 WebSocketHandshakeResponseHandler::WebSocketHandshakeResponseHandler() 349 int WebSocketHandshakeRequestHandler::protocol_version() const {
284 : original_header_length_(0) { 350 DCHECK_GE(protocol_version_, 0);
351 return protocol_version_;
285 } 352 }
286 353
354 WebSocketHandshakeResponseHandler::WebSocketHandshakeResponseHandler()
355 : original_header_length_(0),
356 protocol_version_(0) {}
357
287 WebSocketHandshakeResponseHandler::~WebSocketHandshakeResponseHandler() {} 358 WebSocketHandshakeResponseHandler::~WebSocketHandshakeResponseHandler() {}
288 359
360 int WebSocketHandshakeResponseHandler::protocol_version() const {
361 DCHECK_GE(protocol_version_, 0);
362 return protocol_version_;
363 }
364
365 void WebSocketHandshakeResponseHandler::set_protocol_version(
366 int protocol_version) {
367 DCHECK_GE(protocol_version, 0);
368 protocol_version_ = protocol_version;
369 }
370
289 size_t WebSocketHandshakeResponseHandler::ParseRawResponse( 371 size_t WebSocketHandshakeResponseHandler::ParseRawResponse(
290 const char* data, int length) { 372 const char* data, int length) {
291 DCHECK_GT(length, 0); 373 DCHECK_GT(length, 0);
292 if (HasResponse()) { 374 if (HasResponse()) {
293 DCHECK(!status_line_.empty()); 375 DCHECK(!status_line_.empty());
294 DCHECK(!headers_.empty()); 376 DCHECK(!headers_.empty());
295 DCHECK_EQ(kResponseKeySize, key_.size()); 377 DCHECK_EQ(GetResponseKeySize(), key_.size());
296 return 0; 378 return 0;
297 } 379 }
298 380
299 size_t old_original_length = original_.size(); 381 size_t old_original_length = original_.size();
300 382
301 original_.append(data, length); 383 original_.append(data, length);
302 // TODO(ukai): fail fast when response gives wrong status code. 384 // TODO(ukai): fail fast when response gives wrong status code.
303 original_header_length_ = HttpUtil::LocateEndOfHeaders( 385 original_header_length_ = HttpUtil::LocateEndOfHeaders(
304 original_.data(), original_.size(), 0); 386 original_.data(), original_.size(), 0);
305 if (!HasResponse()) 387 if (!HasResponse())
306 return length; 388 return length;
307 389
308 ParseHandshakeHeader(original_.data(), 390 ParseHandshakeHeader(original_.data(),
309 original_header_length_, 391 original_header_length_,
310 &status_line_, 392 &status_line_,
311 &headers_); 393 &headers_);
312 int header_size = status_line_.size() + headers_.size(); 394 int header_size = status_line_.size() + headers_.size();
313 DCHECK_GE(original_header_length_, header_size); 395 DCHECK_GE(original_header_length_, header_size);
314 header_separator_ = std::string(original_.data() + header_size, 396 header_separator_ = std::string(original_.data() + header_size,
315 original_header_length_ - header_size); 397 original_header_length_ - header_size);
316 key_ = std::string(original_.data() + original_header_length_, 398 key_ = std::string(original_.data() + original_header_length_,
317 kResponseKeySize); 399 GetResponseKeySize());
318 400 return original_header_length_ + GetResponseKeySize() - old_original_length;
319 return original_header_length_ + kResponseKeySize - old_original_length;
320 } 401 }
321 402
322 bool WebSocketHandshakeResponseHandler::HasResponse() const { 403 bool WebSocketHandshakeResponseHandler::HasResponse() const {
323 return original_header_length_ > 0 && 404 return original_header_length_ > 0 &&
324 original_header_length_ + kResponseKeySize <= original_.size(); 405 original_header_length_ + GetResponseKeySize() <= original_.size();
325 } 406 }
326 407
327 bool WebSocketHandshakeResponseHandler::ParseResponseInfo( 408 bool WebSocketHandshakeResponseHandler::ParseResponseInfo(
328 const HttpResponseInfo& response_info, 409 const HttpResponseInfo& response_info,
329 const std::string& challenge) { 410 const std::string& challenge) {
330 if (!response_info.headers.get()) 411 if (!response_info.headers.get())
331 return false; 412 return false;
332 413
333 std::string response_message; 414 std::string response_message;
334 response_message = response_info.headers->GetStatusLine(); 415 response_message = response_info.headers->GetStatusLine();
335 response_message += "\r\n"; 416 response_message += "\r\n";
336 response_message += "Upgrade: WebSocket\r\n"; 417 if (protocol_version_ >= kMinVersionOfHybiNewHandshake)
418 response_message += "Upgrade: websocket\r\n";
419 else
420 response_message += "Upgrade: WebSocket\r\n";
337 response_message += "Connection: Upgrade\r\n"; 421 response_message += "Connection: Upgrade\r\n";
422
423 if (protocol_version_ >= kMinVersionOfHybiNewHandshake) {
424 std::string hash = base::SHA1HashString(challenge + kWebSocketGuid);
425 std::string websocket_accept;
426 bool encode_success = base::Base64Encode(hash, &websocket_accept);
427 DCHECK(encode_success);
428 response_message += "Sec-WebSocket-Accept: " + websocket_accept + "\r\n";
429 }
430
338 void* iter = NULL; 431 void* iter = NULL;
339 std::string name; 432 std::string name;
340 std::string value; 433 std::string value;
341 while (response_info.headers->EnumerateHeaderLines(&iter, &name, &value)) { 434 while (response_info.headers->EnumerateHeaderLines(&iter, &name, &value)) {
342 response_message += name + ": " + value + "\r\n"; 435 response_message += name + ": " + value + "\r\n";
343 } 436 }
344 response_message += "\r\n"; 437 response_message += "\r\n";
345 438
346 MD5Digest digest; 439 if (protocol_version_ < kMinVersionOfHybiNewHandshake) {
347 MD5Sum(challenge.data(), challenge.size(), &digest); 440 MD5Digest digest;
441 MD5Sum(challenge.data(), challenge.size(), &digest);
348 442
349 const char* digest_data = reinterpret_cast<char*>(digest.a); 443 const char* digest_data = reinterpret_cast<char*>(digest.a);
350 response_message.append(digest_data, sizeof(digest.a)); 444 response_message.append(digest_data, sizeof(digest.a));
445 }
351 446
352 return ParseRawResponse(response_message.data(), 447 return ParseRawResponse(response_message.data(),
353 response_message.size()) == response_message.size(); 448 response_message.size()) == response_message.size();
354 } 449 }
355 450
356 bool WebSocketHandshakeResponseHandler::ParseResponseHeaderBlock( 451 bool WebSocketHandshakeResponseHandler::ParseResponseHeaderBlock(
357 const spdy::SpdyHeaderBlock& headers, 452 const spdy::SpdyHeaderBlock& headers,
358 const std::string& challenge) { 453 const std::string& challenge) {
359 std::string response_message; 454 std::string response_message;
360 response_message = "HTTP/1.1 101 WebSocket Protocol Handshake\r\n"; 455 if (protocol_version_ >= kMinVersionOfHybiNewHandshake) {
361 response_message += "Upgrade: WebSocket\r\n"; 456 response_message = "HTTP/1.1 101 Switching Protocols\r\n";
457 response_message += "Upgrade: websocket\r\n";
458 } else {
459 response_message = "HTTP/1.1 101 WebSocket Protocol Handshake\r\n";
460 response_message += "Upgrade: WebSocket\r\n";
461 }
362 response_message += "Connection: Upgrade\r\n"; 462 response_message += "Connection: Upgrade\r\n";
463
464 if (protocol_version_ >= kMinVersionOfHybiNewHandshake) {
465 std::string hash = base::SHA1HashString(challenge + kWebSocketGuid);
466 std::string websocket_accept;
467 bool encode_success = base::Base64Encode(hash, &websocket_accept);
468 DCHECK(encode_success);
469 response_message += "Sec-WebSocket-Accept: " + websocket_accept + "\r\n";
470 }
471
363 for (spdy::SpdyHeaderBlock::const_iterator iter = headers.begin(); 472 for (spdy::SpdyHeaderBlock::const_iterator iter = headers.begin();
364 iter != headers.end(); 473 iter != headers.end();
365 ++iter) { 474 ++iter) {
366 // For each value, if the server sends a NUL-separated list of values, 475 // For each value, if the server sends a NUL-separated list of values,
367 // we separate that back out into individual headers for each value 476 // we separate that back out into individual headers for each value
368 // in the list. 477 // in the list.
369 const std::string& value = iter->second; 478 const std::string& value = iter->second;
370 size_t start = 0; 479 size_t start = 0;
371 size_t end = 0; 480 size_t end = 0;
372 do { 481 do {
373 end = value.find('\0', start); 482 end = value.find('\0', start);
374 std::string tval; 483 std::string tval;
375 if (end != std::string::npos) 484 if (end != std::string::npos)
376 tval = value.substr(start, (end - start)); 485 tval = value.substr(start, (end - start));
377 else 486 else
378 tval = value.substr(start); 487 tval = value.substr(start);
379 response_message += iter->first + ": " + tval + "\r\n"; 488 response_message += iter->first + ": " + tval + "\r\n";
380 start = end + 1; 489 start = end + 1;
381 } while (end != std::string::npos); 490 } while (end != std::string::npos);
382 } 491 }
383 response_message += "\r\n"; 492 response_message += "\r\n";
384 493
385 MD5Digest digest; 494 if (protocol_version_ < kMinVersionOfHybiNewHandshake) {
386 MD5Sum(challenge.data(), challenge.size(), &digest); 495 MD5Digest digest;
496 MD5Sum(challenge.data(), challenge.size(), &digest);
387 497
388 const char* digest_data = reinterpret_cast<char*>(digest.a); 498 const char* digest_data = reinterpret_cast<char*>(digest.a);
389 response_message.append(digest_data, sizeof(digest.a)); 499 response_message.append(digest_data, sizeof(digest.a));
500 }
390 501
391 return ParseRawResponse(response_message.data(), 502 return ParseRawResponse(response_message.data(),
392 response_message.size()) == response_message.size(); 503 response_message.size()) == response_message.size();
393 } 504 }
394 505
395 void WebSocketHandshakeResponseHandler::GetHeaders( 506 void WebSocketHandshakeResponseHandler::GetHeaders(
396 const char* const headers_to_get[], 507 const char* const headers_to_get[],
397 size_t headers_to_get_len, 508 size_t headers_to_get_len,
398 std::vector<std::string>* values) { 509 std::vector<std::string>* values) {
399 DCHECK(HasResponse()); 510 DCHECK(HasResponse());
400 DCHECK(!status_line_.empty()); 511 DCHECK(!status_line_.empty());
401 DCHECK(!headers_.empty()); 512 DCHECK(!headers_.empty());
402 DCHECK_EQ(kResponseKeySize, key_.size()); 513 DCHECK_EQ(GetResponseKeySize(), key_.size());
403 514
404 FetchHeaders(headers_, headers_to_get, headers_to_get_len, values); 515 FetchHeaders(headers_, headers_to_get, headers_to_get_len, values);
405 } 516 }
406 517
407 void WebSocketHandshakeResponseHandler::RemoveHeaders( 518 void WebSocketHandshakeResponseHandler::RemoveHeaders(
408 const char* const headers_to_remove[], 519 const char* const headers_to_remove[],
409 size_t headers_to_remove_len) { 520 size_t headers_to_remove_len) {
410 DCHECK(HasResponse()); 521 DCHECK(HasResponse());
411 DCHECK(!status_line_.empty()); 522 DCHECK(!status_line_.empty());
412 DCHECK(!headers_.empty()); 523 DCHECK(!headers_.empty());
413 DCHECK_EQ(kResponseKeySize, key_.size()); 524 DCHECK_EQ(GetResponseKeySize(), key_.size());
414 525
415 headers_ = FilterHeaders(headers_, headers_to_remove, headers_to_remove_len); 526 headers_ = FilterHeaders(headers_, headers_to_remove, headers_to_remove_len);
416 } 527 }
417 528
418 std::string WebSocketHandshakeResponseHandler::GetRawResponse() const { 529 std::string WebSocketHandshakeResponseHandler::GetRawResponse() const {
419 DCHECK(HasResponse()); 530 DCHECK(HasResponse());
420 return std::string(original_.data(), 531 return std::string(original_.data(),
421 original_header_length_ + kResponseKeySize); 532 original_header_length_ + GetResponseKeySize());
422 } 533 }
423 534
424 std::string WebSocketHandshakeResponseHandler::GetResponse() { 535 std::string WebSocketHandshakeResponseHandler::GetResponse() {
425 DCHECK(HasResponse()); 536 DCHECK(HasResponse());
426 DCHECK(!status_line_.empty()); 537 DCHECK(!status_line_.empty());
427 // headers_ might be empty for wrong response from server. 538 // headers_ might be empty for wrong response from server.
428 DCHECK_EQ(kResponseKeySize, key_.size()); 539 DCHECK_EQ(GetResponseKeySize(), key_.size());
429 540
430 return status_line_ + headers_ + header_separator_ + key_; 541 return status_line_ + headers_ + header_separator_ + key_;
431 } 542 }
432 543
544 size_t WebSocketHandshakeResponseHandler::GetResponseKeySize() const {
545 if (protocol_version_ >= kMinVersionOfHybiNewHandshake)
546 return 0;
547 return kResponseKeySize;
548 }
549
433 } // namespace net 550 } // namespace net
OLDNEW
« no previous file with comments | « net/websockets/websocket_handshake_handler.h ('k') | net/websockets/websocket_handshake_handler_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698