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