• 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 
38 using namespace KNetwork;
39 
40 KResolverEntry KHttpProxySocketDevice::defaultProxy;
41 
42 class KNetwork::KHttpProxySocketDevicePrivate
43 {
44 public:
45  KResolverEntry proxy;
46  TQCString request;
47  TQCString reply;
48  TDESocketAddress peer;
49 
50  KHttpProxySocketDevicePrivate()
51  : proxy(KHttpProxySocketDevice::defaultProxy)
52  { }
53 };
54 
55 KHttpProxySocketDevice::KHttpProxySocketDevice(const TDESocketBase* parent)
56  : TDESocketDevice(parent), d(new KHttpProxySocketDevicePrivate)
57 {
58 }
59 
60 KHttpProxySocketDevice::KHttpProxySocketDevice(const KResolverEntry& proxy)
61  : d(new KHttpProxySocketDevicePrivate)
62 {
63  d->proxy = proxy;
64 }
65 
66 KHttpProxySocketDevice::~KHttpProxySocketDevice()
67 {
68  // nothing special to be done during closing
69  // TDESocketDevice::~TDESocketDevice closes the socket
70 
71  delete d;
72 }
73 
74 int KHttpProxySocketDevice::capabilities() const
75 {
76  return CanConnectString | CanNotBind | CanNotListen | CanNotUseDatagrams;
77 }
78 
79 const KResolverEntry&
80 KHttpProxySocketDevice::proxyServer() const
81 {
82  return d->proxy;
83 }
84 
85 void KHttpProxySocketDevice::setProxyServer(const KResolverEntry& proxy)
86 {
87  d->proxy = proxy;
88 }
89 
90 void KHttpProxySocketDevice::close()
91 {
92  d->reply = d->request = TQCString();
93  d->peer = TDESocketAddress();
94  TDESocketDevice::close();
95 }
96 
97 TDESocketAddress KHttpProxySocketDevice::peerAddress() const
98 {
99  if (isOpen())
100  return d->peer;
101  return TDESocketAddress();
102 }
103 
104 TDESocketAddress KHttpProxySocketDevice::externalAddress() const
105 {
106  return TDESocketAddress();
107 }
108 
109 bool 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 
131 bool 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 
170 bool 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 = tqwriteBlock(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  tqreadBlock(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  tqreadBlock(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::TDESocketAddress::serviceName
virtual TQString serviceName() const
Returns the service name for this socket.
Definition: tdesocketaddress.cpp:603
KNetwork::TDESocketAddress
A generic socket address.
Definition: tdesocketaddress.h:423
KNetwork::KHttpProxySocketDevice::proxyServer
const KResolverEntry & proxyServer() const
Retrieves the proxy server address.
Definition: khttpproxysocketdevice.cpp:80
KNetwork::TDESocketBase::blocking
bool blocking() const
Retrieves this socket's blocking mode.
Definition: tdesocketbase.cpp:81
KNetwork::TDESocketDevice::CanNotListen
Can not listen.
Definition: tdesocketdevice.h:79
KNetwork::KActiveSocketBase::getch
virtual int getch()
Reads one character from the socket.
Definition: tdesocketbase.cpp:291
KNetwork::KResolverEntry
One resolution entry.
Definition: kresolver.h:66
KNetwork::KActiveSocketBase::resetError
void resetError()
Resets the socket error code and the I/O Device's status.
Definition: tdesocketbase.cpp:315
KNetwork::TDESocketDevice
Low-level socket functionality.
Definition: tdesocketdevice.h:50
KNetwork::TDESocketBase::error
SocketError error() const
Retrieves the socket error code.
Definition: tdesocketbase.cpp:160
KNetwork::KHttpProxySocketDevice::connect
virtual bool connect(const KResolverEntry &address)
Overrides connection.
Definition: khttpproxysocketdevice.cpp:109
KNetwork::TDESocketDevice::tqwriteBlock
virtual TQT_TQIO_LONG tqwriteBlock(const char *data, TQT_TQIO_ULONG len)
Writes data to the socket.
Definition: tdesocketdevice.cpp:506
KNetwork::KResolverEntry::address
TDESocketAddress address() const
Retrieves the socket address associated with this entry.
Definition: kresolver.cpp:142
KNetwork::TDESocketDevice::CanNotBind
Can not bind.
Definition: tdesocketdevice.h:75
KNetwork
A namespace to store all networking-related (socket) classes.
Definition: kbufferedsocket.h:36
KNetwork::KHttpProxySocketDevice::peerAddress
virtual TDESocketAddress peerAddress() const
Return the peer address.
Definition: khttpproxysocketdevice.cpp:97
KNetwork::KHttpProxySocketDevice::defaultProxy
static KResolverEntry defaultProxy
This is the default proxy server to be used.
Definition: khttpproxysocketdevice.h:117
KNetwork::KHttpProxySocketDevice::KHttpProxySocketDevice
KHttpProxySocketDevice(const TDESocketBase *=0L)
Constructor.
Definition: khttpproxysocketdevice.cpp:55
KNetwork::KHttpProxySocketDevice
The low-level backend for HTTP proxying.
Definition: khttpproxysocketdevice.h:43
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::KHttpProxySocketDevice::externalAddress
virtual TDESocketAddress externalAddress() const
Return the externally visible address.
Definition: khttpproxysocketdevice.cpp:104
KNetwork::TDESocketDevice::m_sockfd
int m_sockfd
The socket file descriptor.
Definition: tdesocketdevice.h:95
KNetwork::KHttpProxySocketDevice::setProxyServer
void setProxyServer(const KResolverEntry &proxy)
Sets the proxy server address.
Definition: khttpproxysocketdevice.cpp:85
KNetwork::TDESocketDevice::connect
virtual bool connect(const KResolverEntry &address)
Connect to a remote host.
Definition: tdesocketdevice.cpp:276
KNetwork::TDESocketDevice::tqreadBlock
virtual TQT_TQIO_LONG tqreadBlock(char *data, TQT_TQIO_ULONG maxlen)
Reads data from this socket.
Definition: tdesocketdevice.cpp:422
KNetwork::KHttpProxySocketDevice::capabilities
virtual int capabilities() const
Sets our capabilities.
Definition: khttpproxysocketdevice.cpp:74
KNetwork::KHttpProxySocketDevice::close
virtual void close()
Closes the socket.
Definition: khttpproxysocketdevice.cpp:90
KNetwork::TDESocketDevice::CanConnectString
Can connect to hostnames.
Definition: tdesocketdevice.h:67
KNetwork::TDESocketDevice::CanNotUseDatagrams
Can not use datagrams.
Definition: tdesocketdevice.h:90
KNetwork::TDESocketBase
Basic socket functionality.
Definition: tdesocketbase.h:97
KNetwork::TDESocketAddress::nodeName
virtual TQString nodeName() const
Returns the node name of this socket.
Definition: tdesocketaddress.cpp:576
KNetwork::KHttpProxySocketDevice::~KHttpProxySocketDevice
virtual ~KHttpProxySocketDevice()
Destructor.
Definition: khttpproxysocketdevice.cpp:66
KNetwork::TDESocketDevice::peekBlock
virtual TQ_LONG peekBlock(char *data, TQ_ULONG maxlen)
Peeks data in the socket.
Definition: tdesocketdevice.cpp:464
KNetwork::TDESocketDevice::close
virtual void close()
Closes the socket.
Definition: tdesocketdevice.cpp:180

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
  •     tdecore
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  • tdeioslave
  •   http
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdecore by doxygen 1.8.8
This website is maintained by Timothy Pearson.