summaryrefslogtreecommitdiffstats
path: root/net/url_request/url_request_inet_job.h
blob: c5777bac5a19d575fb8d4cd84d8ccbe00285c2d1 (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
// 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_INET_JOB_H__
#define NET_URL_REQUEST_URL_REQUEST_INET_JOB_H__

#include <windows.h>
#include <wininet.h>

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

namespace net {
class AuthData;
}

class MessageLoop;

// For all WinInet-based URL requests
class URLRequestInetJob : public URLRequestJob {
 public:
  URLRequestInetJob(URLRequest* request);
  virtual ~URLRequestInetJob();

  virtual void SetExtraRequestHeaders(const std::string& headers) {
    extra_request_headers_ = headers;
  }

  virtual void Kill();
  virtual bool ReadRawData(net::IOBuffer* buf, int buf_size, int *bytes_read);

  // URLRequestJob Authentication methods
  virtual void SetAuth(const std::wstring& username,
                       const std::wstring& password);
  virtual void CancelAuth();

  // A structure holding the result and error code of an asynchronous IO.
  // This is a copy of INTERNET_ASYNC_RESULT.
  struct AsyncResult {
    DWORD_PTR dwResult;
    DWORD dwError;
  };

  // A virtual method to handle WinInet callbacks.  If this class
  // issues asynchronous IO, it will need to override this method
  // to receive completions of those asynchronous IOs.  The class
  // must track whether it has an async IO outstanding, and if it
  // does not it must call the base class' OnIOComplete.
  virtual void OnIOComplete(const AsyncResult& result) = 0;

  // Used internally to setup the OnIOComplete call. Public because this
  // is called from the Windows procedure, and we don't want to make it a
  // friend so we can avoid the Windows headers for this header file.
  void CallOnIOComplete(const AsyncResult& result);

  HINTERNET request_handle() const { return request_handle_; }

protected:
  // Called by this class and subclasses to send or resend this request.
  virtual void SendRequest() = 0;

  // Calls InternetReadFile(Ex) depending on the derived class.
  // Returns ERROR_SUCCESS on success, or else a standard Windows error code
  // on failure (from GetLastError()).
  virtual int CallInternetRead(char* dest, int dest_size, int *bytes_read) = 0;

  // After the base class calls CallInternetRead and the result is available,
  // it will call this method to get the number of received bytes.
  virtual bool GetReadBytes(const AsyncResult& result, int* bytes_read) = 0;

  // Called by this class and subclasses whenever a WinInet call fails.  This
  // method returns true if the error just means that we have to wait for
  // OnIOComplete to be called.
  bool ProcessRequestError(int error);

  // Called by URLRequestJob to get more data from the data stream of this job.
  virtual bool GetMoreData();

  // Cleans up the connection, if necessary, and closes the connection and
  // request handles. May be called multiple times, it will be a NOP if
  // there is nothing to do.
  void CleanupConnection();

  // Closes the given handle.
  void CleanupHandle(HINTERNET handle);

  // Returns the global handle to the internet (NOT the same as the connection
  // or request handle below)
  static HINTERNET GetTheInternet();

  // Makes appropriate asynch call to re-send a request based on
  // dynamic scheme type and user action at authentication prompt
  //(OK or Cancel)
  virtual void OnCancelAuth() = 0;
  virtual void OnSetAuth() = 0;

  // Handle of the connection for this request. This handle is created
  // by subclasses that create the connection according to their requirements.
  // It will be automatically destroyed by this class when the connection is
  // being closed. See also 'request_handle_'
  HINTERNET connection_handle_;

  // Handle of the specific request created by subclasses to meet their own
  // requirements. This handle has a more narrow scope than the connection
  // handle. If non-null, it will be automatically destroyed by this class
  // when the connection is being closed. It will be destroyed before the
  // connection handle.
  HINTERNET request_handle_;

  // The last error that occurred.  Used by ContinueDespiteLastError to adjust
  // the request's load_flags to ignore this error.
  DWORD last_error_;

  // Any extra request headers (\n-delimited) that should be included in the
  // request.
  std::string extra_request_headers_;

  // Authentication information.
  scoped_refptr<net::AuthData> proxy_auth_;
  scoped_refptr<net::AuthData> server_auth_;

 private:

  // One-time global state setup
  static void InitializeTheInternet(const std::string& user_agent);

  // Runs on some background thread (called by WinInet)
  static void CALLBACK URLRequestStatusCallback(HINTERNET handle,
                                                DWORD_PTR job_id,
                                                DWORD status,
                                                LPVOID status_info,
                                                DWORD status_info_len);

  static HINTERNET the_internet_;
#ifndef NDEBUG
  static MessageLoop* my_message_loop_;  // Used to sanity-check that all
                                         // requests are made on the same
                                         // thread
#endif

  // true if waiting for OnIOComplete to be called
  bool is_waiting_;

  // debugging state - is there a read already in progress
  bool read_in_progress_;

  // The result and error code of asynchronous IO.  It is modified by the
  // status callback functions on asynchronous IO completion and passed to
  // CallOnIOComplete.  Since there is at most one pending IO, the object
  // can reuse the async_result_ member for all its asynchronous IOs.
  AsyncResult async_result_;

  Lock loop_lock_;
  MessageLoop* loop_;

  DISALLOW_EVIL_CONSTRUCTORS(URLRequestInetJob);
};

#endif  // NET_URL_REQUEST_URL_REQUEST_INET_JOB_H__