Panda3D
httpClient.h
1 // Filename: httpClient.h
2 // Created by: drose (24Sep02)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #ifndef HTTPCLIENT_H
16 #define HTTPCLIENT_H
17 
18 #include "pandabase.h"
19 
20 // This module requires OpenSSL to compile, even if you do not intend
21 // to use this to establish https connections; this is because it uses
22 // the OpenSSL library to portably handle all of the socket
23 // communications.
24 
25 #ifdef HAVE_OPENSSL
26 
27 #include "urlSpec.h"
28 #include "httpAuthorization.h"
29 #include "httpEnum.h"
30 #include "httpCookie.h"
31 #include "globPattern.h"
32 #include "pointerTo.h"
33 #include "pvector.h"
34 #include "pmap.h"
35 #include "pset.h"
36 #include "referenceCount.h"
37 #include "openSSLWrapper.h"
38 
39 class Filename;
40 class HTTPChannel;
41 
42 ////////////////////////////////////////////////////////////////////
43 // Class : HTTPClient
44 // Description : Handles contacting an HTTP server and retrieving a
45 // document. Each HTTPClient object represents a
46 // separate context, and stores its own list of cookies,
47 // passwords, and certificates; however, a given
48 // HTTPClient is capable of making multiple simultaneous
49 // requests to the same or different servers.
50 //
51 // It is up to the programmer whether one HTTPClient
52 // should be used to retrieve all documents, or a
53 // separate one should be created each time. There is a
54 // default, global HTTPClient available in
55 // HTTPClient::get_global_ptr().
56 ////////////////////////////////////////////////////////////////////
57 class EXPCL_PANDAEXPRESS HTTPClient : public ReferenceCount {
58 PUBLISHED:
59  HTTPClient();
60  HTTPClient(const HTTPClient &copy);
61  void operator = (const HTTPClient &copy);
62  ~HTTPClient();
63 
64  static void init_random_seed();
65 
66  void set_proxy_spec(const string &proxy_spec);
67  string get_proxy_spec() const;
68 
69  void set_direct_host_spec(const string &direct_host_spec);
70  string get_direct_host_spec() const;
71 
72  INLINE void set_try_all_direct(bool try_all_direct);
73  INLINE bool get_try_all_direct() const;
74 
75  void clear_proxy();
76  void add_proxy(const string &scheme, const URLSpec &proxy);
77  void clear_direct_host();
78  void add_direct_host(const string &hostname);
79 
80  void get_proxies_for_url(const URLSpec &url, pvector<URLSpec> &proxies) const;
81  string get_proxies_for_url(const URLSpec &url) const;
82 
83  void set_username(const string &server, const string &realm, const string &username);
84  string get_username(const string &server, const string &realm) const;
85 
86  void set_cookie(const HTTPCookie &cookie);
87  bool clear_cookie(const HTTPCookie &cookie);
88  void clear_all_cookies();
89  bool has_cookie(const HTTPCookie &cookie) const;
90  HTTPCookie get_cookie(const HTTPCookie &cookie) const;
91  void copy_cookies_from(const HTTPClient &other);
92 
93  void write_cookies(ostream &out) const;
94  void send_cookies(ostream &out, const URLSpec &url);
95 
96  INLINE void set_client_certificate_filename(const Filename &filename);
97  INLINE void set_client_certificate_pem(const string &pem);
98  INLINE void set_client_certificate_passphrase(const string &passphrase);
99  bool load_client_certificate();
100 
101  bool add_preapproved_server_certificate_filename(const URLSpec &url, const Filename &filename);
102  bool add_preapproved_server_certificate_pem(const URLSpec &url, const string &pem);
103  bool add_preapproved_server_certificate_name(const URLSpec &url, const string &name);
104  void clear_preapproved_server_certificates(const URLSpec &url);
105  void clear_all_preapproved_server_certificates();
106 
107  INLINE void set_http_version(HTTPEnum::HTTPVersion version);
108  INLINE HTTPEnum::HTTPVersion get_http_version() const;
109  string get_http_version_string() const;
110  static HTTPEnum::HTTPVersion parse_http_version_string(const string &version);
111 
112  bool load_certificates(const Filename &filename);
113 
114  enum VerifySSL {
115  VS_no_verify, // Don't care who we talk to
116  VS_no_date_check, // Must identify certs, but old, expired certs are OK
117  VS_normal // Identify certs and also check expiration dates.
118  };
119 
120  INLINE void set_verify_ssl(VerifySSL verify_ssl);
121  INLINE VerifySSL get_verify_ssl() const;
122 
123  INLINE void set_cipher_list(const string &cipher_list);
124  INLINE const string &get_cipher_list() const;
125 
126  PT(HTTPChannel) make_channel(bool persistent_connection);
127  BLOCKING PT(HTTPChannel) post_form(const URLSpec &url, const string &body);
128  BLOCKING PT(HTTPChannel) get_document(const URLSpec &url);
129  BLOCKING PT(HTTPChannel) get_header(const URLSpec &url);
130 
131  INLINE static string base64_encode(const string &s);
132  INLINE static string base64_decode(const string &s);
133 
134  static HTTPClient *get_global_ptr();
135 
136 public:
137  SSL_CTX *get_ssl_ctx();
138 
139 private:
140  void check_preapproved_server_certificate(const URLSpec &url, X509 *cert,
141  bool &cert_preapproved, bool &cert_name_preapproved) const;
142 
143  bool get_proxies_for_scheme(const string &scheme,
144  pvector<URLSpec> &proxies) const;
145 
146  void add_http_username(const string &http_username);
147  string select_username(const URLSpec &url, bool is_proxy,
148  const string &realm) const;
149 
150  HTTPAuthorization *select_auth(const URLSpec &url, bool is_proxy,
151  const string &last_realm);
152  PT(HTTPAuthorization) generate_auth(const URLSpec &url, bool is_proxy,
153  const string &challenge);
154 
155  void unload_client_certificate();
156 
157  static X509_NAME *parse_x509_name(const string &source);
158  static bool x509_name_subset(X509_NAME *name_a, X509_NAME *name_b);
159 
160  static void split_whitespace(string &a, string &b, const string &c);
161 
162 #if defined(SSL_097) && !defined(NDEBUG)
163  static void ssl_msg_callback(int write_p, int version, int content_type,
164  const void *buf, size_t len, SSL *ssl,
165  void *arg);
166 #endif
167 
168  typedef pvector<URLSpec> Proxies;
169  typedef pmap<string, Proxies> ProxiesByScheme;
170  ProxiesByScheme _proxies_by_scheme;
171  typedef pvector<GlobPattern> DirectHosts;
172  DirectHosts _direct_hosts;
173  bool _try_all_direct;
174 
175  HTTPEnum::HTTPVersion _http_version;
176  VerifySSL _verify_ssl;
177  string _cipher_list;
178 
179  typedef pmap<string, string> Usernames;
180  Usernames _usernames;
181 
183  class Domain {
184  public:
185  Realms _realms;
186  };
187  typedef pmap<string, Domain> Domains;
188  Domains _proxy_domains, _www_domains;
189 
190  // Not a phash_set, since we want this to be maintained in order.
191  typedef pset<HTTPCookie> Cookies;
192  Cookies _cookies;
193 
194  Filename _client_certificate_filename;
195  string _client_certificate_pem;
196  string _client_certificate_passphrase;
197 
198  SSL_CTX *_ssl_ctx;
199  bool _client_certificate_loaded;
200  X509 *_client_certificate_pub;
201  EVP_PKEY *_client_certificate_priv;
202 
203  typedef pvector<X509 *> ServerCerts;
204  typedef pvector<X509_NAME *> ServerCertNames;
205  class PreapprovedServerCert {
206  public:
207  ~PreapprovedServerCert();
208 
209  ServerCerts _certs;
210  ServerCertNames _cert_names;
211  };
212 
213  typedef pmap<string, PreapprovedServerCert> PreapprovedServerCerts;
214  PreapprovedServerCerts _preapproved_server_certs;
215 
216  static PT(HTTPClient) _global_ptr;
217 
218  friend class HTTPChannel;
219 };
220 
221 #include "httpClient.I"
222 
223 #endif // HAVE_OPENSSL
224 
225 #endif
226 
This is our own Panda specialization on the default STL map.
Definition: pmap.h:52
A container for a URL, e.g.
Definition: urlSpec.h:29
This is our own Panda specialization on the default STL vector.
Definition: pvector.h:39
The name of a file, such as a texture file or an Egg file.
Definition: filename.h:44
A base class for all things that want to be reference-counted.
This is our own Panda specialization on the default STL set.
Definition: pset.h:52