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 |