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

#include <algorithm>
#include <cmath>
#include <sstream>
#include <string>

#include "include/base/cef_bind.h"
#include "include/base/cef_scoped_ptr.h"
#include "include/cef_request_context_handler.h"
#include "include/cef_scheme.h"
#include "include/wrapper/cef_closure_task.h"
#include "include/wrapper/cef_stream_resource_handler.h"
#include "tests/ceftests/routing_test_handler.h"
#include "tests/ceftests/test_handler.h"
#include "tests/ceftests/test_util.h"
#include "tests/gtest/include/gtest/gtest.h"

namespace {

// Normal stream resource handler implementation that additionally verifies
// calls to Cancel.
// This also tests the CefStreamResourceHandler implementation.
class NormalResourceHandler : public CefStreamResourceHandler {
 public:
  NormalResourceHandler(int status_code,
                        const CefString& status_text,
                        const CefString& mime_type,
                        CefResponse::HeaderMap header_map,
                        CefRefPtr<CefStreamReader> stream,
                        const base::Closure& destroy_callback)
      : CefStreamResourceHandler(status_code,
                                 status_text,
                                 mime_type,
                                 header_map,
                                 stream),
        destroy_callback_(destroy_callback) {}

  ~NormalResourceHandler() override {
    EXPECT_EQ(1, cancel_ct_);
    destroy_callback_.Run();
  }

  void Cancel() override {
    EXPECT_IO_THREAD();
    cancel_ct_++;
  }

 private:
  const base::Closure destroy_callback_;
  int cancel_ct_ = 0;
};

// Normal stream resource handler implementation that additionally continues
// using the callback object and verifies calls to Cancel.
class CallbackResourceHandler : public CefResourceHandler {
 public:
  enum Mode {
    DELAYED_OPEN,
    DELAYED_READ,
    IMMEDIATE_OPEN,
    IMMEDIATE_READ,
    DELAYED_ALL,
    IMMEDIATE_ALL,
  };

  bool IsDelayedOpen() const {
    return mode_ == DELAYED_OPEN || mode_ == DELAYED_ALL;
  }

  bool IsDelayedRead() const {
    return mode_ == DELAYED_READ || mode_ == DELAYED_ALL;
  }

  bool IsImmediateOpen() const {
    return mode_ == IMMEDIATE_OPEN || mode_ == IMMEDIATE_ALL;
  }

  bool IsImmediateRead() const {
    return mode_ == IMMEDIATE_READ || mode_ == IMMEDIATE_ALL;
  }

  CallbackResourceHandler(Mode mode,
                          int status_code,
                          const CefString& status_text,
                          const CefString& mime_type,
                          CefResponse::HeaderMap header_map,
                          CefRefPtr<CefStreamReader> stream,
                          const base::Closure& destroy_callback)
      : mode_(mode),
        status_code_(status_code),
        status_text_(status_text),
        mime_type_(mime_type),
        header_map_(header_map),
        stream_(stream),
        destroy_callback_(destroy_callback) {
    DCHECK(!mime_type_.empty());
    DCHECK(stream_.get());
  }

  ~CallbackResourceHandler() override {
    EXPECT_EQ(1, cancel_ct_);
    destroy_callback_.Run();
  }

  bool Open(CefRefPtr<CefRequest> request,
            bool& handle_request,
            CefRefPtr<CefCallback> callback) override {
    EXPECT_FALSE(CefCurrentlyOn(TID_UI) || CefCurrentlyOn(TID_IO));

    if (IsDelayedOpen()) {
      // Continue the request asynchronously by executing the callback.
      CefPostTask(TID_FILE_USER_VISIBLE,
                  base::Bind(&CefCallback::Continue, callback));
      handle_request = false;
      return true;
    } else if (IsImmediateOpen()) {
      // Continue the request immediately be executing the callback.
      callback->Continue();
      handle_request = false;
      return true;
    }

    // Continue the request immediately in the default manner.
    handle_request = true;
    return true;
  }

  void GetResponseHeaders(CefRefPtr<CefResponse> response,
                          int64& response_length,
                          CefString& redirectUrl) override {
    response->SetStatus(status_code_);
    response->SetStatusText(status_text_);
    response->SetMimeType(mime_type_);

    if (!header_map_.empty())
      response->SetHeaderMap(header_map_);

    response_length = -1;
  }

  bool Read(void* data_out,
            int bytes_to_read,
            int& bytes_read,
            CefRefPtr<CefResourceReadCallback> callback) override {
    EXPECT_FALSE(CefCurrentlyOn(TID_UI) || CefCurrentlyOn(TID_IO));
    EXPECT_GT(bytes_to_read, 0);

    bytes_read = 0;

    if (IsDelayedRead()) {
      // Continue the request asynchronously by executing the callback.
      CefPostTask(TID_FILE_USER_VISIBLE,
                  base::Bind(&CallbackResourceHandler::ContinueRead, this,
                             data_out, bytes_to_read, callback));
      return true;
    } else if (IsImmediateRead()) {
      // Continue the request immediately be executing the callback.
      ContinueRead(data_out, bytes_to_read, callback);
      return true;
    }

    // Continue the request immediately in the default manner.
    return DoRead(data_out, bytes_to_read, bytes_read);
  }

  void Cancel() override {
    EXPECT_IO_THREAD();
    cancel_ct_++;
  }

 private:
  void ContinueRead(void* data_out,
                    int bytes_to_read,
                    CefRefPtr<CefResourceReadCallback> callback) {
    EXPECT_FALSE(CefCurrentlyOn(TID_UI) || CefCurrentlyOn(TID_IO));

    int bytes_read = 0;
    DoRead(data_out, bytes_to_read, bytes_read);
    callback->Continue(bytes_read);
  }

  bool DoRead(void* data_out, int bytes_to_read, int& bytes_read) {
    DCHECK_GT(bytes_to_read, 0);

    // Read until the buffer is full or until Read() returns 0 to indicate no
    // more data.
    bytes_read = 0;
    int read = 0;
    do {
      read = static_cast<int>(
          stream_->Read(static_cast<char*>(data_out) + bytes_read, 1,
                        bytes_to_read - bytes_read));
      bytes_read += read;
    } while (read != 0 && bytes_read < bytes_to_read);

    return (bytes_read > 0);
  }

  const Mode mode_;

  const int status_code_;
  const CefString status_text_;
  const CefString mime_type_;
  const CefResponse::HeaderMap header_map_;
  const CefRefPtr<CefStreamReader> stream_;

  const base::Closure destroy_callback_;
  int cancel_ct_ = 0;

  IMPLEMENT_REFCOUNTING(CallbackResourceHandler);
  DISALLOW_COPY_AND_ASSIGN(CallbackResourceHandler);
};

// Resource handler implementation that never completes. Used to test
// destruction handling behavior for in-progress requests.
class IncompleteResourceHandlerOld : public CefResourceHandler {
 public:
  enum TestMode {
    BLOCK_PROCESS_REQUEST,
    BLOCK_READ_RESPONSE,
  };

  IncompleteResourceHandlerOld(TestMode test_mode,
                               const std::string& mime_type,
                               const base::Closure& destroy_callback)
      : test_mode_(test_mode),
        mime_type_(mime_type),
        destroy_callback_(destroy_callback) {}

  ~IncompleteResourceHandlerOld() override {
    EXPECT_EQ(1, process_request_ct_);

    EXPECT_EQ(1, cancel_ct_);

    if (test_mode_ == BLOCK_READ_RESPONSE) {
      EXPECT_EQ(1, get_response_headers_ct_);
      EXPECT_EQ(1, read_response_ct_);
    } else {
      EXPECT_EQ(0, get_response_headers_ct_);
      EXPECT_EQ(0, read_response_ct_);
    }

    destroy_callback_.Run();
  }

  bool ProcessRequest(CefRefPtr<CefRequest> request,
                      CefRefPtr<CefCallback> callback) override {
    EXPECT_IO_THREAD();

    process_request_ct_++;

    if (test_mode_ == BLOCK_PROCESS_REQUEST) {
      // Never release or execute this callback.
      incomplete_callback_ = callback;
    } else {
      callback->Continue();
    }
    return true;
  }

  void GetResponseHeaders(CefRefPtr<CefResponse> response,
                          int64& response_length,
                          CefString& redirectUrl) override {
    EXPECT_IO_THREAD();
    EXPECT_EQ(test_mode_, BLOCK_READ_RESPONSE);

    get_response_headers_ct_++;

    response->SetStatus(200);
    response->SetStatusText("OK");
    response->SetMimeType(mime_type_);
    response_length = 100;
  }

  bool ReadResponse(void* data_out,
                    int bytes_to_read,
                    int& bytes_read,
                    CefRefPtr<CefCallback> callback) override {
    EXPECT_IO_THREAD();
    EXPECT_EQ(test_mode_, BLOCK_READ_RESPONSE);

    read_response_ct_++;

    // Never release or execute this callback.
    incomplete_callback_ = callback;
    bytes_read = 0;
    return true;
  }

  void Cancel() override {
    EXPECT_IO_THREAD();
    cancel_ct_++;
  }

 private:
  const TestMode test_mode_;
  const std::string mime_type_;
  const base::Closure destroy_callback_;

  int process_request_ct_ = 0;
  int get_response_headers_ct_ = 0;
  int read_response_ct_ = 0;
  int cancel_ct_ = 0;

  CefRefPtr<CefCallback> incomplete_callback_;

  IMPLEMENT_REFCOUNTING(IncompleteResourceHandlerOld);
  DISALLOW_COPY_AND_ASSIGN(IncompleteResourceHandlerOld);
};

class IncompleteResourceHandler : public CefResourceHandler {
 public:
  enum TestMode {
    BLOCK_OPEN,
    BLOCK_READ,
  };

  IncompleteResourceHandler(TestMode test_mode,
                            const std::string& mime_type,
                            const base::Closure& destroy_callback)
      : test_mode_(test_mode),
        mime_type_(mime_type),
        destroy_callback_(destroy_callback) {}

  ~IncompleteResourceHandler() override {
    EXPECT_EQ(1, open_ct_);

    EXPECT_EQ(1, cancel_ct_);

    if (test_mode_ == BLOCK_READ) {
      EXPECT_EQ(1, get_response_headers_ct_);
      EXPECT_EQ(1, read_ct_);
    } else {
      EXPECT_EQ(0, get_response_headers_ct_);
      EXPECT_EQ(0, read_ct_);
    }

    destroy_callback_.Run();
  }

  bool Open(CefRefPtr<CefRequest> request,
            bool& handle_request,
            CefRefPtr<CefCallback> callback) override {
    EXPECT_FALSE(CefCurrentlyOn(TID_UI) || CefCurrentlyOn(TID_IO));

    open_ct_++;

    if (test_mode_ == BLOCK_OPEN) {
      // Never release or execute this callback.
      incomplete_open_callback_ = callback;
    } else {
      // Continue immediately.
      handle_request = true;
    }
    return true;
  }

  bool ProcessRequest(CefRefPtr<CefRequest> request,
                      CefRefPtr<CefCallback> callback) override {
    EXPECT_TRUE(false);  // Not reached.
    return false;
  }

  void GetResponseHeaders(CefRefPtr<CefResponse> response,
                          int64& response_length,
                          CefString& redirectUrl) override {
    EXPECT_IO_THREAD();
    EXPECT_EQ(test_mode_, BLOCK_READ);

    get_response_headers_ct_++;

    response->SetStatus(200);
    response->SetStatusText("OK");
    response->SetMimeType(mime_type_);
    response_length = 100;
  }

  bool Read(void* data_out,
            int bytes_to_read,
            int& bytes_read,
            CefRefPtr<CefResourceReadCallback> callback) override {
    EXPECT_FALSE(CefCurrentlyOn(TID_UI) || CefCurrentlyOn(TID_IO));
    EXPECT_EQ(test_mode_, BLOCK_READ);

    read_ct_++;

    // Never release or execute this callback.
    incomplete_read_callback_ = callback;
    bytes_read = 0;
    return true;
  }

  bool ReadResponse(void* data_out,
                    int bytes_to_read,
                    int& bytes_read,
                    CefRefPtr<CefCallback> callback) override {
    EXPECT_TRUE(false);  // Not reached.
    bytes_read = -2;
    return false;
  }

  void Cancel() override {
    EXPECT_IO_THREAD();
    cancel_ct_++;
  }

 private:
  const TestMode test_mode_;
  const std::string mime_type_;
  const base::Closure destroy_callback_;

  int open_ct_ = 0;
  int get_response_headers_ct_ = 0;
  int read_ct_ = 0;
  int cancel_ct_ = 0;

  CefRefPtr<CefCallback> incomplete_open_callback_;
  CefRefPtr<CefResourceReadCallback> incomplete_read_callback_;

  IMPLEMENT_REFCOUNTING(IncompleteResourceHandler);
  DISALLOW_COPY_AND_ASSIGN(IncompleteResourceHandler);
};

class BasicResponseTest : public TestHandler {
 public:
  enum TestMode {
    // Normal load, nothing fancy.
    LOAD,

    // Close the browser in OnAfterCreated to verify destruction handling of
    // uninitialized requests.
    ABORT_AFTER_CREATED,

    // Close the browser in OnBeforeBrowse to verify destruction handling of
    // uninitialized requests.
    ABORT_BEFORE_BROWSE,

    // Don't continue from OnBeforeResourceLoad, then close the browser to
    // verify destruction handling of in-progress requests.
    INCOMPLETE_BEFORE_RESOURCE_LOAD,

    // Modify the request (add headers) in OnBeforeResourceLoad.
    MODIFY_BEFORE_RESOURCE_LOAD,

    // Redirect the request (change the URL) in OnBeforeResourceLoad.
    REDIRECT_BEFORE_RESOURCE_LOAD,

    // Return a CefResourceHandler from GetResourceHandler that continues
    // immediately by using the callback object instead of the return value.
    IMMEDIATE_REQUEST_HANDLER_OPEN,
    IMMEDIATE_REQUEST_HANDLER_READ,
    IMMEDIATE_REQUEST_HANDLER_ALL,

    // Return a CefResourceHandler from GetResourceHandler that continues with
    // a delay by using the callback object.
    DELAYED_REQUEST_HANDLER_OPEN,
    DELAYED_REQUEST_HANDLER_READ,
    DELAYED_REQUEST_HANDLER_ALL,

    // Return a CefResourceHandler from GetResourceHandler that never completes,
    // then close the browser to verify destruction handling of in-progress
    // requests.
    INCOMPLETE_REQUEST_HANDLER_OPEN,
    INCOMPLETE_REQUEST_HANDLER_READ,

    // Redirect the request using a CefResourceHandler returned from
    // GetResourceHandler.
    REDIRECT_REQUEST_HANDLER,

    // Redirect the request (change the URL) an additional time in
    // OnResourceRedirect after using a CefResourceHandler returned from
    // GetResourceHandler for the first redirect.
    REDIRECT_RESOURCE_REDIRECT,

    // Redirect the request (change the URL) in OnResourceResponse.
    REDIRECT_RESOURCE_RESPONSE,

    // Restart the request (add headers) in OnResourceResponse.
    RESTART_RESOURCE_RESPONSE,
  };

  // If |custom_scheme| is true all requests will use a custom scheme.
  // If |unhandled| is true the final request (after any redirects) will be
  // unhandled, meaning that default handling is disabled and GetResourceHandler
  // returns null.
  BasicResponseTest(TestMode mode, bool custom_scheme, bool unhandled)
      : mode_(mode), custom_scheme_(custom_scheme), unhandled_(unhandled) {}

  void RunTest() override {
    CreateBrowser(GetStartupURL());
    SetTestTimeout();
  }

  void OnAfterCreated(CefRefPtr<CefBrowser> browser) override {
    EXPECT_UI_THREAD();
    TestHandler::OnAfterCreated(browser);

    if (mode_ == ABORT_AFTER_CREATED) {
      SetSignalCompletionWhenAllBrowsersClose(false);
      CloseBrowser(browser, false);
    }
  }

  void OnBeforeClose(CefRefPtr<CefBrowser> browser) override {
    EXPECT_UI_THREAD();
    TestHandler::OnBeforeClose(browser);

    if (IsAborted()) {
      DestroyTest();
    }
  }

  bool OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
                      CefRefPtr<CefFrame> frame,
                      CefRefPtr<CefRequest> request,
                      bool user_gesture,
                      bool is_redirect) override {
    EXPECT_UI_THREAD();
    if (browser_id_ == 0) {
      // This is the first callback that provides a browser ID.
      browser_id_ = browser->GetIdentifier();
      EXPECT_GT(browser_id_, 0);
    } else {
      EXPECT_EQ(browser_id_, browser->GetIdentifier());
    }
    EXPECT_TRUE(frame->IsMain());

    EXPECT_FALSE(user_gesture);
    if (on_before_browse_ct_ == 0 || mode_ == RESTART_RESOURCE_RESPONSE) {
      EXPECT_FALSE(is_redirect) << on_before_browse_ct_;
    } else {
      EXPECT_TRUE(is_redirect) << on_before_browse_ct_;
    }

    on_before_browse_ct_++;

    VerifyState(kOnBeforeBrowse, request, nullptr);

    if (mode_ == ABORT_BEFORE_BROWSE) {
      SetSignalCompletionWhenAllBrowsersClose(false);
      CloseBrowser(browser, false);
    }

    return false;
  }

  CefRefPtr<CefResourceRequestHandler> GetResourceRequestHandler(
      CefRefPtr<CefBrowser> browser,
      CefRefPtr<CefFrame> frame,
      CefRefPtr<CefRequest> request,
      bool is_navigation,
      bool is_download,
      const CefString& request_initiator,
      bool& disable_default_handling) override {
    EXPECT_IO_THREAD();
    EXPECT_EQ(browser_id_, browser->GetIdentifier());
    EXPECT_TRUE(frame->IsMain());

    if (request_id_ == 0U) {
      // This is the first callback that provides a request ID.
      request_id_ = request->GetIdentifier();
      EXPECT_GT(request_id_, 0U);
    }

    VerifyState(kGetResourceRequestHandler, request, nullptr);

    EXPECT_TRUE(is_navigation);
    EXPECT_FALSE(is_download);
    EXPECT_STREQ("null", request_initiator.ToString().c_str());

    // Check expected default value.
    if (custom_scheme_) {
      // There is no default handling for custom schemes.
      EXPECT_TRUE(disable_default_handling);
    } else {
      EXPECT_FALSE(disable_default_handling);
      // If |unhandled_| is true then we don't want default handling of requests
      // (e.g. attempts to resolve over the network).
      disable_default_handling = unhandled_;
    }

    get_resource_request_handler_ct_++;

    return this;
  }

  CefRefPtr<CefCookieAccessFilter> GetCookieAccessFilter(
      CefRefPtr<CefBrowser> browser,
      CefRefPtr<CefFrame> frame,
      CefRefPtr<CefRequest> request) override {
    EXPECT_IO_THREAD();
    EXPECT_EQ(browser_id_, browser->GetIdentifier());
    EXPECT_TRUE(frame->IsMain());

    VerifyState(kGetCookieAccessFilter, request, nullptr);

    get_cookie_access_filter_ct_++;

    return nullptr;
  }

  cef_return_value_t OnBeforeResourceLoad(
      CefRefPtr<CefBrowser> browser,
      CefRefPtr<CefFrame> frame,
      CefRefPtr<CefRequest> request,
      CefRefPtr<CefRequestCallback> callback) override {
    EXPECT_IO_THREAD();
    EXPECT_EQ(browser_id_, browser->GetIdentifier());
    EXPECT_TRUE(frame->IsMain());

    VerifyState(kOnBeforeResourceLoad, request, nullptr);

    on_before_resource_load_ct_++;

    if (mode_ == INCOMPLETE_BEFORE_RESOURCE_LOAD) {
      incomplete_callback_ = callback;

      // Close the browser asynchronously to complete the test.
      CloseBrowserAsync();
      return RV_CONTINUE_ASYNC;
    }

    if (mode_ == MODIFY_BEFORE_RESOURCE_LOAD) {
      // Expect this data in the request for future callbacks.
      SetCustomHeader(request);
    } else if (mode_ == REDIRECT_BEFORE_RESOURCE_LOAD) {
      // Redirect to this URL.
      request->SetURL(GetURL(RESULT_HTML));
    }

    // Other continuation modes are tested by
    // ResourceRequestHandlerTest.BeforeResourceLoad*.
    return RV_CONTINUE;
  }

  CefRefPtr<CefResourceHandler> GetResourceHandler(
      CefRefPtr<CefBrowser> browser,
      CefRefPtr<CefFrame> frame,
      CefRefPtr<CefRequest> request) override {
    EXPECT_IO_THREAD();
    EXPECT_EQ(browser_id_, browser->GetIdentifier());
    EXPECT_TRUE(frame->IsMain());

    VerifyState(kGetResourceHandler, request, nullptr);

    get_resource_handler_ct_++;

    if (IsIncompleteRequestHandler()) {
      // Close the browser asynchronously to complete the test.
      CloseBrowserAsync();
      return GetIncompleteResource();
    }

    const std::string& url = request->GetURL();
    if (url == GetURL(RESULT_HTML) && mode_ == RESTART_RESOURCE_RESPONSE) {
      if (get_resource_handler_ct_ == 1) {
        // First request that will be restarted after response.
        return GetOKResource();
      } else {
        // Restarted request.
        if (unhandled_)
          return nullptr;
        return GetOKResource();
      }
    } else if (url == GetURL(RESULT_HTML)) {
      if (unhandled_)
        return nullptr;
      return GetOKResource();
    } else if (url == GetURL(REDIRECT_HTML) &&
               mode_ == REDIRECT_RESOURCE_RESPONSE) {
      if (get_resource_handler_ct_ == 1) {
        // First request that will be redirected after response.
        return GetOKResource();
      } else {
        // Redirected request.
        if (unhandled_)
          return nullptr;
        return GetOKResource();
      }
    } else if (url == GetURL(REDIRECT_HTML) || url == GetURL(REDIRECT2_HTML)) {
      std::string redirect_url;
      if (mode_ == REDIRECT_REQUEST_HANDLER ||
          mode_ == REDIRECT_RESOURCE_RESPONSE) {
        EXPECT_STREQ(GetURL(REDIRECT_HTML), url.c_str());
        redirect_url = GetURL(RESULT_HTML);
      } else if (mode_ == REDIRECT_RESOURCE_REDIRECT) {
        EXPECT_STREQ(GetURL(REDIRECT2_HTML), url.c_str());
        redirect_url = GetURL(REDIRECT_HTML);
      } else {
        NOTREACHED();
      }

      return GetRedirectResource(redirect_url);
    } else {
      NOTREACHED();
      return nullptr;
    }
  }

  void OnResourceRedirect(CefRefPtr<CefBrowser> browser,
                          CefRefPtr<CefFrame> frame,
                          CefRefPtr<CefRequest> request,
                          CefRefPtr<CefResponse> response,
                          CefString& new_url) override {
    EXPECT_IO_THREAD();
    EXPECT_EQ(browser_id_, browser->GetIdentifier());
    EXPECT_TRUE(frame->IsMain());

    VerifyState(kOnResourceRedirect, request, response);

    if (mode_ == REDIRECT_REQUEST_HANDLER ||
        mode_ == REDIRECT_RESOURCE_RESPONSE) {
      // The URL redirected to from GetResourceHandler or OnResourceResponse.
      EXPECT_STREQ(GetURL(RESULT_HTML), new_url.ToString().c_str());
    } else if (mode_ == REDIRECT_RESOURCE_REDIRECT) {
      if (on_resource_redirect_ct_ == 0) {
        // The URL redirected to from GetResourceHandler.
        EXPECT_STREQ(GetURL(REDIRECT_HTML), new_url.ToString().c_str());
        // Redirect again.
        new_url = GetURL(RESULT_HTML);
      } else {
        NOTREACHED();
      }
    }

    on_resource_redirect_ct_++;
  }

  bool OnResourceResponse(CefRefPtr<CefBrowser> browser,
                          CefRefPtr<CefFrame> frame,
                          CefRefPtr<CefRequest> request,
                          CefRefPtr<CefResponse> response) override {
    EXPECT_IO_THREAD();
    EXPECT_EQ(browser_id_, browser->GetIdentifier());
    EXPECT_TRUE(frame->IsMain());

    VerifyState(kOnResourceResponse, request, response);

    on_resource_response_ct_++;

    if (on_resource_response_ct_ == 1) {
      if (mode_ == REDIRECT_RESOURCE_RESPONSE) {
        // Redirect the request to this URL.
        request->SetURL(GetURL(RESULT_HTML));
        return true;
      } else if (mode_ == RESTART_RESOURCE_RESPONSE) {
        // Restart the request loading this data.
        SetCustomHeader(request);
        return true;
      }
    }

    return false;
  }

  CefRefPtr<CefResponseFilter> GetResourceResponseFilter(
      CefRefPtr<CefBrowser> browser,
      CefRefPtr<CefFrame> frame,
      CefRefPtr<CefRequest> request,
      CefRefPtr<CefResponse> response) override {
    EXPECT_IO_THREAD();
    EXPECT_EQ(browser_id_, browser->GetIdentifier());
    EXPECT_TRUE(frame->IsMain());

    VerifyState(kGetResourceResponseFilter, request, response);

    get_resource_response_filter_ct_++;

    return nullptr;
  }

  void OnResourceLoadComplete(CefRefPtr<CefBrowser> browser,
                              CefRefPtr<CefFrame> frame,
                              CefRefPtr<CefRequest> request,
                              CefRefPtr<CefResponse> response,
                              URLRequestStatus status,
                              int64 received_content_length) override {
    EXPECT_IO_THREAD();
    EXPECT_EQ(browser_id_, browser->GetIdentifier());
    EXPECT_TRUE(frame->IsMain());

    VerifyState(kOnResourceLoadComplete, request, response);

    if (unhandled_ || IsIncomplete() || IsAborted()) {
      EXPECT_EQ(UR_FAILED, status);
      EXPECT_EQ(0, received_content_length);
    } else {
      EXPECT_EQ(UR_SUCCESS, status);
      EXPECT_EQ(static_cast<int64>(GetResponseBody().length()),
                received_content_length);
    }

    on_resource_load_complete_ct_++;

    if (IsIncomplete()) {
      MaybeDestroyTest(false);
    }
  }

  void OnProtocolExecution(CefRefPtr<CefBrowser> browser,
                           CefRefPtr<CefFrame> frame,
                           CefRefPtr<CefRequest> request,
                           bool& allow_os_execution) override {
    EXPECT_IO_THREAD();
    EXPECT_EQ(browser_id_, browser->GetIdentifier());
    EXPECT_TRUE(frame->IsMain());

    EXPECT_TRUE(custom_scheme_);
    EXPECT_TRUE(unhandled_);

    // Check expected default value.
    EXPECT_FALSE(allow_os_execution);

    VerifyState(kOnProtocolExecution, request, nullptr);
    on_protocol_execution_ct_++;
  }

  void OnLoadEnd(CefRefPtr<CefBrowser> browser,
                 CefRefPtr<CefFrame> frame,
                 int httpStatusCode) override {
    EXPECT_UI_THREAD();
    EXPECT_EQ(browser_id_, browser->GetIdentifier());
    EXPECT_TRUE(frame->IsMain());

    if (unhandled_)
      EXPECT_EQ(httpStatusCode, 0);
    else
      EXPECT_EQ(httpStatusCode, 200);

    on_load_end_ct_++;

    TestHandler::OnLoadEnd(browser, frame, httpStatusCode);
    DestroyTest();
  }

  void DestroyTest() override {
    if (mode_ == RESTART_RESOURCE_RESPONSE) {
      EXPECT_EQ(1, on_before_browse_ct_);
      EXPECT_EQ(2, get_resource_request_handler_ct_);
      EXPECT_EQ(2, get_cookie_access_filter_ct_);
      EXPECT_EQ(2, on_before_resource_load_ct_);
      EXPECT_EQ(2, get_resource_handler_ct_);
      EXPECT_EQ(0, on_resource_redirect_ct_);
      // Unhandled requests won't see a call to GetResourceResponseFilter or
      // OnResourceResponse. In this case we're restarting from inside
      // OnResourceResponse.
      if (unhandled_) {
        EXPECT_EQ(0, get_resource_response_filter_ct_);
        EXPECT_EQ(1, on_resource_response_ct_);
      } else {
        EXPECT_EQ(1, get_resource_response_filter_ct_);
        EXPECT_EQ(2, on_resource_response_ct_);
      }
    } else if (IsLoad()) {
      EXPECT_EQ(1, on_before_browse_ct_);
      EXPECT_EQ(1, get_resource_request_handler_ct_);
      EXPECT_EQ(1, get_cookie_access_filter_ct_);
      EXPECT_EQ(1, on_before_resource_load_ct_);
      EXPECT_EQ(1, get_resource_handler_ct_);
      EXPECT_EQ(0, on_resource_redirect_ct_);

      // Unhandled requests won't see a call to GetResourceResponseFilter
      // or OnResourceResponse.
      if (unhandled_) {
        EXPECT_EQ(0, get_resource_response_filter_ct_);
        EXPECT_EQ(0, on_resource_response_ct_);
      } else {
        EXPECT_EQ(1, get_resource_response_filter_ct_);
        EXPECT_EQ(1, on_resource_response_ct_);
      }
    } else if (IsRedirect()) {
      EXPECT_EQ(2, on_before_browse_ct_);
      EXPECT_EQ(2, get_resource_request_handler_ct_);
      EXPECT_EQ(2, get_cookie_access_filter_ct_);
      EXPECT_EQ(2, on_before_resource_load_ct_);
      if (mode_ == REDIRECT_BEFORE_RESOURCE_LOAD) {
        EXPECT_EQ(1, get_resource_handler_ct_);
      } else {
        EXPECT_EQ(2, get_resource_handler_ct_);
      }
      EXPECT_EQ(1, on_resource_redirect_ct_);

      // Unhandled requests won't see a call to GetResourceResponseFilter.
      if (unhandled_) {
        EXPECT_EQ(0, get_resource_response_filter_ct_);
      } else {
        EXPECT_EQ(1, get_resource_response_filter_ct_);
      }

      // Unhandled requests won't see a call to OnResourceResponse.
      if (mode_ == REDIRECT_RESOURCE_RESPONSE) {
        // In this case we're redirecting from inside OnResourceResponse.
        if (unhandled_) {
          EXPECT_EQ(1, on_resource_response_ct_);
        } else {
          EXPECT_EQ(2, on_resource_response_ct_);
        }
      } else {
        if (unhandled_) {
          EXPECT_EQ(0, on_resource_response_ct_);
        } else {
          EXPECT_EQ(1, on_resource_response_ct_);
        }
      }
    } else if (IsIncomplete()) {
      EXPECT_EQ(1, on_before_browse_ct_);
      EXPECT_EQ(1, get_resource_request_handler_ct_);
      EXPECT_EQ(1, get_cookie_access_filter_ct_);
      EXPECT_EQ(1, on_before_resource_load_ct_);

      if (IsIncompleteRequestHandler()) {
        EXPECT_EQ(1, get_resource_handler_ct_);
      } else {
        EXPECT_EQ(0, get_resource_handler_ct_);
      }

      EXPECT_EQ(0, on_resource_redirect_ct_);

      if (mode_ == INCOMPLETE_REQUEST_HANDLER_READ) {
        EXPECT_EQ(1, get_resource_response_filter_ct_);
        EXPECT_EQ(1, on_resource_response_ct_);
      } else {
        EXPECT_EQ(0, get_resource_response_filter_ct_);
        EXPECT_EQ(0, on_resource_response_ct_);
      }
    } else if (IsAborted()) {
      EXPECT_EQ(1, on_before_browse_ct_);
      if (custom_scheme_) {
        EXPECT_EQ(0, get_resource_request_handler_ct_);
        EXPECT_EQ(0, get_cookie_access_filter_ct_);
      } else {
        // The callbacks executed for standard schemes may vary based on timing.
      }
      EXPECT_EQ(0, on_before_resource_load_ct_);
      EXPECT_EQ(0, get_resource_handler_ct_);
      EXPECT_EQ(0, on_resource_redirect_ct_);
      EXPECT_EQ(0, get_resource_response_filter_ct_);
      EXPECT_EQ(0, on_resource_response_ct_);
    } else {
      NOTREACHED();
    }

    EXPECT_EQ(resource_handler_created_ct_, resource_handler_destroyed_ct_);

    if (IsAborted()) {
      EXPECT_EQ(0, on_resource_load_complete_ct_);
    } else {
      EXPECT_EQ(1, on_resource_load_complete_ct_);
    }

    if (IsIncomplete() || IsAborted()) {
      EXPECT_EQ(0, on_load_end_ct_);
    } else {
      EXPECT_EQ(1, on_load_end_ct_);
    }

    if (custom_scheme_ && unhandled_ && !(IsIncomplete() || IsAborted())) {
      EXPECT_EQ(1, on_protocol_execution_ct_);
    } else {
      EXPECT_EQ(0, on_protocol_execution_ct_);
    }

    TestHandler::DestroyTest();

    if (!SignalCompletionWhenAllBrowsersClose()) {
      // Complete asynchronously so the call stack has a chance to unwind.
      CefPostTask(TID_UI, base::Bind(&BasicResponseTest::TestComplete, this));
    }
  }

 private:
  enum TestUrl {
    RESULT_HTML,
    REDIRECT_HTML,
    REDIRECT2_HTML,
  };

  const char* GetURL(TestUrl url) const {
    if (custom_scheme_) {
      if (url == RESULT_HTML)
        return "rrhcustom://test.com/result.html";
      if (url == REDIRECT_HTML)
        return "rrhcustom://test.com/redirect.html";
      if (url == REDIRECT2_HTML)
        return "rrhcustom://test.com/redirect2.html";
    } else {
      if (url == RESULT_HTML)
        return "http://test.com/result.html";
      if (url == REDIRECT_HTML)
        return "http://test.com/redirect.html";
      if (url == REDIRECT2_HTML)
        return "http://test.com/redirect2.html";
    }

    NOTREACHED();
    return "";
  }

  const char* GetStartupURL() const {
    if (IsLoad() || IsIncomplete() || IsAborted()) {
      return GetURL(RESULT_HTML);
    } else if (mode_ == REDIRECT_RESOURCE_REDIRECT) {
      return GetURL(REDIRECT2_HTML);
    } else if (IsRedirect()) {
      return GetURL(REDIRECT_HTML);
    }

    NOTREACHED();
    return "";
  }

  std::string GetResponseBody() const {
    return "<html><body>Response</body></html>";
  }
  std::string GetRedirectBody() const {
    return "<html><body>Redirect</body></html>";
  }

  base::Closure GetResourceDestroyCallback() {
    resource_handler_created_ct_++;
    return base::Bind(&BasicResponseTest::MaybeDestroyTest, this, true);
  }

  bool GetCallbackResourceHandlerMode(CallbackResourceHandler::Mode& mode) {
    switch (mode_) {
      case IMMEDIATE_REQUEST_HANDLER_OPEN:
        mode = CallbackResourceHandler::IMMEDIATE_OPEN;
        return true;
      case IMMEDIATE_REQUEST_HANDLER_READ:
        mode = CallbackResourceHandler::IMMEDIATE_READ;
        return true;
      case IMMEDIATE_REQUEST_HANDLER_ALL:
        mode = CallbackResourceHandler::IMMEDIATE_ALL;
        return true;
      case DELAYED_REQUEST_HANDLER_OPEN:
        mode = CallbackResourceHandler::DELAYED_OPEN;
        return true;
      case DELAYED_REQUEST_HANDLER_READ:
        mode = CallbackResourceHandler::DELAYED_READ;
        return true;
      case DELAYED_REQUEST_HANDLER_ALL:
        mode = CallbackResourceHandler::DELAYED_ALL;
        return true;
      default:
        break;
    }
    return false;
  }

  CefRefPtr<CefResourceHandler> GetResource(int status_code,
                                            const CefString& status_text,
                                            const CefString& mime_type,
                                            CefResponse::HeaderMap header_map,
                                            const std::string& body) {
    CefRefPtr<CefStreamReader> stream = CefStreamReader::CreateForData(
        const_cast<char*>(body.c_str()), body.size());

    CallbackResourceHandler::Mode handler_mode;
    if (GetCallbackResourceHandlerMode(handler_mode)) {
      return new CallbackResourceHandler(handler_mode, status_code, status_text,
                                         mime_type, header_map, stream,
                                         GetResourceDestroyCallback());
    }

    return new NormalResourceHandler(status_code, status_text, mime_type,
                                     header_map, stream,
                                     GetResourceDestroyCallback());
  }

  CefRefPtr<CefResourceHandler> GetOKResource() {
    return GetResource(200, "OK", "text/html", CefResponse::HeaderMap(),
                       GetResponseBody());
  }

  CefRefPtr<CefResourceHandler> GetRedirectResource(
      const std::string& redirect_url) {
    CefResponse::HeaderMap headerMap;
    headerMap.insert(std::make_pair("Location", redirect_url));

    return GetResource(307, "Temporary Redirect", "text/html", headerMap,
                       GetRedirectBody());
  }

  CefRefPtr<CefResourceHandler> GetIncompleteResource() {
    if (TestOldResourceAPI()) {
      return new IncompleteResourceHandlerOld(
          mode_ == INCOMPLETE_REQUEST_HANDLER_OPEN
              ? IncompleteResourceHandlerOld::BLOCK_PROCESS_REQUEST
              : IncompleteResourceHandlerOld::BLOCK_READ_RESPONSE,
          "text/html", GetResourceDestroyCallback());
    }

    return new IncompleteResourceHandler(
        mode_ == INCOMPLETE_REQUEST_HANDLER_OPEN
            ? IncompleteResourceHandler::BLOCK_OPEN
            : IncompleteResourceHandler::BLOCK_READ,
        "text/html", GetResourceDestroyCallback());
  }

  bool IsLoad() const {
    return mode_ == LOAD || mode_ == MODIFY_BEFORE_RESOURCE_LOAD ||
           mode_ == RESTART_RESOURCE_RESPONSE ||
           mode_ == IMMEDIATE_REQUEST_HANDLER_OPEN ||
           mode_ == IMMEDIATE_REQUEST_HANDLER_READ ||
           mode_ == IMMEDIATE_REQUEST_HANDLER_ALL ||
           mode_ == DELAYED_REQUEST_HANDLER_OPEN ||
           mode_ == DELAYED_REQUEST_HANDLER_READ ||
           mode_ == DELAYED_REQUEST_HANDLER_ALL;
  }

  bool IsIncompleteRequestHandler() const {
    return mode_ == INCOMPLETE_REQUEST_HANDLER_OPEN ||
           mode_ == INCOMPLETE_REQUEST_HANDLER_READ;
  }

  bool IsIncomplete() const {
    return mode_ == INCOMPLETE_BEFORE_RESOURCE_LOAD ||
           IsIncompleteRequestHandler();
  }

  bool IsAborted() const {
    return mode_ == ABORT_AFTER_CREATED || mode_ == ABORT_BEFORE_BROWSE;
  }

  bool IsRedirect() const {
    return mode_ == REDIRECT_BEFORE_RESOURCE_LOAD ||
           mode_ == REDIRECT_REQUEST_HANDLER ||
           mode_ == REDIRECT_RESOURCE_REDIRECT ||
           mode_ == REDIRECT_RESOURCE_RESPONSE;
  }

  static void SetCustomHeader(CefRefPtr<CefRequest> request) {
    EXPECT_FALSE(request->IsReadOnly());
    request->SetHeaderByName("X-Custom-Header", "value", false);
  }

  static std::string GetCustomHeader(CefRefPtr<CefRequest> request) {
    return request->GetHeaderByName("X-Custom-Header");
  }

  // Resource-related callbacks.
  enum Callback {
    kOnBeforeBrowse,
    kGetResourceRequestHandler,
    kGetCookieAccessFilter,
    kOnBeforeResourceLoad,
    kGetResourceHandler,
    kOnResourceRedirect,
    kOnResourceResponse,
    kGetResourceResponseFilter,
    kOnResourceLoadComplete,
    kOnProtocolExecution,
  };

  bool ShouldHaveResponse(Callback callback) const {
    return callback >= kOnResourceRedirect &&
           callback <= kOnResourceLoadComplete;
  }

  bool ShouldHaveWritableRequest(Callback callback) const {
    return callback == kOnBeforeResourceLoad || callback == kOnResourceResponse;
  }

  void VerifyState(Callback callback,
                   CefRefPtr<CefRequest> request,
                   CefRefPtr<CefResponse> response) const {
    EXPECT_TRUE(request) << callback;

    if (ShouldHaveResponse(callback)) {
      EXPECT_TRUE(response) << callback;
      EXPECT_TRUE(response->IsReadOnly()) << callback;
    } else {
      EXPECT_FALSE(response) << callback;
    }

    if (ShouldHaveWritableRequest(callback)) {
      EXPECT_FALSE(request->IsReadOnly()) << callback;
    } else {
      EXPECT_TRUE(request->IsReadOnly()) << callback;
    }

    if (callback == kOnBeforeBrowse) {
      // Browser-side navigation no longer exposes the actual request
      // information.
      EXPECT_EQ(0U, request->GetIdentifier()) << callback;
    } else {
      // All resource-related callbacks share the same request ID.
      EXPECT_EQ(request_id_, request->GetIdentifier()) << callback;
    }

    if (IsLoad() || IsIncomplete() || IsAborted()) {
      EXPECT_STREQ("GET", request->GetMethod().ToString().c_str()) << callback;
      EXPECT_STREQ(GetURL(RESULT_HTML), request->GetURL().ToString().c_str())
          << callback;

      // Expect the header for all callbacks following the callback that
      // initially sets it.
      const std::string& custom_header = GetCustomHeader(request);
      if ((mode_ == RESTART_RESOURCE_RESPONSE &&
           on_resource_response_ct_ > 0) ||
          (mode_ == MODIFY_BEFORE_RESOURCE_LOAD &&
           on_before_resource_load_ct_ > 0)) {
        EXPECT_STREQ("value", custom_header.c_str()) << callback;
      } else {
        EXPECT_STREQ("", custom_header.c_str()) << callback;
      }

      if (response)
        VerifyOKResponse(callback, response);
    } else if (IsRedirect()) {
      EXPECT_STREQ("GET", request->GetMethod().ToString().c_str()) << callback;
      if (on_before_browse_ct_ == 1) {
        // Before the redirect.
        EXPECT_STREQ(GetStartupURL(), request->GetURL().ToString().c_str())
            << callback;
      } else if (on_before_browse_ct_ == 2) {
        // After the redirect.
        EXPECT_STREQ(GetURL(RESULT_HTML), request->GetURL().ToString().c_str())
            << callback;
      } else {
        NOTREACHED() << callback;
      }

      if (response) {
        if (callback == kOnResourceRedirect) {
          // Before the redirect.
          VerifyRedirectResponse(callback, response);
        } else {
          // After the redirect.
          VerifyOKResponse(callback, response);
        }
      }
    } else {
      NOTREACHED() << callback;
    }
  }

  void VerifyOKResponse(Callback callback,
                        CefRefPtr<CefResponse> response) const {
    // True for the first response in cases where we're redirecting/restarting
    // from inside OnResourceResponse (e.g. the first response always succeeds).
    const bool override_unhandled = unhandled_ &&
                                    (mode_ == REDIRECT_RESOURCE_RESPONSE ||
                                     mode_ == RESTART_RESOURCE_RESPONSE) &&
                                    get_resource_handler_ct_ == 1;

    // True for tests where the request will be incomplete and never receive a
    // response.
    const bool incomplete_unhandled =
        (mode_ == INCOMPLETE_BEFORE_RESOURCE_LOAD ||
         mode_ == INCOMPLETE_REQUEST_HANDLER_OPEN ||
         (IsAborted() && !custom_scheme_));

    if ((unhandled_ && !override_unhandled) || incomplete_unhandled) {
      if (incomplete_unhandled) {
        EXPECT_EQ(ERR_ABORTED, response->GetError()) << callback;
      } else {
        EXPECT_EQ(ERR_UNKNOWN_URL_SCHEME, response->GetError()) << callback;
      }
      EXPECT_EQ(0, response->GetStatus()) << callback;
      EXPECT_STREQ("", response->GetStatusText().ToString().c_str())
          << callback;
      EXPECT_STREQ("", response->GetURL().ToString().c_str()) << callback;
      EXPECT_STREQ("", response->GetMimeType().ToString().c_str()) << callback;
      EXPECT_STREQ("", response->GetCharset().ToString().c_str()) << callback;
    } else {
      if ((mode_ == INCOMPLETE_REQUEST_HANDLER_READ || IsAborted()) &&
          callback == kOnResourceLoadComplete) {
        // We got a response, but we also got aborted.
        EXPECT_EQ(ERR_ABORTED, response->GetError()) << callback;
      } else {
        EXPECT_EQ(ERR_NONE, response->GetError()) << callback;
      }
      EXPECT_EQ(200, response->GetStatus()) << callback;
      EXPECT_STREQ("OK", response->GetStatusText().ToString().c_str())
          << callback;
      EXPECT_STREQ("", response->GetURL().ToString().c_str()) << callback;
      EXPECT_STREQ("text/html", response->GetMimeType().ToString().c_str())
          << callback;
      EXPECT_STREQ("", response->GetCharset().ToString().c_str()) << callback;
    }
  }

  void VerifyRedirectResponse(Callback callback,
                              CefRefPtr<CefResponse> response) const {
    EXPECT_EQ(ERR_NONE, response->GetError()) << callback;
    EXPECT_EQ(307, response->GetStatus()) << callback;
    const std::string& status_text = response->GetStatusText();
    EXPECT_TRUE(status_text == "Internal Redirect" ||
                status_text == "Temporary Redirect")
        << status_text << callback;
    EXPECT_STREQ("", response->GetURL().ToString().c_str()) << callback;
    EXPECT_STREQ("", response->GetMimeType().ToString().c_str()) << callback;
    EXPECT_STREQ("", response->GetCharset().ToString().c_str()) << callback;
  }

  void CloseBrowserAsync() {
    EXPECT_TRUE(IsIncomplete());
    SetSignalCompletionWhenAllBrowsersClose(false);
    CefPostDelayedTask(
        TID_UI, base::Bind(&TestHandler::CloseBrowser, GetBrowser(), false),
        100);
  }

  void MaybeDestroyTest(bool from_handler) {
    if (!CefCurrentlyOn(TID_UI)) {
      CefPostTask(TID_UI, base::Bind(&BasicResponseTest::MaybeDestroyTest, this,
                                     from_handler));
      return;
    }

    if (from_handler) {
      resource_handler_destroyed_ct_++;
    }

    bool destroy_test = false;
    if (IsIncomplete()) {
      // Destroy the test if we got OnResourceLoadComplete and either the
      // resource handler will never complete or it was destroyed.
      destroy_test =
          on_resource_load_complete_ct_ > 0 &&
          (!IsIncompleteRequestHandler() ||
           resource_handler_destroyed_ct_ == resource_handler_created_ct_);
    } else {
      // Destroy the test if we got OnLoadEnd and the expected number of
      // resource handlers were destroyed.
      destroy_test = on_load_end_ct_ > 0 && resource_handler_destroyed_ct_ ==
                                                resource_handler_created_ct_;
    }

    if (destroy_test) {
      DestroyTest();
    }
  }

  const TestMode mode_;
  const bool custom_scheme_;
  const bool unhandled_;

  int browser_id_ = 0;
  uint64 request_id_ = 0U;

  int resource_handler_created_ct_ = 0;

  int on_before_browse_ct_ = 0;
  int on_load_end_ct_ = 0;

  int get_resource_request_handler_ct_ = 0;
  int on_before_resource_load_ct_ = 0;
  int get_cookie_access_filter_ct_ = 0;
  int get_resource_handler_ct_ = 0;
  int on_resource_redirect_ct_ = 0;
  int on_resource_response_ct_ = 0;
  int get_resource_response_filter_ct_ = 0;
  int on_resource_load_complete_ct_ = 0;
  int on_protocol_execution_ct_ = 0;
  int resource_handler_destroyed_ct_ = 0;

  // Used with INCOMPLETE_BEFORE_RESOURCE_LOAD.
  CefRefPtr<CefRequestCallback> incomplete_callback_;

  DISALLOW_COPY_AND_ASSIGN(BasicResponseTest);
  IMPLEMENT_REFCOUNTING(BasicResponseTest);
};

}  // namespace

#define BASIC_TEST(name, test_mode, custom, unhandled)            \
  TEST(ResourceRequestHandlerTest, Basic##name) {                 \
    CefRefPtr<BasicResponseTest> handler = new BasicResponseTest( \
        BasicResponseTest::test_mode, custom, unhandled);         \
    handler->ExecuteTest();                                       \
    ReleaseAndWaitForDestructor(handler);                         \
  }

#define BASIC_TEST_ALL_MODES(name, custom, unhandled)                          \
  BASIC_TEST(name##Load, LOAD, custom, unhandled)                              \
  BASIC_TEST(name##AbortAfterCreated, ABORT_AFTER_CREATED, custom, unhandled)  \
  BASIC_TEST(name##AbortBeforeBrowse, ABORT_BEFORE_BROWSE, custom, unhandled)  \
  BASIC_TEST(name##ModifyBeforeResourceLoad, MODIFY_BEFORE_RESOURCE_LOAD,      \
             custom, unhandled)                                                \
  BASIC_TEST(name##RedirectBeforeResourceLoad, REDIRECT_BEFORE_RESOURCE_LOAD,  \
             custom, unhandled)                                                \
  BASIC_TEST(name##RedirectRequestHandler, REDIRECT_REQUEST_HANDLER, custom,   \
             unhandled)                                                        \
  BASIC_TEST(name##RedirectResourceRedirect, REDIRECT_RESOURCE_REDIRECT,       \
             custom, unhandled)                                                \
  BASIC_TEST(name##RedirectResourceResponse, REDIRECT_RESOURCE_RESPONSE,       \
             custom, unhandled)                                                \
  BASIC_TEST(name##RestartResourceResponse, RESTART_RESOURCE_RESPONSE, custom, \
             unhandled)

// Tests only supported in handled mode.
#define BASIC_TEST_HANDLED_MODES(name, custom)                                \
  BASIC_TEST(name##ImmediateRequestHandlerOpen,                               \
             IMMEDIATE_REQUEST_HANDLER_OPEN, custom, false)                   \
  BASIC_TEST(name##ImmediateRequestHandlerRead,                               \
             IMMEDIATE_REQUEST_HANDLER_READ, custom, false)                   \
  BASIC_TEST(name##ImmediateRequestHandlerAll, IMMEDIATE_REQUEST_HANDLER_ALL, \
             custom, false)                                                   \
  BASIC_TEST(name##DelayedRequestHandlerOpen, DELAYED_REQUEST_HANDLER_OPEN,   \
             custom, false)                                                   \
  BASIC_TEST(name##DelayedRequestHandlerRead, DELAYED_REQUEST_HANDLER_READ,   \
             custom, false)                                                   \
  BASIC_TEST(name##DelayedRequestHandlerAll, DELAYED_REQUEST_HANDLER_ALL,     \
             custom, false)                                                   \
  BASIC_TEST(name##IncompleteBeforeResourceLoad,                              \
             INCOMPLETE_BEFORE_RESOURCE_LOAD, custom, false)                  \
  BASIC_TEST(name##IncompleteRequestHandlerOpen,                              \
             INCOMPLETE_REQUEST_HANDLER_OPEN, custom, false)                  \
  BASIC_TEST(name##IncompleteRequestHandlerRead,                              \
             INCOMPLETE_REQUEST_HANDLER_READ, custom, false)

BASIC_TEST_ALL_MODES(StandardHandled, false, false)
BASIC_TEST_ALL_MODES(StandardUnhandled, false, true)
BASIC_TEST_ALL_MODES(CustomHandled, true, false)
BASIC_TEST_ALL_MODES(CustomUnhandled, true, true)

BASIC_TEST_HANDLED_MODES(StandardHandled, false)
BASIC_TEST_HANDLED_MODES(CustomHandled, true)

namespace {

const char kSubresourceProcessMsg[] = "SubresourceMsg";

class SubresourceResponseTest : public RoutingTestHandler {
 public:
  enum TestMode {
    // Normal load, nothing fancy.
    LOAD,

    // Don't continue from OnBeforeResourceLoad, then close the browser to
    // verify destruction handling of in-progress requests.
    INCOMPLETE_BEFORE_RESOURCE_LOAD,

    // Modify the request (add headers) in OnBeforeResourceLoad.
    MODIFY_BEFORE_RESOURCE_LOAD,

    // Redirect the request (change the URL) in OnBeforeResourceLoad.
    REDIRECT_BEFORE_RESOURCE_LOAD,

    // Return a CefResourceHandler from GetResourceHandler that continues
    // immediately by using the callback object instead of the return value.
    IMMEDIATE_REQUEST_HANDLER_OPEN,
    IMMEDIATE_REQUEST_HANDLER_READ,
    IMMEDIATE_REQUEST_HANDLER_ALL,

    // Return a CefResourceHandler from GetResourceHandler that continues with
    // a delay by using the callback object.
    DELAYED_REQUEST_HANDLER_OPEN,
    DELAYED_REQUEST_HANDLER_READ,
    DELAYED_REQUEST_HANDLER_ALL,

    // Return a CefResourceHandler from GetResourceHandler that never completes,
    // then close the browser to verify destruction handling of in-progress
    // requests.
    INCOMPLETE_REQUEST_HANDLER_OPEN,
    INCOMPLETE_REQUEST_HANDLER_READ,

    // Redirect the request using a CefResourceHandler returned from
    // GetResourceHandler.
    REDIRECT_REQUEST_HANDLER,

    // Redirect the request (change the URL) an additional time in
    // OnResourceRedirect after using a CefResourceHandler returned from
    // GetResourceHandler for the first redirect.
    REDIRECT_RESOURCE_REDIRECT,

    // Redirect the request (change the URL) in OnResourceResponse.
    REDIRECT_RESOURCE_RESPONSE,

    // Restart the request (add headers) in OnResourceResponse.
    RESTART_RESOURCE_RESPONSE,
  };

  // If |custom_scheme| is true all requests will use a custom scheme.
  // If |unhandled| is true the final request (after any redirects) will be
  // unhandled, meaning that default handling is disabled and GetResourceHandler
  // returns null.
  // If |subframe| is true the resource will be loaded in an iframe.
  SubresourceResponseTest(TestMode mode,
                          bool custom_scheme,
                          bool unhandled,
                          bool subframe)
      : mode_(mode),
        custom_scheme_(custom_scheme),
        unhandled_(unhandled),
        subframe_(subframe) {}

  void RunTest() override {
    CreateBrowser(GetMainURL());
    SetTestTimeout();
  }

  bool OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
                      CefRefPtr<CefFrame> frame,
                      CefRefPtr<CefRequest> request,
                      bool user_gesture,
                      bool is_redirect) override {
    EXPECT_UI_THREAD();
    if (browser_id_ == 0) {
      // This is the first callback that provides a browser ID.
      browser_id_ = browser->GetIdentifier();
      EXPECT_GT(browser_id_, 0);
    } else {
      EXPECT_EQ(browser_id_, browser->GetIdentifier());
    }

    if (IsMainURL(request->GetURL())) {
      EXPECT_TRUE(frame->IsMain());
    } else if (IsSubURL(request->GetURL())) {
      EXPECT_FALSE(frame->IsMain());
      EXPECT_TRUE(subframe_);
    } else {
      EXPECT_FALSE(true);  // Not reached.
    }

    EXPECT_FALSE(user_gesture);
    EXPECT_FALSE(is_redirect);

    on_before_browse_ct_++;
    return false;
  }

  CefRefPtr<CefResourceRequestHandler> GetResourceRequestHandler(
      CefRefPtr<CefBrowser> browser,
      CefRefPtr<CefFrame> frame,
      CefRefPtr<CefRequest> request,
      bool is_navigation,
      bool is_download,
      const CefString& request_initiator,
      bool& disable_default_handling) override {
    EXPECT_IO_THREAD();
    EXPECT_EQ(browser_id_, browser->GetIdentifier());

    if (IsMainURL(request->GetURL())) {
      EXPECT_TRUE(frame->IsMain());
    } else if (IsSubURL(request->GetURL())) {
      EXPECT_FALSE(frame->IsMain());
      EXPECT_TRUE(subframe_);
    }

    if (IsMainURL(request->GetURL()) || IsSubURL(request->GetURL())) {
      // Track the frame ID that we'll expect for resource callbacks.
      // Do this here instead of OnBeforeBrowse because OnBeforeBrowse may
      // return -4 (kInvalidFrameId) for the initial navigation.
      if (frame_id_ == 0) {
        if (subframe_) {
          if (IsSubURL(request->GetURL()))
            frame_id_ = frame->GetIdentifier();
        } else {
          frame_id_ = frame->GetIdentifier();
        }
      }
      return this;
    }

    VerifyFrame(kGetResourceRequestHandler, frame);

    if (request_id_ == 0U) {
      // This is the first callback that provides a request ID.
      request_id_ = request->GetIdentifier();
      EXPECT_GT(request_id_, 0U);
    }

    VerifyState(kGetResourceRequestHandler, request, nullptr);

    EXPECT_FALSE(is_navigation);
    EXPECT_FALSE(is_download);
    EXPECT_STREQ(GetOrigin(), request_initiator.ToString().c_str());

    // Check expected default value.
    if (custom_scheme_) {
      // There is no default handling for custom schemes.
      EXPECT_TRUE(disable_default_handling);
    } else {
      EXPECT_FALSE(disable_default_handling);
      // If |unhandled_| is true then we don't want default handling of requests
      // (e.g. attempts to resolve over the network).
      disable_default_handling = unhandled_;
    }

    get_resource_request_handler_ct_++;

    return this;
  }

  CefRefPtr<CefCookieAccessFilter> GetCookieAccessFilter(
      CefRefPtr<CefBrowser> browser,
      CefRefPtr<CefFrame> frame,
      CefRefPtr<CefRequest> request) override {
    EXPECT_IO_THREAD();
    EXPECT_EQ(browser_id_, browser->GetIdentifier());

    if (IsMainURL(request->GetURL())) {
      EXPECT_TRUE(frame->IsMain());
      return nullptr;
    } else if (IsSubURL(request->GetURL())) {
      EXPECT_FALSE(frame->IsMain());
      EXPECT_TRUE(subframe_);
      return nullptr;
    }

    VerifyFrame(kGetCookieAccessFilter, frame);

    VerifyState(kGetCookieAccessFilter, request, nullptr);

    get_cookie_access_filter_ct_++;

    return nullptr;
  }

  cef_return_value_t OnBeforeResourceLoad(
      CefRefPtr<CefBrowser> browser,
      CefRefPtr<CefFrame> frame,
      CefRefPtr<CefRequest> request,
      CefRefPtr<CefRequestCallback> callback) override {
    EXPECT_IO_THREAD();
    EXPECT_EQ(browser_id_, browser->GetIdentifier());

    if (IsMainURL(request->GetURL())) {
      EXPECT_TRUE(frame->IsMain());
      return RV_CONTINUE;
    } else if (IsSubURL(request->GetURL())) {
      EXPECT_FALSE(frame->IsMain());
      EXPECT_TRUE(subframe_);
      return RV_CONTINUE;
    }

    VerifyFrame(kOnBeforeResourceLoad, frame);

    VerifyState(kOnBeforeResourceLoad, request, nullptr);

    on_before_resource_load_ct_++;

    if (mode_ == INCOMPLETE_BEFORE_RESOURCE_LOAD) {
      incomplete_callback_ = callback;

      // Close the browser asynchronously to complete the test.
      CloseBrowserAsync();
      return RV_CONTINUE_ASYNC;
    }

    if (mode_ == MODIFY_BEFORE_RESOURCE_LOAD) {
      // Expect this data in the request for future callbacks.
      SetCustomHeader(request);
    } else if (mode_ == REDIRECT_BEFORE_RESOURCE_LOAD) {
      // Redirect to this URL.
      request->SetURL(GetURL(RESULT_JS));
    }

    // Other continuation modes are tested by
    // ResourceRequestHandlerTest.BeforeResourceLoad*.
    return RV_CONTINUE;
  }

  CefRefPtr<CefResourceHandler> GetResourceHandler(
      CefRefPtr<CefBrowser> browser,
      CefRefPtr<CefFrame> frame,
      CefRefPtr<CefRequest> request) override {
    EXPECT_IO_THREAD();
    EXPECT_EQ(browser_id_, browser->GetIdentifier());

    if (IsMainURL(request->GetURL())) {
      EXPECT_TRUE(frame->IsMain());
      return GetMainResource();
    } else if (IsSubURL(request->GetURL())) {
      EXPECT_FALSE(frame->IsMain());
      EXPECT_TRUE(subframe_);
      return GetSubResource();
    }

    VerifyFrame(kGetResourceHandler, frame);

    VerifyState(kGetResourceHandler, request, nullptr);

    get_resource_handler_ct_++;

    if (IsIncompleteRequestHandler()) {
      // Close the browser asynchronously to complete the test.
      CloseBrowserAsync();
      return GetIncompleteResource();
    }

    const std::string& url = request->GetURL();
    if (url == GetURL(RESULT_JS) && mode_ == RESTART_RESOURCE_RESPONSE) {
      if (get_resource_handler_ct_ == 1) {
        // First request that will be restarted after response.
        return GetOKResource();
      } else {
        // Restarted request.
        if (unhandled_)
          return nullptr;
        return GetOKResource();
      }
    } else if (url == GetURL(RESULT_JS)) {
      if (unhandled_)
        return nullptr;
      return GetOKResource();
    } else if (url == GetURL(REDIRECT_JS) &&
               mode_ == REDIRECT_RESOURCE_RESPONSE) {
      if (get_resource_handler_ct_ == 1) {
        // First request that will be redirected after response.
        return GetOKResource();
      } else {
        // Redirected request.
        if (unhandled_)
          return nullptr;
        return GetOKResource();
      }
    } else if (url == GetURL(REDIRECT_JS) || url == GetURL(REDIRECT2_JS)) {
      std::string redirect_url;
      if (mode_ == REDIRECT_REQUEST_HANDLER ||
          mode_ == REDIRECT_RESOURCE_RESPONSE) {
        EXPECT_STREQ(GetURL(REDIRECT_JS), url.c_str());
        redirect_url = GetURL(RESULT_JS);
      } else if (mode_ == REDIRECT_RESOURCE_REDIRECT) {
        EXPECT_STREQ(GetURL(REDIRECT2_JS), url.c_str());
        redirect_url = GetURL(REDIRECT_JS);
      } else {
        NOTREACHED();
      }

      return GetRedirectResource(redirect_url);
    } else {
      NOTREACHED();
      return nullptr;
    }
  }

  void OnResourceRedirect(CefRefPtr<CefBrowser> browser,
                          CefRefPtr<CefFrame> frame,
                          CefRefPtr<CefRequest> request,
                          CefRefPtr<CefResponse> response,
                          CefString& new_url) override {
    EXPECT_IO_THREAD();
    EXPECT_EQ(browser_id_, browser->GetIdentifier());

    if (IsMainURL(request->GetURL()) || IsSubURL(request->GetURL())) {
      EXPECT_FALSE(true);  // Not reached.
      return;
    }

    VerifyFrame(kOnResourceRedirect, frame);

    VerifyState(kOnResourceRedirect, request, response);

    if (mode_ == REDIRECT_REQUEST_HANDLER ||
        mode_ == REDIRECT_RESOURCE_RESPONSE) {
      // The URL redirected to from GetResourceHandler or OnResourceResponse.
      EXPECT_STREQ(GetURL(RESULT_JS), new_url.ToString().c_str());
    } else if (mode_ == REDIRECT_RESOURCE_REDIRECT) {
      if (on_resource_redirect_ct_ == 0) {
        // The URL redirected to from GetResourceHandler.
        EXPECT_STREQ(GetURL(REDIRECT_JS), new_url.ToString().c_str());
        // Redirect again.
        new_url = GetURL(RESULT_JS);
      } else {
        NOTREACHED();
      }
    }

    on_resource_redirect_ct_++;
  }

  bool OnResourceResponse(CefRefPtr<CefBrowser> browser,
                          CefRefPtr<CefFrame> frame,
                          CefRefPtr<CefRequest> request,
                          CefRefPtr<CefResponse> response) override {
    EXPECT_IO_THREAD();
    EXPECT_EQ(browser_id_, browser->GetIdentifier());

    if (IsMainURL(request->GetURL())) {
      EXPECT_TRUE(frame->IsMain());
      return false;
    } else if (IsSubURL(request->GetURL())) {
      EXPECT_FALSE(frame->IsMain());
      EXPECT_TRUE(subframe_);
      return false;
    }

    VerifyFrame(kOnResourceResponse, frame);

    VerifyState(kOnResourceResponse, request, response);

    on_resource_response_ct_++;

    if (on_resource_response_ct_ == 1) {
      if (mode_ == REDIRECT_RESOURCE_RESPONSE) {
        // Redirect the request to this URL.
        request->SetURL(GetURL(RESULT_JS));
        return true;
      } else if (mode_ == RESTART_RESOURCE_RESPONSE) {
        // Restart the request loading this data.
        SetCustomHeader(request);
        return true;
      }
    }

    return false;
  }

  CefRefPtr<CefResponseFilter> GetResourceResponseFilter(
      CefRefPtr<CefBrowser> browser,
      CefRefPtr<CefFrame> frame,
      CefRefPtr<CefRequest> request,
      CefRefPtr<CefResponse> response) override {
    EXPECT_IO_THREAD();
    EXPECT_EQ(browser_id_, browser->GetIdentifier());

    if (IsMainURL(request->GetURL())) {
      EXPECT_TRUE(frame->IsMain());
      return nullptr;
    } else if (IsSubURL(request->GetURL())) {
      EXPECT_FALSE(frame->IsMain());
      EXPECT_TRUE(subframe_);
      return nullptr;
    }

    VerifyFrame(kGetResourceResponseFilter, frame);

    VerifyState(kGetResourceResponseFilter, request, response);

    get_resource_response_filter_ct_++;

    return nullptr;
  }

  void OnResourceLoadComplete(CefRefPtr<CefBrowser> browser,
                              CefRefPtr<CefFrame> frame,
                              CefRefPtr<CefRequest> request,
                              CefRefPtr<CefResponse> response,
                              URLRequestStatus status,
                              int64 received_content_length) override {
    EXPECT_IO_THREAD();
    EXPECT_EQ(browser_id_, browser->GetIdentifier());

    if (IsMainURL(request->GetURL())) {
      EXPECT_TRUE(frame->IsMain());
      EXPECT_EQ(UR_SUCCESS, status);
      EXPECT_EQ(static_cast<int64>(GetMainResponseBody().length()),
                received_content_length);
      return;
    } else if (IsSubURL(request->GetURL())) {
      EXPECT_FALSE(frame->IsMain());
      EXPECT_EQ(UR_SUCCESS, status);
      EXPECT_EQ(static_cast<int64>(GetSubResponseBody().length()),
                received_content_length);
      EXPECT_TRUE(subframe_);
      return;
    }

    VerifyFrame(kOnResourceLoadComplete, frame);

    VerifyState(kOnResourceLoadComplete, request, response);

    if (unhandled_ || IsIncomplete()) {
      EXPECT_EQ(UR_FAILED, status);
      EXPECT_EQ(0, received_content_length);
    } else {
      EXPECT_EQ(UR_SUCCESS, status);
      EXPECT_EQ(static_cast<int64>(GetResponseBody().length()),
                received_content_length);
    }

    on_resource_load_complete_ct_++;

    if (IsIncomplete()) {
      MaybeDestroyTest(false);
    }
  }

  void OnProtocolExecution(CefRefPtr<CefBrowser> browser,
                           CefRefPtr<CefFrame> frame,
                           CefRefPtr<CefRequest> request,
                           bool& allow_os_execution) override {
    EXPECT_IO_THREAD();
    EXPECT_EQ(browser_id_, browser->GetIdentifier());

    if (IsMainURL(request->GetURL()) || IsSubURL(request->GetURL())) {
      EXPECT_FALSE(true);  // Not reached.
      return;
    }

    VerifyFrame(kOnProtocolExecution, frame);

    EXPECT_TRUE(custom_scheme_);
    EXPECT_TRUE(unhandled_);

    // Check expected default value.
    EXPECT_FALSE(allow_os_execution);

    VerifyState(kOnProtocolExecution, request, nullptr);
    on_protocol_execution_ct_++;
  }

  void OnLoadEnd(CefRefPtr<CefBrowser> browser,
                 CefRefPtr<CefFrame> frame,
                 int httpStatusCode) override {
    EXPECT_UI_THREAD();
    EXPECT_EQ(browser_id_, browser->GetIdentifier());

    EXPECT_EQ(httpStatusCode, 200);

    on_load_end_ct_++;

    TestHandler::OnLoadEnd(browser, frame, httpStatusCode);
    MaybeDestroyTest(false);
  }

  bool OnQuery(CefRefPtr<CefBrowser> browser,
               CefRefPtr<CefFrame> frame,
               int64 query_id,
               const CefString& request,
               bool persistent,
               CefRefPtr<Callback> callback) override {
    EXPECT_UI_THREAD();
    EXPECT_EQ(browser_id_, browser->GetIdentifier());

    EXPECT_STREQ(kSubresourceProcessMsg, request.ToString().c_str());

    VerifyFrame(kOnQuery, frame);

    callback->Success("");

    on_query_ct_++;
    MaybeDestroyTest(false);

    return true;
  }

  void DestroyTest() override {
    // Only called for the main and/or sub frame load.
    if (subframe_) {
      EXPECT_EQ(2, on_before_browse_ct_);
    } else {
      EXPECT_EQ(1, on_before_browse_ct_);
    }

    if (mode_ == RESTART_RESOURCE_RESPONSE) {
      EXPECT_EQ(2, get_resource_request_handler_ct_);
      EXPECT_EQ(2, get_cookie_access_filter_ct_);
      EXPECT_EQ(2, on_before_resource_load_ct_);
      EXPECT_EQ(2, get_resource_handler_ct_);
      EXPECT_EQ(0, on_resource_redirect_ct_);
      // Unhandled requests won't see a call to GetResourceResponseFilter or
      // OnResourceResponse. In this case we're restarting from inside
      // OnResourceResponse.
      if (unhandled_) {
        EXPECT_EQ(0, get_resource_response_filter_ct_);
        EXPECT_EQ(1, on_resource_response_ct_);
      } else {
        EXPECT_EQ(1, get_resource_response_filter_ct_);
        EXPECT_EQ(2, on_resource_response_ct_);
      }
    } else if (IsLoad()) {
      EXPECT_EQ(1, get_resource_request_handler_ct_);
      EXPECT_EQ(1, get_cookie_access_filter_ct_);
      EXPECT_EQ(1, on_before_resource_load_ct_);
      EXPECT_EQ(1, get_resource_handler_ct_);
      EXPECT_EQ(0, on_resource_redirect_ct_);
      // Unhandled requests won't see a call to GetResourceResponseFilter or
      // OnResourceResponse.
      if (unhandled_) {
        EXPECT_EQ(0, get_resource_response_filter_ct_);
        EXPECT_EQ(0, on_resource_response_ct_);
      } else {
        EXPECT_EQ(1, get_resource_response_filter_ct_);
        EXPECT_EQ(1, on_resource_response_ct_);
      }
    } else if (IsRedirect()) {
      EXPECT_EQ(2, get_resource_request_handler_ct_);
      EXPECT_EQ(2, get_cookie_access_filter_ct_);
      EXPECT_EQ(2, on_before_resource_load_ct_);
      if (mode_ == REDIRECT_BEFORE_RESOURCE_LOAD) {
        EXPECT_EQ(1, get_resource_handler_ct_);
      } else {
        EXPECT_EQ(2, get_resource_handler_ct_);
      }
      EXPECT_EQ(1, on_resource_redirect_ct_);

      // Unhandled requests won't see a call to GetResourceResponseFilter.
      if (unhandled_)
        EXPECT_EQ(0, get_resource_response_filter_ct_);
      else
        EXPECT_EQ(1, get_resource_response_filter_ct_);

      // Unhandled requests won't see a call to OnResourceResponse.
      if (mode_ == REDIRECT_RESOURCE_RESPONSE) {
        // In this case we're redirecting from inside OnResourceResponse.
        if (unhandled_)
          EXPECT_EQ(1, on_resource_response_ct_);
        else
          EXPECT_EQ(2, on_resource_response_ct_);
      } else {
        if (unhandled_)
          EXPECT_EQ(0, on_resource_response_ct_);
        else
          EXPECT_EQ(1, on_resource_response_ct_);
      }
    } else if (IsIncomplete()) {
      EXPECT_EQ(1, get_resource_request_handler_ct_);
      EXPECT_EQ(1, get_cookie_access_filter_ct_);
      EXPECT_EQ(1, on_before_resource_load_ct_);

      if (IsIncompleteRequestHandler()) {
        EXPECT_EQ(1, get_resource_handler_ct_);
      } else {
        EXPECT_EQ(0, get_resource_handler_ct_);
      }

      EXPECT_EQ(0, on_resource_redirect_ct_);

      if (mode_ == INCOMPLETE_REQUEST_HANDLER_READ) {
        EXPECT_EQ(1, get_resource_response_filter_ct_);
        EXPECT_EQ(1, on_resource_response_ct_);
      } else {
        EXPECT_EQ(0, get_resource_response_filter_ct_);
        EXPECT_EQ(0, on_resource_response_ct_);
      }
    } else {
      NOTREACHED();
    }

    EXPECT_EQ(resource_handler_created_ct_, resource_handler_destroyed_ct_);
    EXPECT_EQ(1, on_resource_load_complete_ct_);

    // Only called for the main and/or sub frame load.
    if (IsIncomplete()) {
      EXPECT_EQ(0, on_load_end_ct_);
    } else {
      if (subframe_) {
        EXPECT_EQ(2, on_load_end_ct_);
      } else {
        EXPECT_EQ(1, on_load_end_ct_);
      }
    }

    if (unhandled_ || IsIncomplete()) {
      EXPECT_EQ(0, on_query_ct_);
    } else {
      EXPECT_EQ(1, on_query_ct_);
    }

    if (custom_scheme_ && unhandled_ && !IsIncomplete()) {
      EXPECT_EQ(1, on_protocol_execution_ct_);
    } else {
      EXPECT_EQ(0, on_protocol_execution_ct_);
    }

    TestHandler::DestroyTest();

    if (!SignalCompletionWhenAllBrowsersClose()) {
      // Complete asynchronously so the call stack has a chance to unwind.
      CefPostTask(TID_UI,
                  base::Bind(&SubresourceResponseTest::TestComplete, this));
    }
  }

 private:
  const char* GetMainURL() const {
    if (custom_scheme_) {
      return "rrhcustom://test.com/main.html";
    } else {
      return "http://test.com/main.html";
    }
  }

  const char* GetSubURL() const {
    if (custom_scheme_) {
      return "rrhcustom://test.com/subframe.html";
    } else {
      return "http://test.com/subframe.html";
    }
  }

  const char* GetOrigin() const {
    if (custom_scheme_) {
      return "rrhcustom://test.com";
    } else {
      return "http://test.com";
    }
  }

  bool IsMainURL(const std::string& url) const { return url == GetMainURL(); }
  bool IsSubURL(const std::string& url) const { return url == GetSubURL(); }

  enum TestUrl {
    RESULT_JS,
    REDIRECT_JS,
    REDIRECT2_JS,
  };

  const char* GetURL(TestUrl url) const {
    if (custom_scheme_) {
      if (url == RESULT_JS)
        return "rrhcustom://test.com/result.js";
      if (url == REDIRECT_JS)
        return "rrhcustom://test.com/redirect.js";
      if (url == REDIRECT2_JS)
        return "rrhcustom://test.com/redirect2.js";
    } else {
      if (url == RESULT_JS)
        return "http://test.com/result.js";
      if (url == REDIRECT_JS)
        return "http://test.com/redirect.js";
      if (url == REDIRECT2_JS)
        return "http://test.com/redirect2.js";
    }

    NOTREACHED();
    return "";
  }

  const char* GetStartupURL() const {
    if (IsLoad() || IsIncomplete()) {
      return GetURL(RESULT_JS);
    } else if (mode_ == REDIRECT_RESOURCE_REDIRECT) {
      return GetURL(REDIRECT2_JS);
    } else if (IsRedirect()) {
      return GetURL(REDIRECT_JS);
    }

    NOTREACHED();
    return "";
  }

  std::string GetMainResponseBody() const {
    std::stringstream html;
    html << "<html><head>";

    if (subframe_) {
      const std::string& url = GetSubURL();
      html << "<iframe src=\"" << url << "\"></iframe>";
    } else {
      const std::string& url = GetStartupURL();
      html << "<script type=\"text/javascript\" src=\"" << url
           << "\"></script>";
    }

    html << "</head><body><p>Main</p></body></html>";
    return html.str();
  }

  std::string GetSubResponseBody() const {
    DCHECK(subframe_);

    std::stringstream html;
    html << "<html><head>";

    const std::string& url = GetStartupURL();
    html << "<script type=\"text/javascript\" src=\"" << url << "\"></script>";

    html << "</head><body><p>Sub</p></body></html>";
    return html.str();
  }

  std::string GetResponseBody() const {
    return "window.testQuery({request:'" + std::string(kSubresourceProcessMsg) +
           "'});";
  }
  std::string GetRedirectBody() const {
    return "<html><body>Redirect</body></html>";
  }

  base::Closure GetResourceDestroyCallback() {
    resource_handler_created_ct_++;
    return base::Bind(&SubresourceResponseTest::MaybeDestroyTest, this, true);
  }

  bool GetCallbackResourceHandlerMode(CallbackResourceHandler::Mode& mode) {
    switch (mode_) {
      case IMMEDIATE_REQUEST_HANDLER_OPEN:
        mode = CallbackResourceHandler::IMMEDIATE_OPEN;
        return true;
      case IMMEDIATE_REQUEST_HANDLER_READ:
        mode = CallbackResourceHandler::IMMEDIATE_READ;
        return true;
      case IMMEDIATE_REQUEST_HANDLER_ALL:
        mode = CallbackResourceHandler::IMMEDIATE_ALL;
        return true;
      case DELAYED_REQUEST_HANDLER_OPEN:
        mode = CallbackResourceHandler::DELAYED_OPEN;
        return true;
      case DELAYED_REQUEST_HANDLER_READ:
        mode = CallbackResourceHandler::DELAYED_READ;
        return true;
      case DELAYED_REQUEST_HANDLER_ALL:
        mode = CallbackResourceHandler::DELAYED_ALL;
        return true;
      default:
        break;
    }
    return false;
  }

  CefRefPtr<CefResourceHandler> GetResource(int status_code,
                                            const CefString& status_text,
                                            const CefString& mime_type,
                                            CefResponse::HeaderMap header_map,
                                            const std::string& body) {
    CefRefPtr<CefStreamReader> stream = CefStreamReader::CreateForData(
        const_cast<char*>(body.c_str()), body.size());

    CallbackResourceHandler::Mode handler_mode;
    if (GetCallbackResourceHandlerMode(handler_mode)) {
      return new CallbackResourceHandler(handler_mode, status_code, status_text,
                                         mime_type, header_map, stream,
                                         GetResourceDestroyCallback());
    }

    return new NormalResourceHandler(status_code, status_text, mime_type,
                                     header_map, stream,
                                     GetResourceDestroyCallback());
  }

  CefRefPtr<CefResourceHandler> GetMainResource() {
    return GetResource(200, "OK", "text/html", CefResponse::HeaderMap(),
                       GetMainResponseBody());
  }

  CefRefPtr<CefResourceHandler> GetSubResource() {
    return GetResource(200, "OK", "text/html", CefResponse::HeaderMap(),
                       GetSubResponseBody());
  }

  CefRefPtr<CefResourceHandler> GetOKResource() {
    return GetResource(200, "OK", "text/javascript", CefResponse::HeaderMap(),
                       GetResponseBody());
  }

  CefRefPtr<CefResourceHandler> GetRedirectResource(
      const std::string& redirect_url) {
    CefResponse::HeaderMap headerMap;
    headerMap.insert(std::make_pair("Location", redirect_url));

    return GetResource(307, "Temporary Redirect", "text/javascript", headerMap,
                       GetRedirectBody());
  }

  CefRefPtr<CefResourceHandler> GetIncompleteResource() {
    if (TestOldResourceAPI()) {
      return new IncompleteResourceHandlerOld(
          mode_ == INCOMPLETE_REQUEST_HANDLER_OPEN
              ? IncompleteResourceHandlerOld::BLOCK_PROCESS_REQUEST
              : IncompleteResourceHandlerOld::BLOCK_READ_RESPONSE,
          "text/javascript", GetResourceDestroyCallback());
    }

    return new IncompleteResourceHandler(
        mode_ == INCOMPLETE_REQUEST_HANDLER_OPEN
            ? IncompleteResourceHandler::BLOCK_OPEN
            : IncompleteResourceHandler::BLOCK_READ,
        "text/javascript", GetResourceDestroyCallback());
  }

  bool IsLoad() const {
    return mode_ == LOAD || mode_ == MODIFY_BEFORE_RESOURCE_LOAD ||
           mode_ == RESTART_RESOURCE_RESPONSE ||
           mode_ == IMMEDIATE_REQUEST_HANDLER_OPEN ||
           mode_ == IMMEDIATE_REQUEST_HANDLER_READ ||
           mode_ == IMMEDIATE_REQUEST_HANDLER_ALL ||
           mode_ == DELAYED_REQUEST_HANDLER_OPEN ||
           mode_ == DELAYED_REQUEST_HANDLER_READ ||
           mode_ == DELAYED_REQUEST_HANDLER_ALL;
  }

  bool IsIncompleteRequestHandler() const {
    return mode_ == INCOMPLETE_REQUEST_HANDLER_OPEN ||
           mode_ == INCOMPLETE_REQUEST_HANDLER_READ;
  }

  bool IsIncomplete() const {
    return mode_ == INCOMPLETE_BEFORE_RESOURCE_LOAD ||
           IsIncompleteRequestHandler();
  }

  bool IsRedirect() const {
    return mode_ == REDIRECT_BEFORE_RESOURCE_LOAD ||
           mode_ == REDIRECT_REQUEST_HANDLER ||
           mode_ == REDIRECT_RESOURCE_REDIRECT ||
           mode_ == REDIRECT_RESOURCE_RESPONSE;
  }

  static void SetCustomHeader(CefRefPtr<CefRequest> request) {
    EXPECT_FALSE(request->IsReadOnly());
    request->SetHeaderByName("X-Custom-Header", "value", false);
  }

  static std::string GetCustomHeader(CefRefPtr<CefRequest> request) {
    return request->GetHeaderByName("X-Custom-Header");
  }

  // Resource-related callbacks.
  enum Callback {
    kGetResourceRequestHandler,
    kGetCookieAccessFilter,
    kOnBeforeResourceLoad,
    kGetResourceHandler,
    kOnResourceRedirect,
    kOnResourceResponse,
    kGetResourceResponseFilter,
    kOnResourceLoadComplete,
    kOnProtocolExecution,
    kOnQuery,
  };

  bool ShouldHaveResponse(Callback callback) const {
    return callback >= kOnResourceRedirect &&
           callback <= kOnResourceLoadComplete;
  }

  bool ShouldHaveWritableRequest(Callback callback) const {
    return callback == kOnBeforeResourceLoad || callback == kOnResourceResponse;
  }

  void VerifyFrame(Callback callback, CefRefPtr<CefFrame> frame) const {
    EXPECT_TRUE(frame);

    if (subframe_)
      EXPECT_FALSE(frame->IsMain()) << callback;
    else
      EXPECT_TRUE(frame->IsMain()) << callback;

    EXPECT_EQ(frame_id_, frame->GetIdentifier()) << callback;
  }

  void VerifyState(Callback callback,
                   CefRefPtr<CefRequest> request,
                   CefRefPtr<CefResponse> response) const {
    EXPECT_TRUE(request) << callback;

    if (ShouldHaveResponse(callback)) {
      EXPECT_TRUE(response) << callback;
      EXPECT_TRUE(response->IsReadOnly()) << callback;
    } else {
      EXPECT_FALSE(response) << callback;
    }

    if (ShouldHaveWritableRequest(callback)) {
      EXPECT_FALSE(request->IsReadOnly()) << callback;
    } else {
      EXPECT_TRUE(request->IsReadOnly()) << callback;
    }

    // All resource-related callbacks share the same request ID.
    EXPECT_EQ(request_id_, request->GetIdentifier()) << callback;

    if (IsLoad() || IsIncomplete()) {
      EXPECT_STREQ("GET", request->GetMethod().ToString().c_str()) << callback;
      EXPECT_STREQ(GetURL(RESULT_JS), request->GetURL().ToString().c_str())
          << callback;

      // Expect the header for all callbacks following the callback that
      // initially sets it.
      const std::string& custom_header = GetCustomHeader(request);
      if ((mode_ == RESTART_RESOURCE_RESPONSE &&
           on_resource_response_ct_ > 0) ||
          (mode_ == MODIFY_BEFORE_RESOURCE_LOAD &&
           on_before_resource_load_ct_ > 0)) {
        EXPECT_STREQ("value", custom_header.c_str()) << callback;
      } else {
        EXPECT_STREQ("", custom_header.c_str()) << callback;
      }

      if (response)
        VerifyOKResponse(callback, response);
    } else if (IsRedirect()) {
      EXPECT_STREQ("GET", request->GetMethod().ToString().c_str()) << callback;
      // Subresource loads don't get OnBeforeBrowse calls, so this check is a
      // bit less exact then with main resource loads.
      if (on_resource_redirect_ct_ == 0) {
        // Before the redirect.
        EXPECT_STREQ(GetStartupURL(), request->GetURL().ToString().c_str())
            << callback;
      } else {
        // After the redirect.
        EXPECT_STREQ(GetURL(RESULT_JS), request->GetURL().ToString().c_str())
            << callback;
      }

      if (response) {
        if (callback == kOnResourceRedirect) {
          // Before the redirect.
          VerifyRedirectResponse(callback, response);
        } else {
          // After the redirect.
          VerifyOKResponse(callback, response);
        }
      }
    } else {
      NOTREACHED() << callback;
    }
  }

  void VerifyOKResponse(Callback callback,
                        CefRefPtr<CefResponse> response) const {
    // True for the first response in cases where we're redirecting/restarting
    // from inside OnResourceResponse (e.g. the first response always succeeds).
    const bool override_unhandled = unhandled_ &&
                                    (mode_ == REDIRECT_RESOURCE_RESPONSE ||
                                     mode_ == RESTART_RESOURCE_RESPONSE) &&
                                    get_resource_handler_ct_ == 1;

    // True for tests where the request will be incomplete and never receive a
    // response.
    const bool incomplete_unhandled =
        (mode_ == INCOMPLETE_BEFORE_RESOURCE_LOAD ||
         mode_ == INCOMPLETE_REQUEST_HANDLER_OPEN);

    if ((unhandled_ && !override_unhandled) || incomplete_unhandled) {
      if (incomplete_unhandled) {
        EXPECT_EQ(ERR_ABORTED, response->GetError()) << callback;
      } else {
        EXPECT_EQ(ERR_UNKNOWN_URL_SCHEME, response->GetError()) << callback;
      }
      EXPECT_EQ(0, response->GetStatus()) << callback;
      EXPECT_STREQ("", response->GetStatusText().ToString().c_str())
          << callback;
      EXPECT_STREQ("", response->GetURL().ToString().c_str()) << callback;
      EXPECT_STREQ("", response->GetMimeType().ToString().c_str()) << callback;
      EXPECT_STREQ("", response->GetCharset().ToString().c_str()) << callback;
    } else {
      if (mode_ == INCOMPLETE_REQUEST_HANDLER_READ &&
          callback == kOnResourceLoadComplete) {
        // We got a response, but we also got aborted.
        EXPECT_EQ(ERR_ABORTED, response->GetError()) << callback;
      } else {
        EXPECT_EQ(ERR_NONE, response->GetError()) << callback;
      }
      EXPECT_EQ(200, response->GetStatus()) << callback;
      EXPECT_STREQ("OK", response->GetStatusText().ToString().c_str())
          << callback;
      EXPECT_STREQ("", response->GetURL().ToString().c_str()) << callback;
      EXPECT_STREQ("text/javascript",
                   response->GetMimeType().ToString().c_str())
          << callback;
      EXPECT_STREQ("", response->GetCharset().ToString().c_str()) << callback;
    }
  }

  void VerifyRedirectResponse(Callback callback,
                              CefRefPtr<CefResponse> response) const {
    EXPECT_EQ(ERR_NONE, response->GetError()) << callback;
    EXPECT_EQ(307, response->GetStatus()) << callback;
    const std::string& status_text = response->GetStatusText();
    EXPECT_TRUE(status_text == "Internal Redirect" ||
                status_text == "Temporary Redirect")
        << status_text << callback;
    EXPECT_STREQ("", response->GetURL().ToString().c_str()) << callback;
    EXPECT_STREQ("", response->GetMimeType().ToString().c_str()) << callback;
    EXPECT_STREQ("", response->GetCharset().ToString().c_str()) << callback;
  }

  void CloseBrowserAsync() {
    EXPECT_TRUE(IsIncomplete());
    SetSignalCompletionWhenAllBrowsersClose(false);
    CefPostDelayedTask(
        TID_UI, base::Bind(&TestHandler::CloseBrowser, GetBrowser(), false),
        100);
  }

  void MaybeDestroyTest(bool from_handler) {
    if (!CefCurrentlyOn(TID_UI)) {
      CefPostTask(TID_UI, base::Bind(&SubresourceResponseTest::MaybeDestroyTest,
                                     this, from_handler));
      return;
    }

    if (from_handler) {
      resource_handler_destroyed_ct_++;
    }

    bool destroy_test = false;
    if (IsIncomplete()) {
      // Destroy the test if we got OnResourceLoadComplete and either the
      // resource handler will never complete or it was destroyed.
      destroy_test =
          on_resource_load_complete_ct_ > 0 &&
          (!IsIncompleteRequestHandler() ||
           resource_handler_destroyed_ct_ == resource_handler_created_ct_);
    } else {
      // Destroy the test if we got the expected number of OnLoadEnd and
      // OnQuery, and the expected number of resource handlers were destroyed.
      destroy_test =
          on_load_end_ct_ > (subframe_ ? 1 : 0) &&
          (on_query_ct_ > 0 || unhandled_) &&
          resource_handler_destroyed_ct_ == resource_handler_created_ct_;
    }

    if (destroy_test) {
      DestroyTest();
    }
  }

  const TestMode mode_;
  const bool custom_scheme_;
  const bool unhandled_;
  const bool subframe_;

  int browser_id_ = 0;
  int64 frame_id_ = 0;
  uint64 request_id_ = 0U;

  int resource_handler_created_ct_ = 0;

  int on_before_browse_ct_ = 0;
  int on_load_end_ct_ = 0;
  int on_query_ct_ = 0;

  int get_resource_request_handler_ct_ = 0;
  int get_cookie_access_filter_ct_ = 0;
  int on_before_resource_load_ct_ = 0;
  int get_resource_handler_ct_ = 0;
  int on_resource_redirect_ct_ = 0;
  int on_resource_response_ct_ = 0;
  int get_resource_response_filter_ct_ = 0;
  int on_resource_load_complete_ct_ = 0;
  int on_protocol_execution_ct_ = 0;
  int resource_handler_destroyed_ct_ = 0;

  // Used with INCOMPLETE_BEFORE_RESOURCE_LOAD.
  CefRefPtr<CefRequestCallback> incomplete_callback_;

  DISALLOW_COPY_AND_ASSIGN(SubresourceResponseTest);
  IMPLEMENT_REFCOUNTING(SubresourceResponseTest);
};

}  // namespace

#define SUBRESOURCE_TEST(name, test_mode, custom, unhandled, subframe)        \
  TEST(ResourceRequestHandlerTest, Subresource##name) {                       \
    CefRefPtr<SubresourceResponseTest> handler = new SubresourceResponseTest( \
        SubresourceResponseTest::test_mode, custom, unhandled, subframe);     \
    handler->ExecuteTest();                                                   \
    ReleaseAndWaitForDestructor(handler);                                     \
  }

#define SUBRESOURCE_TEST_ALL_MODES(name, custom, unhandled, subframe)          \
  SUBRESOURCE_TEST(name##Load, LOAD, custom, unhandled, subframe)              \
  SUBRESOURCE_TEST(name##ModifyBeforeResourceLoad,                             \
                   MODIFY_BEFORE_RESOURCE_LOAD, custom, unhandled, subframe)   \
  SUBRESOURCE_TEST(name##RedirectBeforeResourceLoad,                           \
                   REDIRECT_BEFORE_RESOURCE_LOAD, custom, unhandled, subframe) \
  SUBRESOURCE_TEST(name##RedirectRequestHandler, REDIRECT_REQUEST_HANDLER,     \
                   custom, unhandled, subframe)                                \
  SUBRESOURCE_TEST(name##RedirectResourceRedirect, REDIRECT_RESOURCE_REDIRECT, \
                   custom, unhandled, subframe)                                \
  SUBRESOURCE_TEST(name##RedirectResourceResponse, REDIRECT_RESOURCE_RESPONSE, \
                   custom, unhandled, subframe)                                \
  SUBRESOURCE_TEST(name##RestartResourceResponse, RESTART_RESOURCE_RESPONSE,   \
                   custom, unhandled, subframe)

// Tests only supported in handled mode.
#define SUBRESOURCE_TEST_HANDLED_MODES(name, custom, subframe)               \
  SUBRESOURCE_TEST(name##ImmediateRequestHandlerOpen,                        \
                   IMMEDIATE_REQUEST_HANDLER_OPEN, custom, false, subframe)  \
  SUBRESOURCE_TEST(name##ImmediateRequestHandlerRead,                        \
                   IMMEDIATE_REQUEST_HANDLER_READ, custom, false, subframe)  \
  SUBRESOURCE_TEST(name##ImmediateRequestHandlerAll,                         \
                   IMMEDIATE_REQUEST_HANDLER_ALL, custom, false, subframe)   \
  SUBRESOURCE_TEST(name##DelayedRequestHandlerOpen,                          \
                   DELAYED_REQUEST_HANDLER_OPEN, custom, false, subframe)    \
  SUBRESOURCE_TEST(name##DelayedRequestHandlerRead,                          \
                   DELAYED_REQUEST_HANDLER_READ, custom, false, subframe)    \
  SUBRESOURCE_TEST(name##DelayedRequestHandlerAll,                           \
                   DELAYED_REQUEST_HANDLER_ALL, custom, false, subframe)     \
  SUBRESOURCE_TEST(name##IncompleteBeforeResourceLoad,                       \
                   INCOMPLETE_BEFORE_RESOURCE_LOAD, custom, false, subframe) \
  SUBRESOURCE_TEST(name##IncompleteRequestHandlerOpen,                       \
                   INCOMPLETE_REQUEST_HANDLER_OPEN, custom, false, subframe) \
  SUBRESOURCE_TEST(name##IncompleteRequestHandlerRead,                       \
                   INCOMPLETE_REQUEST_HANDLER_READ, custom, false, subframe)

SUBRESOURCE_TEST_ALL_MODES(StandardHandledMainFrame, false, false, false)
SUBRESOURCE_TEST_ALL_MODES(StandardUnhandledMainFrame, false, true, false)
SUBRESOURCE_TEST_ALL_MODES(CustomHandledMainFrame, true, false, false)
SUBRESOURCE_TEST_ALL_MODES(CustomUnhandledMainFrame, true, true, false)

SUBRESOURCE_TEST_ALL_MODES(StandardHandledSubFrame, false, false, true)
SUBRESOURCE_TEST_ALL_MODES(StandardUnhandledSubFrame, false, true, true)
SUBRESOURCE_TEST_ALL_MODES(CustomHandledSubFrame, true, false, true)
SUBRESOURCE_TEST_ALL_MODES(CustomUnhandledSubFrame, true, true, true)

SUBRESOURCE_TEST_HANDLED_MODES(StandardHandledMainFrame, false, false)
SUBRESOURCE_TEST_HANDLED_MODES(CustomHandledMainFrame, true, false)

SUBRESOURCE_TEST_HANDLED_MODES(StandardHandledSubFrame, false, true)
SUBRESOURCE_TEST_HANDLED_MODES(CustomHandledSubFrame, true, true)

namespace {

const char kResourceTestHtml[] = "http://test.com/resource.html";

class RedirectResponseTest : public TestHandler {
 public:
  enum TestMode {
    URL,
    HEADER,
    POST,
  };

  RedirectResponseTest(TestMode mode, bool via_request_context_handler)
      : via_request_context_handler_(via_request_context_handler) {
    if (mode == URL)
      resource_test_.reset(new UrlResourceTest);
    else if (mode == HEADER)
      resource_test_.reset(new HeaderResourceTest);
    else
      resource_test_.reset(new PostResourceTest);
  }

  void RunTest() override {
    AddResource(kResourceTestHtml, GetHtml(), "text/html");

    resource_request_handler_ = new ResourceRequestHandler(this);

    CefRefPtr<CefRequestContext> request_context =
        CefRequestContext::GetGlobalContext();
    if (via_request_context_handler_) {
      CefRefPtr<CefRequestContextHandler> request_context_handler =
          new RequestContextHandler(resource_request_handler_.get());
      CefRequestContextSettings settings;
      request_context = CefRequestContext::CreateContext(
          request_context, request_context_handler);
    }

    CreateBrowser(kResourceTestHtml, request_context);
    SetTestTimeout();
  }

  CefRefPtr<CefResourceRequestHandler> GetResourceRequestHandler(
      CefRefPtr<CefBrowser> browser,
      CefRefPtr<CefFrame> frame,
      CefRefPtr<CefRequest> request,
      bool is_navigation,
      bool is_download,
      const CefString& request_initiator,
      bool& disable_default_handling) override {
    if (via_request_context_handler_) {
      // Use the handler returned by RequestContextHandler.
      return nullptr;
    }
    return resource_request_handler_.get();
  }

  bool OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
                      CefRefPtr<CefFrame> frame,
                      CefRefPtr<CefRequest> request,
                      bool user_gesture,
                      bool is_redirect) override {
    EXPECT_UI_THREAD();
    EXPECT_EQ(0, browser_id_);
    browser_id_ = browser->GetIdentifier();
    EXPECT_GT(browser_id_, 0);

    // This method is only called for the main resource.
    EXPECT_STREQ(kResourceTestHtml, request->GetURL().ToString().c_str());

    // Browser-side navigation no longer exposes the actual request information.
    EXPECT_EQ(0U, request->GetIdentifier());

    return false;
  }

  void OnLoadEnd(CefRefPtr<CefBrowser> browser,
                 CefRefPtr<CefFrame> frame,
                 int httpStatusCode) override {
    EXPECT_UI_THREAD();
    EXPECT_EQ(browser_id_, browser->GetIdentifier());

    TestHandler::OnLoadEnd(browser, frame, httpStatusCode);
    DestroyTest();
  }

  void DestroyTest() override {
    resource_test_->CheckExpected();
    resource_test_.reset(nullptr);

    TestHandler::DestroyTest();
  }

 private:
  std::string GetHtml() const {
    std::stringstream html;
    html << "<html><head>";

    const std::string& url = resource_test_->start_url();
    html << "<script type=\"text/javascript\" src=\"" << url << "\"></script>";

    html << "</head><body><p>Main</p></body></html>";
    return html.str();
  }

  class ResourceTest {
   public:
    ResourceTest(const std::string& start_url,
                 size_t expected_resource_response_ct = 2U,
                 size_t expected_before_resource_load_ct = 1U,
                 size_t expected_resource_redirect_ct = 0U,
                 size_t expected_resource_load_complete_ct = 1U)
        : start_url_(start_url),
          expected_resource_response_ct_(expected_resource_response_ct),
          expected_before_resource_load_ct_(expected_before_resource_load_ct),
          expected_resource_redirect_ct_(expected_resource_redirect_ct),
          expected_resource_load_complete_ct_(
              expected_resource_load_complete_ct) {}
    virtual ~ResourceTest() {}

    const std::string& start_url() const { return start_url_; }

    virtual bool OnBeforeResourceLoad(CefRefPtr<CefBrowser> browser,
                                      CefRefPtr<CefFrame> frame,
                                      CefRefPtr<CefRequest> request) {
      before_resource_load_ct_++;
      return false;
    }

    virtual CefRefPtr<CefResourceHandler> GetResourceHandler(
        CefRefPtr<CefBrowser> browser,
        CefRefPtr<CefFrame> frame,
        CefRefPtr<CefRequest> request) {
      get_resource_handler_ct_++;

      const std::string& js_content = "<!-- -->";

      CefRefPtr<CefStreamReader> stream = CefStreamReader::CreateForData(
          const_cast<char*>(js_content.c_str()), js_content.size());

      return new CefStreamResourceHandler(200, "OK", "text/javascript",
                                          CefResponse::HeaderMap(), stream);
    }

    virtual void OnResourceRedirect(CefRefPtr<CefBrowser> browser,
                                    CefRefPtr<CefFrame> frame,
                                    CefRefPtr<CefRequest> request,
                                    CefString& new_url) {
      resource_redirect_ct_++;
    }

    bool OnResourceResponse(CefRefPtr<CefBrowser> browser,
                            CefRefPtr<CefFrame> frame,
                            CefRefPtr<CefRequest> request,
                            CefRefPtr<CefResponse> response) {
      EXPECT_TRUE(CheckUrl(request->GetURL()));

      // Verify the response returned by GetResourceHandler.
      EXPECT_EQ(200, response->GetStatus());
      EXPECT_STREQ("OK", response->GetStatusText().ToString().c_str());
      EXPECT_STREQ("text/javascript",
                   response->GetMimeType().ToString().c_str());

      if (resource_response_ct_++ == 0U) {
        // Always redirect at least one time.
        OnResourceReceived(browser, frame, request, response);
        return true;
      }

      OnRetryReceived(browser, frame, request, response);
      return (resource_response_ct_ < expected_resource_response_ct_);
    }

    CefRefPtr<CefResponseFilter> GetResourceResponseFilter(
        CefRefPtr<CefBrowser> browser,
        CefRefPtr<CefFrame> frame,
        CefRefPtr<CefRequest> request,
        CefRefPtr<CefResponse> response) {
      get_resource_response_filter_ct_++;
      return nullptr;
    }

    void OnResourceLoadComplete(CefRefPtr<CefBrowser> browser,
                                CefRefPtr<CefFrame> frame,
                                CefRefPtr<CefRequest> request,
                                CefRefPtr<CefResponse> response,
                                URLRequestStatus status,
                                int64 received_content_length) {
      EXPECT_TRUE(CheckUrl(request->GetURL()));

      // Verify the response returned by GetResourceHandler.
      EXPECT_EQ(200, response->GetStatus());
      EXPECT_STREQ("OK", response->GetStatusText().ToString().c_str());
      EXPECT_STREQ("text/javascript",
                   response->GetMimeType().ToString().c_str());

      resource_load_complete_ct_++;
    }

    virtual bool CheckUrl(const std::string& url) const {
      return (url == start_url_);
    }

    virtual void CheckExpected() {
      EXPECT_TRUE(got_resource_);
      EXPECT_TRUE(got_resource_retry_);

      EXPECT_EQ(expected_resource_response_ct_, resource_response_ct_);
      EXPECT_EQ(expected_resource_response_ct_, get_resource_handler_ct_);
      EXPECT_EQ(expected_resource_load_complete_ct_,
                get_resource_response_filter_ct_);
      EXPECT_EQ(expected_before_resource_load_ct_, before_resource_load_ct_);
      EXPECT_EQ(expected_resource_redirect_ct_, resource_redirect_ct_);
      EXPECT_EQ(expected_resource_load_complete_ct_,
                resource_load_complete_ct_);
    }

   protected:
    virtual void OnResourceReceived(CefRefPtr<CefBrowser> browser,
                                    CefRefPtr<CefFrame> frame,
                                    CefRefPtr<CefRequest> request,
                                    CefRefPtr<CefResponse> response) {
      got_resource_.yes();
    }

    virtual void OnRetryReceived(CefRefPtr<CefBrowser> browser,
                                 CefRefPtr<CefFrame> frame,
                                 CefRefPtr<CefRequest> request,
                                 CefRefPtr<CefResponse> response) {
      got_resource_retry_.yes();
    }

   private:
    std::string start_url_;

    size_t resource_response_ct_ = 0U;
    size_t expected_resource_response_ct_;
    size_t before_resource_load_ct_ = 0U;
    size_t expected_before_resource_load_ct_;
    size_t get_resource_handler_ct_ = 0U;
    size_t resource_redirect_ct_ = 0U;
    size_t expected_resource_redirect_ct_;
    size_t get_resource_response_filter_ct_ = 0U;
    size_t resource_load_complete_ct_ = 0U;
    size_t expected_resource_load_complete_ct_;

    TrackCallback got_resource_;
    TrackCallback got_resource_retry_;
  };

  class UrlResourceTest : public ResourceTest {
   public:
    // With NetworkService we don't get an additional (unnecessary) redirect
    // callback.
    UrlResourceTest()
        : ResourceTest("http://test.com/start_url.js", 2U, 2U, 1U) {
      redirect_url_ = "http://test.com/redirect_url.js";
    }

    bool CheckUrl(const std::string& url) const override {
      if (url == redirect_url_)
        return true;

      return ResourceTest::CheckUrl(url);
    }

    void OnResourceRedirect(CefRefPtr<CefBrowser> browser,
                            CefRefPtr<CefFrame> frame,
                            CefRefPtr<CefRequest> request,
                            CefString& new_url) override {
      ResourceTest::OnResourceRedirect(browser, frame, request, new_url);
      const std::string& old_url = request->GetURL();
      EXPECT_STREQ(start_url().c_str(), old_url.c_str());
      EXPECT_STREQ(redirect_url_.c_str(), new_url.ToString().c_str());
    }

   private:
    void OnResourceReceived(CefRefPtr<CefBrowser> browser,
                            CefRefPtr<CefFrame> frame,
                            CefRefPtr<CefRequest> request,
                            CefRefPtr<CefResponse> response) override {
      ResourceTest::OnResourceReceived(browser, frame, request, response);
      request->SetURL(redirect_url_);
    }

    void OnRetryReceived(CefRefPtr<CefBrowser> browser,
                         CefRefPtr<CefFrame> frame,
                         CefRefPtr<CefRequest> request,
                         CefRefPtr<CefResponse> response) override {
      ResourceTest::OnRetryReceived(browser, frame, request, response);
      const std::string& new_url = request->GetURL();
      EXPECT_STREQ(redirect_url_.c_str(), new_url.c_str());
    }

    std::string redirect_url_;
  };

  class HeaderResourceTest : public ResourceTest {
   public:
    // With NetworkService we restart the request, so we get another call to
    // OnBeforeResourceLoad.
    HeaderResourceTest()
        : ResourceTest("http://test.com/start_header.js", 2U, 2U) {
      expected_headers_.insert(std::make_pair("Test-Key1", "Value1"));
      expected_headers_.insert(std::make_pair("Test-Key2", "Value2"));
    }

   private:
    void OnResourceReceived(CefRefPtr<CefBrowser> browser,
                            CefRefPtr<CefFrame> frame,
                            CefRefPtr<CefRequest> request,
                            CefRefPtr<CefResponse> response) override {
      ResourceTest::OnResourceReceived(browser, frame, request, response);
      request->SetHeaderMap(expected_headers_);
    }

    void OnRetryReceived(CefRefPtr<CefBrowser> browser,
                         CefRefPtr<CefFrame> frame,
                         CefRefPtr<CefRequest> request,
                         CefRefPtr<CefResponse> response) override {
      ResourceTest::OnRetryReceived(browser, frame, request, response);
      CefRequest::HeaderMap actual_headers;
      request->GetHeaderMap(actual_headers);
      TestMapEqual(expected_headers_, actual_headers, true);
    }

    CefRequest::HeaderMap expected_headers_;
  };

  class PostResourceTest : public ResourceTest {
   public:
    // With NetworkService we restart the request, so we get another call to
    // OnBeforeResourceLoad.
    PostResourceTest() : ResourceTest("http://test.com/start_post.js", 2U, 2U) {
      CefRefPtr<CefPostDataElement> elem = CefPostDataElement::Create();
      const std::string data("Test Post Data");
      elem->SetToBytes(data.size(), data.c_str());

      expected_post_ = CefPostData::Create();
      expected_post_->AddElement(elem);
    }

   private:
    void OnResourceReceived(CefRefPtr<CefBrowser> browser,
                            CefRefPtr<CefFrame> frame,
                            CefRefPtr<CefRequest> request,
                            CefRefPtr<CefResponse> response) override {
      ResourceTest::OnResourceReceived(browser, frame, request, response);
      request->SetPostData(expected_post_);
    }

    void OnRetryReceived(CefRefPtr<CefBrowser> browser,
                         CefRefPtr<CefFrame> frame,
                         CefRefPtr<CefRequest> request,
                         CefRefPtr<CefResponse> response) override {
      ResourceTest::OnRetryReceived(browser, frame, request, response);
      CefRefPtr<CefPostData> actual_post = request->GetPostData();
      TestPostDataEqual(expected_post_, actual_post);
    }

    CefRefPtr<CefPostData> expected_post_;
  };

  class RequestContextHandler : public CefRequestContextHandler {
   public:
    explicit RequestContextHandler(
        CefRefPtr<CefResourceRequestHandler> resource_request_handler)
        : resource_request_handler_(resource_request_handler) {}

    CefRefPtr<CefResourceRequestHandler> GetResourceRequestHandler(
        CefRefPtr<CefBrowser> browser,
        CefRefPtr<CefFrame> frame,
        CefRefPtr<CefRequest> request,
        bool is_navigation,
        bool is_download,
        const CefString& request_initiator,
        bool& disable_default_handling) override {
      return resource_request_handler_;
    }

   private:
    CefRefPtr<CefResourceRequestHandler> resource_request_handler_;

    IMPLEMENT_REFCOUNTING(RequestContextHandler);
    DISALLOW_COPY_AND_ASSIGN(RequestContextHandler);
  };

  class ResourceRequestHandler : public CefResourceRequestHandler {
   public:
    explicit ResourceRequestHandler(RedirectResponseTest* test) : test_(test) {}

    cef_return_value_t OnBeforeResourceLoad(
        CefRefPtr<CefBrowser> browser,
        CefRefPtr<CefFrame> frame,
        CefRefPtr<CefRequest> request,
        CefRefPtr<CefRequestCallback> callback) override {
      EXPECT_IO_THREAD();
      EXPECT_EQ(test_->browser_id_, browser->GetIdentifier());

      if (request->GetURL() == kResourceTestHtml) {
        // All loads of the main resource should keep the same request id.
        EXPECT_EQ(0U, main_request_id_);
        main_request_id_ = request->GetIdentifier();
        EXPECT_GT(main_request_id_, 0U);
        return RV_CONTINUE;
      }

      // All redirects of the sub-resource should keep the same request id.
      if (sub_request_id_ == 0U) {
        sub_request_id_ = request->GetIdentifier();
        EXPECT_GT(sub_request_id_, 0U);
      } else {
        EXPECT_EQ(sub_request_id_, request->GetIdentifier());
      }

      return test_->resource_test_->OnBeforeResourceLoad(browser, frame,
                                                         request)
                 ? RV_CANCEL
                 : RV_CONTINUE;
    }

    CefRefPtr<CefResourceHandler> GetResourceHandler(
        CefRefPtr<CefBrowser> browser,
        CefRefPtr<CefFrame> frame,
        CefRefPtr<CefRequest> request) override {
      EXPECT_IO_THREAD();
      EXPECT_EQ(test_->browser_id_, browser->GetIdentifier());

      if (request->GetURL() == kResourceTestHtml) {
        EXPECT_EQ(main_request_id_, request->GetIdentifier());
        return test_->GetResourceHandler(browser, frame, request);
      }

      EXPECT_EQ(sub_request_id_, request->GetIdentifier());
      return test_->resource_test_->GetResourceHandler(browser, frame, request);
    }

    void OnResourceRedirect(CefRefPtr<CefBrowser> browser,
                            CefRefPtr<CefFrame> frame,
                            CefRefPtr<CefRequest> request,
                            CefRefPtr<CefResponse> response,
                            CefString& new_url) override {
      EXPECT_IO_THREAD();
      EXPECT_EQ(test_->browser_id_, browser->GetIdentifier());
      EXPECT_EQ(sub_request_id_, request->GetIdentifier());

      test_->resource_test_->OnResourceRedirect(browser, frame, request,
                                                new_url);
    }

    bool OnResourceResponse(CefRefPtr<CefBrowser> browser,
                            CefRefPtr<CefFrame> frame,
                            CefRefPtr<CefRequest> request,
                            CefRefPtr<CefResponse> response) override {
      EXPECT_IO_THREAD();
      EXPECT_TRUE(browser.get());
      EXPECT_EQ(test_->browser_id_, browser->GetIdentifier());

      EXPECT_TRUE(frame.get());
      EXPECT_TRUE(frame->IsMain());

      if (request->GetURL() == kResourceTestHtml) {
        EXPECT_EQ(main_request_id_, request->GetIdentifier());
        return false;
      }

      EXPECT_EQ(sub_request_id_, request->GetIdentifier());
      return test_->resource_test_->OnResourceResponse(browser, frame, request,
                                                       response);
    }

    CefRefPtr<CefResponseFilter> GetResourceResponseFilter(
        CefRefPtr<CefBrowser> browser,
        CefRefPtr<CefFrame> frame,
        CefRefPtr<CefRequest> request,
        CefRefPtr<CefResponse> response) override {
      EXPECT_IO_THREAD();
      EXPECT_TRUE(browser.get());
      EXPECT_EQ(test_->browser_id_, browser->GetIdentifier());

      EXPECT_TRUE(frame.get());
      EXPECT_TRUE(frame->IsMain());

      if (request->GetURL() == kResourceTestHtml) {
        EXPECT_EQ(main_request_id_, request->GetIdentifier());
        return nullptr;
      }

      return test_->resource_test_->GetResourceResponseFilter(
          browser, frame, request, response);
    }

    void OnResourceLoadComplete(CefRefPtr<CefBrowser> browser,
                                CefRefPtr<CefFrame> frame,
                                CefRefPtr<CefRequest> request,
                                CefRefPtr<CefResponse> response,
                                URLRequestStatus status,
                                int64 received_content_length) override {
      EXPECT_IO_THREAD();
      EXPECT_TRUE(browser.get());
      EXPECT_EQ(test_->browser_id_, browser->GetIdentifier());

      EXPECT_TRUE(frame.get());
      EXPECT_TRUE(frame->IsMain());

      if (request->GetURL() == kResourceTestHtml) {
        EXPECT_EQ(main_request_id_, request->GetIdentifier());
        return;
      }

      EXPECT_EQ(sub_request_id_, request->GetIdentifier());
      test_->resource_test_->OnResourceLoadComplete(
          browser, frame, request, response, status, received_content_length);
    }

   private:
    RedirectResponseTest* const test_;

    uint64 main_request_id_ = 0U;
    uint64 sub_request_id_ = 0U;

    IMPLEMENT_REFCOUNTING(ResourceRequestHandler);
    DISALLOW_COPY_AND_ASSIGN(ResourceRequestHandler);
  };

  const bool via_request_context_handler_;

  int browser_id_ = 0;
  scoped_ptr<ResourceTest> resource_test_;
  CefRefPtr<ResourceRequestHandler> resource_request_handler_;

  IMPLEMENT_REFCOUNTING(RedirectResponseTest);
};

}  // namespace

// Verify redirect with client handler.
TEST(ResourceRequestHandlerTest, RedirectURLViaClient) {
  CefRefPtr<RedirectResponseTest> handler =
      new RedirectResponseTest(RedirectResponseTest::URL, false);
  handler->ExecuteTest();
  ReleaseAndWaitForDestructor(handler);
}

// Verify redirect + modified headers with client handler.
TEST(ResourceRequestHandlerTest, RedirectHeaderViaClient) {
  CefRefPtr<RedirectResponseTest> handler =
      new RedirectResponseTest(RedirectResponseTest::HEADER, false);
  handler->ExecuteTest();
  ReleaseAndWaitForDestructor(handler);
}

// Verify redirect + modified post data with client handler.
TEST(ResourceRequestHandlerTest, RedirectPostViaClient) {
  CefRefPtr<RedirectResponseTest> handler =
      new RedirectResponseTest(RedirectResponseTest::POST, false);
  handler->ExecuteTest();
  ReleaseAndWaitForDestructor(handler);
}

// Verify redirect with context handler.
TEST(ResourceRequestHandlerTest, RedirectURLViaContext) {
  CefRefPtr<RedirectResponseTest> handler =
      new RedirectResponseTest(RedirectResponseTest::URL, true);
  handler->ExecuteTest();
  ReleaseAndWaitForDestructor(handler);
}

// Verify redirect + modified headers with context handler.
TEST(ResourceRequestHandlerTest, RedirectHeaderViaContext) {
  CefRefPtr<RedirectResponseTest> handler =
      new RedirectResponseTest(RedirectResponseTest::HEADER, true);
  handler->ExecuteTest();
  ReleaseAndWaitForDestructor(handler);
}

// Verify redirect + modified post data with context handler.
TEST(ResourceRequestHandlerTest, RedirectPostViaContext) {
  CefRefPtr<RedirectResponseTest> handler =
      new RedirectResponseTest(RedirectResponseTest::POST, true);
  handler->ExecuteTest();
  ReleaseAndWaitForDestructor(handler);
}

namespace {

const char kResourceTestHtml2[] = "http://test.com/resource2.html";

class BeforeResourceLoadTest : public TestHandler {
 public:
  enum TestMode {
    CANCEL,
    CANCEL_ASYNC,
    CANCEL_NAV,
    CONTINUE,
    CONTINUE_ASYNC,
  };

  explicit BeforeResourceLoadTest(TestMode mode) : test_mode_(mode) {}

  void RunTest() override {
    AddResource(kResourceTestHtml, "<html><body>Test</body></html>",
                "text/html");
    AddResource(kResourceTestHtml2, "<html><body>Test2</body></html>",
                "text/html");
    CreateBrowser(kResourceTestHtml);
    SetTestTimeout();
  }

  cef_return_value_t OnBeforeResourceLoad(
      CefRefPtr<CefBrowser> browser,
      CefRefPtr<CefFrame> frame,
      CefRefPtr<CefRequest> request,
      CefRefPtr<CefRequestCallback> callback) override {
    EXPECT_IO_THREAD();

    // Allow the 2nd navigation to continue.
    const std::string& url = request->GetURL();
    if (url == kResourceTestHtml2) {
      got_before_resource_load2_.yes();
      EXPECT_EQ(CANCEL_NAV, test_mode_);
      return RV_CONTINUE;
    }

    EXPECT_FALSE(got_before_resource_load_);
    got_before_resource_load_.yes();

    if (test_mode_ == CANCEL) {
      // Cancel immediately.
      return RV_CANCEL;
    } else if (test_mode_ == CONTINUE) {
      // Continue immediately.
      return RV_CONTINUE;
    } else {
      if (test_mode_ == CANCEL_NAV) {
        // Cancel the request by navigating to a new URL.
        browser->GetMainFrame()->LoadURL(kResourceTestHtml2);
      } else {
        // Continue or cancel asynchronously.
        CefPostTask(TID_UI,
                    base::Bind(&CefRequestCallback::Continue, callback.get(),
                               test_mode_ == CONTINUE_ASYNC));
      }
      return RV_CONTINUE_ASYNC;
    }
  }

  void OnLoadEnd(CefRefPtr<CefBrowser> browser,
                 CefRefPtr<CefFrame> frame,
                 int httpStatusCode) override {
    EXPECT_UI_THREAD();

    EXPECT_FALSE(got_load_end_);
    got_load_end_.yes();

    const std::string& url = frame->GetURL();
    if (test_mode_ == CANCEL_NAV)
      EXPECT_STREQ(kResourceTestHtml2, url.data());
    else
      EXPECT_STREQ(kResourceTestHtml, url.data());

    TestHandler::OnLoadEnd(browser, frame, httpStatusCode);
    DestroyTest();
  }

  void OnLoadError(CefRefPtr<CefBrowser> browser,
                   CefRefPtr<CefFrame> frame,
                   ErrorCode errorCode,
                   const CefString& errorText,
                   const CefString& failedUrl) override {
    EXPECT_UI_THREAD();

    EXPECT_FALSE(got_load_error_);
    got_load_error_.yes();

    const std::string& url = failedUrl;
    EXPECT_STREQ(kResourceTestHtml, url.data());

    TestHandler::OnLoadError(browser, frame, errorCode, errorText, failedUrl);
    if (test_mode_ != CANCEL_NAV)
      DestroyTest();
  }

  void DestroyTest() override {
    EXPECT_TRUE(got_before_resource_load_);

    if (test_mode_ == CANCEL_NAV)
      EXPECT_TRUE(got_before_resource_load2_);
    else
      EXPECT_FALSE(got_before_resource_load2_);

    if (test_mode_ == CONTINUE || test_mode_ == CONTINUE_ASYNC) {
      EXPECT_TRUE(got_load_end_);
      EXPECT_FALSE(got_load_error_);
    } else if (test_mode_ == CANCEL || test_mode_ == CANCEL_ASYNC) {
      EXPECT_FALSE(got_load_end_);
      EXPECT_TRUE(got_load_error_);
    }

    TestHandler::DestroyTest();
  }

 private:
  const TestMode test_mode_;

  TrackCallback got_before_resource_load_;
  TrackCallback got_before_resource_load2_;
  TrackCallback got_load_end_;
  TrackCallback got_load_error_;

  IMPLEMENT_REFCOUNTING(BeforeResourceLoadTest);
};

}  // namespace

TEST(ResourceRequestHandlerTest, BeforeResourceLoadCancel) {
  CefRefPtr<BeforeResourceLoadTest> handler =
      new BeforeResourceLoadTest(BeforeResourceLoadTest::CANCEL);
  handler->ExecuteTest();
  ReleaseAndWaitForDestructor(handler);
}

TEST(ResourceRequestHandlerTest, BeforeResourceLoadCancelAsync) {
  CefRefPtr<BeforeResourceLoadTest> handler =
      new BeforeResourceLoadTest(BeforeResourceLoadTest::CANCEL_ASYNC);
  handler->ExecuteTest();
  ReleaseAndWaitForDestructor(handler);
}

TEST(ResourceRequestHandlerTest, BeforeResourceLoadCancelNav) {
  CefRefPtr<BeforeResourceLoadTest> handler =
      new BeforeResourceLoadTest(BeforeResourceLoadTest::CANCEL_NAV);
  handler->ExecuteTest();
  ReleaseAndWaitForDestructor(handler);
}

TEST(ResourceRequestHandlerTest, BeforeResourceLoadContinue) {
  CefRefPtr<BeforeResourceLoadTest> handler =
      new BeforeResourceLoadTest(BeforeResourceLoadTest::CONTINUE);
  handler->ExecuteTest();
  ReleaseAndWaitForDestructor(handler);
}

TEST(ResourceRequestHandlerTest, BeforeResourceLoadContinueAsync) {
  CefRefPtr<BeforeResourceLoadTest> handler =
      new BeforeResourceLoadTest(BeforeResourceLoadTest::CONTINUE_ASYNC);
  handler->ExecuteTest();
  ReleaseAndWaitForDestructor(handler);
}

namespace {

// For response filtering we need to test:
// - Passing through content unchanged.
// - Not reading all of the input buffer.
// - Needing more input and getting it.
// - Needing more input and not getting it.
// - Filter error.

const char kResponseFilterTestUrl[] = "http://tests.com/response_filter.html";

size_t GetResponseBufferSize() {
  // Match the default |capacity_num_bytes| value from
  // mojo::Core::CreateDataPipe.
  return 64 * 1024;  // 64kb
}

const char kInputHeader[] = "<html><head></head><body>";
const char kInputFooter[] = "</body></html>";

// Repeat |content| the minimum number of times necessary to satisfy
// |desired_min_size|. If |calculated_repeat_ct| is non-NULL it will be set to
// the number of times that |content| was repeated.
std::string CreateInput(const std::string& content,
                        size_t desired_min_size,
                        size_t* calculated_repeat_ct = nullptr) {
  const size_t header_footer_size =
      sizeof(kInputHeader) + sizeof(kInputFooter) - 2;
  EXPECT_GE(desired_min_size, header_footer_size + content.size());
  desired_min_size -= header_footer_size;

  size_t repeat_ct =
      static_cast<size_t>(std::ceil(static_cast<double>(desired_min_size) /
                                    static_cast<double>(content.size())));
  if (calculated_repeat_ct)
    *calculated_repeat_ct = repeat_ct;

  std::string result;
  result.reserve(header_footer_size + (content.size() * repeat_ct));

  result = kInputHeader;
  while (repeat_ct--)
    result += content;
  result += kInputFooter;

  return result;
}

std::string CreateOutput(const std::string& content, size_t repeat_ct) {
  const size_t header_footer_size =
      sizeof(kInputHeader) + sizeof(kInputFooter) - 2;

  std::string result;
  result.reserve(header_footer_size + (content.size() * repeat_ct));

  result = kInputHeader;
  while (repeat_ct--)
    result += content;
  result += kInputFooter;

  return result;
}

// Base class for test filters.
class ResponseFilterTestBase : public CefResponseFilter {
 public:
  ResponseFilterTestBase() : filter_count_(0U) {}

  bool InitFilter() override {
    EXPECT_FALSE(got_init_filter_);
    got_init_filter_.yes();
    return true;
  }

  FilterStatus Filter(void* data_in,
                      size_t data_in_size,
                      size_t& data_in_read,
                      void* data_out,
                      size_t data_out_size,
                      size_t& data_out_written) override {
    if (data_in_size == 0U)
      EXPECT_FALSE(data_in);
    else
      EXPECT_TRUE(data_in);
    EXPECT_EQ(data_in_read, 0U);
    EXPECT_TRUE(data_out);
    EXPECT_GT(data_out_size, 0U);
    EXPECT_EQ(data_out_written, 0U);
    filter_count_++;
    return RESPONSE_FILTER_ERROR;
  }

  // Returns the input that will be fed into the filter.
  virtual std::string GetInput() = 0;

  // Verify the output from the filter.
  virtual void VerifyOutput(cef_urlrequest_status_t status,
                            int64 received_content_length,
                            const std::string& received_content) {
    EXPECT_TRUE(got_init_filter_);
    EXPECT_GT(filter_count_, 0U);
  }

  virtual void VerifyStatusCode(int httpStatusCode) const {
    EXPECT_TRUE(httpStatusCode == 0 || httpStatusCode == 200) << httpStatusCode;
  }

 protected:
  TrackCallback got_init_filter_;
  size_t filter_count_;

  IMPLEMENT_REFCOUNTING(ResponseFilterTestBase);
};

// Pass through the contents unchanged.
class ResponseFilterPassThru : public ResponseFilterTestBase {
 public:
  explicit ResponseFilterPassThru(bool limit_read) : limit_read_(limit_read) {}

  FilterStatus Filter(void* data_in,
                      size_t data_in_size,
                      size_t& data_in_read,
                      void* data_out,
                      size_t data_out_size,
                      size_t& data_out_written) override {
    ResponseFilterTestBase::Filter(data_in, data_in_size, data_in_read,
                                   data_out, data_out_size, data_out_written);

    if (limit_read_) {
      // Read at most 1k bytes.
      data_in_read = std::min(data_in_size, static_cast<size_t>(1024U));
    } else {
      // Read all available bytes.
      data_in_read = data_in_size;
    }

    data_out_written = std::min(data_in_read, data_out_size);
    memcpy(data_out, data_in, data_out_written);

    return RESPONSE_FILTER_DONE;
  }

  std::string GetInput() override {
    input_ = CreateInput("FOOBAR ", GetResponseBufferSize() * 2U + 1);
    return input_;
  }

  void VerifyOutput(cef_urlrequest_status_t status,
                    int64 received_content_length,
                    const std::string& received_content) override {
    ResponseFilterTestBase::VerifyOutput(status, received_content_length,
                                         received_content);

    if (limit_read_)
      // Expected to read 2 full buffers of GetResponseBufferSize() at 1kb
      // increments and one partial buffer.
      EXPECT_EQ(2U * (GetResponseBufferSize() / 1024) + 1U, filter_count_);
    else {
      // Expected to read 2 full buffers of GetResponseBufferSize() and one
      // partial buffer.
      EXPECT_EQ(3U, filter_count_);
    }
    EXPECT_STREQ(input_.c_str(), received_content.c_str());

    // Input size and content size should match.
    EXPECT_EQ(input_.size(), static_cast<size_t>(received_content_length));
    EXPECT_EQ(input_.size(), received_content.size());
  }

 private:
  std::string input_;
  bool limit_read_;
};

const char kFindString[] = "REPLACE_THIS_STRING";
const char kReplaceString[] = "This is the replaced string!";

// Helper for passing params to Write().
#define WRITE_PARAMS data_out_ptr, data_out_size, data_out_written

// Replace all instances of |kFindString| with |kReplaceString|.
// This implementation is similar to the example in
// tests/shared/response_filter_test.cc.
class ResponseFilterNeedMore : public ResponseFilterTestBase {
 public:
  ResponseFilterNeedMore()
      : find_match_offset_(0U),
        replace_overflow_size_(0U),
        input_size_(0U),
        repeat_ct_(0U) {}

  FilterStatus Filter(void* data_in,
                      size_t data_in_size,
                      size_t& data_in_read,
                      void* data_out,
                      size_t data_out_size,
                      size_t& data_out_written) override {
    ResponseFilterTestBase::Filter(data_in, data_in_size, data_in_read,
                                   data_out, data_out_size, data_out_written);

    // All data will be read.
    data_in_read = data_in_size;

    const size_t find_size = sizeof(kFindString) - 1;

    const char* data_in_ptr = static_cast<char*>(data_in);
    char* data_out_ptr = static_cast<char*>(data_out);

    // Reset the overflow.
    std::string old_overflow;
    if (!overflow_.empty()) {
      old_overflow = overflow_;
      overflow_.clear();
    }

    const size_t likely_out_size =
        data_in_size + replace_overflow_size_ + old_overflow.size();
    if (data_out_size < likely_out_size) {
      // We'll likely need to use the overflow buffer. Size it appropriately.
      overflow_.reserve(likely_out_size - data_out_size);
    }

    if (!old_overflow.empty()) {
      // Write the overflow from last time.
      Write(old_overflow.c_str(), old_overflow.size(), WRITE_PARAMS);
    }

    // Evaluate each character in the input buffer. Track how many characters in
    // a row match kFindString. If kFindString is completely matched then write
    // kReplaceString. Otherwise, write the input characters as-is.
    for (size_t i = 0U; i < data_in_size; ++i) {
      if (data_in_ptr[i] == kFindString[find_match_offset_]) {
        // Matched the next character in the find string.
        if (++find_match_offset_ == find_size) {
          // Complete match of the find string. Write the replace string.
          Write(kReplaceString, sizeof(kReplaceString) - 1, WRITE_PARAMS);

          // Start over looking for a match.
          find_match_offset_ = 0;
        }
        continue;
      }

      // Character did not match the find string.
      if (find_match_offset_ > 0) {
        // Write the portion of the find string that has matched so far.
        Write(kFindString, find_match_offset_, WRITE_PARAMS);

        // Start over looking for a match.
        find_match_offset_ = 0;
      }

      // Write the current character.
      Write(&data_in_ptr[i], 1, WRITE_PARAMS);
    }

    // If a match is currently in-progress and input was provided then we need
    // more data. Otherwise, we're done.
    return find_match_offset_ > 0 && data_in_size > 0
               ? RESPONSE_FILTER_NEED_MORE_DATA
               : RESPONSE_FILTER_DONE;
  }

  std::string GetInput() override {
    const std::string& input =
        CreateInput(std::string(kFindString) + " ",
                    GetResponseBufferSize() * 2U + 1, &repeat_ct_);
    input_size_ = input.size();

    const size_t find_size = sizeof(kFindString) - 1;
    const size_t replace_size = sizeof(kReplaceString) - 1;

    // Determine a reasonable amount of space for find/replace overflow.
    if (replace_size > find_size)
      replace_overflow_size_ = (replace_size - find_size) * repeat_ct_;

    return input;
  }

  void VerifyOutput(cef_urlrequest_status_t status,
                    int64 received_content_length,
                    const std::string& received_content) override {
    ResponseFilterTestBase::VerifyOutput(status, received_content_length,
                                         received_content);

    const std::string& output =
        CreateOutput(std::string(kReplaceString) + " ", repeat_ct_);
    EXPECT_STREQ(output.c_str(), received_content.c_str());

    // Pre-filter content length should be the original input size.
    EXPECT_EQ(input_size_, static_cast<size_t>(received_content_length));

    // Filtered content length should be the output size.
    EXPECT_EQ(output.size(), received_content.size());

    // Expected to read 2 full buffers of GetResponseBufferSize() and one
    // partial buffer, and then one additional call to drain the overflow.
    EXPECT_EQ(4U, filter_count_);
  }

 private:
  inline void Write(const char* str,
                    size_t str_size,
                    char*& data_out_ptr,
                    size_t data_out_size,
                    size_t& data_out_written) {
    // Number of bytes remaining in the output buffer.
    const size_t remaining_space = data_out_size - data_out_written;
    // Maximum number of bytes we can write into the output buffer.
    const size_t max_write = std::min(str_size, remaining_space);

    // Write the maximum portion that fits in the output buffer.
    if (max_write == 1) {
      // Small optimization for single character writes.
      *data_out_ptr = str[0];
      data_out_ptr += 1;
      data_out_written += 1;
    } else if (max_write > 1) {
      memcpy(data_out_ptr, str, max_write);
      data_out_ptr += max_write;
      data_out_written += max_write;
    }

    if (max_write < str_size) {
      // Need to write more bytes than will fit in the output buffer. Store the
      // remainder in the overflow buffer.
      overflow_ += std::string(str + max_write, str_size - max_write);
    }
  }

  // The portion of the find string that is currently matching.
  size_t find_match_offset_;

  // The likely amount of overflow.
  size_t replace_overflow_size_;

  // Overflow from the output buffer.
  std::string overflow_;

  // The original input size.
  size_t input_size_;

  // The number of times the find string was repeated.
  size_t repeat_ct_;
};

// Return a filter error.
class ResponseFilterError : public ResponseFilterTestBase {
 public:
  ResponseFilterError() {}

  FilterStatus Filter(void* data_in,
                      size_t data_in_size,
                      size_t& data_in_read,
                      void* data_out,
                      size_t data_out_size,
                      size_t& data_out_written) override {
    ResponseFilterTestBase::Filter(data_in, data_in_size, data_in_read,
                                   data_out, data_out_size, data_out_written);

    return RESPONSE_FILTER_ERROR;
  }

  std::string GetInput() override {
    return kInputHeader + std::string("ERROR") + kInputFooter;
  }

  void VerifyOutput(cef_urlrequest_status_t status,
                    int64 received_content_length,
                    const std::string& received_content) override {
    ResponseFilterTestBase::VerifyOutput(status, received_content_length,
                                         received_content);

    EXPECT_EQ(UR_FAILED, status);

    // Expect empty content.
    EXPECT_STREQ("", received_content.c_str());
    EXPECT_EQ(0U, received_content_length);

    // Expect to only be called one time.
    EXPECT_EQ(filter_count_, 1U);
  }

  void VerifyStatusCode(int httpStatusCode) const override {
    EXPECT_EQ(ERR_CONTENT_DECODING_FAILED, httpStatusCode);
  }
};

class ResponseFilterTestHandler : public TestHandler {
 public:
  explicit ResponseFilterTestHandler(
      CefRefPtr<ResponseFilterTestBase> response_filter)
      : response_filter_(response_filter) {}

  void RunTest() override {
    const std::string& resource = response_filter_->GetInput();
    AddResource(kResponseFilterTestUrl, resource, "text/html");

    // Create the browser.
    CreateBrowser(kResponseFilterTestUrl);

    // Time out the test after a reasonable period of time.
    SetTestTimeout();
  }

  CefRefPtr<CefResponseFilter> GetResourceResponseFilter(
      CefRefPtr<CefBrowser> browser,
      CefRefPtr<CefFrame> frame,
      CefRefPtr<CefRequest> request,
      CefRefPtr<CefResponse> response) override {
    EXPECT_IO_THREAD();

    DCHECK(!got_resource_response_filter_);
    got_resource_response_filter_.yes();
    return response_filter_;
  }

  void OnResourceLoadComplete(CefRefPtr<CefBrowser> browser,
                              CefRefPtr<CefFrame> frame,
                              CefRefPtr<CefRequest> request,
                              CefRefPtr<CefResponse> response,
                              URLRequestStatus status,
                              int64 received_content_length) override {
    EXPECT_IO_THREAD();

    DCHECK(!got_resource_load_complete_);
    got_resource_load_complete_.yes();

    status_ = status;
    received_content_length_ = received_content_length;
  }

  void OnLoadEnd(CefRefPtr<CefBrowser> browser,
                 CefRefPtr<CefFrame> frame,
                 int httpStatusCode) override {
    DCHECK(!got_load_end_);
    got_load_end_.yes();

    response_filter_->VerifyStatusCode(httpStatusCode);

    GetOutputContent(frame);
  }

 private:
  // Retrieve the output content using a StringVisitor. This effectively
  // serializes the DOM from the renderer process so any comparison to the
  // filter output is somewhat error-prone.
  void GetOutputContent(CefRefPtr<CefFrame> frame) {
    class StringVisitor : public CefStringVisitor {
     public:
      typedef base::Callback<void(const std::string& /*received_content*/)>
          VisitorCallback;

      explicit StringVisitor(const VisitorCallback& callback)
          : callback_(callback) {}

      void Visit(const CefString& string) override {
        callback_.Run(string);
        callback_.Reset();
      }

     private:
      VisitorCallback callback_;

      IMPLEMENT_REFCOUNTING(StringVisitor);
    };

    frame->GetSource(new StringVisitor(
        base::Bind(&ResponseFilterTestHandler::VerifyOutput, this)));
  }

  void VerifyOutput(const std::string& received_content) {
    response_filter_->VerifyOutput(status_, received_content_length_,
                                   received_content);
    response_filter_ = nullptr;

    DestroyTest();
  }

  void DestroyTest() override {
    EXPECT_TRUE(got_resource_response_filter_);
    EXPECT_TRUE(got_resource_load_complete_);
    EXPECT_TRUE(got_load_end_);

    TestHandler::DestroyTest();
  }

  CefRefPtr<ResponseFilterTestBase> response_filter_;

  TrackCallback got_resource_response_filter_;
  TrackCallback got_resource_load_complete_;
  TrackCallback got_load_end_;

  URLRequestStatus status_;
  int64 received_content_length_;

  IMPLEMENT_REFCOUNTING(ResponseFilterTestHandler);
};

}  // namespace

// Pass through contents unchanged. Read all available input.
TEST(ResourceRequestHandlerTest, FilterPassThruReadAll) {
  CefRefPtr<ResponseFilterTestHandler> handler =
      new ResponseFilterTestHandler(new ResponseFilterPassThru(false));
  handler->ExecuteTest();
  ReleaseAndWaitForDestructor(handler);
}

// Pass through contents unchanged. Read limited input.
TEST(ResourceRequestHandlerTest, FilterPassThruReadLimited) {
  CefRefPtr<ResponseFilterTestHandler> handler =
      new ResponseFilterTestHandler(new ResponseFilterPassThru(true));
  handler->ExecuteTest();
  ReleaseAndWaitForDestructor(handler);
}

// Find/replace contents such that we occasionally need more data.
TEST(ResourceRequestHandlerTest, FilterNeedMore) {
  CefRefPtr<ResponseFilterTestHandler> handler =
      new ResponseFilterTestHandler(new ResponseFilterNeedMore());
  handler->ExecuteTest();
  ReleaseAndWaitForDestructor(handler);
}

// Error during filtering.
TEST(ResourceRequestHandlerTest, FilterError) {
  CefRefPtr<ResponseFilterTestHandler> handler =
      new ResponseFilterTestHandler(new ResponseFilterError());
  handler->ExecuteTest();
  ReleaseAndWaitForDestructor(handler);
}

// Entry point for registering custom schemes.
// Called from client_app_delegates.cc.
void RegisterResourceRequestHandlerCustomSchemes(
    CefRawPtr<CefSchemeRegistrar> registrar,
    std::vector<CefString>& cookiable_schemes) {
  // Add a custom standard scheme.
  registrar->AddCustomScheme(
      "rrhcustom", CEF_SCHEME_OPTION_STANDARD | CEF_SCHEME_OPTION_CORS_ENABLED);
}
