gloox 1.0.28
connectionhttpproxy.cpp
1/*
2 Copyright (c) 2004-2023 by Jakob Schröter <js@camaya.net>
3 This file is part of the gloox library. http://camaya.net/gloox
4
5 This software is distributed under a license. The full license
6 agreement can be found in the file LICENSE in this distribution.
7 This software may not be copied, modified, sold or distributed
8 other than expressed in the named license agreement.
9
10 This software is distributed without any warranty.
11*/
12
13
14
15#include "gloox.h"
16
17#include "connectionhttpproxy.h"
18#include "dns.h"
19#include "logsink.h"
20#include "prep.h"
21#include "base64.h"
22#include "util.h"
23
24#include <string>
25
26namespace gloox
27{
28
30 const LogSink& logInstance,
31 const std::string& server, int port )
32 : ConnectionBase( 0 ), m_connection( connection ),
33 m_logInstance( logInstance ), m_http11( false )
34 {
35// FIXME check return value?
37 m_port = port;
38
39 if( m_connection )
40 m_connection->registerConnectionDataHandler( this );
41 }
42
44 ConnectionBase* connection,
45 const LogSink& logInstance,
46 const std::string& server, int port )
47 : ConnectionBase( cdh ), m_connection( connection ),
48 m_logInstance( logInstance )
49 {
50// FIXME check return value?
52 m_port = port;
53
54 if( m_connection )
55 m_connection->registerConnectionDataHandler( this );
56 }
57
59 {
60 delete m_connection;
61 }
62
64 {
65 ConnectionBase* conn = m_connection ? m_connection->newInstance() : 0;
66 return new ConnectionHTTPProxy( m_handler, conn, m_logInstance, m_server, m_port );
67 }
68
70 {
71 if( m_connection )
72 delete m_connection;
73
74 m_connection = connection;
75 }
76
78 {
79 if( m_connection && m_handler )
80 {
82 return m_connection->connect();
83 }
84
85 return ConnNotConnected;
86 }
87
89 {
91 if( m_connection )
92 m_connection->disconnect();
93 }
94
96 {
97 return m_connection ? m_connection->recv( timeout ) : ConnNotConnected;
98 }
99
101 {
102 return m_connection ? m_connection->receive() : ConnNotConnected;
103 }
104
105 bool ConnectionHTTPProxy::send( const std::string& data )
106 {
107 return m_connection && m_connection->send( data );
108 }
109
111 {
113
114 if( m_connection )
115 m_connection->cleanup();
116 }
117
118 void ConnectionHTTPProxy::getStatistics( long int& totalIn, long int& totalOut )
119 {
120 if( m_connection )
121 m_connection->getStatistics( totalIn, totalOut );
122 else
123 totalIn = totalOut = 0;
124 }
125
127 const std::string& data )
128 {
129 if( !m_handler )
130 return;
131
132 if( m_state == StateConnecting )
133 {
134 m_proxyHandshakeBuffer += data;
135 if( ( !m_proxyHandshakeBuffer.compare( 0, 12, "HTTP/1.0 200" )
136 || !m_proxyHandshakeBuffer.compare( 0, 12, "HTTP/1.1 200" ) )
137 && !m_proxyHandshakeBuffer.compare( m_proxyHandshakeBuffer.length() - 4, 4, "\r\n\r\n" ) )
138 {
139 m_proxyHandshakeBuffer = EmptyString;
142 "HTTP proxy connection established" );
143 m_handler->handleConnect( this );
144 }
145 else if( !m_proxyHandshakeBuffer.compare( 9, 3, "407" ) )
146 {
148 m_connection->disconnect();
149 }
150 else if( !m_proxyHandshakeBuffer.compare( 9, 3, "403" )
151 || !m_proxyHandshakeBuffer.compare( 9, 3, "404" ) )
152 {
154 m_connection->disconnect();
155 }
156 }
157 else if( m_state == StateConnected )
158 m_handler->handleReceivedData( this, data );
159 }
160
162 {
163 if( m_connection )
164 {
165 std::string server = m_server;
166 int port = m_port;
167 if( port == -1 )
168 {
169 const DNS::HostMap& servers = DNS::resolve( m_server, m_logInstance );
170 if( !servers.empty() )
171 {
172 const std::pair< std::string, int >& host = *servers.begin();
173 server = host.first;
174 port = host.second;
175 }
176 }
177 std::string message = "Requesting HTTP proxy connection to " + server + ":"
178 + util::int2string( port );
179 m_logInstance.dbg( LogAreaClassConnectionHTTPProxy, message );
180
181 std::string os = "CONNECT " + server + ":" + util::int2string( port ) + " HTTP/1."
182 + util::int2string( m_http11 ? 1 : 0 ) + "\r\n"
183 "Host: " + server + "\r\n"
184 "Content-Length: 0\r\n"
185 "Proxy-Connection: Keep-Alive\r\n"
186 "Pragma: no-cache\r\n"
187 "User-Agent: gloox/" + GLOOX_VERSION + "\r\n";
188
189 if( !m_proxyUser.empty() && !m_proxyPwd.empty() )
190 {
191 os += "Proxy-Authorization: Basic " + Base64::encode64( m_proxyUser + ":" + m_proxyPwd )
192 + "\r\n";
193 }
194 os += "\r\n";
195
196 if( !m_connection->send( os ) )
197 {
199 if( m_handler )
201 }
202 }
203 }
204
206 ConnectionError reason )
207 {
209 m_logInstance.dbg( LogAreaClassConnectionHTTPProxy, "HTTP Proxy connection closed" );
210
211 if( m_handler )
212 m_handler->handleDisconnect( this, reason );
213 }
214
215}
An abstract base class for a connection.
virtual void cleanup()
ConnectionState m_state
const std::string & server() const
virtual ConnectionBase * newInstance() const =0
virtual ConnectionError recv(int timeout=-1)=0
virtual bool send(const std::string &data)=0
ConnectionDataHandler * m_handler
virtual ConnectionError connect()=0
virtual ConnectionError receive()=0
virtual void getStatistics(long int &totalIn, long int &totalOut)=0
virtual void disconnect()=0
void registerConnectionDataHandler(ConnectionDataHandler *cdh)
This is an abstract base class to receive events from a ConnectionBase-derived object.
virtual void handleReceivedData(const ConnectionBase *connection, const std::string &data)=0
virtual void handleDisconnect(const ConnectionBase *connection, ConnectionError reason)=0
virtual void handleConnect(const ConnectionBase *connection)=0
This is an implementation of a simple HTTP Proxying connection.
virtual void handleDisconnect(const ConnectionBase *connection, ConnectionError reason)
virtual ConnectionError recv(int timeout=-1)
virtual void handleConnect(const ConnectionBase *connection)
virtual void handleReceivedData(const ConnectionBase *connection, const std::string &data)
virtual ConnectionBase * newInstance() const
virtual ConnectionError connect()
void setConnectionImpl(ConnectionBase *connection)
virtual bool send(const std::string &data)
ConnectionHTTPProxy(ConnectionBase *connection, const LogSink &logInstance, const std::string &server, int port=-1)
virtual ConnectionError receive()
virtual void getStatistics(long int &totalIn, long int &totalOut)
static HostMap resolve(const std::string &service, const std::string &proto, const std::string &domain, const LogSink &logInstance)
Definition dns.cpp:83
std::map< std::string, int > HostMap
Definition dns.h:68
An implementation of log sink and source.
Definition logsink.h:39
void dbg(LogArea area, const std::string &message) const
Definition logsink.h:66
const std::string encode64(const std::string &input)
Definition base64.cpp:38
bool idna(const std::string &domain, std::string &out)
Definition prep.cpp:107
The namespace for the gloox library.
Definition adhoc.cpp:28
const std::string GLOOX_VERSION
Definition gloox.cpp:119
ConnectionError
Definition gloox.h:684
@ ConnNotConnected
Definition gloox.h:715
@ ConnProxyAuthFailed
Definition gloox.h:692
@ ConnProxyAuthRequired
Definition gloox.h:690
@ ConnIoError
Definition gloox.h:696
@ LogAreaClassConnectionHTTPProxy
Definition gloox.h:1060
const std::string EmptyString
Definition gloox.cpp:124
@ StateDisconnected
Definition gloox.h:642
@ StateConnected
Definition gloox.h:644
@ StateConnecting
Definition gloox.h:643