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 |