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 virtual ~HttpClient(); 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 // Deprecated 87 void set_fail_redirect(bool fail_redirect) { 88 redirect_action_ = REDIRECT_NEVER; 89 } 90 bool fail_redirect() const { return (REDIRECT_NEVER == redirect_action_); } 91 92 enum UriForm { URI_DEFAULT, URI_ABSOLUTE, URI_RELATIVE }; 93 void set_uri_form(UriForm form) { uri_form_ = form; } 94 UriForm uri_form() const { return uri_form_; } 95 96 void set_cache(DiskCache* cache) { ASSERT(!IsCacheActive()); cache_ = cache; } 97 bool cache_enabled() const { return (NULL != cache_); } 98 99 // reset clears the server, request, and response structures. It will also 100 // abort an active request. 101 void reset(); 102 103 void set_server(const SocketAddress& address); 104 const SocketAddress& server() const { return server_; } 105 106 // Note: in order for HttpClient to retry a POST in response to 107 // an authentication challenge, a redirect response, or socket disconnection, 108 // the request document must support 'replaying' by calling Rewind() on it. 109 // In the case where just a subset of a stream should be used as the request 110 // document, the stream may be wrapped with the StreamSegment adapter. 111 HttpTransaction* transaction() { return transaction_; } 112 const HttpTransaction* transaction() const { return transaction_; } 113 HttpRequestData& request() { return transaction_->request; } 114 const HttpRequestData& request() const { return transaction_->request; } 115 HttpResponseData& response() { return transaction_->response; } 116 const HttpResponseData& response() const { return transaction_->response; } 117 118 // convenience methods 119 void prepare_get(const std::string& url); 120 void prepare_post(const std::string& url, const std::string& content_type, 121 StreamInterface* request_doc); 122 123 // Convert HttpClient to a pull-based I/O model. 124 StreamInterface* GetDocumentStream(); 125 126 // After you finish setting up your request, call start. 127 void start(); 128 129 // Signalled when the header has finished downloading, before the document 130 // content is processed. You may change the response document in response 131 // to this signal. The second parameter indicates whether this is an 132 // intermediate (false) or final (true) header. An intermediate header is 133 // one that generates another request, such as a redirect or authentication 134 // challenge. The third parameter indicates the length of the response 135 // document, or else SIZE_UNKNOWN. Note: Do NOT abort the request in response 136 // to this signal. 137 sigslot::signal3<HttpClient*,bool,size_t> SignalHeaderAvailable; 138 // Signalled when the current request finishes. On success, err is 0. 139 sigslot::signal2<HttpClient*,HttpErrorType> SignalHttpClientComplete; 140 141 protected: 142 void connect(); 143 void release(); 144 145 bool ShouldRedirect(std::string* location) const; 146 147 bool BeginCacheFile(); 148 HttpError WriteCacheHeaders(const std::string& id); 149 void CompleteCacheFile(); 150 151 bool CheckCache(); 152 HttpError ReadCacheHeaders(const std::string& id, bool override); 153 HttpError ReadCacheBody(const std::string& id); 154 155 bool PrepareValidate(); 156 HttpError CompleteValidate(); 157 158 HttpError OnHeaderAvailable(bool ignore_data, bool chunked, size_t data_size); 159 160 void StartDNSLookup(); 161 void OnResolveResult(AsyncResolverInterface* resolver); 162 163 // IHttpNotify Interface 164 virtual HttpError onHttpHeaderComplete(bool chunked, size_t& data_size); 165 virtual void onHttpComplete(HttpMode mode, HttpError err); 166 virtual void onHttpClosed(HttpError err); 167 168 private: 169 enum CacheState { CS_READY, CS_WRITING, CS_READING, CS_VALIDATING }; 170 bool IsCacheActive() const { return (cache_state_ > CS_READY); } 171 172 std::string agent_; 173 StreamPool* pool_; 174 HttpBase base_; 175 SocketAddress server_; 176 ProxyInfo proxy_; 177 HttpTransaction* transaction_; 178 bool free_transaction_; 179 size_t retries_, attempt_, redirects_; 180 RedirectAction redirect_action_; 181 UriForm uri_form_; 182 scoped_ptr<HttpAuthContext> context_; 183 DiskCache* cache_; 184 CacheState cache_state_; 185 AsyncResolverInterface* resolver_; 186 }; 187 188 ////////////////////////////////////////////////////////////////////// 189 // HttpClientDefault - Default implementation of HttpClient 190 ////////////////////////////////////////////////////////////////////// 191 192 class HttpClientDefault : public ReuseSocketPool, public HttpClient { 193 public: 194 HttpClientDefault(SocketFactory* factory, const std::string& agent, 195 HttpTransaction* transaction = NULL); 196 }; 197 198 ////////////////////////////////////////////////////////////////////// 199 200 } // namespace rtc 201 202 #endif // WEBRTC_BASE_HTTPCLIENT_H__ 203