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

kdecore

  • kdecore
  • network
khttpproxysocketdevice.cpp
1 /* -*- C++ -*-
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 "ksocketaddress.h"
35 #include "ksocketdevice.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  KSocketAddress peer;
49 
50  KHttpProxySocketDevicePrivate()
51  : proxy(KHttpProxySocketDevice::defaultProxy)
52  { }
53 };
54 
55 KHttpProxySocketDevice::KHttpProxySocketDevice(const KSocketBase* parent)
56  : KSocketDevice(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  // KSocketDevice::~KSocketDevice 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 = KSocketAddress();
94  KSocketDevice::close();
95 }
96 
97 KSocketAddress KHttpProxySocketDevice::peerAddress() const
98 {
99  if (isOpen())
100  return d->peer;
101  return KSocketAddress();
102 }
103 
104 KSocketAddress KHttpProxySocketDevice::externalAddress() const
105 {
106  return KSocketAddress();
107 }
108 
109 bool KHttpProxySocketDevice::connect(const KResolverEntry& address)
110 {
111  if (d->proxy.family() == AF_UNSPEC)
112  // no proxy server set !
113  return KSocketDevice::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 (!KSocketDevice::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 (!KSocketDevice::connect(d->proxy))
174  if (error() == InProgress)
175  return true;
176  else if (error() != NoError)
177  return false;
178 
179  if (!d->request.isEmpty())
180  {
181  // send request
182  TQ_LONG written = tqwriteBlock(d->request, d->request.length());
183  if (written < 0)
184  {
185  qDebug("KHttpProxySocketDevice: would block writing request!");
186  if (error() == WouldBlock)
187  setError(IO_ConnectError, InProgress);
188  return error() == WouldBlock; // error
189  }
190  qDebug("KHttpProxySocketDevice: request written");
191 
192  d->request.remove(0, written);
193 
194  if (!d->request.isEmpty())
195  {
196  setError(IO_ConnectError, InProgress);
197  return true; // still in progress
198  }
199  }
200 
201  // request header is sent
202  // must parse reply, but must also be careful not to read too much
203  // from the buffer
204 
205  int index;
206  if (!blocking())
207  {
208  TQ_LONG avail = bytesAvailable();
209  qDebug("KHttpProxySocketDevice: %ld bytes available", avail);
210  setState(0);
211  if (avail == 0)
212  {
213  setError(IO_ConnectError, InProgress);
214  return true;
215  }
216  else if (avail < 0)
217  return false; // error!
218 
219  TQByteArray buf(avail);
220  if (peekBlock(buf.data(), avail) < 0)
221  return false; // error!
222 
223  TQCString fullHeaders = d->reply + buf.data();
224  // search for the end of the headers
225  index = fullHeaders.find("\r\n\r\n");
226  if (index == -1)
227  {
228  // no, headers not yet finished...
229  // consume data from socket
230  tqreadBlock(buf.data(), avail);
231  d->reply += buf.data();
232  setError(IO_ConnectError, InProgress);
233  return true;
234  }
235 
236  // headers are finished
237  index -= d->reply.length();
238  d->reply += fullHeaders.mid(d->reply.length(), index + 4);
239 
240  // consume from socket
241  tqreadBlock(buf.data(), index + 4);
242  }
243  else
244  {
245  int state = 0;
246  if (d->reply.right(3) == "\r\n\r")
247  state = 3;
248  else if (d->reply.right(2) == "\r\n")
249  state = 2;
250  else if (d->reply.right(1) == "\r")
251  state = 1;
252  while (state != 4)
253  {
254  char c = getch();
255  d->reply += c;
256 
257  if ((state == 3 && c == '\n') ||
258  (state == 1 && c == '\n') ||
259  c == '\r')
260  ++state;
261  else
262  state = 0;
263  }
264  }
265 
266  // now really parse the reply
267  qDebug("KHttpProxySocketDevice: get reply: %s\n",
268  d->reply.left(d->reply.find('\r')).data());
269  if (d->reply.left(7) != "HTTP/1." ||
270  (index = d->reply.find(' ')) == -1 ||
271  d->reply[index + 1] != '2')
272  {
273  setError(IO_ConnectError, NetFailure);
274  return false;
275  }
276 
277  // we've got it
278  resetError();
279  setState(IO_Open);
280  return true;
281 }

kdecore

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

kdecore

Skip menu "kdecore"
  • arts
  • dcop
  • dnssd
  • interfaces
  •     interface
  •     library
  •   kspeech
  •   ktexteditor
  • kabc
  • kate
  • kcmshell
  • kdecore
  • kded
  • kdefx
  • kdeprint
  • kdesu
  • kdeui
  • kdoctools
  • khtml
  • kimgio
  • kinit
  • kio
  •   bookmarks
  •   httpfilter
  •   kfile
  •   kio
  •   kioexec
  •   kpasswdserver
  •   kssl
  • kioslave
  •   http
  • kjs
  • kmdi
  •   kmdi
  • knewstuff
  • kparts
  • krandr
  • kresources
  • kspell2
  • kunittest
  • kutils
  • kwallet
  • libkmid
  • libkscreensaver
Generated for kdecore by doxygen 1.8.3.1
This website is maintained by Timothy Pearson.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. |