Fix infinite recursion on hiding panel when created during fullscreen mode.
[chromium-blink-merge.git] / net / websockets / websocket_stream.cc
blob48135d16f2ae8a84d5ee3ae1cbafb04ad046b933
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
3 // found in the LICENSE file.
5 #include "net/websockets/websocket_stream.h"
7 #include "base/logging.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "net/http/http_request_headers.h"
10 #include "net/http/http_status_code.h"
11 #include "net/url_request/url_request.h"
12 #include "net/url_request/url_request_context.h"
13 #include "net/websockets/websocket_errors.h"
14 #include "net/websockets/websocket_handshake_constants.h"
15 #include "net/websockets/websocket_handshake_stream_base.h"
16 #include "net/websockets/websocket_handshake_stream_create_helper.h"
17 #include "net/websockets/websocket_test_util.h"
18 #include "url/gurl.h"
19 #include "url/origin.h"
21 namespace net {
22 namespace {
24 class StreamRequestImpl;
26 class Delegate : public URLRequest::Delegate {
27 public:
28 explicit Delegate(StreamRequestImpl* owner) : owner_(owner) {}
29 virtual ~Delegate() {}
31 // Implementation of URLRequest::Delegate methods.
32 virtual void OnResponseStarted(URLRequest* request) OVERRIDE;
34 virtual void OnAuthRequired(URLRequest* request,
35 AuthChallengeInfo* auth_info) OVERRIDE;
37 virtual void OnCertificateRequested(URLRequest* request,
38 SSLCertRequestInfo* cert_request_info)
39 OVERRIDE;
41 virtual void OnSSLCertificateError(URLRequest* request,
42 const SSLInfo& ssl_info,
43 bool fatal) OVERRIDE;
45 virtual void OnReadCompleted(URLRequest* request, int bytes_read) OVERRIDE;
47 private:
48 StreamRequestImpl* owner_;
51 class StreamRequestImpl : public WebSocketStreamRequest {
52 public:
53 StreamRequestImpl(
54 const GURL& url,
55 const URLRequestContext* context,
56 scoped_ptr<WebSocketStream::ConnectDelegate> connect_delegate,
57 WebSocketHandshakeStreamCreateHelper* create_helper)
58 : delegate_(new Delegate(this)),
59 url_request_(url, DEFAULT_PRIORITY, delegate_.get(), context),
60 connect_delegate_(connect_delegate.Pass()),
61 create_helper_(create_helper) {}
63 // Destroying this object destroys the URLRequest, which cancels the request
64 // and so terminates the handshake if it is incomplete.
65 virtual ~StreamRequestImpl() {}
67 URLRequest* url_request() { return &url_request_; }
69 void PerformUpgrade() {
70 connect_delegate_->OnSuccess(create_helper_->stream()->Upgrade());
73 void ReportFailure() {
74 std::string failure_message;
75 if (create_helper_->stream()) {
76 failure_message = create_helper_->stream()->GetFailureMessage();
77 } else {
78 switch (url_request_.status().status()) {
79 case URLRequestStatus::SUCCESS:
80 case URLRequestStatus::IO_PENDING:
81 break;
82 case URLRequestStatus::CANCELED:
83 failure_message = "WebSocket opening handshake was canceled";
84 break;
85 case URLRequestStatus::FAILED:
86 failure_message =
87 std::string("Error in connection establishment: ") +
88 ErrorToString(url_request_.status().error());
89 break;
92 connect_delegate_->OnFailure(failure_message);
95 private:
96 // |delegate_| needs to be declared before |url_request_| so that it gets
97 // initialised first.
98 scoped_ptr<Delegate> delegate_;
100 // Deleting the StreamRequestImpl object deletes this URLRequest object,
101 // cancelling the whole connection.
102 URLRequest url_request_;
104 scoped_ptr<WebSocketStream::ConnectDelegate> connect_delegate_;
106 // Owned by the URLRequest.
107 WebSocketHandshakeStreamCreateHelper* create_helper_;
110 void Delegate::OnResponseStarted(URLRequest* request) {
111 switch (request->GetResponseCode()) {
112 case HTTP_SWITCHING_PROTOCOLS:
113 owner_->PerformUpgrade();
114 return;
116 case HTTP_UNAUTHORIZED:
117 case HTTP_PROXY_AUTHENTICATION_REQUIRED:
118 return;
120 default:
121 owner_->ReportFailure();
125 void Delegate::OnAuthRequired(URLRequest* request,
126 AuthChallengeInfo* auth_info) {
127 request->CancelAuth();
130 void Delegate::OnCertificateRequested(URLRequest* request,
131 SSLCertRequestInfo* cert_request_info) {
132 request->ContinueWithCertificate(NULL);
135 void Delegate::OnSSLCertificateError(URLRequest* request,
136 const SSLInfo& ssl_info,
137 bool fatal) {
138 request->Cancel();
141 void Delegate::OnReadCompleted(URLRequest* request, int bytes_read) {
142 NOTREACHED();
145 // Internal implementation of CreateAndConnectStream and
146 // CreateAndConnectStreamForTesting.
147 scoped_ptr<WebSocketStreamRequest> CreateAndConnectStreamWithCreateHelper(
148 const GURL& socket_url,
149 scoped_ptr<WebSocketHandshakeStreamCreateHelper> create_helper,
150 const url::Origin& origin,
151 URLRequestContext* url_request_context,
152 const BoundNetLog& net_log,
153 scoped_ptr<WebSocketStream::ConnectDelegate> connect_delegate) {
154 scoped_ptr<StreamRequestImpl> request(
155 new StreamRequestImpl(socket_url,
156 url_request_context,
157 connect_delegate.Pass(),
158 create_helper.get()));
159 HttpRequestHeaders headers;
160 headers.SetHeader(websockets::kUpgrade, websockets::kWebSocketLowercase);
161 headers.SetHeader(HttpRequestHeaders::kConnection, websockets::kUpgrade);
162 headers.SetHeader(HttpRequestHeaders::kOrigin, origin.string());
163 headers.SetHeader(websockets::kSecWebSocketVersion,
164 websockets::kSupportedVersion);
165 request->url_request()->SetExtraRequestHeaders(headers);
166 request->url_request()->SetUserData(
167 WebSocketHandshakeStreamBase::CreateHelper::DataKey(),
168 create_helper.release());
169 request->url_request()->SetLoadFlags(LOAD_DISABLE_CACHE |
170 LOAD_BYPASS_CACHE |
171 LOAD_DO_NOT_PROMPT_FOR_LOGIN);
172 request->url_request()->Start();
173 return request.PassAs<WebSocketStreamRequest>();
176 } // namespace
178 WebSocketStreamRequest::~WebSocketStreamRequest() {}
180 WebSocketStream::WebSocketStream() {}
181 WebSocketStream::~WebSocketStream() {}
183 WebSocketStream::ConnectDelegate::~ConnectDelegate() {}
185 scoped_ptr<WebSocketStreamRequest> WebSocketStream::CreateAndConnectStream(
186 const GURL& socket_url,
187 const std::vector<std::string>& requested_subprotocols,
188 const url::Origin& origin,
189 URLRequestContext* url_request_context,
190 const BoundNetLog& net_log,
191 scoped_ptr<ConnectDelegate> connect_delegate) {
192 scoped_ptr<WebSocketHandshakeStreamCreateHelper> create_helper(
193 new WebSocketHandshakeStreamCreateHelper(connect_delegate.get(),
194 requested_subprotocols));
195 return CreateAndConnectStreamWithCreateHelper(socket_url,
196 create_helper.Pass(),
197 origin,
198 url_request_context,
199 net_log,
200 connect_delegate.Pass());
203 // This is declared in websocket_test_util.h.
204 scoped_ptr<WebSocketStreamRequest> CreateAndConnectStreamForTesting(
205 const GURL& socket_url,
206 scoped_ptr<WebSocketHandshakeStreamCreateHelper> create_helper,
207 const url::Origin& origin,
208 URLRequestContext* url_request_context,
209 const BoundNetLog& net_log,
210 scoped_ptr<WebSocketStream::ConnectDelegate> connect_delegate) {
211 return CreateAndConnectStreamWithCreateHelper(socket_url,
212 create_helper.Pass(),
213 origin,
214 url_request_context,
215 net_log,
216 connect_delegate.Pass());
219 } // namespace net