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_stream.h" | 5 #include "net/websockets/websocket_stream.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
9 #include "base/metrics/histogram.h" | 9 #include "base/metrics/histogram.h" |
10 #include "net/base/load_flags.h" | 10 #include "net/base/load_flags.h" |
11 #include "net/http/http_request_headers.h" | 11 #include "net/http/http_request_headers.h" |
12 #include "net/http/http_status_code.h" | 12 #include "net/http/http_status_code.h" |
13 #include "net/url_request/url_request.h" | 13 #include "net/url_request/url_request.h" |
14 #include "net/url_request/url_request_context.h" | 14 #include "net/url_request/url_request_context.h" |
15 #include "net/websockets/websocket_errors.h" | 15 #include "net/websockets/websocket_errors.h" |
| 16 #include "net/websockets/websocket_event_interface.h" |
16 #include "net/websockets/websocket_handshake_constants.h" | 17 #include "net/websockets/websocket_handshake_constants.h" |
17 #include "net/websockets/websocket_handshake_stream_base.h" | 18 #include "net/websockets/websocket_handshake_stream_base.h" |
18 #include "net/websockets/websocket_handshake_stream_create_helper.h" | 19 #include "net/websockets/websocket_handshake_stream_create_helper.h" |
19 #include "net/websockets/websocket_test_util.h" | 20 #include "net/websockets/websocket_test_util.h" |
20 #include "url/gurl.h" | 21 #include "url/gurl.h" |
21 #include "url/origin.h" | 22 #include "url/origin.h" |
22 | 23 |
23 namespace net { | 24 namespace net { |
24 namespace { | 25 namespace { |
25 | 26 |
26 class StreamRequestImpl; | 27 class StreamRequestImpl; |
27 | 28 |
28 class Delegate : public URLRequest::Delegate { | 29 class Delegate : public URLRequest::Delegate { |
29 public: | 30 public: |
30 enum HandshakeResult { | 31 enum HandshakeResult { |
31 INCOMPLETE, | 32 INCOMPLETE, |
32 CONNECTED, | 33 CONNECTED, |
33 FAILED, | 34 FAILED, |
34 NUM_HANDSHAKE_RESULT_TYPES, | 35 NUM_HANDSHAKE_RESULT_TYPES, |
35 }; | 36 }; |
36 | 37 |
37 explicit Delegate(StreamRequestImpl* owner) | 38 explicit Delegate(StreamRequestImpl* owner) |
38 : owner_(owner), result_(INCOMPLETE) {} | 39 : owner_(owner), result_(INCOMPLETE) {} |
39 virtual ~Delegate() { | 40 virtual ~Delegate() { |
40 UMA_HISTOGRAM_ENUMERATION( | 41 UMA_HISTOGRAM_ENUMERATION( |
41 "Net.WebSocket.HandshakeResult", result_, NUM_HANDSHAKE_RESULT_TYPES); | 42 "Net.WebSocket.HandshakeResult", result_, NUM_HANDSHAKE_RESULT_TYPES); |
42 } | 43 } |
43 | 44 |
44 // Implementation of URLRequest::Delegate methods. | 45 // Implementation of URLRequest::Delegate methods. |
| 46 virtual void OnReceivedRedirect(URLRequest* request, |
| 47 const GURL& new_url, |
| 48 bool* defer_redirect) OVERRIDE { |
| 49 // HTTP status codes returned by HttpStreamParser are filtered by |
| 50 // WebSocketBasicHandshakeStream, and only 101, 401 and 407 are permitted |
| 51 // back up the stack to HttpNetworkTransaction. In particular, redirect |
| 52 // codes are never allowed, and so URLRequest never sees a redirect on a |
| 53 // WebSocket request. |
| 54 NOTREACHED(); |
| 55 } |
| 56 |
45 virtual void OnResponseStarted(URLRequest* request) OVERRIDE; | 57 virtual void OnResponseStarted(URLRequest* request) OVERRIDE; |
46 | 58 |
47 virtual void OnAuthRequired(URLRequest* request, | 59 virtual void OnAuthRequired(URLRequest* request, |
48 AuthChallengeInfo* auth_info) OVERRIDE; | 60 AuthChallengeInfo* auth_info) OVERRIDE; |
49 | 61 |
50 virtual void OnCertificateRequested(URLRequest* request, | 62 virtual void OnCertificateRequested(URLRequest* request, |
51 SSLCertRequestInfo* cert_request_info) | 63 SSLCertRequestInfo* cert_request_info) |
52 OVERRIDE; | 64 OVERRIDE; |
53 | 65 |
54 virtual void OnSSLCertificateError(URLRequest* request, | 66 virtual void OnSSLCertificateError(URLRequest* request, |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
118 case URLRequestStatus::FAILED: | 130 case URLRequestStatus::FAILED: |
119 failure_message = | 131 failure_message = |
120 std::string("Error in connection establishment: ") + | 132 std::string("Error in connection establishment: ") + |
121 ErrorToString(url_request_.status().error()); | 133 ErrorToString(url_request_.status().error()); |
122 break; | 134 break; |
123 } | 135 } |
124 } | 136 } |
125 connect_delegate_->OnFailure(failure_message); | 137 connect_delegate_->OnFailure(failure_message); |
126 } | 138 } |
127 | 139 |
| 140 WebSocketStream::ConnectDelegate* connect_delegate() const { |
| 141 return connect_delegate_.get(); |
| 142 } |
| 143 |
128 private: | 144 private: |
129 // |delegate_| needs to be declared before |url_request_| so that it gets | 145 // |delegate_| needs to be declared before |url_request_| so that it gets |
130 // initialised first. | 146 // initialised first. |
131 scoped_ptr<Delegate> delegate_; | 147 scoped_ptr<Delegate> delegate_; |
132 | 148 |
133 // Deleting the StreamRequestImpl object deletes this URLRequest object, | 149 // Deleting the StreamRequestImpl object deletes this URLRequest object, |
134 // cancelling the whole connection. | 150 // cancelling the whole connection. |
135 URLRequest url_request_; | 151 URLRequest url_request_; |
136 | 152 |
137 scoped_ptr<WebSocketStream::ConnectDelegate> connect_delegate_; | 153 scoped_ptr<WebSocketStream::ConnectDelegate> connect_delegate_; |
138 | 154 |
139 // Owned by the URLRequest. | 155 // Owned by the URLRequest. |
140 WebSocketHandshakeStreamCreateHelper* create_helper_; | 156 WebSocketHandshakeStreamCreateHelper* create_helper_; |
141 }; | 157 }; |
142 | 158 |
| 159 class SSLErrorCallbacks : public WebSocketEventInterface::SSLErrorCallbacks { |
| 160 public: |
| 161 explicit SSLErrorCallbacks(URLRequest* url_request) |
| 162 : url_request_(url_request) {} |
| 163 |
| 164 virtual void CancelSSLRequest(int error, const SSLInfo* ssl_info) OVERRIDE { |
| 165 if (ssl_info) { |
| 166 url_request_->CancelWithSSLError(error, *ssl_info); |
| 167 } else { |
| 168 url_request_->CancelWithError(error); |
| 169 } |
| 170 } |
| 171 |
| 172 virtual void ContinueSSLRequest() OVERRIDE { |
| 173 url_request_->ContinueDespiteLastError(); |
| 174 } |
| 175 |
| 176 private: |
| 177 URLRequest* url_request_; |
| 178 }; |
| 179 |
143 void Delegate::OnResponseStarted(URLRequest* request) { | 180 void Delegate::OnResponseStarted(URLRequest* request) { |
| 181 if (!request->status().is_success()) { |
| 182 DVLOG(3) << "OnResponseStarted (request failed)"; |
| 183 owner_->ReportFailure(); |
| 184 return; |
| 185 } |
| 186 DVLOG(3) << "OnResponseStarted (response code " << request->GetResponseCode() |
| 187 << ")"; |
144 switch (request->GetResponseCode()) { | 188 switch (request->GetResponseCode()) { |
145 case HTTP_SWITCHING_PROTOCOLS: | 189 case HTTP_SWITCHING_PROTOCOLS: |
146 result_ = CONNECTED; | 190 result_ = CONNECTED; |
147 owner_->PerformUpgrade(); | 191 owner_->PerformUpgrade(); |
148 return; | 192 return; |
149 | 193 |
150 case HTTP_UNAUTHORIZED: | 194 case HTTP_UNAUTHORIZED: |
151 case HTTP_PROXY_AUTHENTICATION_REQUIRED: | 195 case HTTP_PROXY_AUTHENTICATION_REQUIRED: |
152 return; | 196 return; |
153 | 197 |
154 default: | 198 default: |
155 result_ = FAILED; | 199 result_ = FAILED; |
156 owner_->ReportFailure(); | 200 owner_->ReportFailure(); |
157 } | 201 } |
158 } | 202 } |
159 | 203 |
160 void Delegate::OnAuthRequired(URLRequest* request, | 204 void Delegate::OnAuthRequired(URLRequest* request, |
161 AuthChallengeInfo* auth_info) { | 205 AuthChallengeInfo* auth_info) { |
| 206 // This should only be called if credentials are not already stored. |
162 request->CancelAuth(); | 207 request->CancelAuth(); |
163 } | 208 } |
164 | 209 |
165 void Delegate::OnCertificateRequested(URLRequest* request, | 210 void Delegate::OnCertificateRequested(URLRequest* request, |
166 SSLCertRequestInfo* cert_request_info) { | 211 SSLCertRequestInfo* cert_request_info) { |
167 request->ContinueWithCertificate(NULL); | 212 // This method is called when a client certificate is requested, and the |
| 213 // request context does not already contain a client certificate selection for |
| 214 // the endpoint. In this case, a main frame resource request would pop-up UI |
| 215 // to permit selection of a client certificate, but since WebSockets are |
| 216 // sub-resources they should not pop-up UI and so there is nothing more we can |
| 217 // do. |
| 218 request->Cancel(); |
168 } | 219 } |
169 | 220 |
170 void Delegate::OnSSLCertificateError(URLRequest* request, | 221 void Delegate::OnSSLCertificateError(URLRequest* request, |
171 const SSLInfo& ssl_info, | 222 const SSLInfo& ssl_info, |
172 bool fatal) { | 223 bool fatal) { |
173 request->Cancel(); | 224 owner_->connect_delegate()->OnSSLCertificateError( |
| 225 scoped_ptr<WebSocketEventInterface::SSLErrorCallbacks>( |
| 226 new SSLErrorCallbacks(request)), |
| 227 ssl_info, |
| 228 fatal); |
174 } | 229 } |
175 | 230 |
176 void Delegate::OnReadCompleted(URLRequest* request, int bytes_read) { | 231 void Delegate::OnReadCompleted(URLRequest* request, int bytes_read) { |
177 NOTREACHED(); | 232 NOTREACHED(); |
178 } | 233 } |
179 | 234 |
180 } // namespace | 235 } // namespace |
181 | 236 |
182 WebSocketStreamRequest::~WebSocketStreamRequest() {} | 237 WebSocketStreamRequest::~WebSocketStreamRequest() {} |
183 | 238 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
218 new StreamRequestImpl(socket_url, | 273 new StreamRequestImpl(socket_url, |
219 url_request_context, | 274 url_request_context, |
220 origin, | 275 origin, |
221 connect_delegate.Pass(), | 276 connect_delegate.Pass(), |
222 create_helper.Pass())); | 277 create_helper.Pass())); |
223 request->Start(); | 278 request->Start(); |
224 return request.PassAs<WebSocketStreamRequest>(); | 279 return request.PassAs<WebSocketStreamRequest>(); |
225 } | 280 } |
226 | 281 |
227 } // namespace net | 282 } // namespace net |
OLD | NEW |