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 <memory> | 7 #include <memory> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
54 ~Delegate() override { | 54 ~Delegate() override { |
55 UMA_HISTOGRAM_ENUMERATION( | 55 UMA_HISTOGRAM_ENUMERATION( |
56 "Net.WebSocket.HandshakeResult", result_, NUM_HANDSHAKE_RESULT_TYPES); | 56 "Net.WebSocket.HandshakeResult", result_, NUM_HANDSHAKE_RESULT_TYPES); |
57 } | 57 } |
58 | 58 |
59 // Implementation of URLRequest::Delegate methods. | 59 // Implementation of URLRequest::Delegate methods. |
60 void OnReceivedRedirect(URLRequest* request, | 60 void OnReceivedRedirect(URLRequest* request, |
61 const RedirectInfo& redirect_info, | 61 const RedirectInfo& redirect_info, |
62 bool* defer_redirect) override; | 62 bool* defer_redirect) override; |
63 | 63 |
64 void OnResponseStarted(URLRequest* request) override; | 64 void OnResponseStarted(URLRequest* request, int net_error) override; |
65 | 65 |
66 void OnAuthRequired(URLRequest* request, | 66 void OnAuthRequired(URLRequest* request, |
67 AuthChallengeInfo* auth_info) override; | 67 AuthChallengeInfo* auth_info) override; |
68 | 68 |
69 void OnCertificateRequested(URLRequest* request, | 69 void OnCertificateRequested(URLRequest* request, |
70 SSLCertRequestInfo* cert_request_info) override; | 70 SSLCertRequestInfo* cert_request_info) override; |
71 | 71 |
72 void OnSSLCertificateError(URLRequest* request, | 72 void OnSSLCertificateError(URLRequest* request, |
73 const SSLInfo& ssl_info, | 73 const SSLInfo& ssl_info, |
74 bool fatal) override; | 74 bool fatal) override; |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
146 DCHECK(timer_); | 146 DCHECK(timer_); |
147 DCHECK(handshake_stream_); | 147 DCHECK(handshake_stream_); |
148 | 148 |
149 timer_->Stop(); | 149 timer_->Stop(); |
150 | 150 |
151 WebSocketHandshakeStreamBase* handshake_stream = handshake_stream_; | 151 WebSocketHandshakeStreamBase* handshake_stream = handshake_stream_; |
152 handshake_stream_ = nullptr; | 152 handshake_stream_ = nullptr; |
153 connect_delegate_->OnSuccess(handshake_stream->Upgrade()); | 153 connect_delegate_->OnSuccess(handshake_stream->Upgrade()); |
154 } | 154 } |
155 | 155 |
156 std::string FailureMessageFromNetError() { | 156 std::string FailureMessageFromNetError(int net_error) { |
157 int error = url_request_->status().error(); | 157 if (net_error == ERR_TUNNEL_CONNECTION_FAILED) { |
158 if (error == ERR_TUNNEL_CONNECTION_FAILED) { | |
159 // This error is common and confusing, so special-case it. | 158 // This error is common and confusing, so special-case it. |
160 // TODO(ricea): Include the HostPortPair of the selected proxy server in | 159 // TODO(ricea): Include the HostPortPair of the selected proxy server in |
161 // the error message. This is not currently possible because it isn't set | 160 // the error message. This is not currently possible because it isn't set |
162 // in HttpResponseInfo when a ERR_TUNNEL_CONNECTION_FAILED error happens. | 161 // in HttpResponseInfo when a ERR_TUNNEL_CONNECTION_FAILED error happens. |
163 return "Establishing a tunnel via proxy server failed."; | 162 return "Establishing a tunnel via proxy server failed."; |
164 } else { | 163 } else { |
165 return std::string("Error in connection establishment: ") + | 164 return std::string("Error in connection establishment: ") + |
166 ErrorToString(url_request_->status().error()); | 165 ErrorToString(net_error); |
167 } | 166 } |
168 } | 167 } |
169 | 168 |
170 void ReportFailure() { | 169 void ReportFailure(int net_error) { |
171 DCHECK(timer_); | 170 DCHECK(timer_); |
172 timer_->Stop(); | 171 timer_->Stop(); |
173 if (failure_message_.empty()) { | 172 if (failure_message_.empty()) { |
174 switch (url_request_->status().status()) { | 173 switch (net_error) { |
175 case URLRequestStatus::SUCCESS: | 174 case OK: |
176 case URLRequestStatus::IO_PENDING: | 175 case ERR_IO_PENDING: |
177 break; | 176 break; |
178 case URLRequestStatus::CANCELED: | 177 case ERR_ABORTED: |
179 if (url_request_->status().error() == ERR_TIMED_OUT) | 178 failure_message_ = "WebSocket opening handshake was canceled"; |
180 failure_message_ = "WebSocket opening handshake timed out"; | |
181 else | |
182 failure_message_ = "WebSocket opening handshake was canceled"; | |
183 break; | 179 break; |
184 case URLRequestStatus::FAILED: | 180 case ERR_TIMED_OUT: |
185 failure_message_ = FailureMessageFromNetError(); | 181 failure_message_ = "WebSocket opening handshake timed out"; |
| 182 break; |
| 183 default: |
| 184 failure_message_ = FailureMessageFromNetError(net_error); |
186 break; | 185 break; |
187 } | 186 } |
188 } | 187 } |
189 ReportFailureWithMessage(failure_message_); | 188 ReportFailureWithMessage(failure_message_); |
190 } | 189 } |
191 | 190 |
192 void ReportFailureWithMessage(const std::string& failure_message) { | 191 void ReportFailureWithMessage(const std::string& failure_message) { |
193 connect_delegate_->OnFailure(failure_message); | 192 connect_delegate_->OnFailure(failure_message); |
194 } | 193 } |
195 | 194 |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
275 if (redirect_info.new_method != "GET" || | 274 if (redirect_info.new_method != "GET" || |
276 redirect_info.new_url != expected_url) { | 275 redirect_info.new_url != expected_url) { |
277 // This should not happen. | 276 // This should not happen. |
278 DLOG(FATAL) << "Unauthorized WebSocket redirect to " | 277 DLOG(FATAL) << "Unauthorized WebSocket redirect to " |
279 << redirect_info.new_method << " " | 278 << redirect_info.new_method << " " |
280 << redirect_info.new_url.spec(); | 279 << redirect_info.new_url.spec(); |
281 request->Cancel(); | 280 request->Cancel(); |
282 } | 281 } |
283 } | 282 } |
284 | 283 |
285 void Delegate::OnResponseStarted(URLRequest* request) { | 284 void Delegate::OnResponseStarted(URLRequest* request, int net_error) { |
| 285 DCHECK_NE(ERR_IO_PENDING, net_error); |
286 // All error codes, including OK and ABORTED, as with | 286 // All error codes, including OK and ABORTED, as with |
287 // Net.ErrorCodesForMainFrame3 | 287 // Net.ErrorCodesForMainFrame3 |
288 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.WebSocket.ErrorCodes", | 288 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.WebSocket.ErrorCodes", -net_error); |
289 -request->status().error()); | 289 if (net_error != OK) { |
290 if (!request->status().is_success()) { | |
291 DVLOG(3) << "OnResponseStarted (request failed)"; | 290 DVLOG(3) << "OnResponseStarted (request failed)"; |
292 owner_->ReportFailure(); | 291 owner_->ReportFailure(net_error); |
293 return; | 292 return; |
294 } | 293 } |
295 const int response_code = request->GetResponseCode(); | 294 const int response_code = request->GetResponseCode(); |
296 DVLOG(3) << "OnResponseStarted (response code " << response_code << ")"; | 295 DVLOG(3) << "OnResponseStarted (response code " << response_code << ")"; |
297 switch (response_code) { | 296 switch (response_code) { |
298 case HTTP_SWITCHING_PROTOCOLS: | 297 case HTTP_SWITCHING_PROTOCOLS: |
299 result_ = CONNECTED; | 298 result_ = CONNECTED; |
300 owner_->PerformUpgrade(); | 299 owner_->PerformUpgrade(); |
301 return; | 300 return; |
302 | 301 |
303 case HTTP_UNAUTHORIZED: | 302 case HTTP_UNAUTHORIZED: |
304 result_ = FAILED; | 303 result_ = FAILED; |
305 owner_->OnFinishOpeningHandshake(); | 304 owner_->OnFinishOpeningHandshake(); |
306 owner_->ReportFailureWithMessage( | 305 owner_->ReportFailureWithMessage( |
307 "HTTP Authentication failed; no valid credentials available"); | 306 "HTTP Authentication failed; no valid credentials available"); |
308 return; | 307 return; |
309 | 308 |
310 case HTTP_PROXY_AUTHENTICATION_REQUIRED: | 309 case HTTP_PROXY_AUTHENTICATION_REQUIRED: |
311 result_ = FAILED; | 310 result_ = FAILED; |
312 owner_->OnFinishOpeningHandshake(); | 311 owner_->OnFinishOpeningHandshake(); |
313 owner_->ReportFailureWithMessage("Proxy authentication failed"); | 312 owner_->ReportFailureWithMessage("Proxy authentication failed"); |
314 return; | 313 return; |
315 | 314 |
316 default: | 315 default: |
317 result_ = FAILED; | 316 result_ = FAILED; |
318 owner_->ReportFailure(); | 317 owner_->ReportFailure(net_error); |
319 } | 318 } |
320 } | 319 } |
321 | 320 |
322 void Delegate::OnAuthRequired(URLRequest* request, | 321 void Delegate::OnAuthRequired(URLRequest* request, |
323 AuthChallengeInfo* auth_info) { | 322 AuthChallengeInfo* auth_info) { |
324 // This should only be called if credentials are not already stored. | 323 // This should only be called if credentials are not already stored. |
325 request->CancelAuth(); | 324 request->CancelAuth(); |
326 } | 325 } |
327 | 326 |
328 void Delegate::OnCertificateRequested(URLRequest* request, | 327 void Delegate::OnCertificateRequested(URLRequest* request, |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
404 DCHECK(connect_delegate); | 403 DCHECK(connect_delegate); |
405 if (headers.get()) { | 404 if (headers.get()) { |
406 connect_delegate->OnFinishOpeningHandshake( | 405 connect_delegate->OnFinishOpeningHandshake( |
407 base::WrapUnique(new WebSocketHandshakeResponseInfo( | 406 base::WrapUnique(new WebSocketHandshakeResponseInfo( |
408 url, headers->response_code(), headers->GetStatusText(), headers, | 407 url, headers->response_code(), headers->GetStatusText(), headers, |
409 response_time))); | 408 response_time))); |
410 } | 409 } |
411 } | 410 } |
412 | 411 |
413 } // namespace net | 412 } // namespace net |
OLD | NEW |