Back to index

nordugrid-arc-nox  1.1.0~rc6
HTTPSClient.h
Go to the documentation of this file.
00001 #ifndef __HTTPS__CLIENT_H__
00002 #define __HTTPS__CLIENT_H__
00003 
00004 #ifdef WIN32
00005 #include <arc/win32.h> 
00006 #endif
00007 
00008 #include <string>
00009 
00010 #include <globus_io.h>
00011 #include <stdsoap2.h>
00012 
00013 #include <arc/URL.h>
00014 #include <arc/Logger.h>
00015 #include <arc/Thread.h>
00016 #include <arc/DateTime.h>
00017 #include <arc/globusutils/GSSCredential.h>
00018 
00019 namespace Arc {
00020 
00021   typedef enum {
00022     HTTP_OK = 200,
00023     HTTP_NOT_IMPLEMENTED = 501,
00024     HTTP_NOT_ALLOWED = 403,
00025     HTTP_NOT_FOUND = 404,
00026     HTTP_ERROR = 500,
00027     HTTP_FAILURE = -1
00028   } HTTPError;
00029   
00030   class HTTPResponseHeader {
00031    private:
00032     bool keep_alive;
00033   
00034     bool content_length_passed; // Content-Length
00035     unsigned long long int content_length;
00036   
00037     bool content_range_passed;  // Content-Range
00038     unsigned long long int content_size;
00039     unsigned long long int content_start;
00040     unsigned long long int content_end;
00041   
00042     Time expires; // Expires
00043   
00044     Time last_modified; // Last-Modified
00045   
00046    public:
00047     HTTPResponseHeader(bool alive = true);
00048     void reset(bool alive = true);
00049     bool set(const char* name,const char* value);
00050     bool haveContentRange(void) const { return content_range_passed; };
00051     bool haveContentLength(void) const { return content_length_passed; };
00052     bool haveExpires(void) const { return expires != 0; };
00053     bool haveLastModified(void) const { return last_modified != 0; };
00054     unsigned long long int ContentLength(void) const {
00055       if(content_length_passed) return content_length;
00056       if(content_range_passed) return (content_end-content_start+1);
00057       return 0;
00058     };
00059     unsigned long long int ContentStart(void) const {
00060       if(content_range_passed) return content_start;
00061       return 0;
00062     };
00063     unsigned long long int ContentEnd(void) const {
00064       if(content_range_passed) return content_end;
00065       if(content_length_passed && content_length) return content_length-1;
00066       return 0;
00067     };
00068     unsigned long long int ContentSize(void) const {
00069       if(content_range_passed) return content_size;
00070       if(content_length_passed) return content_length;
00071       return 0;
00072     };
00073     Time Expires(void) const { return expires; };
00074     Time LastModified(void) const { return last_modified; };
00075     bool KeepAlive(void) const { return keep_alive; };
00076   };
00077   
00078   class HTTPSClient;
00079   class HTTPSClientSOAP;
00080   
00081   class HTTPSClientConnector {
00082    friend class HTTPSClient;
00083    friend class HTTPSClientSOAP;
00084    protected:
00086     static SimpleCondition * connect_lock;
00088     virtual bool connect(bool& timedout);
00090     virtual bool disconnect(void);
00092     virtual bool clear(void);
00094     virtual bool read(char* buf = NULL,unsigned int* size = NULL);
00096     virtual bool write(const char* buf = NULL,unsigned int size = 0);
00099     virtual bool transfer(bool& read,bool& write,int timeout);
00101     virtual bool eofread(void);
00103     virtual bool eofwrite(void);
00105     static Logger logger;
00106    public:
00107     HTTPSClientConnector(void);
00108     virtual ~HTTPSClientConnector(void);
00109     virtual bool credentials(gss_cred_id_t cred);
00110   };
00111   
00112   class HTTPSClientConnectorGlobus: public HTTPSClientConnector {
00113    private:
00114     bool valid;
00115     URL base_url;
00116     bool connected;
00117     gss_cred_id_t cred;
00118     int timeout;
00119     bool read_registered;
00120     bool write_registered;
00121     unsigned int* read_size;
00122     SimpleCondition cond;
00123     globus_io_handle_t s;
00124     globus_io_attr_t attr;
00125     globus_io_secure_authorization_data_t auth;
00126     int read_done;
00127     int write_done;
00128     static void general_callback(void *arg,globus_io_handle_t *handle,globus_result_t  result);
00129     static void read_callback(void *arg,globus_io_handle_t *handle,globus_result_t result,globus_byte_t *buf,globus_size_t nbytes);
00130     static void write_callback(void *arg,globus_io_handle_t *handle,globus_result_t result,globus_byte_t *buf,globus_size_t nbytes);
00131     static globus_bool_t authorization_callback(void* arg,globus_io_handle_t* h,globus_result_t result,char* identity,gss_ctx_id_t context_handle);
00132    protected:
00133     virtual bool connect(bool& timedout);
00134     virtual bool disconnect(void);
00135     virtual bool read(char* buf = NULL,unsigned int* size = NULL);
00136     virtual bool write(const char* buf = NULL,unsigned int size = 0);
00137     virtual bool clear(void);
00138     virtual bool transfer(bool& read,bool& write,int timeout);
00139     virtual bool eofread(void);
00140     virtual bool eofwrite(void);
00141    public:
00142     HTTPSClientConnectorGlobus(const char* base,bool heavy_encryption,int timeout = 60000,gss_cred_id_t cred = GSS_C_NO_CREDENTIAL);
00143     virtual ~HTTPSClientConnectorGlobus(void);
00144     virtual bool credentials(gss_cred_id_t cred);
00145   };
00146   
00147   class HTTPSClientConnectorGSSAPI: public HTTPSClientConnector {
00148    private:
00149     bool valid;
00150     URL base_url;
00151     int s;
00152     gss_cred_id_t cred;
00153     gss_ctx_id_t context;
00154     int timeout;
00155     int read_SSL_token(void** val,int timeout);
00156     int do_read(char* buf,int size,int& timeout);
00157     int do_write(char* buf,int size,int& timeout);
00158     char* read_buf;
00159     unsigned int read_size;
00160     unsigned int* read_size_result;
00161     bool read_eof_flag;
00162     const char* write_buf;
00163     unsigned int write_size;
00164     bool check_host_cert;
00165    protected:
00166     virtual bool connect(bool& timedout);
00167     virtual bool disconnect(void);
00168     virtual bool clear(void);
00169     virtual bool read(char* buf = NULL,unsigned int* size = NULL);
00170     virtual bool write(const char* buf = NULL,unsigned int size = 0);
00171     virtual bool transfer(bool& read,bool& write,int timeout);
00172     virtual bool eofread(void);
00173     virtual bool eofwrite(void);
00174    public:
00175     HTTPSClientConnectorGSSAPI(const char* base,bool heavy_encryption,int timeout = 60000,gss_cred_id_t cred = GSS_C_NO_CREDENTIAL,bool check_host=true);
00176     virtual ~HTTPSClientConnectorGSSAPI(void);
00177     virtual bool credentials(gss_cred_id_t cred);
00178   };
00179   
00180   
00181   class HTTPSClient {
00182    friend class HTTPSClientSOAP;
00183    private:
00184     static Logger logger;
00185     HTTPSClientConnector* c;
00186     URL base_url;
00187     std::string proxy_hostname;
00188     unsigned int proxy_port;
00189     int timeout;
00190     bool valid;
00191     bool connected;
00192     char answer_buf[256];
00193     unsigned int answer_size;
00194     unsigned int answer_count;
00195     int answer_code;
00196     std::string answer_reason;
00197     HTTPResponseHeader fields;
00198     GSSCredential * cred;
00199     int parse_response(void);
00200     void clear_input(void);
00201     void analyze_response_line(char* line);
00202     int read_response_header(void);
00203     int skip_response_entity(void);
00204     int make_header(const char* path,unsigned long long int offset,unsigned long long int size,unsigned long long int fd_size,std::string& header);
00205     int GET_header(const char* path,unsigned long long int offset,unsigned long long int size);
00206    public:
00207     typedef int (*get_callback_t)(unsigned long long offset,unsigned long long size,unsigned char** buf,unsigned long long* bufsize,void* arg);
00208     typedef int (*put_callback_t)(unsigned long long offset,unsigned long long *size,char* buf);
00209     HTTPSClient(const char* base,bool heavy_encryption = true,bool gssapi_server = false, int timeout=60000, bool check_host_cert = true);
00210     virtual ~HTTPSClient(void);
00211     operator bool(void) { return valid; };
00212     bool credentials(const char* filename);
00214     int connect(void);
00215     int disconnect(void);
00216     int PUT(const char* path,unsigned long long int offset,unsigned long long int size,const unsigned char* buf,unsigned long long int fd_size,bool wait = true);
00217     int GET(const char* path,unsigned long long int offset,unsigned long long int size,get_callback_t callback,void* arg,unsigned char* buf = NULL,unsigned long long int bufsize = 0);
00218     bool keep_alive(void) const { return fields.KeepAlive(); };
00219     // unsigned long long int size(void) const { return fields.ContentSize(); };
00220     const HTTPResponseHeader& response(void) { return fields; };
00221   };
00222   
00223   class HTTPSClientSOAP: public HTTPSClient {
00224    private:
00225     struct ::soap *soap;
00226     struct Namespace* namespaces;
00227     static int local_fsend(struct soap *sp, const char* buf, size_t l);
00228     static size_t local_frecv(struct soap* sp, char* buf, size_t l);
00229 
00230 #ifndef WIN32
00231     static int local_fopen(struct soap* sp, const char* endpoint, const char* host, int port);
00232 #else
00233     static SOCKET local_fopen(struct soap* sp, const char* endpoint, const char* host, int port);
00234 #endif
00235 
00236     static int local_fclose(struct soap* sp);
00237     std::string soap_url;
00238    public:
00239     HTTPSClientSOAP(const char* base,struct soap *sp,bool gssapi_server = false, int soap_timeout = 60, bool check_host_cert = true);
00240     ~HTTPSClientSOAP(void);
00241     const char* SOAP_URL(void) { return soap_url.c_str(); };
00242     std::string SOAP_URL(const char* path);
00243     void reset(void);
00244     void AddSOAPNamespaces(struct Namespace* namespaces);
00245     const struct Namespace* Namespaces(void);
00246   };
00247 
00248 } // namespace Arc
00249 
00250 #endif /*  __HTTPS__CLIENT_H__ */