Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(82)

Side by Side Diff: ios/net/crn_http_protocol_handler.mm

Issue 2857733002: iOS Cronet: Put cap on the buffer size passed to onReadCompleted delegate (Closed)
Patch Set: Improved Cronet unit test bug fix Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 #if !defined(__has_feature) || !__has_feature(objc_arc) 43 #if !defined(__has_feature) || !__has_feature(objc_arc)
44 #error "This file requires ARC support." 44 #error "This file requires ARC support."
45 #endif 45 #endif
46 46
47 namespace net { 47 namespace net {
48 class HttpProtocolHandlerCore; 48 class HttpProtocolHandlerCore;
49 } 49 }
50 50
51 namespace { 51 namespace {
52 52
53 // Size of the buffer used to read the net::URLRequest. 53 // Size of the buffer used to read the net::URLRequest. This value must always
54 // be less or equal to |kClientMaxBufferSize|.
54 const int kIOBufferSize = 64 * 1024; 55 const int kIOBufferSize = 64 * 1024;
55 56
57 // The maximum size of NSData that can be passed to the client 'didReceiveData'
58 // callback. This value must always be greater or equal to |kIOBufferSize|.
59 const int kClientMaxBufferSize = 256 * 1024;
60
56 // Global instance of the HTTPProtocolHandlerDelegate. 61 // Global instance of the HTTPProtocolHandlerDelegate.
57 net::HTTPProtocolHandlerDelegate* g_protocol_handler_delegate = nullptr; 62 net::HTTPProtocolHandlerDelegate* g_protocol_handler_delegate = nullptr;
58 63
59 // Empty callback. 64 // Empty callback.
60 void DoNothing(bool flag) {} 65 void DoNothing(bool flag) {}
61 66
62 } // namespace 67 } // namespace
63 68
64 // Bridge class to forward NSStream events to the HttpProtocolHandlerCore. 69 // Bridge class to forward NSStream events to the HttpProtocolHandlerCore.
65 // Lives on the IO thread. 70 // Lives on the IO thread.
(...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after
507 } 512 }
508 513
509 void HttpProtocolHandlerCore::OnReadCompleted(URLRequest* request, 514 void HttpProtocolHandlerCore::OnReadCompleted(URLRequest* request,
510 int bytes_read) { 515 int bytes_read) {
511 DCHECK_NE(net::ERR_IO_PENDING, bytes_read); 516 DCHECK_NE(net::ERR_IO_PENDING, bytes_read);
512 DCHECK(thread_checker_.CalledOnValidThread()); 517 DCHECK(thread_checker_.CalledOnValidThread());
513 518
514 if (net_request_ == nullptr) 519 if (net_request_ == nullptr)
515 return; 520 return;
516 521
517 base::scoped_nsobject<NSMutableData> data([[NSMutableData alloc] init]); 522 DCHECK_EQ(net_request_, request);
lilyhoughton 2017/05/05 16:33:05 Why does OnReadCompleted take request as an argume
mef 2017/05/05 17:08:19 It is implementing UrlRequest::Delegate, which all
518 523
519 // Read all we can from the socket and put it into data. 524 // Read all we can from the socket and put it into data.
520 // TODO(droger): It may be possible to avoid some of the copies (using 525 // TODO(droger): It may be possible to avoid some of the copies (using
521 // WrappedIOBuffer for example). 526 // WrappedIOBuffer for example).
522 NSUInteger data_length; 527 NSUInteger data_length;
523 uint64_t total_byte_read = 0; 528 uint64_t total_byte_read = 0;
mef 2017/05/05 17:08:19 nit: rename to total_bytes_read for consistency.
kapishnikov 2017/05/05 19:13:42 Done.
524 while (bytes_read > 0) { 529 while (bytes_read > 0) {
525 total_byte_read += bytes_read; 530 base::scoped_nsobject<NSMutableData> data(
526 data_length = [data length]; // Assumes that getting the length is fast. 531 [[NSMutableData alloc] initWithCapacity:bytes_read]);
527 [data increaseLengthBy:bytes_read]; 532 // |bytes_read| should always be less or equal to |kClientMaxBufferSize|.
528 memcpy(reinterpret_cast<char*>([data mutableBytes]) + data_length, 533 // This is ensured by the fact that the max read buffer size (i.e.
529 buffer_->data(), bytes_read); 534 // |kIOBufferSize|) is always smaller or equal to |kClientMaxBufferSize|.
530 bytes_read = request->Read(buffer_.get(), kIOBufferSize); 535 while (bytes_read > 0 &&
531 } 536 [data length] + bytes_read <= kClientMaxBufferSize) {
537 total_byte_read += bytes_read;
538 data_length = [data length];
mef 2017/05/05 17:08:19 move NSUInteger data_length declaration here to li
kapishnikov 2017/05/05 19:13:42 Done.
539 [data increaseLengthBy:bytes_read];
540 memcpy(reinterpret_cast<char*>([data mutableBytes]) + data_length,
541 buffer_->data(), bytes_read);
542 bytes_read = request->Read(buffer_.get(), kIOBufferSize);
543 }
532 544
533 if (tracker_)
534 tracker_->CaptureReceivedBytes(request, total_byte_read);
535
536 // Notify the client.
537 if (bytes_read == net::OK || bytes_read == net::ERR_IO_PENDING) {
538 if ([data length] > 0) { 545 if ([data length] > 0) {
539 // If the data is not encoded in UTF8, the NSString is nil. 546 // If the data is not encoded in UTF8, the NSString is nil.
540 DVLOG(3) << "To client:" << std::endl 547 DVLOG(3) << "To client:" << std::endl
541 << base::SysNSStringToUTF8([[NSString alloc] 548 << base::SysNSStringToUTF8([[NSString alloc]
542 initWithData:data 549 initWithData:data
543 encoding:NSUTF8StringEncoding]); 550 encoding:NSUTF8StringEncoding]);
544 [client_ didLoadData:data]; 551 [client_ didLoadData:data];
545 } 552 }
546 if (bytes_read == 0) { 553 }
547 DCHECK_EQ(net_request_, request); 554
548 // There is nothing more to read. 555 if (tracker_)
549 StopNetRequest(); 556 tracker_->CaptureReceivedBytes(request, total_byte_read);
550 [client_ didFinishLoading]; 557
551 } 558 // If there is nothing more to read.
552 } else { 559 if (bytes_read == 0) {
lilyhoughton 2017/05/05 16:33:05 Does it make sense for this to be |if (bytes_read
kapishnikov 2017/05/05 19:13:42 Changed it.
553 // Request failed (not canceled). 560 StopNetRequest();
561 [client_ didFinishLoading];
562 }
563
564 // If there was an error (not canceled).
565 if (bytes_read != net::OK && bytes_read != net::ERR_IO_PENDING) {
lilyhoughton 2017/05/05 16:33:05 I think comparing bytes_read to both 0 and net::OK
kapishnikov 2017/05/05 19:13:42 Done.
554 int error = bytes_read; 566 int error = bytes_read;
555 StopRequestWithError(IOSErrorCode(error), error); 567 StopRequestWithError(IOSErrorCode(error), error);
556 } 568 }
557 } 569 }
558 570
559 HttpProtocolHandlerCore::~HttpProtocolHandlerCore() { 571 HttpProtocolHandlerCore::~HttpProtocolHandlerCore() {
560 DCHECK(thread_checker_.CalledOnValidThread()); 572 DCHECK(thread_checker_.CalledOnValidThread());
561 [client_ cancelAuthRequest]; 573 [client_ cancelAuthRequest];
562 DCHECK(!net_request_); 574 DCHECK(!net_request_);
563 DCHECK(!stream_delegate_); 575 DCHECK(!stream_delegate_);
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after
958 base::Bind(&net::HttpProtocolHandlerCore::Cancel, _core)); 970 base::Bind(&net::HttpProtocolHandlerCore::Cancel, _core));
959 [_protocolProxy invalidate]; 971 [_protocolProxy invalidate];
960 } 972 }
961 973
962 - (void)stopLoading { 974 - (void)stopLoading {
963 [self cancelRequest]; 975 [self cancelRequest];
964 _protocolProxy.reset(); 976 _protocolProxy.reset();
965 } 977 }
966 978
967 @end 979 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698