| // Copyright 2016 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CONTENT_BROWSER_LOADER_TEST_RESOURCE_HANDLER_H_ |
| #define CONTENT_BROWSER_LOADER_TEST_RESOURCE_HANDLER_H_ |
| |
| #include <memory> |
| #include <string> |
| |
| #include "base/macros.h" |
| #include "base/memory/ref_counted.h" |
| #include "base/memory/weak_ptr.h" |
| #include "base/run_loop.h" |
| #include "content/browser/loader/resource_handler.h" |
| #include "net/base/io_buffer.h" |
| #include "net/base/net_errors.h" |
| #include "net/url_request/url_request_status.h" |
| #include "url/gurl.h" |
| |
| namespace net { |
| class URLRequestStatus; |
| } |
| |
| namespace network { |
| struct ResourceResponse; |
| } |
| |
| namespace content { |
| |
| class ResourceController; |
| class ResourceHandler; |
| |
| // A test version of a ResourceHandler. It returns a configurable buffer in |
| // response to OnWillStart. It records what ResourceHandler methods are called, |
| // and verifies that they are called in the correct order. It can optionally |
| // defer or fail the request at any stage, and record the response body and |
| // final status it sees. Redirects currently not supported. |
| class TestResourceHandler : public ResourceHandler { |
| public: |
| // If non-null, |request_status| will be updated when the response is complete |
| // with the final status of the request received by the handler and |body| |
| // will be updated on each OnReadCompleted call. |
| TestResourceHandler(net::URLRequestStatus* request_status, std::string* body); |
| TestResourceHandler(); |
| ~TestResourceHandler() override; |
| |
| // ResourceHandler implementation: |
| void OnRequestRedirected( |
| const net::RedirectInfo& redirect_info, |
| network::ResourceResponse* response, |
| std::unique_ptr<ResourceController> controller) override; |
| void OnResponseStarted( |
| network::ResourceResponse* response, |
| std::unique_ptr<ResourceController> controller) override; |
| void OnWillStart(const GURL& url, |
| std::unique_ptr<ResourceController> controller) override; |
| void OnWillRead(scoped_refptr<net::IOBuffer>* buf, |
| int* buf_size, |
| std::unique_ptr<ResourceController> controller) override; |
| void OnReadCompleted(int bytes_read, |
| std::unique_ptr<ResourceController> controller) override; |
| void OnResponseCompleted( |
| const net::URLRequestStatus& status, |
| std::unique_ptr<ResourceController> controller) override; |
| |
| void Resume(); |
| void CancelWithError(net::Error error_code); |
| |
| // Sets the size of the read buffer returned by OnWillRead. Releases reference |
| // to previous read buffer. Default size is 2048 bytes. |
| void SetBufferSize(int buffer_size); |
| |
| scoped_refptr<net::IOBuffer> buffer() const { return buffer_; } |
| |
| // Sets the result returned by each method. All default to returning true. |
| void set_on_will_start_result(bool on_will_start_result) { |
| on_will_start_result_ = on_will_start_result; |
| } |
| void set_on_request_redirected_result(bool on_request_redirected_result) { |
| on_request_redirected_result_ = on_request_redirected_result; |
| } |
| void set_on_response_started_result(bool on_response_started_result) { |
| on_response_started_result_ = on_response_started_result; |
| } |
| void set_on_will_read_result(bool on_will_read_result) { |
| on_will_read_result_ = on_will_read_result; |
| } |
| void set_on_read_completed_result(bool on_read_completed_result) { |
| on_read_completed_result_ = on_read_completed_result; |
| } |
| void set_on_read_eof_result(bool on_read_eof_result) { |
| on_read_eof_result_ = on_read_eof_result; |
| } |
| |
| // Cause |defer| to be set to true when the specified method is invoked. The |
| // test itself is responsible for resuming the request after deferral. |
| |
| void set_defer_on_will_start(bool defer_on_will_start) { |
| defer_on_will_start_ = defer_on_will_start; |
| } |
| void set_defer_on_request_redirected(bool defer_on_request_redirected) { |
| defer_on_request_redirected_ = defer_on_request_redirected; |
| } |
| void set_defer_on_response_started(bool defer_on_response_started) { |
| defer_on_response_started_ = defer_on_response_started; |
| } |
| // Only the next OnWillRead call will set |defer| to true. |
| void set_defer_on_will_read(bool defer_on_will_read) { |
| defer_on_will_read_ = defer_on_will_read; |
| } |
| // Only the next OnReadCompleted call will set |defer| to true. |
| void set_defer_on_read_completed(bool defer_on_read_completed) { |
| defer_on_read_completed_ = defer_on_read_completed; |
| } |
| // The final-byte read will set |defer| to true. |
| void set_defer_on_read_eof(bool defer_on_read_eof) { |
| defer_on_read_eof_ = defer_on_read_eof; |
| } |
| void set_defer_on_response_completed(bool defer_on_response_completed) { |
| defer_on_response_completed_ = defer_on_response_completed; |
| } |
| |
| // Sets whether to expect a final 0-byte read on success. Defaults to true. |
| void set_expect_eof_read(bool expect_eof_read) { |
| expect_eof_read_ = expect_eof_read; |
| } |
| |
| // Return the number of times the corresponding method was invoked. |
| |
| int on_will_start_called() const { return on_will_start_called_; } |
| int on_request_redirected_called() const { |
| return on_request_redirected_called_; |
| } |
| int on_response_started_called() const { return on_response_started_called_; } |
| int on_will_read_called() const { return on_will_read_called_; } |
| int on_read_completed_called() const { return on_read_completed_called_; } |
| int on_read_eof_called() const { return on_read_eof_called_; } |
| int on_response_completed_called() const { |
| return on_response_completed_called_; |
| } |
| |
| // URL passed to OnResponseStarted, if it was called. |
| const GURL& start_url() const { return start_url_; } |
| |
| network::ResourceResponse* resource_response() { |
| return resource_response_.get(); |
| }; |
| |
| const std::string& body() const { return body_; } |
| net::URLRequestStatus final_status() const { return final_status_; } |
| |
| // Returns the current number of |this|'s methods on the callstack. |
| int call_depth() const { return call_depth_; } |
| |
| // Spins the message loop until the request is deferred. Using this is |
| // optional, but if used, must use it exclusively to wait for the request. If |
| // the request was deferred and then resumed/canceled without calling this |
| // method, behavior is undefined. |
| void WaitUntilDeferred(); |
| |
| void WaitUntilResponseStarted(); |
| void WaitUntilResponseComplete(); |
| |
| // Returns a weak pointer to |this|. Allows testing object lifetime. |
| base::WeakPtr<TestResourceHandler> GetWeakPtr(); |
| |
| private: |
| // TODO(mmenke): Remove these, in favor of final_status_ and body_. |
| net::URLRequestStatus* request_status_ptr_; |
| std::string* body_ptr_; |
| |
| scoped_refptr<net::IOBuffer> buffer_; |
| size_t buffer_size_; |
| |
| bool on_will_start_result_ = true; |
| bool on_request_redirected_result_ = true; |
| bool on_response_started_result_ = true; |
| bool on_will_read_result_ = true; |
| bool on_read_completed_result_ = true; |
| bool on_read_eof_result_ = true; |
| |
| bool defer_on_will_start_ = false; |
| bool defer_on_request_redirected_ = false; |
| bool defer_on_response_started_ = false; |
| bool defer_on_will_read_ = false; |
| bool defer_on_read_completed_ = false; |
| bool defer_on_read_eof_ = false; |
| bool defer_on_response_completed_ = false; |
| |
| bool expect_eof_read_ = true; |
| |
| int on_will_start_called_ = 0; |
| int on_request_redirected_called_ = 0; |
| int on_response_started_called_ = 0; |
| int on_will_read_called_ = 0; |
| int on_read_completed_called_ = 0; |
| int on_read_eof_called_ = 0; |
| int on_response_completed_called_ = 0; |
| |
| GURL start_url_; |
| scoped_refptr<network::ResourceResponse> resource_response_; |
| std::string body_; |
| net::URLRequestStatus final_status_ = |
| net::URLRequestStatus::FromError(net::ERR_UNEXPECTED); |
| bool canceled_ = false; |
| |
| // Pointers to the parent's read buffer and size. Only non-NULL during |
| // OnWillRead call, until cancellation or resumption. |
| scoped_refptr<net::IOBuffer>* parent_read_buffer_ = nullptr; |
| int* parent_read_buffer_size_ = nullptr; |
| |
| // Tracks recursive calls, which aren't allowed. |
| int call_depth_ = 0; |
| |
| std::unique_ptr<base::RunLoop> deferred_run_loop_; |
| |
| base::RunLoop response_started_run_loop_; |
| |
| base::RunLoop response_complete_run_loop_; |
| |
| base::WeakPtrFactory<TestResourceHandler> weak_ptr_factory_; |
| |
| DISALLOW_COPY_AND_ASSIGN(TestResourceHandler); |
| }; |
| |
| } // namespace content |
| |
| #endif // CONTENT_BROWSER_LOADER_TEST_RESOURCE_HANDLER_H_ |