Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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_basic_handshake_stream.h" | 5 #include "net/websockets/websocket_basic_handshake_stream.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <iterator> | 8 #include <iterator> |
| 9 #include <set> | 9 #include <set> |
| 10 #include <string> | 10 #include <string> |
| 11 #include <vector> | 11 #include <vector> |
| 12 | 12 |
| 13 #include "base/base64.h" | 13 #include "base/base64.h" |
| 14 #include "base/basictypes.h" | 14 #include "base/basictypes.h" |
| 15 #include "base/bind.h" | 15 #include "base/bind.h" |
| 16 #include "base/compiler_specific.h" | |
| 16 #include "base/containers/hash_tables.h" | 17 #include "base/containers/hash_tables.h" |
| 17 #include "base/logging.h" | 18 #include "base/logging.h" |
| 18 #include "base/metrics/histogram.h" | 19 #include "base/metrics/histogram.h" |
| 19 #include "base/metrics/sparse_histogram.h" | 20 #include "base/metrics/sparse_histogram.h" |
| 20 #include "base/stl_util.h" | 21 #include "base/stl_util.h" |
| 21 #include "base/strings/string_number_conversions.h" | 22 #include "base/strings/string_number_conversions.h" |
| 22 #include "base/strings/string_piece.h" | 23 #include "base/strings/string_piece.h" |
| 23 #include "base/strings/string_util.h" | 24 #include "base/strings/string_util.h" |
| 24 #include "base/strings/stringprintf.h" | 25 #include "base/strings/stringprintf.h" |
| 25 #include "base/time/time.h" | 26 #include "base/time/time.h" |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 39 #include "net/websockets/websocket_deflater.h" | 40 #include "net/websockets/websocket_deflater.h" |
| 40 #include "net/websockets/websocket_extension_parser.h" | 41 #include "net/websockets/websocket_extension_parser.h" |
| 41 #include "net/websockets/websocket_handshake_constants.h" | 42 #include "net/websockets/websocket_handshake_constants.h" |
| 42 #include "net/websockets/websocket_handshake_handler.h" | 43 #include "net/websockets/websocket_handshake_handler.h" |
| 43 #include "net/websockets/websocket_handshake_request_info.h" | 44 #include "net/websockets/websocket_handshake_request_info.h" |
| 44 #include "net/websockets/websocket_handshake_response_info.h" | 45 #include "net/websockets/websocket_handshake_response_info.h" |
| 45 #include "net/websockets/websocket_stream.h" | 46 #include "net/websockets/websocket_stream.h" |
| 46 | 47 |
| 47 namespace net { | 48 namespace net { |
| 48 | 49 |
| 50 namespace { | |
|
Adam Rice
2014/10/30 05:54:25
Please at a TODO to remove these once the bug is f
yhirano
2014/10/30 06:10:10
Done.
| |
| 51 | |
| 52 NOINLINE void RunCallbackWithOk(const CompletionCallback& callback, | |
| 53 int result) { | |
| 54 DCHECK_EQ(result, OK); | |
| 55 callback.Run(OK); | |
| 56 } | |
| 57 | |
| 58 NOINLINE void RunCallbackWithInvalidResponseCausedByRedirect( | |
| 59 const CompletionCallback& callback, | |
| 60 int result) { | |
| 61 DCHECK_EQ(result, ERR_INVALID_RESPONSE); | |
| 62 callback.Run(ERR_INVALID_RESPONSE); | |
| 63 } | |
| 64 | |
| 65 NOINLINE void RunCallbackWithInvalidResponse( | |
| 66 const CompletionCallback& callback, | |
| 67 int result) { | |
| 68 DCHECK_EQ(result, ERR_INVALID_RESPONSE); | |
| 69 callback.Run(ERR_INVALID_RESPONSE); | |
| 70 } | |
| 71 | |
| 72 NOINLINE void RunCallback(const CompletionCallback& callback, int result) { | |
| 73 callback.Run(result); | |
| 74 } | |
| 75 | |
| 76 } // namespace | |
| 77 | |
| 49 // TODO(ricea): If more extensions are added, replace this with a more general | 78 // TODO(ricea): If more extensions are added, replace this with a more general |
| 50 // mechanism. | 79 // mechanism. |
| 51 struct WebSocketExtensionParams { | 80 struct WebSocketExtensionParams { |
| 52 WebSocketExtensionParams() | 81 WebSocketExtensionParams() |
| 53 : deflate_enabled(false), | 82 : deflate_enabled(false), |
| 54 client_window_bits(15), | 83 client_window_bits(15), |
| 55 deflate_mode(WebSocketDeflater::TAKE_OVER_CONTEXT) {} | 84 deflate_mode(WebSocketDeflater::TAKE_OVER_CONTEXT) {} |
| 56 | 85 |
| 57 bool deflate_enabled; | 86 bool deflate_enabled; |
| 58 int client_window_bits; | 87 int client_window_bits; |
| (...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 423 // HttpStreamParser uses a weak pointer when reading from the | 452 // HttpStreamParser uses a weak pointer when reading from the |
| 424 // socket, so it won't be called back after being destroyed. The | 453 // socket, so it won't be called back after being destroyed. The |
| 425 // HttpStreamParser is owned by HttpBasicState which is owned by this object, | 454 // HttpStreamParser is owned by HttpBasicState which is owned by this object, |
| 426 // so this use of base::Unretained() is safe. | 455 // so this use of base::Unretained() is safe. |
| 427 int rv = parser()->ReadResponseHeaders( | 456 int rv = parser()->ReadResponseHeaders( |
| 428 base::Bind(&WebSocketBasicHandshakeStream::ReadResponseHeadersCallback, | 457 base::Bind(&WebSocketBasicHandshakeStream::ReadResponseHeadersCallback, |
| 429 base::Unretained(this), | 458 base::Unretained(this), |
| 430 callback)); | 459 callback)); |
| 431 if (rv == ERR_IO_PENDING) | 460 if (rv == ERR_IO_PENDING) |
| 432 return rv; | 461 return rv; |
| 433 return ValidateResponse(rv); | 462 bool is_redirect = false; |
| 463 return ValidateResponse(rv, &is_redirect); | |
| 434 } | 464 } |
| 435 | 465 |
| 436 int WebSocketBasicHandshakeStream::ReadResponseBody( | 466 int WebSocketBasicHandshakeStream::ReadResponseBody( |
| 437 IOBuffer* buf, | 467 IOBuffer* buf, |
| 438 int buf_len, | 468 int buf_len, |
| 439 const CompletionCallback& callback) { | 469 const CompletionCallback& callback) { |
| 440 return parser()->ReadResponseBody(buf, buf_len, callback); | 470 return parser()->ReadResponseBody(buf, buf_len, callback); |
| 441 } | 471 } |
| 442 | 472 |
| 443 void WebSocketBasicHandshakeStream::Close(bool not_reusable) { | 473 void WebSocketBasicHandshakeStream::Close(bool not_reusable) { |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 528 } | 558 } |
| 529 | 559 |
| 530 void WebSocketBasicHandshakeStream::SetWebSocketKeyForTesting( | 560 void WebSocketBasicHandshakeStream::SetWebSocketKeyForTesting( |
| 531 const std::string& key) { | 561 const std::string& key) { |
| 532 handshake_challenge_for_testing_.reset(new std::string(key)); | 562 handshake_challenge_for_testing_.reset(new std::string(key)); |
| 533 } | 563 } |
| 534 | 564 |
| 535 void WebSocketBasicHandshakeStream::ReadResponseHeadersCallback( | 565 void WebSocketBasicHandshakeStream::ReadResponseHeadersCallback( |
| 536 const CompletionCallback& callback, | 566 const CompletionCallback& callback, |
| 537 int result) { | 567 int result) { |
| 538 callback.Run(ValidateResponse(result)); | 568 bool is_redirect = false; |
| 569 int rv = ValidateResponse(result, &is_redirect); | |
| 570 | |
| 571 switch (rv) { | |
| 572 case OK: | |
| 573 RunCallbackWithOk(callback, rv); | |
| 574 break; | |
| 575 case ERR_INVALID_RESPONSE: | |
| 576 if (is_redirect) | |
| 577 RunCallbackWithInvalidResponseCausedByRedirect(callback, rv); | |
| 578 else | |
| 579 RunCallbackWithInvalidResponse(callback, rv); | |
| 580 break; | |
| 581 default: | |
| 582 RunCallback(callback, rv); | |
| 583 break; | |
| 584 } | |
| 539 } | 585 } |
| 540 | 586 |
| 541 void WebSocketBasicHandshakeStream::OnFinishOpeningHandshake() { | 587 void WebSocketBasicHandshakeStream::OnFinishOpeningHandshake() { |
| 542 DCHECK(http_response_info_); | 588 DCHECK(http_response_info_); |
| 543 WebSocketDispatchOnFinishOpeningHandshake(connect_delegate_, | 589 WebSocketDispatchOnFinishOpeningHandshake(connect_delegate_, |
| 544 url_, | 590 url_, |
| 545 http_response_info_->headers, | 591 http_response_info_->headers, |
| 546 http_response_info_->response_time); | 592 http_response_info_->response_time); |
| 547 } | 593 } |
| 548 | 594 |
| 549 int WebSocketBasicHandshakeStream::ValidateResponse(int rv) { | 595 int WebSocketBasicHandshakeStream::ValidateResponse(int rv, |
| 596 bool* is_redirect) { | |
| 550 DCHECK(http_response_info_); | 597 DCHECK(http_response_info_); |
| 598 *is_redirect = false; | |
| 551 // Most net errors happen during connection, so they are not seen by this | 599 // Most net errors happen during connection, so they are not seen by this |
| 552 // method. The histogram for error codes is created in | 600 // method. The histogram for error codes is created in |
| 553 // Delegate::OnResponseStarted in websocket_stream.cc instead. | 601 // Delegate::OnResponseStarted in websocket_stream.cc instead. |
| 554 if (rv >= 0) { | 602 if (rv >= 0) { |
| 555 const HttpResponseHeaders* headers = http_response_info_->headers.get(); | 603 const HttpResponseHeaders* headers = http_response_info_->headers.get(); |
| 556 const int response_code = headers->response_code(); | 604 const int response_code = headers->response_code(); |
| 605 *is_redirect = HttpResponseHeaders::IsRedirectResponseCode(response_code); | |
| 557 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.WebSocket.ResponseCode", response_code); | 606 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.WebSocket.ResponseCode", response_code); |
| 558 switch (response_code) { | 607 switch (response_code) { |
| 559 case HTTP_SWITCHING_PROTOCOLS: | 608 case HTTP_SWITCHING_PROTOCOLS: |
| 560 OnFinishOpeningHandshake(); | 609 OnFinishOpeningHandshake(); |
| 561 return ValidateUpgradeResponse(headers); | 610 return ValidateUpgradeResponse(headers); |
| 562 | 611 |
| 563 // We need to pass these through for authentication to work. | 612 // We need to pass these through for authentication to work. |
| 564 case HTTP_UNAUTHORIZED: | 613 case HTTP_UNAUTHORIZED: |
| 565 case HTTP_PROXY_AUTHENTICATION_REQUIRED: | 614 case HTTP_PROXY_AUTHENTICATION_REQUIRED: |
| 566 return OK; | 615 return OK; |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 618 set_failure_message("Error during WebSocket handshake: " + failure_message); | 667 set_failure_message("Error during WebSocket handshake: " + failure_message); |
| 619 return ERR_INVALID_RESPONSE; | 668 return ERR_INVALID_RESPONSE; |
| 620 } | 669 } |
| 621 | 670 |
| 622 void WebSocketBasicHandshakeStream::set_failure_message( | 671 void WebSocketBasicHandshakeStream::set_failure_message( |
| 623 const std::string& failure_message) { | 672 const std::string& failure_message) { |
| 624 *failure_message_ = failure_message; | 673 *failure_message_ = failure_message; |
| 625 } | 674 } |
| 626 | 675 |
| 627 } // namespace net | 676 } // namespace net |
| OLD | NEW |