• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • tdecore
 

tdecore

  • tdecore
  • network
khttpproxysocketdevice.cpp
1/*
2 * Copyright (C) 2003 Thiago Macieira <thiago.macieira@kdemail.net>
3 *
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25#include <config.h>
26
27#include <sys/types.h>
28#include <sys/socket.h>
29
30#include <tqsocketnotifier.h>
31#include <tqcstring.h>
32
33#include "kresolver.h"
34#include "tdesocketaddress.h"
35#include "tdesocketdevice.h"
36#include "khttpproxysocketdevice.h"
37
38using namespace KNetwork;
39
40KResolverEntry KHttpProxySocketDevice::defaultProxy;
41
42class KNetwork::KHttpProxySocketDevicePrivate
43{
44public:
45 KResolverEntry proxy;
46 TQCString request;
47 TQCString reply;
48 TDESocketAddress peer;
49
50 KHttpProxySocketDevicePrivate()
51 : proxy(KHttpProxySocketDevice::defaultProxy)
52 { }
53};
54
55KHttpProxySocketDevice::KHttpProxySocketDevice(const TDESocketBase* parent)
56 : TDESocketDevice(parent), d(new KHttpProxySocketDevicePrivate)
57{
58}
59
60KHttpProxySocketDevice::KHttpProxySocketDevice(const KResolverEntry& proxy)
61 : d(new KHttpProxySocketDevicePrivate)
62{
63 d->proxy = proxy;
64}
65
66KHttpProxySocketDevice::~KHttpProxySocketDevice()
67{
68 // nothing special to be done during closing
69 // TDESocketDevice::~TDESocketDevice closes the socket
70
71 delete d;
72}
73
74int KHttpProxySocketDevice::capabilities() const
75{
76 return CanConnectString | CanNotBind | CanNotListen | CanNotUseDatagrams;
77}
78
79const KResolverEntry&
80KHttpProxySocketDevice::proxyServer() const
81{
82 return d->proxy;
83}
84
85void KHttpProxySocketDevice::setProxyServer(const KResolverEntry& proxy)
86{
87 d->proxy = proxy;
88}
89
90void KHttpProxySocketDevice::close()
91{
92 d->reply = d->request = TQCString();
93 d->peer = TDESocketAddress();
94 TDESocketDevice::close();
95}
96
97TDESocketAddress KHttpProxySocketDevice::peerAddress() const
98{
99 if (isOpen())
100 return d->peer;
101 return TDESocketAddress();
102}
103
104TDESocketAddress KHttpProxySocketDevice::externalAddress() const
105{
106 return TDESocketAddress();
107}
108
109bool KHttpProxySocketDevice::connect(const KResolverEntry& address)
110{
111 if (d->proxy.family() == AF_UNSPEC)
112 // no proxy server set !
113 return TDESocketDevice::connect(address);
114
115 if (isOpen())
116 {
117 // socket is already open
118 resetError();
119 return true;
120 }
121
122 if (m_sockfd == -1)
123 // socket isn't created yet
124 return connect(address.address().nodeName(),
125 address.address().serviceName());
126
127 d->peer = address.address();
128 return parseServerReply();
129}
130
131bool KHttpProxySocketDevice::connect(const TQString& node, const TQString& service)
132{
133 // same safety checks as above
134 if (m_sockfd == -1 && (d->proxy.family() == AF_UNSPEC ||
135 node.isEmpty() || service.isEmpty()))
136 {
137 // no proxy server set !
138 setError(IO_ConnectError, NotSupported);
139 return false;
140 }
141
142 if (isOpen())
143 {
144 // socket is already open
145 return true;
146 }
147
148 if (m_sockfd == -1)
149 {
150 // must create the socket
151 if (!TDESocketDevice::connect(d->proxy))
152 return false; // also unable to contact proxy server
153 setState(0); // unset open flag
154
155 // prepare the request
156 TQString request = TQString::fromLatin1("CONNECT %1:%2 HTTP/1.1\r\n"
157 "Cache-Control: no-cache\r\n"
158 "Host: \r\n"
159 "\r\n");
160 TQString node2 = node;
161 if (node.contains(':'))
162 node2 = '[' + node + ']';
163
164 d->request = TQString(request.arg(node2).arg(service)).latin1();
165 }
166
167 return parseServerReply();
168}
169
170bool KHttpProxySocketDevice::parseServerReply()
171{
172 // make sure we're connected
173 if (!TDESocketDevice::connect(d->proxy)) {
174 if (error() == InProgress) {
175 return true;
176 }
177 else if (error() != NoError) {
178 return false;
179 }
180 }
181
182 if (!d->request.isEmpty())
183 {
184 // send request
185 TQ_LONG written = writeBlock(d->request, d->request.length());
186 if (written < 0)
187 {
188 tqDebug("KHttpProxySocketDevice: would block writing request!");
189 if (error() == WouldBlock)
190 setError(IO_ConnectError, InProgress);
191 return error() == WouldBlock; // error
192 }
193 tqDebug("KHttpProxySocketDevice: request written");
194
195 d->request.remove(0, written);
196
197 if (!d->request.isEmpty())
198 {
199 setError(IO_ConnectError, InProgress);
200 return true; // still in progress
201 }
202 }
203
204 // request header is sent
205 // must parse reply, but must also be careful not to read too much
206 // from the buffer
207
208 int index;
209 if (!blocking())
210 {
211 TQ_LONG avail = bytesAvailable();
212 tqDebug("KHttpProxySocketDevice: %ld bytes available", avail);
213 setState(0);
214 if (avail == 0)
215 {
216 setError(IO_ConnectError, InProgress);
217 return true;
218 }
219 else if (avail < 0)
220 return false; // error!
221
222 TQByteArray buf(avail);
223 if (peekBlock(buf.data(), avail) < 0)
224 return false; // error!
225
226 TQCString fullHeaders = d->reply + buf.data();
227 // search for the end of the headers
228 index = fullHeaders.find("\r\n\r\n");
229 if (index == -1)
230 {
231 // no, headers not yet finished...
232 // consume data from socket
233 readBlock(buf.data(), avail);
234 d->reply += buf.data();
235 setError(IO_ConnectError, InProgress);
236 return true;
237 }
238
239 // headers are finished
240 index -= d->reply.length();
241 d->reply += fullHeaders.mid(d->reply.length(), index + 4);
242
243 // consume from socket
244 readBlock(buf.data(), index + 4);
245 }
246 else
247 {
248 int state = 0;
249 if (d->reply.right(3) == "\r\n\r")
250 state = 3;
251 else if (d->reply.right(2) == "\r\n")
252 state = 2;
253 else if (d->reply.right(1) == "\r")
254 state = 1;
255 while (state != 4)
256 {
257 char c = getch();
258 d->reply += c;
259
260 if ((state == 3 && c == '\n') ||
261 (state == 1 && c == '\n') ||
262 c == '\r')
263 ++state;
264 else
265 state = 0;
266 }
267 }
268
269 // now really parse the reply
270 tqDebug("KHttpProxySocketDevice: get reply: %s\n",
271 d->reply.left(d->reply.find('\r')).data());
272 if (d->reply.left(7) != "HTTP/1." ||
273 (index = d->reply.find(' ')) == -1 ||
274 d->reply[index + 1] != '2')
275 {
276 setError(IO_ConnectError, NetFailure);
277 return false;
278 }
279
280 // we've got it
281 resetError();
282 setState(IO_Open);
283 return true;
284}
KNetwork::KActiveSocketBase::setError
void setError(int status, SocketError error)
Sets the socket's error code and the I/O Device's status.
Definition: tdesocketbase.cpp:309
KNetwork::KActiveSocketBase::resetError
void resetError()
Resets the socket error code and the I/O Device's status.
Definition: tdesocketbase.cpp:315
KNetwork::KActiveSocketBase::getch
virtual int getch()
Reads one character from the socket.
Definition: tdesocketbase.cpp:291
KNetwork::KHttpProxySocketDevice
The low-level backend for HTTP proxying.
Definition: khttpproxysocketdevice.h:44
KNetwork::KHttpProxySocketDevice::capabilities
virtual int capabilities() const
Sets our capabilities.
Definition: khttpproxysocketdevice.cpp:74
KNetwork::KHttpProxySocketDevice::KHttpProxySocketDevice
KHttpProxySocketDevice(const TDESocketBase *=0L)
Constructor.
Definition: khttpproxysocketdevice.cpp:55
KNetwork::KHttpProxySocketDevice::setProxyServer
void setProxyServer(const KResolverEntry &proxy)
Sets the proxy server address.
Definition: khttpproxysocketdevice.cpp:85
KNetwork::KHttpProxySocketDevice::proxyServer
const KResolverEntry & proxyServer() const
Retrieves the proxy server address.
Definition: khttpproxysocketdevice.cpp:80
KNetwork::KHttpProxySocketDevice::peerAddress
virtual TDESocketAddress peerAddress() const
Return the peer address.
Definition: khttpproxysocketdevice.cpp:97
KNetwork::KHttpProxySocketDevice::close
virtual void close()
Closes the socket.
Definition: khttpproxysocketdevice.cpp:90
KNetwork::KHttpProxySocketDevice::connect
virtual bool connect(const KResolverEntry &address)
Overrides connection.
Definition: khttpproxysocketdevice.cpp:109
KNetwork::KHttpProxySocketDevice::~KHttpProxySocketDevice
virtual ~KHttpProxySocketDevice()
Destructor.
Definition: khttpproxysocketdevice.cpp:66
KNetwork::KHttpProxySocketDevice::externalAddress
virtual TDESocketAddress externalAddress() const
Return the externally visible address.
Definition: khttpproxysocketdevice.cpp:104
KNetwork::KResolverEntry
One resolution entry.
Definition: kresolver.h:67
KNetwork::KResolverEntry::address
TDESocketAddress address() const
Retrieves the socket address associated with this entry.
Definition: kresolver.cpp:142
KNetwork::TDESocketAddress
A generic socket address.
Definition: tdesocketaddress.h:424
KNetwork::TDESocketAddress::serviceName
virtual TQString serviceName() const
Returns the service name for this socket.
Definition: tdesocketaddress.cpp:603
KNetwork::TDESocketAddress::nodeName
virtual TQString nodeName() const
Returns the node name of this socket.
Definition: tdesocketaddress.cpp:576
KNetwork::TDESocketBase
Basic socket functionality.
Definition: tdesocketbase.h:98
KNetwork::TDESocketBase::error
SocketError error() const
Retrieves the socket error code.
Definition: tdesocketbase.cpp:160
KNetwork::TDESocketBase::blocking
bool blocking() const
Retrieves this socket's blocking mode.
Definition: tdesocketbase.cpp:81
KNetwork::TDESocketDevice
Low-level socket functionality.
Definition: tdesocketdevice.h:51
KNetwork::TDESocketDevice::peekBlock
virtual TQ_LONG peekBlock(char *data, TQ_ULONG maxlen)
Peeks data in the socket.
Definition: tdesocketdevice.cpp:459
KNetwork::TDESocketDevice::writeBlock
virtual TQ_LONG writeBlock(const char *data, TQ_ULONG len)
Writes data to the socket.
Definition: tdesocketdevice.cpp:501
KNetwork::TDESocketDevice::close
virtual void close()
Closes the socket.
Definition: tdesocketdevice.cpp:180
KNetwork::TDESocketDevice::readBlock
virtual TQ_LONG readBlock(char *data, TQ_ULONG maxlen)
Reads data from this socket.
Definition: tdesocketdevice.cpp:417
KNetwork::TDESocketDevice::m_sockfd
int m_sockfd
The socket file descriptor.
Definition: tdesocketdevice.h:95
KNetwork::TDESocketDevice::bytesAvailable
virtual TQ_LONG bytesAvailable() const
Returns the number of bytes available for reading without blocking.
Definition: tdesocketdevice.cpp:367
KNetwork::TDESocketDevice::connect
virtual bool connect(const KResolverEntry &address)
Connect to a remote host.
Definition: tdesocketdevice.cpp:276
KNetwork::TDESocketDevice::CanConnectString
@ CanConnectString
Can connect to hostnames.
Definition: tdesocketdevice.h:67
KNetwork::TDESocketDevice::CanNotUseDatagrams
@ CanNotUseDatagrams
Can not use datagrams.
Definition: tdesocketdevice.h:90
KNetwork::TDESocketDevice::CanNotListen
@ CanNotListen
Can not listen.
Definition: tdesocketdevice.h:79
KNetwork::TDESocketDevice::CanNotBind
@ CanNotBind
Can not bind.
Definition: tdesocketdevice.h:75
KNetwork
A namespace to store all networking-related (socket) classes.
Definition: kbufferedsocket.h:36

tdecore

Skip menu "tdecore"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

tdecore

Skip menu "tdecore"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdecore by doxygen 1.9.4
This website is maintained by Timothy Pearson.