Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 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 #import "ios/net/crn_http_protocol_handler.h" | 5 #import "ios/net/crn_http_protocol_handler.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <memory> | 9 #include <memory> |
| 10 #include <utility> | 10 #include <utility> |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 143 void OnReceivedRedirect(URLRequest* request, | 143 void OnReceivedRedirect(URLRequest* request, |
| 144 const RedirectInfo& new_url, | 144 const RedirectInfo& new_url, |
| 145 bool* defer_redirect) override; | 145 bool* defer_redirect) override; |
| 146 void OnAuthRequired(URLRequest* request, | 146 void OnAuthRequired(URLRequest* request, |
| 147 AuthChallengeInfo* auth_info) override; | 147 AuthChallengeInfo* auth_info) override; |
| 148 void OnCertificateRequested(URLRequest* request, | 148 void OnCertificateRequested(URLRequest* request, |
| 149 SSLCertRequestInfo* cert_request_info) override; | 149 SSLCertRequestInfo* cert_request_info) override; |
| 150 void OnSSLCertificateError(URLRequest* request, | 150 void OnSSLCertificateError(URLRequest* request, |
| 151 const SSLInfo& ssl_info, | 151 const SSLInfo& ssl_info, |
| 152 bool fatal) override; | 152 bool fatal) override; |
| 153 void OnResponseStarted(URLRequest* request) override; | 153 void OnResponseStarted(URLRequest* request, int net_error) override; |
| 154 void OnReadCompleted(URLRequest* request, int bytes_read) override; | 154 void OnReadCompleted(URLRequest* request, int bytes_read) override; |
| 155 | 155 |
| 156 private: | 156 private: |
| 157 friend class base::RefCountedThreadSafe<HttpProtocolHandlerCore, | 157 friend class base::RefCountedThreadSafe<HttpProtocolHandlerCore, |
| 158 HttpProtocolHandlerCore>; | 158 HttpProtocolHandlerCore>; |
| 159 friend class base::DeleteHelper<HttpProtocolHandlerCore>; | 159 friend class base::DeleteHelper<HttpProtocolHandlerCore>; |
| 160 ~HttpProtocolHandlerCore() override; | 160 ~HttpProtocolHandlerCore() override; |
| 161 | 161 |
| 162 // RefCountedThreadSafe traits implementation: | 162 // RefCountedThreadSafe traits implementation: |
| 163 static void Destruct(const HttpProtocolHandlerCore* x); | 163 static void Destruct(const HttpProtocolHandlerCore* x); |
| (...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 446 } else { | 446 } else { |
| 447 // The tracker will decide, eventually asking the user, and will invoke the | 447 // The tracker will decide, eventually asking the user, and will invoke the |
| 448 // callback. | 448 // callback. |
| 449 RequestTracker::SSLCallback callback = | 449 RequestTracker::SSLCallback callback = |
| 450 base::Bind(&HttpProtocolHandlerCore::SSLErrorCallback, this); | 450 base::Bind(&HttpProtocolHandlerCore::SSLErrorCallback, this); |
| 451 DCHECK(tracker_); | 451 DCHECK(tracker_); |
| 452 tracker_->OnSSLCertificateError(request, ssl_info, !fatal, callback); | 452 tracker_->OnSSLCertificateError(request, ssl_info, !fatal, callback); |
| 453 } | 453 } |
| 454 } | 454 } |
| 455 | 455 |
| 456 void HttpProtocolHandlerCore::OnResponseStarted(URLRequest* request) { | 456 void HttpProtocolHandlerCore::OnResponseStarted(URLRequest* request, |
| 457 int net_error) { | |
| 457 DCHECK(thread_checker_.CalledOnValidThread()); | 458 DCHECK(thread_checker_.CalledOnValidThread()); |
| 459 DCHECK_NE(net::ERR_IO_PENDING, net_error); | |
| 458 | 460 |
| 459 if (net_request_ == nullptr) | 461 if (net_request_ == nullptr) |
| 460 return; | 462 return; |
| 461 | 463 |
| 462 const URLRequestStatus& status = request->status(); | 464 if (net_error != net::OK) { |
| 463 if (!status.is_success()) { | 465 StopRequestWithError(IOSErrorCode(net_error), net_error); |
| 464 int error = status.error(); | |
| 465 StopRequestWithError(IOSErrorCode(error), error); | |
| 466 return; | 466 return; |
| 467 } | 467 } |
| 468 | 468 |
| 469 if (tracker_ && IsCertStatusError(request->ssl_info().cert_status) && | 469 if (tracker_ && IsCertStatusError(request->ssl_info().cert_status) && |
| 470 !request->context()->GetNetworkSessionParams()-> | 470 !request->context()->GetNetworkSessionParams()-> |
| 471 ignore_certificate_errors) { | 471 ignore_certificate_errors) { |
| 472 // The certificate policy cache is captured here because SSL errors do not | 472 // The certificate policy cache is captured here because SSL errors do not |
| 473 // always trigger OnSSLCertificateError (this is the case when a page comes | 473 // always trigger OnSSLCertificateError (this is the case when a page comes |
| 474 // from the HTTP cache). | 474 // from the HTTP cache). |
| 475 RequestTracker::SSLCallback callback = | 475 RequestTracker::SSLCallback callback = |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 500 | 500 |
| 501 // Add clients from tracker. | 501 // Add clients from tracker. |
| 502 PushClients( | 502 PushClients( |
| 503 tracker_->ClientsHandlingRequestAndResponse(*net_request_, response)); | 503 tracker_->ClientsHandlingRequestAndResponse(*net_request_, response)); |
| 504 } | 504 } |
| 505 | 505 |
| 506 // Don't call any function on the response from now on, as the client may be | 506 // Don't call any function on the response from now on, as the client may be |
| 507 // using it and the object is not re-entrant. | 507 // using it and the object is not re-entrant. |
| 508 [top_level_client_ didReceiveResponse:response]; | 508 [top_level_client_ didReceiveResponse:response]; |
| 509 | 509 |
| 510 int bytes_read = 0; | 510 int bytes_read = net_request_->Read(buffer_.get(), kIOBufferSize); |
| 511 if (bytes_read == net::ERR_IO_PENDING) | |
| 512 return; | |
| 511 | 513 |
| 512 if (net_request_->Read(buffer_.get(), kIOBufferSize, &bytes_read)) { | 514 if (bytes_read >= 0) { |
| 513 OnReadCompleted(net_request_, bytes_read); | 515 OnReadCompleted(net_request_, bytes_read); |
| 514 } else if (!net_request_->status().is_success()) { | 516 } else { |
| 515 int error = net_request_->status().error(); | 517 int error = bytes_read; |
| 516 StopRequestWithError(IOSErrorCode(error), error); | 518 StopRequestWithError(IOSErrorCode(error), error); |
| 517 } | 519 } |
| 518 } | 520 } |
| 519 | 521 |
| 520 void HttpProtocolHandlerCore::OnReadCompleted(URLRequest* request, | 522 void HttpProtocolHandlerCore::OnReadCompleted(URLRequest* request, |
| 521 int bytes_read) { | 523 int bytes_read) { |
| 524 DCHECK_NE(net::ERR_IO_PENDING, bytes_read); | |
| 522 DCHECK(thread_checker_.CalledOnValidThread()); | 525 DCHECK(thread_checker_.CalledOnValidThread()); |
| 523 | 526 |
| 524 if (net_request_ == nullptr) | 527 if (net_request_ == nullptr) |
| 525 return; | 528 return; |
| 526 | 529 |
| 527 base::scoped_nsobject<NSMutableData> data([[NSMutableData alloc] init]); | 530 base::scoped_nsobject<NSMutableData> data([[NSMutableData alloc] init]); |
| 528 | 531 |
| 529 // Read all we can from the socket and put it into data. | 532 // Read all we can from the socket and put it into data. |
| 530 // TODO(droger): It may be possible to avoid some of the copies (using | 533 // TODO(droger): It may be possible to avoid some of the copies (using |
| 531 // WrappedIOBuffer for example). | 534 // WrappedIOBuffer for example). |
| 532 NSUInteger data_length; | 535 NSUInteger data_length; |
| 533 bool loop = (bytes_read > 0); | 536 uint64_t total_byte_read = 0; |
| 534 bool io_pending = false; | 537 while (bytes_read > 0) { |
| 535 uint64_t total_byte_read = loop ? bytes_read : 0; | 538 total_byte_read += bytes_read; |
| 536 while (loop) { | |
| 537 data_length = [data length]; // Assumes that getting the length is fast. | 539 data_length = [data length]; // Assumes that getting the length is fast. |
| 538 [data increaseLengthBy:bytes_read]; | 540 [data increaseLengthBy:bytes_read]; |
| 539 memcpy(reinterpret_cast<char*>([data mutableBytes]) + data_length, | 541 memcpy(reinterpret_cast<char*>([data mutableBytes]) + data_length, |
| 540 buffer_->data(), bytes_read); | 542 buffer_->data(), bytes_read); |
| 541 io_pending = !request->Read(buffer_.get(), kIOBufferSize, &bytes_read); | 543 request->Read(buffer_.get(), kIOBufferSize, &bytes_read); |
|
droger
2016/09/05 09:21:31
Do you want to update this call too?
maksims (do not use this acc)
2016/09/05 10:39:12
Yes.
https://codereview.chromium.org/2262653003/d
| |
| 542 loop = !io_pending && (bytes_read > 0); | |
| 543 total_byte_read += bytes_read; | |
| 544 } | 544 } |
| 545 | 545 |
| 546 if (tracker_) | 546 if (tracker_) |
| 547 tracker_->CaptureReceivedBytes(request, total_byte_read); | 547 tracker_->CaptureReceivedBytes(request, total_byte_read); |
| 548 | 548 |
| 549 // Notify the client. | 549 // Notify the client. |
| 550 const URLRequestStatus& status = request->status(); | 550 if (bytes_read == net::OK || bytes_read == net::ERR_IO_PENDING) { |
| 551 if (status.is_success()) { | |
| 552 if ([data length] > 0) { | 551 if ([data length] > 0) { |
| 553 // If the data is not encoded in UTF8, the NSString is nil. | 552 // If the data is not encoded in UTF8, the NSString is nil. |
| 554 DVLOG(3) << "To client:" << std::endl | 553 DVLOG(3) << "To client:" << std::endl |
| 555 << base::SysNSStringToUTF8([[[NSString alloc] | 554 << base::SysNSStringToUTF8([[[NSString alloc] |
| 556 initWithData:data | 555 initWithData:data |
| 557 encoding:NSUTF8StringEncoding] autorelease]); | 556 encoding:NSUTF8StringEncoding] autorelease]); |
| 558 [top_level_client_ didLoadData:data]; | 557 [top_level_client_ didLoadData:data]; |
| 559 } | 558 } |
| 560 if (bytes_read == 0 && !io_pending) { | 559 if (bytes_read == 0) { |
| 561 DCHECK_EQ(net_request_, request); | 560 DCHECK_EQ(net_request_, request); |
| 562 // There is nothing more to read. | 561 // There is nothing more to read. |
| 563 StopNetRequest(); | 562 StopNetRequest(); |
| 564 [top_level_client_ didFinishLoading]; | 563 [top_level_client_ didFinishLoading]; |
| 565 } | 564 } |
| 566 } else { | 565 } else { |
| 567 // Request failed (not canceled). | 566 // Request failed (not canceled). |
| 568 int error = status.error(); | 567 int error = bytes_read; |
| 569 StopRequestWithError(IOSErrorCode(error), error); | 568 StopRequestWithError(IOSErrorCode(error), error); |
| 570 } | 569 } |
| 571 } | 570 } |
| 572 | 571 |
| 573 HttpProtocolHandlerCore::~HttpProtocolHandlerCore() { | 572 HttpProtocolHandlerCore::~HttpProtocolHandlerCore() { |
| 574 DCHECK(thread_checker_.CalledOnValidThread()); | 573 DCHECK(thread_checker_.CalledOnValidThread()); |
| 575 [top_level_client_ cancelAuthRequest]; | 574 [top_level_client_ cancelAuthRequest]; |
| 576 DCHECK(!net_request_); | 575 DCHECK(!net_request_); |
| 577 DCHECK(!stream_delegate_); | 576 DCHECK(!stream_delegate_); |
| 578 } | 577 } |
| (...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1096 [[DeferredCancellation alloc] initWithCore:[self getCore]]; | 1095 [[DeferredCancellation alloc] initWithCore:[self getCore]]; |
| 1097 NSArray* modes = @[ [[NSRunLoop currentRunLoop] currentMode] ]; | 1096 NSArray* modes = @[ [[NSRunLoop currentRunLoop] currentMode] ]; |
| 1098 [cancellation performSelector:@selector(cancel) | 1097 [cancellation performSelector:@selector(cancel) |
| 1099 onThread:[self getClientThread] | 1098 onThread:[self getClientThread] |
| 1100 withObject:nil | 1099 withObject:nil |
| 1101 waitUntilDone:NO | 1100 waitUntilDone:NO |
| 1102 modes:modes]; | 1101 modes:modes]; |
| 1103 } | 1102 } |
| 1104 | 1103 |
| 1105 @end | 1104 @end |
| OLD | NEW |