hs.hsadmin/hsacppcli/hsadminc/source/httpclient.h

164 lines
6.2 KiB
C
Raw Permalink Normal View History

/***************************************************************************
* 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 <iosfwd>
#include <string>
#include <iostream>
#include <boost/lexical_cast.hpp>
#include <boost/iostreams/stream.hpp>
#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<boost::iostreams::bidirectional> {
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 <int protocol> 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<HTTP>: 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<TCPDevice>(*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<HTTPS>: 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<SSLDevice>(*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<HTTP> or HttpClient<HTTPS> 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 */