OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. | |
3 * | |
4 * Use of this source code is governed by a BSD-style license | |
5 * that can be found in the LICENSE file in the root of the source | |
6 * tree. An additional intellectual property rights grant can be found | |
7 * in the file PATENTS. All contributing project authors may | |
8 * be found in the AUTHORS file in the root of the source tree. | |
9 */ | |
10 | |
11 #ifndef WEBRTC_BASE_HTTPCLIENT_H__ | |
12 #define WEBRTC_BASE_HTTPCLIENT_H__ | |
13 | |
14 #include <memory> | |
15 | |
16 #include "webrtc/base/checks.h" | |
17 #include "webrtc/base/httpbase.h" | |
18 #include "webrtc/base/nethelpers.h" | |
19 #include "webrtc/base/proxyinfo.h" | |
20 #include "webrtc/base/sigslot.h" | |
21 #include "webrtc/base/socketaddress.h" | |
22 #include "webrtc/base/socketpool.h" | |
23 | |
24 namespace rtc { | |
25 | |
26 ////////////////////////////////////////////////////////////////////// | |
27 // Client-specific http utilities | |
28 ////////////////////////////////////////////////////////////////////// | |
29 | |
30 // Write cache-relevant response headers to output stream. If size is non-null, | |
31 // it contains the length of the output in bytes. output may be null if only | |
32 // the length is desired. | |
33 bool HttpWriteCacheHeaders(const HttpResponseData* response, | |
34 StreamInterface* output, size_t* size); | |
35 // Read cached headers from a stream, and them merge them into the response | |
36 // object using the specified combine operation. | |
37 bool HttpReadCacheHeaders(StreamInterface* input, | |
38 HttpResponseData* response, | |
39 HttpData::HeaderCombine combine); | |
40 | |
41 ////////////////////////////////////////////////////////////////////// | |
42 // HttpClient | |
43 // Implements an HTTP 1.1 client. | |
44 ////////////////////////////////////////////////////////////////////// | |
45 | |
46 class DiskCache; | |
47 class HttpClient; | |
48 class IPNetPool; | |
49 | |
50 class SignalThread; | |
51 // What to do: Define STRICT_HTTP_ERROR=1 in your makefile. Use HttpError in | |
52 // your code (HttpErrorType should only be used for code that is shared | |
53 // with groups which have not yet migrated). | |
54 #if defined(STRICT_HTTP_ERROR) && STRICT_HTTP_ERROR | |
55 typedef HttpError HttpErrorType; | |
56 #else // !STRICT_HTTP_ERROR | |
57 typedef int HttpErrorType; | |
58 #endif // !STRICT_HTTP_ERROR | |
59 | |
60 class HttpClient : private IHttpNotify, public sigslot::has_slots<> { | |
61 public: | |
62 // If HttpRequestData and HttpResponseData objects are provided, they must | |
63 // be freed by the caller. Otherwise, an internal object is allocated. | |
64 HttpClient(const std::string& agent, StreamPool* pool, | |
65 HttpTransaction* transaction = NULL); | |
66 ~HttpClient() override; | |
67 | |
68 void set_pool(StreamPool* pool) { pool_ = pool; } | |
69 | |
70 void set_agent(const std::string& agent) { agent_ = agent; } | |
71 const std::string& agent() const { return agent_; } | |
72 | |
73 void set_proxy(const ProxyInfo& proxy) { proxy_ = proxy; } | |
74 const ProxyInfo& proxy() const { return proxy_; } | |
75 | |
76 // Request retries occur when the connection closes before the beginning of | |
77 // an http response is received. In these cases, the http server may have | |
78 // timed out the keepalive connection before it received our request. Note | |
79 // that if a request document cannot be rewound, no retry is made. The | |
80 // default is 1. | |
81 void set_request_retries(size_t retries) { retries_ = retries; } | |
82 size_t request_retries() const { return retries_; } | |
83 | |
84 enum RedirectAction { REDIRECT_DEFAULT, REDIRECT_ALWAYS, REDIRECT_NEVER }; | |
85 void set_redirect_action(RedirectAction action) { redirect_action_ = action; } | |
86 RedirectAction redirect_action() const { return redirect_action_; } | |
87 | |
88 enum UriForm { URI_DEFAULT, URI_ABSOLUTE, URI_RELATIVE }; | |
89 void set_uri_form(UriForm form) { uri_form_ = form; } | |
90 UriForm uri_form() const { return uri_form_; } | |
91 | |
92 void set_cache(DiskCache* cache) { | |
93 RTC_DCHECK(!IsCacheActive()); | |
94 cache_ = cache; | |
95 } | |
96 bool cache_enabled() const { return (NULL != cache_); } | |
97 | |
98 // reset clears the server, request, and response structures. It will also | |
99 // abort an active request. | |
100 void reset(); | |
101 | |
102 void set_server(const SocketAddress& address); | |
103 const SocketAddress& server() const { return server_; } | |
104 | |
105 // Note: in order for HttpClient to retry a POST in response to | |
106 // an authentication challenge, a redirect response, or socket disconnection, | |
107 // the request document must support 'replaying' by calling Rewind() on it. | |
108 HttpTransaction* transaction() { return transaction_; } | |
109 const HttpTransaction* transaction() const { return transaction_; } | |
110 HttpRequestData& request() { return transaction_->request; } | |
111 const HttpRequestData& request() const { return transaction_->request; } | |
112 HttpResponseData& response() { return transaction_->response; } | |
113 const HttpResponseData& response() const { return transaction_->response; } | |
114 | |
115 // convenience methods | |
116 void prepare_get(const std::string& url); | |
117 void prepare_post(const std::string& url, const std::string& content_type, | |
118 StreamInterface* request_doc); | |
119 | |
120 // Convert HttpClient to a pull-based I/O model. | |
121 StreamInterface* GetDocumentStream(); | |
122 | |
123 // After you finish setting up your request, call start. | |
124 void start(); | |
125 | |
126 // Signalled when the header has finished downloading, before the document | |
127 // content is processed. You may change the response document in response | |
128 // to this signal. The second parameter indicates whether this is an | |
129 // intermediate (false) or final (true) header. An intermediate header is | |
130 // one that generates another request, such as a redirect or authentication | |
131 // challenge. The third parameter indicates the length of the response | |
132 // document, or else SIZE_UNKNOWN. Note: Do NOT abort the request in response | |
133 // to this signal. | |
134 sigslot::signal3<HttpClient*,bool,size_t> SignalHeaderAvailable; | |
135 // Signalled when the current request finishes. On success, err is 0. | |
136 sigslot::signal2<HttpClient*,HttpErrorType> SignalHttpClientComplete; | |
137 | |
138 protected: | |
139 void connect(); | |
140 void release(); | |
141 | |
142 bool ShouldRedirect(std::string* location) const; | |
143 | |
144 bool BeginCacheFile(); | |
145 HttpError WriteCacheHeaders(const std::string& id); | |
146 void CompleteCacheFile(); | |
147 | |
148 bool CheckCache(); | |
149 HttpError ReadCacheHeaders(const std::string& id, bool override); | |
150 HttpError ReadCacheBody(const std::string& id); | |
151 | |
152 bool PrepareValidate(); | |
153 HttpError CompleteValidate(); | |
154 | |
155 HttpError OnHeaderAvailable(bool ignore_data, bool chunked, size_t data_size); | |
156 | |
157 void StartDNSLookup(); | |
158 void OnResolveResult(AsyncResolverInterface* resolver); | |
159 | |
160 // IHttpNotify Interface | |
161 HttpError onHttpHeaderComplete(bool chunked, size_t& data_size) override; | |
162 void onHttpComplete(HttpMode mode, HttpError err) override; | |
163 void onHttpClosed(HttpError err) override; | |
164 | |
165 private: | |
166 enum CacheState { CS_READY, CS_WRITING, CS_READING, CS_VALIDATING }; | |
167 bool IsCacheActive() const { return (cache_state_ > CS_READY); } | |
168 | |
169 std::string agent_; | |
170 StreamPool* pool_; | |
171 HttpBase base_; | |
172 SocketAddress server_; | |
173 ProxyInfo proxy_; | |
174 HttpTransaction* transaction_; | |
175 bool free_transaction_; | |
176 size_t retries_, attempt_, redirects_; | |
177 RedirectAction redirect_action_; | |
178 UriForm uri_form_; | |
179 std::unique_ptr<HttpAuthContext> context_; | |
180 DiskCache* cache_; | |
181 CacheState cache_state_; | |
182 AsyncResolverInterface* resolver_; | |
183 }; | |
184 | |
185 ////////////////////////////////////////////////////////////////////// | |
186 // HttpClientDefault - Default implementation of HttpClient | |
187 ////////////////////////////////////////////////////////////////////// | |
188 | |
189 class HttpClientDefault : public ReuseSocketPool, public HttpClient { | |
190 public: | |
191 HttpClientDefault(SocketFactory* factory, const std::string& agent, | |
192 HttpTransaction* transaction = NULL); | |
193 }; | |
194 | |
195 ////////////////////////////////////////////////////////////////////// | |
196 | |
197 } // namespace rtc | |
198 | |
199 #endif // WEBRTC_BASE_HTTPCLIENT_H__ | |
OLD | NEW |