/*************************************************************************** * Copyright (C) 2005 by Christof Donat * * cdonat@gmx.de * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include #include #include #include "sslclient.h" #ifndef HSADMIN_HTTPCLIENT #define HSADMIN_HTTPCLIENT using std::string; using std::iostream; using std::streamsize; using boost::lexical_cast; using boost::bad_lexical_cast; //! A Socket as a Device class TCPDevice : public boost::iostreams::device { public: //! create a TCP-Stream by connecting to the given port at the given address TCPDevice(const string& address, const short int port); //! create a TCP-Stream by connecting to the given port at the given address TCPDevice(const char* address, const short int port); //! create a TCP-Stream from a connected socket - use this with accept TCPDevice(const int socket); //! copy constructor TCPDevice(const TCPDevice& other); //! does not close the socket - use closeSocket before deleting the Device. virtual ~TCPDevice(); //! closes the socket void closeSocket(); //! read n Bytes from socket virtual streamsize read(char* s, streamsize n); //! write n Bytes to socket virtual streamsize write(const char* s, streamsize n); private: void init(const char* address, const short int port); int m_socket; }; //class SSLDevice; const int HTTP = 0; const int HTTPS = 1; //! the basic HTTP Client - can only handle POST method. class GenericHttpClient { public: //! initialize HTTP CLient with URL and default Port (usually 80) GenericHttpClient(const string &url, const unsigned short defaultPort); //! Post string post(string postcontent); protected: //! get a buffered iostream for the connection - must be overridden by derived classes virtual iostream * getConnection(const string &host, unsigned short port) = 0; //! check if this class can handle the protocol - must be overridden by derived classes virtual bool checkProtocol(const string &protocol) { return false; }; //! close the underlying connection virtual void close() = 0; private: iostream * parseUrl(); const string& m_url; string m_protocol; string m_hostname; string m_path; unsigned short m_port; const unsigned short m_defaultPort; }; //! This template should usually be used in one of the specialized Versions below. template class HttpClient: public GenericHttpClient { public: HttpClient(const string &url, unsigned short defaultPort = 80): GenericHttpClient(url,defaultPort) {}; protected: iostream * getConnection(const string &host, unsigned short port) { return (iostream *)0; }; bool checkProtocol(const string &p) { return false; }; virtual void close() { }; }; //! a HTTP CLient with a plain TCP socket as transport template <> class HttpClient: public GenericHttpClient { public: //! initialize HTTP CLient with URL and default Port (usually 80) HttpClient(const string &url, unsigned short defaultPort = 80): GenericHttpClient(url,defaultPort), device(0) {}; protected: //! get a buffered iostream for the connection iostream * getConnection(const string &host, unsigned short port) { if( device == 0 ) device = new TCPDevice(host,port); return (iostream *) new boost::iostreams::stream(*device); } //! check if this class can handle the protocol bool checkProtocol(const string &protocol) { return (protocol == "http"); }; //! close the underlying connection virtual void close() { device->closeSocket(); }; private: TCPDevice *device; }; //! a HTTP CLient with a SSL stream as transport template <> class HttpClient: public GenericHttpClient { public: //! initialize HTTPS CLient with URL and default Port (usually 443) HttpClient(const string &url, unsigned short defaultPort = 443): GenericHttpClient(url,defaultPort), device(0) {}; protected: //! get a buffered iostream for the connection iostream * getConnection(const string &host, unsigned short port) { try { if( device == 0 ) device = new SSLDevice(host,port); return (iostream *) new boost::iostreams::stream(*device); } catch( SSLDevice::CertificateError &e ) { if( device != 0 ) { delete(device); device = 0; } std::cerr << e.msg << std::endl; return (iostream *)0; } } //! check if this class can handle the protocol bool checkProtocol(const string &protocol) { return (protocol == "https"); }; //! close the underlying connection virtual void close() { device->closeSocket(); }; private: SSLDevice *device; }; /** \brief get the best HTTP client for the defined Protocol * * returns HttpClient or HttpClient depending on the protocol */ GenericHttpClient *createHttpClient(const string &uri); #else /* HSADMIN_HTTPCLIENT */ class TCPDevice; class GenericHttpClient; genericHttpClient *createHttpClient(url); extern const int HTTP = 0; extern const int HTTPS = 1; #endif /* HSADMIN_HTTPCLIENT */