Panda3D

httpClient.h

00001 // Filename: httpClient.h
00002 // Created by:  drose (24Sep02)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #ifndef HTTPCLIENT_H
00016 #define HTTPCLIENT_H
00017 
00018 #include "pandabase.h"
00019 
00020 // This module requires OpenSSL to compile, even if you do not intend
00021 // to use this to establish https connections; this is because it uses
00022 // the OpenSSL library to portably handle all of the socket
00023 // communications.
00024 
00025 #ifdef HAVE_OPENSSL
00026 
00027 #include "urlSpec.h"
00028 #include "httpAuthorization.h"
00029 #include "httpEnum.h"
00030 #include "httpCookie.h"
00031 #include "globPattern.h"
00032 #include "pointerTo.h"
00033 #include "pvector.h"
00034 #include "pmap.h"
00035 #include "pset.h"
00036 #include "referenceCount.h"
00037 #include "openSSLWrapper.h"
00038 
00039 class Filename;
00040 class HTTPChannel;
00041 
00042 ////////////////////////////////////////////////////////////////////
00043 //       Class : HTTPClient
00044 // Description : Handles contacting an HTTP server and retrieving a
00045 //               document.  Each HTTPClient object represents a
00046 //               separate context, and stores its own list of cookies,
00047 //               passwords, and certificates; however, a given
00048 //               HTTPClient is capable of making multiple simultaneous
00049 //               requests to the same or different servers.
00050 //
00051 //               It is up to the programmer whether one HTTPClient
00052 //               should be used to retrieve all documents, or a
00053 //               separate one should be created each time.  There is a
00054 //               default, global HTTPClient available in
00055 //               HTTPClient::get_global_ptr().
00056 ////////////////////////////////////////////////////////////////////
00057 class EXPCL_PANDAEXPRESS HTTPClient : public ReferenceCount {
00058 PUBLISHED:
00059   HTTPClient();
00060   HTTPClient(const HTTPClient &copy);
00061   void operator = (const HTTPClient &copy);
00062   ~HTTPClient();
00063 
00064   static void init_random_seed();
00065 
00066   void set_proxy_spec(const string &proxy_spec);
00067   string get_proxy_spec() const;
00068 
00069   void set_direct_host_spec(const string &direct_host_spec);
00070   string get_direct_host_spec() const;
00071 
00072   INLINE void set_try_all_direct(bool try_all_direct);
00073   INLINE bool get_try_all_direct() const;
00074 
00075   void clear_proxy();
00076   void add_proxy(const string &scheme, const URLSpec &proxy);
00077   void clear_direct_host();
00078   void add_direct_host(const string &hostname);
00079 
00080   void get_proxies_for_url(const URLSpec &url, pvector<URLSpec> &proxies) const;
00081   string get_proxies_for_url(const URLSpec &url) const;
00082 
00083   void set_username(const string &server, const string &realm, const string &username);
00084   string get_username(const string &server, const string &realm) const;
00085 
00086   void set_cookie(const HTTPCookie &cookie);
00087   bool clear_cookie(const HTTPCookie &cookie);
00088   void clear_all_cookies();
00089   bool has_cookie(const HTTPCookie &cookie) const;
00090   HTTPCookie get_cookie(const HTTPCookie &cookie) const;
00091   void copy_cookies_from(const HTTPClient &other);
00092 
00093   void write_cookies(ostream &out) const;
00094   void send_cookies(ostream &out, const URLSpec &url);
00095   
00096   INLINE void set_client_certificate_filename(const Filename &filename);
00097   INLINE void set_client_certificate_pem(const string &pem);
00098   INLINE void set_client_certificate_passphrase(const string &passphrase);
00099   bool load_client_certificate();
00100 
00101   bool add_preapproved_server_certificate_filename(const URLSpec &url, const Filename &filename);
00102   bool add_preapproved_server_certificate_pem(const URLSpec &url, const string &pem);
00103   bool add_preapproved_server_certificate_name(const URLSpec &url, const string &name);
00104   void clear_preapproved_server_certificates(const URLSpec &url);
00105   void clear_all_preapproved_server_certificates();
00106 
00107   INLINE void set_http_version(HTTPEnum::HTTPVersion version);
00108   INLINE HTTPEnum::HTTPVersion get_http_version() const;
00109   string get_http_version_string() const;
00110   static HTTPEnum::HTTPVersion parse_http_version_string(const string &version);
00111 
00112   bool load_certificates(const Filename &filename);
00113 
00114   enum VerifySSL {
00115     VS_no_verify,     // Don't care who we talk to
00116     VS_no_date_check, // Must identify certs, but old, expired certs are OK
00117     VS_normal         // Identify certs and also check expiration dates.
00118   };
00119 
00120   INLINE void set_verify_ssl(VerifySSL verify_ssl);
00121   INLINE VerifySSL get_verify_ssl() const;
00122 
00123   INLINE void set_cipher_list(const string &cipher_list);
00124   INLINE const string &get_cipher_list() const;
00125 
00126   PT(HTTPChannel) make_channel(bool persistent_connection);
00127   BLOCKING PT(HTTPChannel) post_form(const URLSpec &url, const string &body);
00128   BLOCKING PT(HTTPChannel) get_document(const URLSpec &url);
00129   BLOCKING PT(HTTPChannel) get_header(const URLSpec &url);
00130 
00131   INLINE static string base64_encode(const string &s);
00132   INLINE static string base64_decode(const string &s);
00133 
00134   static HTTPClient *get_global_ptr();
00135 
00136 public:
00137   SSL_CTX *get_ssl_ctx();
00138 
00139 private:
00140   void check_preapproved_server_certificate(const URLSpec &url, X509 *cert,
00141                                             bool &cert_preapproved, bool &cert_name_preapproved) const;
00142 
00143   bool get_proxies_for_scheme(const string &scheme, 
00144                               pvector<URLSpec> &proxies) const;
00145 
00146   void add_http_username(const string &http_username);
00147   string select_username(const URLSpec &url, bool is_proxy, 
00148                          const string &realm) const;
00149 
00150   HTTPAuthorization *select_auth(const URLSpec &url, bool is_proxy,
00151                                  const string &last_realm);
00152   PT(HTTPAuthorization) generate_auth(const URLSpec &url, bool is_proxy,
00153                                       const string &challenge);
00154 
00155   void unload_client_certificate();
00156 
00157   static X509_NAME *parse_x509_name(const string &source);
00158   static bool x509_name_subset(X509_NAME *name_a, X509_NAME *name_b);
00159 
00160   static void split_whitespace(string &a, string &b, const string &c);
00161 
00162 #if defined(SSL_097) && !defined(NDEBUG)
00163   static void ssl_msg_callback(int write_p, int version, int content_type,
00164                                const void *buf, size_t len, SSL *ssl,
00165                                void *arg);
00166 #endif
00167 
00168   typedef pvector<URLSpec> Proxies;
00169   typedef pmap<string, Proxies> ProxiesByScheme;
00170   ProxiesByScheme _proxies_by_scheme;
00171   typedef pvector<GlobPattern> DirectHosts;
00172   DirectHosts _direct_hosts;
00173   bool _try_all_direct;
00174 
00175   HTTPEnum::HTTPVersion _http_version;
00176   VerifySSL _verify_ssl;
00177   string _cipher_list;
00178 
00179   typedef pmap<string, string> Usernames;
00180   Usernames _usernames;
00181 
00182   typedef pmap<string, PT(HTTPAuthorization)> Realms;
00183   class Domain {
00184   public:
00185     Realms _realms;
00186   };
00187   typedef pmap<string, Domain> Domains;
00188   Domains _proxy_domains, _www_domains;
00189 
00190   // Not a phash_set, since we want this to be maintained in order.
00191   typedef pset<HTTPCookie> Cookies;
00192   Cookies _cookies;
00193 
00194   Filename _client_certificate_filename;
00195   string _client_certificate_pem;
00196   string _client_certificate_passphrase;
00197 
00198   SSL_CTX *_ssl_ctx;
00199   bool _client_certificate_loaded;
00200   X509 *_client_certificate_pub;
00201   EVP_PKEY *_client_certificate_priv;
00202 
00203   typedef pvector<X509 *> ServerCerts;
00204   typedef pvector<X509_NAME *> ServerCertNames;
00205   class PreapprovedServerCert {
00206   public:
00207     ~PreapprovedServerCert();
00208 
00209     ServerCerts _certs;
00210     ServerCertNames _cert_names;
00211   };
00212 
00213   typedef pmap<string, PreapprovedServerCert> PreapprovedServerCerts;
00214   PreapprovedServerCerts _preapproved_server_certs;
00215 
00216   static PT(HTTPClient) _global_ptr;
00217 
00218   friend class HTTPChannel;
00219 };
00220 
00221 #include "httpClient.I"
00222 
00223 #endif  // HAVE_OPENSSL
00224 
00225 #endif
00226   
 All Classes Functions Variables Enumerations