summaryrefslogtreecommitdiffstats
path: root/net/url_request/url_request_test_job.h
blob: eb1db01660e241a36a0d1604e44d284434030317 (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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
// 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.

#ifndef NET_URL_REQUEST_URL_REQUEST_TEST_JOB_H_
#define NET_URL_REQUEST_URL_REQUEST_TEST_JOB_H_

#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 {
 public:
  // 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 use CRLF/LF as the
  // line separator.
  URLRequestTestJob(URLRequest* request,
                    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 scoped_ptr<URLRequestJobFactory::ProtocolHandler>
  CreateProtocolHandler();

  // Job functions
  void SetPriority(RequestPriority priority) override;
  void Start() override;
  int ReadRawData(IOBuffer* buf, int buf_size) override;
  void Kill() override;
  bool GetMimeType(std::string* mime_type) const override;
  void GetResponseInfo(HttpResponseInfo* info) override;
  void GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override;
  int GetResponseCode() const override;
  bool IsRedirectResponse(GURL* location, int* http_status_code) override;

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

  ~URLRequestTestJob() override;

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

#endif  // NET_URL_REQUEST_URL_REQUEST_TEST_JOB_H_