summaryrefslogtreecommitdiffstats
path: root/net/url_request/url_request_test_job.h
blob: ec92dc26b940f0ffeb55a5c29871fb377f5c1f74 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// Copyright (c) 2006-2008 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 NET_URL_REQUEST_URL_REQUEST_TEST_JOB_H_
#define NET_URL_REQUEST_URL_REQUEST_TEST_JOB_H_
#pragma once

#include <string>

#include "net/url_request/url_request.h"
#include "net/url_request/url_request_job.h"

// 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 three 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 URLRequestTestJob : public net::URLRequestJob {
 public:
  // Constructs a job to return one of the canned responses depending on the
  // request url, with auto advance disabled.
  explicit URLRequestTestJob(net::URLRequest* request);

  // Constructs a job to return one of the canned responses depending on the
  // request url, optionally with auto advance enabled.
  explicit URLRequestTestJob(net::URLRequest* request, 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 net::HttpResponseHeaders.
  explicit URLRequestTestJob(net::URLRequest* request,
                             const std::string& response_headers,
                             const std::string& response_data,
                             bool auto_advance);

  // The three 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_error();

  // 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();

  // 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 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; }

  // Factory method for protocol factory registration if callers don't subclass
  static net::URLRequest::ProtocolFactory Factory;

  // Job functions
  virtual void Start();
  virtual bool ReadRawData(net::IOBuffer* buf, int buf_size, int *bytes_read);
  virtual void Kill();
  virtual bool GetMimeType(std::string* mime_type) const;
  virtual void GetResponseInfo(net::HttpResponseInfo* info);
  virtual int GetResponseCode() const;
  virtual bool IsRedirectResponse(GURL* location, int* http_status_code);

 protected:
  // 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.
  enum Stage { WAITING, DATA_AVAILABLE, ALL_DATA, DONE };

  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_;

  // The headers the job should return, will be set in Start() if not provided
  // in the explicit ctor.
  scoped_refptr<net::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
  net::IOBuffer* async_buf_;
  int async_buf_size_;
};

#endif  // NET_URL_REQUEST_URL_REQUEST_TEST_JOB_H_