Panda3D
|
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 ©); 00061 void operator = (const HTTPClient ©); 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