// Copyright 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#import "ios/net/crn_http_protocol_handler.h"

#include <stdint.h>

#include <memory>
#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/command_line.h"
#include "base/logging.h"
#include "base/mac/foundation_util.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_util.h"
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "ios/net/chunked_data_stream_uploader.h"
#import "ios/net/clients/crn_network_client_protocol.h"
#import "ios/net/crn_http_protocol_handler_proxy_with_client_thread.h"
#import "ios/net/http_protocol_logging.h"
#include "ios/net/nsurlrequest_util.h"
#import "ios/net/protocol_handler_util.h"
#include "net/base/auth.h"
#include "net/base/elements_upload_data_stream.h"
#include "net/base/io_buffer.h"
#include "net/base/load_flags.h"
#import "net/base/mac/url_conversions.h"
#include "net/base/net_errors.h"
#include "net/base/upload_bytes_element_reader.h"
#include "net/http/http_request_headers.h"
#include "net/url_request/redirect_info.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"

#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif

namespace net {
class HttpProtocolHandlerCore;
}

namespace {

// Minimum size of the buffer used to read the net::URLRequest.
const int kIOBufferMinSize = 64 * 1024;

// Maximum size of the buffer used to read the net::URLRequest.
const int kIOBufferMaxSize = 16 * kIOBufferMinSize;  // 1MB

// Global instance of the HTTPProtocolHandlerDelegate.
net::HTTPProtocolHandlerDelegate* g_protocol_handler_delegate = nullptr;

// Global instance of the MetricsDelegate.
net::MetricsDelegate* g_metrics_delegate = nullptr;

}  // namespace

// Bridge class to forward NSStream events to the HttpProtocolHandlerCore.
// Lives on the IO thread.
@interface CRWHTTPStreamDelegate : NSObject<NSStreamDelegate> {
 @private
  // The object is owned by |_core| and has a weak reference to it.
  net::HttpProtocolHandlerCore* _core;  // weak
}
- (instancetype)initWithHttpProtocolHandlerCore:
    (net::HttpProtocolHandlerCore*)core;
// NSStreamDelegate method.
- (void)stream:(NSStream*)theStream handleEvent:(NSStreamEvent)streamEvent;
@end

#pragma mark -
#pragma mark HttpProtocolHandlerCore

namespace net {

MetricsDelegate::Metrics::Metrics() = default;
MetricsDelegate::Metrics::~Metrics() = default;

// static
void HTTPProtocolHandlerDelegate::SetInstance(
    HTTPProtocolHandlerDelegate* delegate) {
  g_protocol_handler_delegate = delegate;
}

// static
void MetricsDelegate::SetInstance(MetricsDelegate* delegate) {
  g_metrics_delegate = delegate;
}

// The HttpProtocolHandlerCore class is the bridge between the URLRequest
// and the NSURLProtocolClient.
// Threading and ownership details:
// - The HttpProtocolHandlerCore is owned by the HttpProtocolHandler
// - The HttpProtocolHandler is owned by the system and can be deleted anytime
// - All the methods of HttpProtocolHandlerCore must be called on the IO thread,
//   except its constructor that can be called from any thread.

// Implementation notes from Apple's "Read Me About CustomHttpProtocolHandler":
//
// An NSURLProtocol subclass is expected to call the various methods of the
// NSURLProtocolClient from the loading thread, including all of the following:
//  -URLProtocol:wasRedirectedToRequest:redirectResponse:
//  -URLProtocol:didReceiveResponse:cacheStoragePolicy:
//  -URLProtocol:didLoadData:
//  -URLProtocol:didFinishLoading:
//  -URLProtocol:didFailWithError:
//  -URLProtocol:didReceiveAuthenticationChallenge:
//  -URLProtocol:didCancelAuthenticationChallenge:
//
// The NSURLProtocol subclass must call the client callbacks in the expected
// order. This breaks down into three phases:
//  o pre-response -- In the initial phase the NSURLProtocol can make any number
//    of -URLProtocol:wasRedirectedToRequest:redirectResponse: and
//    -URLProtocol:didReceiveAuthenticationChallenge: callbacks.
//  o response -- It must then call
//    -URLProtocol:didReceiveResponse:cacheStoragePolicy: to indicate the
//    arrival of a definitive response.
//  o post-response -- After receive a response it may then make any number of
//    -URLProtocol:didLoadData: callbacks, followed by a
//    -URLProtocolDidFinishLoading: callback.
//
// The -URLProtocol:didFailWithError: callback can be made at any time
// (although keep in mind the following point).
//
// The NSProtocol subclass must only send one authentication challenge to the
// client at a time. After calling
// -URLProtocol:didReceiveAuthenticationChallenge:, it must wait for the client
// to resolve the challenge before calling any callbacks other than
// -URLProtocol:didCancelAuthenticationChallenge:. This means that, if the
// connection fails while there is an outstanding authentication challenge, the
// NSURLProtocol subclass must call
// -URLProtocol:didCancelAuthenticationChallenge: before calling
// -URLProtocol:didFailWithError:.
class HttpProtocolHandlerCore
    : public base::RefCountedThreadSafe<HttpProtocolHandlerCore,
                                        HttpProtocolHandlerCore>,
      public URLRequest::Delegate,
      public ChunkedDataStreamUploader::Delegate {
 public:
  explicit HttpProtocolHandlerCore(NSURLRequest* request);
  explicit HttpProtocolHandlerCore(NSURLSessionTask* task);
  // Starts the network request, and forwards the data downloaded from the
  // network to |base_client|.
  void Start(id<CRNNetworkClientProtocol> base_client);
  // Cancels the request.
  void Cancel();
  // Called by NSStreamDelegate. Used for POST requests having a HTTPBodyStream.
  void HandleStreamEvent(NSStream* stream, NSStreamEvent event);

  // URLRequest::Delegate methods:
  void OnReceivedRedirect(URLRequest* request,
                          const RedirectInfo& new_url,
                          bool* defer_redirect) override;
  void OnAuthRequired(URLRequest* request,
                      const AuthChallengeInfo& auth_info) override;
  void OnCertificateRequested(URLRequest* request,
                              SSLCertRequestInfo* cert_request_info) override;
  void OnSSLCertificateError(URLRequest* request,
                             int net_error,
                             const SSLInfo& ssl_info,
                             bool fatal) override;
  void OnResponseStarted(URLRequest* request, int net_error) override;
  void OnReadCompleted(URLRequest* request, int bytes_read) override;

  // ChunkedDataStreamUploader::Delegate method:
  int OnRead(char* buffer, int buffer_length) override;

 private:
  friend class base::RefCountedThreadSafe<HttpProtocolHandlerCore,
                                          HttpProtocolHandlerCore>;
  friend class base::DeleteHelper<HttpProtocolHandlerCore>;
  ~HttpProtocolHandlerCore() override;

  // RefCountedThreadSafe traits implementation:
  static void Destruct(const HttpProtocolHandlerCore* x);

  void SetLoadFlags();
  void StopNetRequest();
  // Stop listening the delegate on the IO run loop.
  void StopListeningStream(NSStream* stream);
  NSInteger IOSErrorCode(int os_error);
  void StopRequestWithError(NSInteger ns_error_code, int net_error_code);
  void StripPostSpecificHeaders(NSMutableURLRequest* request);
  void CancelAfterSSLError();
  void StartReading();
  void AllocateReadBuffer(int last_read_data_size);

  base::ThreadChecker thread_checker_;

  // The NSURLProtocol client.
  id<CRNNetworkClientProtocol> client_ = nil;
  std::unique_ptr<char, base::FreeDeleter> read_buffer_;
  int read_buffer_size_ = kIOBufferMinSize;
  scoped_refptr<WrappedIOBuffer> read_buffer_wrapper_;
  NSMutableURLRequest* request_ = nil;
  NSURLSessionTask* task_ = nil;
  // The stream has data to upload.
  NSInputStream* http_body_stream_ = nil;
  // Stream delegate to read the HTTPBodyStream.
  CRWHTTPStreamDelegate* http_body_stream_delegate_ = nullptr;
  // Vector of readers used to accumulate a POST data stream.
  std::vector<std::unique_ptr<UploadElementReader>> post_data_readers_;

  // This cannot be a scoped pointer because it must be deleted on the IO
  // thread.
  URLRequest* net_request_ = nullptr;

  // It is a weak pointer because the owner of the uploader is the URLRequest.
  base::WeakPtr<ChunkedDataStreamUploader> chunked_uploader_;

  DISALLOW_COPY_AND_ASSIGN(HttpProtocolHandlerCore);
};

HttpProtocolHandlerCore::HttpProtocolHandlerCore(NSURLRequest* request) {
  // The request will be accessed from another thread. It is safer to make a
  // copy to avoid conflicts.
  // The copy is mutable, because that request will be given to the client in
  // case of a redirect, but with a different URL. The URL must be created
  // from the absoluteString of the original URL, because mutableCopy only
  // shallowly copies the request, and just retains the non-threadsafe NSURL.
  thread_checker_.DetachFromThread();
  task_ = nil;
  request_ = [request mutableCopy];
  // Will allocate read buffer with size |kIOBufferMinSize|.
  AllocateReadBuffer(0);
  [request_ setURL:request.URL];
}

HttpProtocolHandlerCore::HttpProtocolHandlerCore(NSURLSessionTask* task)
    : HttpProtocolHandlerCore([task currentRequest]) {
  task_ = task;
}

void HttpProtocolHandlerCore::HandleStreamEvent(NSStream* stream,
                                                NSStreamEvent event) {
  DVLOG(2) << "HandleStreamEvent " << stream << " event " << event;
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK(http_body_stream_ == stream);
  DCHECK(http_body_stream_delegate_);
  switch (event) {
    case NSStreamEventErrorOccurred:
      DLOG(ERROR)
          << "Failed to read POST data: "
          << base::SysNSStringToUTF8([[stream streamError] description]);
      StopListeningStream(stream);
      StopRequestWithError(NSURLErrorUnknown, ERR_UNEXPECTED);
      break;
    case NSStreamEventEndEncountered:
      StopListeningStream(stream);
      if (chunked_uploader_) {
        chunked_uploader_->UploadWhenReady(true);
        break;
      }

      if (!post_data_readers_.empty()) {
        // NOTE: This call will result in |post_data_readers_| being cleared,
        // which is the desired behavior.
        net_request_->set_upload(std::make_unique<ElementsUploadDataStream>(
            std::move(post_data_readers_), 0));
        DCHECK(post_data_readers_.empty());
      }
      net_request_->Start();
      break;
    case NSStreamEventHasBytesAvailable: {
      if (chunked_uploader_) {
        chunked_uploader_->UploadWhenReady(false);
        break;
      }

      NSInteger length;
      // TODO(crbug.com/738025): Dynamically change the size of the read buffer
      // to improve the read (POST) performance, see AllocateReadBuffer(), &
      // avoid unnecessary data copy.
      length = [base::mac::ObjCCastStrict<NSInputStream>(stream)
               read:reinterpret_cast<unsigned char*>(read_buffer_.get())
          maxLength:read_buffer_size_];
      if (length > 0) {
        std::vector<char> owned_data(read_buffer_.get(),
                                     read_buffer_.get() + length);
        post_data_readers_.push_back(
            std::make_unique<UploadOwnedBytesElementReader>(&owned_data));
      } else if (length < 0) {  // Error
        StopRequestWithError(stream.streamError.code, ERR_FAILED);
      }
      break;
    }
    case NSStreamEventNone:
    case NSStreamEventOpenCompleted:
    case NSStreamEventHasSpaceAvailable:
      break;
    default:
      NOTREACHED() << "Unexpected stream event: " << event;
      break;
  }
}

#pragma mark URLRequest::Delegate methods

void HttpProtocolHandlerCore::OnReceivedRedirect(
    URLRequest* request,
    const RedirectInfo& redirect_info,
    bool* /* defer_redirect */) {
  DCHECK(thread_checker_.CalledOnValidThread());

  // Cancel the request and notify UIWebView.
  // If we did nothing, the network stack would follow the redirect
  // automatically, however we do not want this because we need the UIWebView to
  // be notified. The UIWebView will then issue a new request following the
  // redirect.
  DCHECK(request_);
  GURL new_url = redirect_info.new_url;

  if (!new_url.is_valid()) {
    StopRequestWithError(NSURLErrorBadURL, ERR_INVALID_URL);
    return;
  }

  DCHECK(new_url.is_valid());
  NSURL* new_nsurl = NSURLWithGURL(new_url);
  // Stash the original URL in case we need to report it in an error.
  [request_ setURL:new_nsurl];

  if (http_body_stream_)
    StopListeningStream(http_body_stream_);

  // TODO(droger): See if we can share some code with URLRequest::Redirect() in
  // net/net_url_request/url_request.cc.

  // For 303 redirects, all request methods except HEAD are converted to GET,
  // as per the latest httpbis draft.  The draft also allows POST requests to
  // be converted to GETs when following 301/302 redirects, for historical
  // reasons. Most major browsers do this and so shall we.
  // See:
  // https://tools.ietf.org/html/draft-ietf-httpbis-p2-semantics-17#section-7.3
  const int http_status_code = request->GetResponseCode();
  NSString* method = [request_ HTTPMethod];
  const bool was_post = [method isEqualToString:@"POST"];
  if ((http_status_code == 303 && ![method isEqualToString:@"HEAD"]) ||
      ((http_status_code == 301 || http_status_code == 302) && was_post)) {
    [request_ setHTTPMethod:@"GET"];
    [request_ setHTTPBody:nil];
    [request_ setHTTPBodyStream:nil];
    if (was_post) {
      // If being switched from POST to GET, must remove headers that were
      // specific to the POST and don't have meaning in GET. For example
      // the inclusion of a multipart Content-Type header in GET can cause
      // problems with some servers:
      // http://code.google.com/p/chromium/issues/detail?id=843
      StripPostSpecificHeaders(request_);
    }
  }

  NSURLResponse* response = GetNSURLResponseForRequest(request);
#if !defined(NDEBUG)
  DVLOG(2) << "Redirect, to client:";
  LogNSURLResponse(response);
  DVLOG(2) << "Redirect, to client:";
  LogNSURLRequest(request_);
#endif  // !defined(NDEBUG)

  [client_ wasRedirectedToRequest:request_
                    nativeRequest:request
                 redirectResponse:response];
  // Don't use |request_| or |response| anymore, as the client may be using them
  // on another thread and they are not re-entrant. As |request_| is mutable, it
  // is also important that it is not modified.
  request_ = nil;
  request->Cancel();
  DCHECK_EQ(net_request_, request);
  StopNetRequest();
}

void HttpProtocolHandlerCore::OnAuthRequired(
    URLRequest* request,
    const AuthChallengeInfo& auth_info) {
  DCHECK(thread_checker_.CalledOnValidThread());
  if (net_request_ != nullptr) {
    net_request_->CancelAuth();
  }
}

void HttpProtocolHandlerCore::OnCertificateRequested(
    URLRequest* request,
    SSLCertRequestInfo* cert_request_info) {
  DCHECK(thread_checker_.CalledOnValidThread());

  // TODO(ios): The network stack does not support SSL client authentication
  // on iOS yet. The request has to be canceled for now.
  request->Cancel();
  StopRequestWithError(NSURLErrorClientCertificateRequired,
                       ERR_SSL_PROTOCOL_ERROR);
}

void HttpProtocolHandlerCore::CancelAfterSSLError(void) {
  DCHECK(thread_checker_.CalledOnValidThread());
  if (net_request_ != nullptr) {
    // Cancel the request.
    net_request_->Cancel();

    // The request is signalled simply cancelled to the consumer, the
    // presentation of the SSL error will be done via the tracker.
    StopRequestWithError(NSURLErrorCancelled, ERR_BLOCKED_BY_CLIENT);
  }
}

void HttpProtocolHandlerCore::OnSSLCertificateError(URLRequest* request,
                                                    int net_error,
                                                    const SSLInfo& ssl_info,
                                                    bool fatal) {
  DCHECK(thread_checker_.CalledOnValidThread());

  CancelAfterSSLError();
}

void HttpProtocolHandlerCore::OnResponseStarted(URLRequest* request,
                                                int net_error) {
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK_NE(net::ERR_IO_PENDING, net_error);

  if (net_request_ == nullptr)
    return;

  if (net_error != net::OK) {
    StopRequestWithError(IOSErrorCode(net_error), net_error);
    return;
  }

  StartReading();
}

void HttpProtocolHandlerCore::StartReading() {
  DCHECK(thread_checker_.CalledOnValidThread());
  if (net_request_ == nullptr)
    return;

  NSURLResponse* response = GetNSURLResponseForRequest(net_request_);
#if !defined(NDEBUG)
  DVLOG(2) << "To client:";
  LogNSURLResponse(response);
#endif  // !defined(NDEBUG)

  // Don't call any function on the response from now on, as the client may be
  // using it and the object is not re-entrant.
  [client_ didReceiveResponse:response];

  int bytes_read =
      net_request_->Read(read_buffer_wrapper_.get(), read_buffer_size_);
  if (bytes_read == net::ERR_IO_PENDING)
    return;

  if (bytes_read >= 0) {
    OnReadCompleted(net_request_, bytes_read);
  } else {
    int error = bytes_read;
    StopRequestWithError(IOSErrorCode(error), error);
  }
}

void HttpProtocolHandlerCore::OnReadCompleted(URLRequest* request,
                                              int bytes_read) {
  DCHECK_NE(net::ERR_IO_PENDING, bytes_read);
  DCHECK(thread_checker_.CalledOnValidThread());

  if (net_request_ == nullptr)
    return;

  DCHECK_EQ(net_request_, request);

  // Read data from the socket until no bytes left to read.
  uint64_t total_bytes_read = 0;
  while (bytes_read > 0) {
    total_bytes_read += bytes_read;
    // The NSData will take the ownership of |read_buffer_|.
    NSData* data =
        [NSData dataWithBytesNoCopy:read_buffer_.release() length:bytes_read];
    // If the data is not encoded in UTF8, the NSString is nil.
    DVLOG(3) << "To client:" << std::endl
             << base::SysNSStringToUTF8([[NSString alloc]
                    initWithData:data
                        encoding:NSUTF8StringEncoding]);
    // Pass the read data to the client.
    [client_ didLoadData:data];

    // Allocate a new buffer and continue reading from the socket.
    AllocateReadBuffer(bytes_read);
    bytes_read = request->Read(read_buffer_wrapper_.get(), read_buffer_size_);
  }

  if (bytes_read == net::OK) {
    // If there is nothing more to read.
    StopNetRequest();
    [client_ didFinishLoading];
  } else if (bytes_read != net::ERR_IO_PENDING) {
    // If there was an error (not canceled).
    int error = bytes_read;
    StopRequestWithError(IOSErrorCode(error), error);
  }
}

void HttpProtocolHandlerCore::AllocateReadBuffer(int last_read_data_size) {
  if (last_read_data_size == read_buffer_size_) {
    // If the whole buffer was filled with data then increase the buffer size
    // for the next read but don't exceed |kIOBufferMaxSize|.
    read_buffer_size_ = std::min(read_buffer_size_ * 2, kIOBufferMaxSize);
  } else if (read_buffer_size_ / 2 >= last_read_data_size) {
    // If only a half or less of the buffer was filled with data then reduce
    // the buffer size for the next read but not make it smaller than
    // |kIOBufferMinSize|.
    read_buffer_size_ = std::max(read_buffer_size_ / 2, kIOBufferMinSize);
  }
  read_buffer_.reset(static_cast<char*>(malloc(read_buffer_size_)));
  read_buffer_wrapper_ = base::MakeRefCounted<WrappedIOBuffer>(
      static_cast<const char*>(read_buffer_.get()));
}

HttpProtocolHandlerCore::~HttpProtocolHandlerCore() {
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK(!net_request_);
  DCHECK(!http_body_stream_delegate_);
}

// static
void HttpProtocolHandlerCore::Destruct(const HttpProtocolHandlerCore* x) {
  scoped_refptr<base::SingleThreadTaskRunner> task_runner =
      g_protocol_handler_delegate->GetDefaultURLRequestContext()
          ->GetNetworkTaskRunner();
  if (task_runner->BelongsToCurrentThread())
    delete x;
  else
    task_runner->DeleteSoon(FROM_HERE, x);
}

void HttpProtocolHandlerCore::SetLoadFlags() {
  DCHECK(thread_checker_.CalledOnValidThread());
  int load_flags = LOAD_NORMAL;

  switch ([request_ cachePolicy]) {
    case NSURLRequestReloadIgnoringLocalAndRemoteCacheData:
      load_flags |= LOAD_BYPASS_CACHE;
      FALLTHROUGH;
    case NSURLRequestReloadIgnoringLocalCacheData:
      load_flags |= LOAD_DISABLE_CACHE;
      break;
    case NSURLRequestReturnCacheDataElseLoad:
      load_flags |= LOAD_SKIP_CACHE_VALIDATION;
      break;
    case NSURLRequestReturnCacheDataDontLoad:
      load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
      break;
    case NSURLRequestReloadRevalidatingCacheData:
      load_flags |= LOAD_VALIDATE_CACHE;
      break;
    case NSURLRequestUseProtocolCachePolicy:
      // Do nothing, normal load.
      break;
  }
  net_request_->SetLoadFlags(load_flags);
}

void HttpProtocolHandlerCore::Start(id<CRNNetworkClientProtocol> base_client) {
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK(!client_);
  DCHECK(base_client);
  client_ = base_client;
  GURL url = GURLWithNSURL([request_ URL]);

  // Now that all of the network clients are set up, if there was an error with
  // the URL, it can be raised and all of the clients will have a chance to
  // handle it.
  if (!url.is_valid()) {
    DLOG(ERROR) << "Trying to load an invalid URL: "
                << base::SysNSStringToUTF8([[request_ URL] absoluteString]);
    [client_ didFailWithNSErrorCode:NSURLErrorBadURL
                       netErrorCode:ERR_INVALID_URL];
    return;
  }

  const URLRequestContext* context =
      g_protocol_handler_delegate->GetDefaultURLRequestContext()
          ->GetURLRequestContext();
  DCHECK(context);

  net_request_ =
      context->CreateRequest(url, DEFAULT_PRIORITY, this).release();
  net_request_->set_method(base::SysNSStringToUTF8([request_ HTTPMethod]));

  net_request_->set_site_for_cookies(
      net::SiteForCookies::FromUrl(GURLWithNSURL([request_ mainDocumentURL])));

#if !defined(NDEBUG)
  DVLOG(2) << "From client:";
  LogNSURLRequest(request_);
#endif  // !defined(NDEBUG)

  CopyHttpHeaders(request_, net_request_);

  [client_ didCreateNativeRequest:net_request_];
  SetLoadFlags();
  net_request_->set_allow_credentials([request_ HTTPShouldHandleCookies]);

  // https://crbug.com/979324 If the application app sets HTTPBody, then system
  // creates new NSInputStream every time HTTPBodyStream is called. Get the
  // stream here and hold on to it.
  http_body_stream_ = [request_ HTTPBodyStream];
  if (http_body_stream_) {
    DCHECK(![request_ HTTPBody]);
    http_body_stream_delegate_ =
        [[CRWHTTPStreamDelegate alloc] initWithHttpProtocolHandlerCore:this];
    [http_body_stream_ setDelegate:http_body_stream_delegate_];
    DVLOG(1) << "input_stream " << http_body_stream_ << " delegate "
             << [http_body_stream_ delegate];
    [http_body_stream_ scheduleInRunLoop:[NSRunLoop currentRunLoop]
                                 forMode:NSDefaultRunLoopMode];
    [http_body_stream_ open];

    if (net_request_->extra_request_headers().HasHeader(
            HttpRequestHeaders::kContentLength)) {
      // The request will be started when the stream is fully read.
      return;
    }

    std::unique_ptr<ChunkedDataStreamUploader> uploader =
        std::make_unique<ChunkedDataStreamUploader>(this);
    chunked_uploader_ = uploader->GetWeakPtr();
    net_request_->set_upload(std::move(uploader));
  } else if ([request_ HTTPBody]) {
    DVLOG(1) << "HTTPBody " << [request_ HTTPBody];
    NSData* body = [request_ HTTPBody];
    const NSUInteger body_length = [body length];
    if (body_length > 0) {
      const char* source_bytes = reinterpret_cast<const char*>([body bytes]);
      std::vector<char> owned_data(source_bytes, source_bytes + body_length);
      std::unique_ptr<UploadElementReader> reader(
          new UploadOwnedBytesElementReader(&owned_data));
      net_request_->set_upload(
          ElementsUploadDataStream::CreateWithReader(std::move(reader), 0));
    }
  }

  net_request_->Start();
}

void HttpProtocolHandlerCore::Cancel() {
  DCHECK(thread_checker_.CalledOnValidThread());
  if (net_request_ == nullptr)
    return;

  DVLOG(2) << "Client canceling request: " << net_request_->url().spec();
  net_request_->Cancel();
  StopNetRequest();
}

void HttpProtocolHandlerCore::StopNetRequest() {
  DCHECK(thread_checker_.CalledOnValidThread());

  if (g_metrics_delegate) {
    auto metrics = std::make_unique<net::MetricsDelegate::Metrics>();

    metrics->response_end_time = base::Time::Now();
    metrics->task = task_;
    metrics->response_info = net_request_->response_info();
    net_request_->GetLoadTimingInfo(&metrics->load_timing_info);

    g_metrics_delegate->OnStopNetRequest(std::move(metrics));
  }

  delete net_request_;
  net_request_ = nullptr;
  if (http_body_stream_)
    StopListeningStream(http_body_stream_);
}

void HttpProtocolHandlerCore::StopListeningStream(NSStream* stream) {
  DVLOG(1) << "StopListeningStream " << stream << " delegate "
           << [stream delegate];
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK(stream);
  DCHECK(http_body_stream_delegate_);
  DCHECK([stream delegate] == http_body_stream_delegate_);
  if (stream != http_body_stream_)
    return;
  [stream setDelegate:nil];
  [stream removeFromRunLoop:[NSRunLoop currentRunLoop]
                    forMode:NSDefaultRunLoopMode];
  http_body_stream_delegate_ = nil;
  http_body_stream_ = nil;
  // Close the stream if needed.
  switch ([stream streamStatus]) {
    case NSStreamStatusOpening:
    case NSStreamStatusOpen:
    case NSStreamStatusReading:
    case NSStreamStatusWriting:
    case NSStreamStatusAtEnd:
      [stream close];
      break;
    case NSStreamStatusNotOpen:
    case NSStreamStatusClosed:
    case NSStreamStatusError:
      break;
    default:
      NOTREACHED() << "Unexpected stream status: " << [stream streamStatus];
      break;
  }
}

NSInteger HttpProtocolHandlerCore::IOSErrorCode(int os_error) {
  DCHECK(thread_checker_.CalledOnValidThread());
  switch (os_error) {
    case ERR_SSL_PROTOCOL_ERROR:
      return NSURLErrorClientCertificateRequired;
    case ERR_CONNECTION_RESET:
    case ERR_NETWORK_CHANGED:
      return NSURLErrorNetworkConnectionLost;
    case ERR_UNEXPECTED:
      return NSURLErrorUnknown;
    default:
      return NSURLErrorCannotConnectToHost;
  }
}

void HttpProtocolHandlerCore::StopRequestWithError(NSInteger ns_error_code,
                                                   int net_error_code) {
  DCHECK(net_request_ != nullptr);
  DCHECK(thread_checker_.CalledOnValidThread());

  // Don't show an error message on ERR_ABORTED because this is error is often
  // fired when switching profiles.
  DLOG_IF(ERROR, net_error_code != ERR_ABORTED)
      << "HttpProtocolHandlerCore - Network error: "
      << ErrorToString(net_error_code) << " (" << net_error_code << ")";

  [client_ didFailWithNSErrorCode:ns_error_code netErrorCode:net_error_code];
  StopNetRequest();
}

void HttpProtocolHandlerCore::StripPostSpecificHeaders(
    NSMutableURLRequest* request) {
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK(request);
  [request setValue:nil forHTTPHeaderField:base::SysUTF8ToNSString(
      HttpRequestHeaders::kContentLength)];
  [request setValue:nil forHTTPHeaderField:base::SysUTF8ToNSString(
      HttpRequestHeaders::kContentType)];
  [request setValue:nil forHTTPHeaderField:base::SysUTF8ToNSString(
      HttpRequestHeaders::kOrigin)];
}

int HttpProtocolHandlerCore::OnRead(char* buffer, int buffer_length) {
  int bytes_read = 0;
  if (http_body_stream_) {
    // NSInputStream read() blocks the thread until there is at least one byte
    // available, so check the status before call read().
    if (![http_body_stream_ hasBytesAvailable])
      return ERR_IO_PENDING;

    bytes_read =
        [http_body_stream_ read:reinterpret_cast<unsigned char*>(buffer)
                      maxLength:buffer_length];
    // NSInputStream can read 0 byte when hasBytesAvailable is true, so do not
    // treat it as a failure.
    if (bytes_read < 0) {
      // If NSInputStream meets an error on read(), fail the request
      // immediately.
      DLOG(ERROR) << "Failed to read POST data: "
                  << base::SysNSStringToUTF8(
                         [[http_body_stream_ streamError] description]);
      StopListeningStream(http_body_stream_);
      StopRequestWithError(NSURLErrorUnknown, ERR_UNEXPECTED);
      return ERR_UNEXPECTED;
    }
  }
  return bytes_read;
}

}  // namespace net

#pragma mark -
#pragma mark CRWHTTPStreamDelegate

@implementation CRWHTTPStreamDelegate
- (instancetype)initWithHttpProtocolHandlerCore:
    (net::HttpProtocolHandlerCore*)core {
  DCHECK(core);
  self = [super init];
  if (self)
    _core = core;
  return self;
}

- (void)stream:(NSStream*)theStream handleEvent:(NSStreamEvent)streamEvent {
  _core->HandleStreamEvent(theStream, streamEvent);
}
@end

#pragma mark -
#pragma mark DeferredCancellation

// An object of class |DeferredCancellation| represents a deferred cancellation
// of a request. In principle this is a block posted to a thread's runloop, but
// since there is no performBlock:onThread:, this class wraps the desired
// behavior in an object.
@interface DeferredCancellation : NSObject

- (instancetype)initWithCore:(scoped_refptr<net::HttpProtocolHandlerCore>)core;
- (void)cancel;

@end

@implementation DeferredCancellation {
  scoped_refptr<net::HttpProtocolHandlerCore> _core;
}

- (instancetype)initWithCore:(scoped_refptr<net::HttpProtocolHandlerCore>)core {
  if ((self = [super init])) {
    _core = core;
  }
  return self;
}

- (void)cancel {
  g_protocol_handler_delegate->GetDefaultURLRequestContext()
      ->GetNetworkTaskRunner()
      ->PostTask(FROM_HERE,
                 base::BindOnce(&net::HttpProtocolHandlerCore::Cancel, _core));
}

@end

#pragma mark -
#pragma mark HttpProtocolHandler

@interface CRNHTTPProtocolHandler (Private)

- (void)ensureProtocolHandlerProxyCreated;
- (void)cancelRequest;

@end

// The HttpProtocolHandler is called by the iOS system to handle the
// NSURLRequest.
@implementation CRNHTTPProtocolHandler {
  scoped_refptr<net::HttpProtocolHandlerCore> _core;
  id<CRNHTTPProtocolHandlerProxy> _protocolProxy;
  __weak NSThread* _clientThread;
  BOOL _supportedURL;
  NSURLSessionTask* _task;
}

#pragma mark NSURLProtocol methods

+ (BOOL)canInitWithRequest:(NSURLRequest*)request {
  DVLOG(5) << "canInitWithRequest " << net::FormatUrlRequestForLogging(request);
  return g_protocol_handler_delegate->CanHandleRequest(request);
}

+ (NSURLRequest*)canonicalRequestForRequest:(NSURLRequest*)request {
  // TODO(droger): Is this used if we disable the cache of UIWebView? If it is,
  // then we need a real implementation, even though Chrome network stack does
  // not need it (GURLs are automatically canonized).
  return request;
}

- (instancetype)initWithRequest:(NSURLRequest*)request
                 cachedResponse:(NSCachedURLResponse*)cachedResponse
                         client:(id<NSURLProtocolClient>)client {
  DCHECK(!cachedResponse);
  self = [super initWithRequest:request
                 cachedResponse:cachedResponse
                         client:client];
  if (self) {
    _supportedURL = g_protocol_handler_delegate->IsRequestSupported(request);
    _core = new net::HttpProtocolHandlerCore(request);
  }
  return self;
}

- (instancetype)initWithTask:(NSURLSessionTask*)task
              cachedResponse:(NSCachedURLResponse*)cachedResponse
                      client:(id<NSURLProtocolClient>)client {
  DCHECK(!cachedResponse);
  self = [super initWithTask:task cachedResponse:cachedResponse client:client];
  if (self) {
    _supportedURL =
        g_protocol_handler_delegate->IsRequestSupported(task.currentRequest);
    _core = new net::HttpProtocolHandlerCore(task);
    _task = task;
  }
  return self;
}

#pragma mark NSURLProtocol overrides.

- (NSCachedURLResponse*)cachedResponse {
  // We do not use the UIWebView cache.
  // TODO(droger): Disable the UIWebView cache.
  return nil;
}

- (void)startLoading {
  // If the scheme is not valid, just return an error right away.
  if (!_supportedURL) {
    NSMutableDictionary* dictionary = [NSMutableDictionary dictionary];

    // It is possible for URL to be nil, so check for that
    // before creating the error object. See http://crbug/349051
    NSURL* url = [[self request] URL];
    if (url)
      [dictionary setObject:url forKey:NSURLErrorKey];

    NSError* error = [NSError errorWithDomain:NSURLErrorDomain
                                         code:NSURLErrorUnsupportedURL
                                     userInfo:dictionary];
    [[self client] URLProtocol:self didFailWithError:error];
    return;
  }

  _clientThread = [NSThread currentThread];

  if (g_metrics_delegate) {
    g_metrics_delegate->OnStartNetRequest(_task);
  }

  // The closure passed to PostTask must to retain the _protocolProxy
  // scoped_nsobject. A call to ensureProtocolHandlerProxyCreated before passing
  // _protocolProxy ensure that _protocolProxy is instanciated before passing
  // it.
  [self ensureProtocolHandlerProxyCreated];
  DCHECK(_protocolProxy);
  g_protocol_handler_delegate->GetDefaultURLRequestContext()
      ->GetNetworkTaskRunner()
      ->PostTask(FROM_HERE, base::BindOnce(&net::HttpProtocolHandlerCore::Start,
                                           _core, _protocolProxy));
}

- (void)ensureProtocolHandlerProxyCreated {
  DCHECK_EQ([NSThread currentThread], _clientThread);
  if (!_protocolProxy) {
    _protocolProxy = [[CRNHTTPProtocolHandlerProxyWithClientThread alloc]
        initWithProtocol:self
            clientThread:_clientThread
             runLoopMode:[[NSRunLoop currentRunLoop] currentMode]];
  }
}

- (void)cancelRequest {
  g_protocol_handler_delegate->GetDefaultURLRequestContext()
      ->GetNetworkTaskRunner()
      ->PostTask(FROM_HERE,
                 base::BindOnce(&net::HttpProtocolHandlerCore::Cancel, _core));
  [_protocolProxy invalidate];
}

- (void)stopLoading {
  [self cancelRequest];
  _protocolProxy = nil;
}

@end
