Index: net/websockets/websocket_stream.cc |
diff --git a/net/websockets/websocket_stream.cc b/net/websockets/websocket_stream.cc |
index 1bd6640ed3fbc79c03ca56275ffc93df8d3e850c..065c0ffcadfce871ae03f9c624a52087d5a613f6 100644 |
--- a/net/websockets/websocket_stream.cc |
+++ b/net/websockets/websocket_stream.cc |
@@ -8,6 +8,8 @@ |
#include "base/memory/scoped_ptr.h" |
#include "base/metrics/histogram.h" |
#include "base/metrics/sparse_histogram.h" |
+#include "base/time/time.h" |
+#include "base/timer/timer.h" |
#include "net/base/load_flags.h" |
#include "net/http/http_request_headers.h" |
#include "net/http/http_response_headers.h" |
@@ -112,22 +114,35 @@ class StreamRequestImpl : public WebSocketStreamRequest { |
// and so terminates the handshake if it is incomplete. |
virtual ~StreamRequestImpl() {} |
- void Start() { |
+ void Start(scoped_ptr<base::Timer> timer) { |
+ const TimeDelta timeout = TimeDelta::FromMinutes(1); |
Adam Rice
2014/09/11 07:52:42
The timeout should be defined as a constant at the
yhirano
2014/09/11 08:45:36
Done.
|
+ DCHECK(timer); |
+ timer_ = timer.Pass(); |
+ timer_->Start(FROM_HERE, timeout, |
+ base::Bind(&StreamRequestImpl::OnTimeout, |
+ base::Unretained(this))); |
url_request_->Start(); |
} |
void PerformUpgrade() { |
+ DCHECK(timer_); |
+ timer_->Stop(); |
connect_delegate_->OnSuccess(create_helper_->Upgrade()); |
} |
void ReportFailure() { |
+ DCHECK(timer_); |
+ timer_->Stop(); |
if (failure_message_.empty()) { |
switch (url_request_->status().status()) { |
case URLRequestStatus::SUCCESS: |
case URLRequestStatus::IO_PENDING: |
break; |
case URLRequestStatus::CANCELED: |
- failure_message_ = "WebSocket opening handshake was canceled"; |
+ if (url_request_->status().error() == ERR_TIMED_OUT) |
+ failure_message_ = "WebSocket opening handshake timed out"; |
+ else |
+ failure_message_ = "WebSocket opening handshake was canceled"; |
break; |
case URLRequestStatus::FAILED: |
failure_message_ = |
@@ -154,6 +169,10 @@ class StreamRequestImpl : public WebSocketStreamRequest { |
return connect_delegate_.get(); |
} |
+ void OnTimeout() { |
+ url_request_->CancelWithError(ERR_TIMED_OUT); |
+ } |
+ |
private: |
// |delegate_| needs to be declared before |url_request_| so that it gets |
// initialised first. |
@@ -170,6 +189,9 @@ class StreamRequestImpl : public WebSocketStreamRequest { |
// The failure message supplied by WebSocketBasicHandshakeStream, if any. |
std::string failure_message_; |
+ |
+ // A timer for handshake timeout. |
+ scoped_ptr<base::Timer> timer_; |
}; |
class SSLErrorCallbacks : public WebSocketEventInterface::SSLErrorCallbacks { |
@@ -286,7 +308,7 @@ scoped_ptr<WebSocketStreamRequest> WebSocketStream::CreateAndConnectStream( |
origin, |
connect_delegate.Pass(), |
create_helper.Pass())); |
- request->Start(); |
+ request->Start(scoped_ptr<base::Timer>(new base::Timer(false, false))); |
return request.PassAs<WebSocketStreamRequest>(); |
} |
@@ -297,14 +319,15 @@ scoped_ptr<WebSocketStreamRequest> CreateAndConnectStreamForTesting( |
const url::Origin& origin, |
URLRequestContext* url_request_context, |
const BoundNetLog& net_log, |
- scoped_ptr<WebSocketStream::ConnectDelegate> connect_delegate) { |
+ scoped_ptr<WebSocketStream::ConnectDelegate> connect_delegate, |
+ scoped_ptr<base::Timer> timer) { |
scoped_ptr<StreamRequestImpl> request( |
new StreamRequestImpl(socket_url, |
url_request_context, |
origin, |
connect_delegate.Pass(), |
create_helper.Pass())); |
- request->Start(); |
+ request->Start(timer.Pass()); |
return request.PassAs<WebSocketStreamRequest>(); |
} |