HSAdmin Backend Domains, E-Mail, Datenbanken
Purodha
2013-02-20 4a7e12928010374d76e677c8ec3ea4f5e63e9487
commit | author | age
c64ab5 1 /***************************************************************************
CD 2  *   Copyright (C) 2005 by Christof Donat   *
3  *   cdonat@gmx.de   *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) any later version.                                   *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU General Public License     *
16  *   along with this program; if not, write to the                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19  ***************************************************************************/
20
21 #include "httpclient.h"
22 #include "logger.h"
23 #include <sys/types.h>
24 #include <sys/socket.h>
25 #include <netinet/in.h>
26 #include <arpa/inet.h>
27 #include <netdb.h>
28
29 using std::string;
30 using std::streamsize;
31 using std::iostream;
32 using boost::lexical_cast;
33 using boost::bad_lexical_cast;
34
35 TCPDevice::TCPDevice(const string& address, const short int port) {
36     this->init(address.c_str(),port);
37 }
38 TCPDevice::TCPDevice(const char* address, const short int port) {
39     this->init(address,port);
40 }
41
42 void TCPDevice::init(const char* address, const short int port) {
43         struct sockaddr_in addr;
44         bzero(&addr,sizeof(addr));
45         addr.sin_family = AF_INET;
46     if( (addr.sin_addr.s_addr = inet_addr(address)) == INADDR_NONE ) {
47         struct hostent* hp = gethostbyname(address);
48         if( hp == 0 ) throw("can't resolve hostname '"+string(address)+"'");
49         bcopy(hp->h_addr, (char*) &addr.sin_addr, hp->h_length);
50     }
51     addr.sin_port = htons(port);
52
53     if( (m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0 ) throw(string("can't open socket"));
54     if( ::connect(m_socket, (struct sockaddr*) &addr, sizeof(addr)) < 0 ) {
55         ::close(m_socket);
56         throw("can't connect to '"+string(address)+"' port "+(lexical_cast<string>(port)));
57     }
58 }
59 TCPDevice::TCPDevice(const int socket) : m_socket(socket) {}
60 TCPDevice::TCPDevice(const TCPDevice& other) : m_socket(other.m_socket) { }
61
62 TCPDevice::~TCPDevice() { }
63
64 void TCPDevice::closeSocket() { ::close(m_socket); }
65
66 streamsize TCPDevice::read(char* s, streamsize n) { return (streamsize)::read(m_socket,(void*)s,(size_t)n); }
67
68 streamsize TCPDevice::write(const char* s, streamsize n) { return (streamsize)::write(m_socket,(const void*)s,(size_t)n); }
69
70 GenericHttpClient::GenericHttpClient(const string &url, const unsigned short defaultPort = 80): 
71     m_url(url), m_defaultPort(defaultPort) {};
72
73 string GenericHttpClient::post(string postcontent) {
74     iostream *connection;
75     try { connection = this->parseUrl(); }
76     catch(string &e) { 
77         Logger::log(Logger::FATAL,"connection failed: "+e);
78         exit(-1);
79     }
80     if( connection == 0 ) return "";
81
82     string outbuf = "POST "+m_path+" HTTP/1.1\r\n";
83     outbuf += "Connection: close\r\n";
84     outbuf += "User-Agent: hsadmin CLI client\r\n";
85     outbuf += "Content-Type: text/xml\r\n";
86     outbuf += "Content-Length: "+boost::lexical_cast<string>(postcontent.length())+"\r\n";
87     outbuf += "Host: "+m_hostname+"\r\n\r\n";
88     outbuf += postcontent;
89
90     for( int i = 0; i < outbuf.length(); i++ )
91         (*connection) << outbuf[i];;
92
93     connection->flush();
94
95     string reply = "";
96
97     char buf[257];
98     do {            // we simply ignore the http header in the response
99         bzero(buf,257);
100         connection->getline(buf,256);
101     } while( string(buf) != "" && string(buf) != "\r" );
102
103     string tmp;
104     do {
105         tmp = "";
106         (*connection) >> tmp;
107         reply += " "+tmp;
108     } while( tmp.length() );
109
110     this->close();
111     delete connection;
112
113     return reply;
114 };
115
116 iostream * GenericHttpClient::parseUrl() {
117     int protocolend = m_url.find("://");
118     m_protocol = m_url.substr(0,protocolend);
119     if( ! this->checkProtocol(m_protocol) ) return (iostream *)0;
120
121     int hostnameend = m_url.find("/",protocolend+3);
122     m_hostname = m_url.substr(protocolend+3,hostnameend-(protocolend+3));
123     m_port = m_defaultPort;
124     m_path = m_url.substr(hostnameend);
125     int portstart = m_hostname.find(":");
126     if( portstart >= 0 ) {
127         string portstring = m_hostname.substr(portstart+1);
128     
129         if( portstring.size() > 0 ) {
130             try {
131                 m_port = lexical_cast<int>(portstring.c_str());
132                 m_hostname = m_hostname.substr(0,m_hostname.find(":"));
133             } catch(bad_lexical_cast &) { }
134         }
135     }
136
137     return this->getConnection(m_hostname, m_port);
138 };
139
140 GenericHttpClient *createHttpClient(const string &url) {
141     int protocolend = url.find("://");
142     string protocol = url.substr(0,protocolend);
143     if( protocol == "http" )  return (GenericHttpClient *) new HttpClient<HTTP>(url);
144     if( protocol == "https" ) return (GenericHttpClient *) new HttpClient<HTTPS>(url);
145     return 0;
146 }