15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NET_URL_REQUEST_URL_REQUEST_TEST_JOB_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NET_URL_REQUEST_URL_REQUEST_TEST_JOB_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/weak_ptr.h"
11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/base/load_timing_info.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_job.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This job type is designed to help with simple unit tests. To use, you
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// probably want to inherit from it to set up the state you want. Then install
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// it as the protocol handler for the "test" scheme.
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// It will respond to several URLs, which you can retrieve using the test_url*
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// getters, which will in turn respond with the corresponding responses returned
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// by test_data*. Any other URLs that begin with "test:" will return an error,
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// which might also be useful, you can use test_url_error() to retreive a
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// standard one.
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// You can override the known URLs or the response data by overriding Start().
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Optionally, you can also construct test jobs to return a headers and data
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// provided to the contstructor in response to any request url.
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// When a job is created, it gets put on a queue of pending test jobs. To
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// process jobs on this queue, use ProcessOnePendingMessage, which will process
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// one step of the next job. If the job is incomplete, it will be added to the
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// end of the queue.
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Optionally, you can also construct test jobs that advance automatically
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// without having to call ProcessOnePendingMessage.
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NET_EXPORT_PRIVATE URLRequestTestJob : public URLRequestJob {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Constructs a job to return one of the canned responses depending on the
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // request url, with auto advance disabled.
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRequestTestJob(URLRequest* request, NetworkDelegate* network_delegate);
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Constructs a job to return one of the canned responses depending on the
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // request url, optionally with auto advance enabled.
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRequestTestJob(URLRequest* request,
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    NetworkDelegate* network_delegate,
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    bool auto_advance);
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Constructs a job to return the given response regardless of the request
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // url. The headers should include the HTTP status line and be formatted as
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // expected by HttpResponseHeaders.
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRequestTestJob(URLRequest* request,
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    net::NetworkDelegate* network_delegate,
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    const std::string& response_headers,
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    const std::string& response_data,
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    bool auto_advance);
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // The canned URLs this handler will respond to without having been
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // explicitly initialized with response headers and data.
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // FIXME(brettw): we should probably also have a redirect one
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static GURL test_url_1();
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static GURL test_url_2();
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static GURL test_url_3();
66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static GURL test_url_4();
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static GURL test_url_error();
68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static GURL test_url_redirect_to_url_2();
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The data that corresponds to each of the URLs above
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static std::string test_data_1();
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static std::string test_data_2();
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static std::string test_data_3();
74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static std::string test_data_4();
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The headers that correspond to each of the URLs above
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static std::string test_headers();
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The headers for a redirect response
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static std::string test_redirect_headers();
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // The headers for a redirect response to the second test url.
83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static std::string test_redirect_to_url_2_headers();
84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The headers for a server error response
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static std::string test_error_headers();
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Processes one pending message from the stack, returning true if any
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // message was processed, or false if there are no more pending request
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // notifications to send. This is not applicable when using auto_advance.
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool ProcessOnePendingMessage();
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // With auto advance enabled, the job will advance thru the stages without
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the caller having to call ProcessOnePendingMessage. Auto advance depends
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // on having a message loop running. The default is to not auto advance.
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Should not be altered after the job has started.
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool auto_advance() { return auto_advance_; }
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_auto_advance(bool auto_advance) { auto_advance_ = auto_advance; }
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void set_load_timing_info(const LoadTimingInfo& load_timing_info) {
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    load_timing_info_ = load_timing_info;
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RequestPriority priority() const { return priority_; }
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Factory method for protocol factory registration if callers don't subclass
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static URLRequest::ProtocolFactory Factory;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Job functions
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void SetPriority(RequestPriority priority) OVERRIDE;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Start() OVERRIDE;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool ReadRawData(IOBuffer* buf,
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           int buf_size,
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           int *bytes_read) OVERRIDE;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Kill() OVERRIDE;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool GetMimeType(std::string* mime_type) const OVERRIDE;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void GetResponseInfo(HttpResponseInfo* info) OVERRIDE;
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void GetLoadTimingInfo(
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      LoadTimingInfo* load_timing_info) const OVERRIDE;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int GetResponseCode() const OVERRIDE;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool IsRedirectResponse(GURL* location,
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  int* http_status_code) OVERRIDE;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Override to specify whether the next read done from this job will
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // return IO pending.  This controls whether or not the WAITING state will
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // transition back to WAITING or to DATA_AVAILABLE after an asynchronous
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // read is processed.
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool NextReadAsync();
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This is what operation we are going to do next when this job is handled.
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When the stage is DONE, this job will not be put on the queue.
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum Stage { WAITING, DATA_AVAILABLE, ALL_DATA, DONE };
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~URLRequestTestJob();
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Call to process the next opeation, usually sending a notification, and
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // advancing the stage if necessary. THIS MAY DELETE THE OBJECT.
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ProcessNextOperation();
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Call to move the job along to the next operation.
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AdvanceJob();
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called via InvokeLater to cause callbacks to occur after Start() returns.
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void StartAsync();
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool auto_advance_;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Stage stage_;
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RequestPriority priority_;
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The headers the job should return, will be set in Start() if not provided
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in the explicit ctor.
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<HttpResponseHeaders> response_headers_;
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The data to send, will be set in Start() if not provided in the explicit
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ctor.
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data_;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // current offset within response_data_
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int offset_;
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Holds the buffer for an asynchronous ReadRawData call
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IOBuffer* async_buf_;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int async_buf_size_;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  LoadTimingInfo load_timing_info_;
169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WeakPtrFactory<URLRequestTestJob> weak_factory_;
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // NET_URL_REQUEST_URL_REQUEST_TEST_JOB_H_
176