HSAdmin Backend Domains, E-Mail, Datenbanken
Purodha
2013-02-20 4a7e12928010374d76e677c8ec3ea4f5e63e9487
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/***************************************************************************
 *   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 */