~ubuntu-branches/debian/experimental/kopete/experimental

« back to all changes in this revision

Viewing changes to protocols/jabber/libjingle/talk/base/httpclient.h

  • Committer: Package Import Robot
  • Author(s): Maximiliano Curia
  • Date: 2015-02-24 11:32:57 UTC
  • mfrom: (1.1.41 vivid)
  • Revision ID: package-import@ubuntu.com-20150224113257-gnupg4v7lzz18ij0
Tags: 4:14.12.2-1
* New upstream release (14.12.2).
* Bump Standards-Version to 3.9.6, no changes needed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * libjingle
 
3
 * Copyright 2004--2005, Google Inc.
 
4
 *
 
5
 * Redistribution and use in source and binary forms, with or without 
 
6
 * modification, are permitted provided that the following conditions are met:
 
7
 *
 
8
 *  1. Redistributions of source code must retain the above copyright notice, 
 
9
 *     this list of conditions and the following disclaimer.
 
10
 *  2. Redistributions in binary form must reproduce the above copyright notice,
 
11
 *     this list of conditions and the following disclaimer in the documentation
 
12
 *     and/or other materials provided with the distribution.
 
13
 *  3. The name of the author may not be used to endorse or promote products 
 
14
 *     derived from this software without specific prior written permission.
 
15
 *
 
16
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 
17
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
 
18
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 
19
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 
20
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 
21
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 
22
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 
23
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
 
24
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
 
25
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
26
 */
 
27
 
 
28
#ifndef TALK_BASE_HTTPCLIENT_H__
 
29
#define TALK_BASE_HTTPCLIENT_H__
 
30
 
 
31
#include "talk/base/common.h"
 
32
#include "talk/base/httpbase.h"
 
33
#include "talk/base/proxyinfo.h"
 
34
#include "talk/base/scoped_ptr.h"
 
35
#include "talk/base/sigslot.h"
 
36
#include "talk/base/socketaddress.h"
 
37
#include "talk/base/socketpool.h"
 
38
 
 
39
namespace talk_base {
 
40
 
 
41
//////////////////////////////////////////////////////////////////////
 
42
// Client-specific http utilities
 
43
//////////////////////////////////////////////////////////////////////
 
44
 
 
45
// Write cache-relevant response headers to output stream.  If size is non-null,
 
46
// it contains the length of the output in bytes.  output may be null if only
 
47
// the length is desired.
 
48
bool HttpWriteCacheHeaders(const HttpResponseData* response,
 
49
                           StreamInterface* output, size_t* size);
 
50
// Read cached headers from a stream, and them merge them into the response
 
51
// object using the specified combine operation.
 
52
bool HttpReadCacheHeaders(StreamInterface* input,
 
53
                          HttpResponseData* response,
 
54
                          HttpData::HeaderCombine combine);
 
55
 
 
56
//////////////////////////////////////////////////////////////////////
 
57
// HttpClient
 
58
// Implements an HTTP 1.1 client.
 
59
//////////////////////////////////////////////////////////////////////
 
60
 
 
61
class DiskCache;
 
62
class HttpClient;
 
63
class IPNetPool;
 
64
 
 
65
// What to do:  Define STRICT_HTTP_ERROR=1 in your makefile.  Use HttpError in
 
66
// your code (HttpErrorType should only be used for code that is shared
 
67
// with groups which have not yet migrated).
 
68
#if STRICT_HTTP_ERROR
 
69
typedef HttpError HttpErrorType;
 
70
#else  // !STRICT_HTTP_ERROR
 
71
typedef int HttpErrorType;
 
72
#endif  // !STRICT_HTTP_ERROR
 
73
 
 
74
class HttpClient : private IHttpNotify {
 
75
public:
 
76
  // If HttpRequestData and HttpResponseData objects are provided, they must
 
77
  // be freed by the caller.  Otherwise, an internal object is allocated.
 
78
  HttpClient(const std::string& agent, StreamPool* pool,
 
79
             HttpTransaction* transaction = NULL);
 
80
  virtual ~HttpClient();
 
81
 
 
82
  void set_pool(StreamPool* pool) { pool_ = pool; }
 
83
 
 
84
  void set_agent(const std::string& agent) { agent_ = agent; }
 
85
  const std::string& agent() const { return agent_; }
 
86
  
 
87
  void set_proxy(const ProxyInfo& proxy) { proxy_ = proxy; }
 
88
  const ProxyInfo& proxy() const { return proxy_; }
 
89
 
 
90
  // Request retries occur when the connection closes before the beginning of
 
91
  // an http response is received.  In these cases, the http server may have
 
92
  // timed out the keepalive connection before it received our request.  Note
 
93
  // that if a request document cannot be rewound, no retry is made.  The
 
94
  // default is 1.
 
95
  void set_request_retries(size_t retries) { retries_ = retries; }
 
96
  size_t request_retries() const { return retries_; }
 
97
 
 
98
  enum RedirectAction { REDIRECT_DEFAULT, REDIRECT_ALWAYS, REDIRECT_NEVER };
 
99
  void set_redirect_action(RedirectAction action) { redirect_action_ = action; }
 
100
  RedirectAction redirect_action() const { return redirect_action_; }
 
101
  // Deprecated
 
102
  void set_fail_redirect(bool fail_redirect) {
 
103
    redirect_action_ = REDIRECT_NEVER;
 
104
  }
 
105
  bool fail_redirect() const { return (REDIRECT_NEVER == redirect_action_); }
 
106
 
 
107
  enum UriForm { URI_DEFAULT, URI_ABSOLUTE, URI_RELATIVE };
 
108
  void set_uri_form(UriForm form) { uri_form_ = form; }
 
109
  UriForm uri_form() const { return uri_form_; }
 
110
 
 
111
  void set_cache(DiskCache* cache) { ASSERT(!IsCacheActive()); cache_ = cache; }
 
112
  bool cache_enabled() const { return (NULL != cache_); }
 
113
 
 
114
  // reset clears the server, request, and response structures.  It will also
 
115
  // abort an active request.
 
116
  void reset();
 
117
  
 
118
  void set_server(const SocketAddress& address);
 
119
  const SocketAddress& server() const { return server_; }
 
120
 
 
121
  // Note: in order for HttpClient to retry a POST in response to
 
122
  // an authentication challenge, a redirect response, or socket disconnection,
 
123
  // the request document must support 'replaying' by calling Rewind() on it.
 
124
  // In the case where just a subset of a stream should be used as the request
 
125
  // document, the stream may be wrapped with the StreamSegment adapter.
 
126
  HttpTransaction* transaction() { return transaction_; }
 
127
  const HttpTransaction* transaction() const { return transaction_; }
 
128
  HttpRequestData& request() { return transaction_->request; }
 
129
  const HttpRequestData& request() const { return transaction_->request; }
 
130
  HttpResponseData& response() { return transaction_->response; }
 
131
  const HttpResponseData& response() const { return transaction_->response; }
 
132
  
 
133
  // convenience methods
 
134
  void prepare_get(const std::string& url);
 
135
  void prepare_post(const std::string& url, const std::string& content_type,
 
136
                    StreamInterface* request_doc);
 
137
 
 
138
  // Convert HttpClient to a pull-based I/O model.
 
139
  StreamInterface* GetDocumentStream();
 
140
 
 
141
  // After you finish setting up your request, call start.
 
142
  void start();
 
143
  
 
144
  // Signalled when the header has finished downloading, before the document
 
145
  // content is processed.  You may change the response document in response
 
146
  // to this signal.  The second parameter indicates whether this is an
 
147
  // intermediate (false) or final (true) header.  An intermediate header is
 
148
  // one that generates another request, such as a redirect or authentication
 
149
  // challenge.  The third parameter indicates the length of the response
 
150
  // document, or else SIZE_UNKNOWN.  Note: Do NOT abort the request in response
 
151
  // to this signal.
 
152
  sigslot::signal3<HttpClient*,bool,size_t> SignalHeaderAvailable;
 
153
  // Signalled when the current request finishes.  On success, err is 0.
 
154
  sigslot::signal2<HttpClient*,HttpErrorType> SignalHttpClientComplete;
 
155
 
 
156
protected:
 
157
  void connect();
 
158
  void release();
 
159
 
 
160
  bool ShouldRedirect(std::string* location) const;
 
161
 
 
162
  bool BeginCacheFile();
 
163
  HttpError WriteCacheHeaders(const std::string& id);
 
164
  void CompleteCacheFile();
 
165
 
 
166
  bool CheckCache();
 
167
  HttpError ReadCacheHeaders(const std::string& id, bool override);
 
168
  HttpError ReadCacheBody(const std::string& id);
 
169
 
 
170
  bool PrepareValidate();
 
171
  HttpError CompleteValidate();
 
172
 
 
173
  HttpError OnHeaderAvailable(bool ignore_data, bool chunked, size_t data_size);
 
174
 
 
175
  // IHttpNotify Interface
 
176
  virtual HttpError onHttpHeaderComplete(bool chunked, size_t& data_size);
 
177
  virtual void onHttpComplete(HttpMode mode, HttpError err);
 
178
  virtual void onHttpClosed(HttpError err);
 
179
  
 
180
private:
 
181
  enum CacheState { CS_READY, CS_WRITING, CS_READING, CS_VALIDATING };
 
182
  bool IsCacheActive() const { return (cache_state_ > CS_READY); }
 
183
 
 
184
  std::string agent_;
 
185
  StreamPool* pool_;
 
186
  HttpBase base_;
 
187
  SocketAddress server_;
 
188
  ProxyInfo proxy_;
 
189
  HttpTransaction* transaction_;
 
190
  bool free_transaction_;
 
191
  size_t retries_, attempt_, redirects_;
 
192
  RedirectAction redirect_action_;
 
193
  UriForm uri_form_;
 
194
  scoped_ptr<HttpAuthContext> context_;
 
195
  DiskCache* cache_;
 
196
  CacheState cache_state_;
 
197
};
 
198
 
 
199
//////////////////////////////////////////////////////////////////////
 
200
// HttpClientDefault - Default implementation of HttpClient
 
201
//////////////////////////////////////////////////////////////////////
 
202
 
 
203
class HttpClientDefault : public ReuseSocketPool, public HttpClient {
 
204
public:
 
205
  HttpClientDefault(SocketFactory* factory, const std::string& agent,
 
206
                    HttpTransaction* transaction = NULL);
 
207
};
 
208
 
 
209
//////////////////////////////////////////////////////////////////////
 
210
 
 
211
}  // namespace talk_base
 
212
 
 
213
#endif // TALK_BASE_HTTPCLIENT_H__