blob: 1a85fb0f38bc5faf73d6c7b068bbd26e49edff76 [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <string>
#include "base/memory/weak_ptr.h"
#include "net/base/load_timing_info.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_job.h"
#include "net/url_request/url_request_job_factory.h"
namespace net {
// This job type is designed to help with simple unit tests. To use, you
// probably want to inherit from it to set up the state you want. Then install
// it as the protocol handler for the "test" scheme.
// It will respond to several URLs, which you can retrieve using the test_url*
// getters, which will in turn respond with the corresponding responses returned
// by test_data*. Any other URLs that begin with "test:" will return an error,
// which might also be useful, you can use test_url_error() to retreive a
// standard one.
// You can override the known URLs or the response data by overriding Start().
// Optionally, you can also construct test jobs to return a headers and data
// provided to the contstructor in response to any request url.
// When a job is created, it gets put on a queue of pending test jobs. To
// process jobs on this queue, use ProcessOnePendingMessage, which will process
// one step of the next job. If the job is incomplete, it will be added to the
// end of the queue.
// Optionally, you can also construct test jobs that advance automatically
// without having to call ProcessOnePendingMessage.
class NET_EXPORT_PRIVATE URLRequestTestJob : public URLRequestJob {
// Constructs a job to return one of the canned responses depending on the
// request url, with auto advance disabled.
URLRequestTestJob(URLRequest* request, NetworkDelegate* network_delegate);
// Constructs a job to return one of the canned responses depending on the
// request url, optionally with auto advance enabled.
URLRequestTestJob(URLRequest* request,
NetworkDelegate* network_delegate,
bool auto_advance);
// Constructs a job to return the given response regardless of the request
// url. The headers should include the HTTP status line and be formatted as
// expected by HttpResponseHeaders.
URLRequestTestJob(URLRequest* request,
net::NetworkDelegate* network_delegate,
const std::string& response_headers,
const std::string& response_data,
bool auto_advance);
// The canned URLs this handler will respond to without having been
// explicitly initialized with response headers and data.
// FIXME(brettw): we should probably also have a redirect one
static GURL test_url_1();
static GURL test_url_2();
static GURL test_url_3();
static GURL test_url_4();
static GURL test_url_error();
static GURL test_url_redirect_to_url_2();
// The data that corresponds to each of the URLs above
static std::string test_data_1();
static std::string test_data_2();
static std::string test_data_3();
static std::string test_data_4();
// The headers that correspond to each of the URLs above
static std::string test_headers();
// The headers for a redirect response
static std::string test_redirect_headers();
// The headers for a redirect response to the second test url.
static std::string test_redirect_to_url_2_headers();
// The headers for a server error response
static std::string test_error_headers();
// Processes one pending message from the stack, returning true if any
// message was processed, or false if there are no more pending request
// notifications to send. This is not applicable when using auto_advance.
static bool ProcessOnePendingMessage();
// With auto advance enabled, the job will advance thru the stages without
// the caller having to call ProcessOnePendingMessage. Auto advance depends
// on having a message loop running. The default is to not auto advance.
// Should not be altered after the job has started.
bool auto_advance() { return auto_advance_; }
void set_auto_advance(bool auto_advance) { auto_advance_ = auto_advance; }
void set_load_timing_info(const LoadTimingInfo& load_timing_info) {
load_timing_info_ = load_timing_info;
RequestPriority priority() const { return priority_; }
// Create a protocol handler for callers that don't subclass.
static URLRequestJobFactory::ProtocolHandler* CreateProtocolHandler();
// Job functions
virtual void SetPriority(RequestPriority priority) OVERRIDE;
virtual void Start() OVERRIDE;
virtual bool ReadRawData(IOBuffer* buf,
int buf_size,
int *bytes_read) OVERRIDE;
virtual void Kill() OVERRIDE;
virtual bool GetMimeType(std::string* mime_type) const OVERRIDE;
virtual void GetResponseInfo(HttpResponseInfo* info) OVERRIDE;
virtual void GetLoadTimingInfo(
LoadTimingInfo* load_timing_info) const OVERRIDE;
virtual int GetResponseCode() const OVERRIDE;
virtual bool IsRedirectResponse(GURL* location,
int* http_status_code) OVERRIDE;
// Override to specify whether the next read done from this job will
// return IO pending. This controls whether or not the WAITING state will
// transition back to WAITING or to DATA_AVAILABLE after an asynchronous
// read is processed.
virtual bool NextReadAsync();
// This is what operation we are going to do next when this job is handled.
// When the stage is DONE, this job will not be put on the queue.
virtual ~URLRequestTestJob();
// Call to process the next opeation, usually sending a notification, and
// advancing the stage if necessary. THIS MAY DELETE THE OBJECT.
void ProcessNextOperation();
// Call to move the job along to the next operation.
void AdvanceJob();
// Called via InvokeLater to cause callbacks to occur after Start() returns.
virtual void StartAsync();
bool auto_advance_;
Stage stage_;
RequestPriority priority_;
// The headers the job should return, will be set in Start() if not provided
// in the explicit ctor.
scoped_refptr<HttpResponseHeaders> response_headers_;
// The data to send, will be set in Start() if not provided in the explicit
// ctor.
std::string response_data_;
// current offset within response_data_
int offset_;
// Holds the buffer for an asynchronous ReadRawData call
IOBuffer* async_buf_;
int async_buf_size_;
LoadTimingInfo load_timing_info_;
base::WeakPtrFactory<URLRequestTestJob> weak_factory_;
} // namespace net