• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdelibs API Reference
  • KDE Home
  • Contact Us
 

KDECore

  • sources
  • kde-4.14
  • kdelibs
  • kdecore
  • network
k3httpproxysocketdevice.cpp
Go to the documentation of this file.
1 /* -*- C++ -*-
2  * Copyright (C) 2003 Thiago Macieira <thiago@kde.org>
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 "k3httpproxysocketdevice.h"
26 
27 #include <config.h>
28 #include <config-network.h>
29 
30 #include <sys/types.h>
31 #include <sys/socket.h>
32 
33 #include <QSocketNotifier>
34 #include <QByteArray>
35 
36 #include "k3resolver.h"
37 #include "k3socketaddress.h"
38 #include "k3socketdevice.h"
39 
40 using namespace KNetwork;
41 
42 KResolverEntry KHttpProxySocketDevice::defaultProxy;
43 
44 class KNetwork::KHttpProxySocketDevicePrivate
45 {
46 public:
47  KResolverEntry proxy;
48  QByteArray request;
49  QByteArray reply;
50  KSocketAddress peer;
51 
52  KHttpProxySocketDevicePrivate()
53  : proxy(KHttpProxySocketDevice::defaultProxy)
54  { }
55 };
56 
57 KHttpProxySocketDevice::KHttpProxySocketDevice(const KSocketBase* parent)
58  : KSocketDevice(parent), d(new KHttpProxySocketDevicePrivate)
59 {
60 }
61 
62 KHttpProxySocketDevice::KHttpProxySocketDevice(const KResolverEntry& proxy)
63  : d(new KHttpProxySocketDevicePrivate)
64 {
65  d->proxy = proxy;
66 }
67 
68 KHttpProxySocketDevice::~KHttpProxySocketDevice()
69 {
70  // nothing special to be done during closing
71  // KSocketDevice::~KSocketDevice closes the socket
72 
73  delete d;
74 }
75 
76 int KHttpProxySocketDevice::capabilities() const
77 {
78  return CanConnectString | CanNotBind | CanNotListen | CanNotUseDatagrams;
79 }
80 
81 const KResolverEntry&
82 KHttpProxySocketDevice::proxyServer() const
83 {
84  return d->proxy;
85 }
86 
87 void KHttpProxySocketDevice::setProxyServer(const KResolverEntry& proxy)
88 {
89  d->proxy = proxy;
90 }
91 
92 void KHttpProxySocketDevice::close()
93 {
94  d->reply = d->request = QByteArray();
95  d->peer = KSocketAddress();
96  KSocketDevice::close();
97 }
98 
99 KSocketAddress KHttpProxySocketDevice::peerAddress() const
100 {
101  if (isOpen())
102  return d->peer;
103  return KSocketAddress();
104 }
105 
106 KSocketAddress KHttpProxySocketDevice::externalAddress() const
107 {
108  return KSocketAddress();
109 }
110 
111 bool KHttpProxySocketDevice::connect(const KResolverEntry& address)
112 {
113  if (d->proxy.family() == AF_UNSPEC)
114  // no proxy server set !
115  return KSocketDevice::connect(address);
116 
117  if (isOpen())
118  {
119  // socket is already open
120  resetError();
121  return true;
122  }
123 
124  if (m_sockfd == -1)
125  // socket isn't created yet
126  return connect(address.address().nodeName(),
127  address.address().serviceName());
128 
129  d->peer = address.address();
130  return parseServerReply();
131 }
132 
133 bool KHttpProxySocketDevice::connect(const QString& node, const QString& service)
134 {
135  // same safety checks as above
136  if (m_sockfd == -1 && (d->proxy.family() == AF_UNSPEC ||
137  node.isEmpty() || service.isEmpty()))
138  {
139  // no proxy server set !
140  setError(NotSupported);
141  return false;
142  }
143 
144  if (isOpen())
145  {
146  // socket is already open
147  return true;
148  }
149 
150  if (m_sockfd == -1)
151  {
152  // must create the socket
153  if (!KSocketDevice::connect(d->proxy))
154  return false; // also unable to contact proxy server
155  KActiveSocketBase::close();
156 
157  // prepare the request
158  QString request = QLatin1String("CONNECT %1:%2 HTTP/1.1\r\n"
159  "Cache-Control: no-cache\r\n"
160  "Host: \r\n"
161  "\r\n");
162  QString node2 = node;
163  if (node.contains(QLatin1Char(':')))
164  node2 = QLatin1Char('[') + node + QLatin1Char(']');
165 
166  d->request = request.arg(node2).arg(service).toLatin1();
167  }
168 
169  return parseServerReply();
170 }
171 
172 bool KHttpProxySocketDevice::parseServerReply()
173 {
174  // make sure we're connected
175  if (!KSocketDevice::connect(d->proxy))
176  if (error() == InProgress)
177  return true;
178  else if (error() != NoError)
179  return false;
180 
181  if (!d->request.isEmpty())
182  {
183  // send request
184  qint64 written = writeData(d->request, d->request.length());
185  if (written < 0)
186  {
187  qDebug("KHttpProxySocketDevice: would block writing request!");
188  if (error() == WouldBlock)
189  setError(InProgress);
190  return error() == WouldBlock; // error
191  }
192  qDebug("KHttpProxySocketDevice: request written");
193 
194  d->request.remove(0, written);
195 
196  if (!d->request.isEmpty())
197  {
198  setError(InProgress);
199  return true; // still in progress
200  }
201  }
202 
203  // request header is sent
204  // must parse reply, but must also be careful not to read too much
205  // from the buffer
206 
207  int index;
208  if (!blocking())
209  {
210  qint64 avail = bytesAvailable();
211  qDebug("KHttpProxySocketDevice: %lld bytes available", avail);
212  KActiveSocketBase::close();
213  if (avail == 0)
214  {
215  setError(InProgress);
216  return true;
217  }
218  else if (avail < 0)
219  return false; // error!
220 
221  QByteArray buf;
222  buf.resize(avail);
223  if (peekData(buf.data(), avail) < 0)
224  return false; // error!
225 
226  QByteArray fullHeaders = d->reply + buf;
227  // search for the end of the headers
228  index = fullHeaders.indexOf("\r\n\r\n");
229  if (index == -1)
230  {
231  // no, headers not yet finished...
232  // consume data from socket
233  readData(buf.data(), avail);
234  d->reply += buf.data();
235  setError(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  readData(buf.data(), index + 4);
245  }
246  else
247  {
248  int state = 0;
249  if (d->reply.endsWith("\r\n\r")) // krazy:exclude=strings
250  state = 3;
251  else if (d->reply.endsWith("\r\n")) // krazy:exclude=strings
252  state = 2;
253  else if (d->reply.endsWith('\r'))// krazy:exclude=strings
254  state = 1;
255  while (state != 4)
256  {
257  char c;
258  getChar(&c);
259  d->reply += c;
260 
261  if ((state == 3 && c == '\n') ||
262  (state == 1 && c == '\n') ||
263  c == '\r')
264  ++state;
265  else
266  state = 0;
267  }
268  }
269 
270  // now really parse the reply
271  qDebug("KHttpProxySocketDevice: get reply: %s\n",
272  d->reply.left(d->reply.indexOf('\r')).data());
273  if (d->reply.left(7) != "HTTP/1." ||
274  (index = d->reply.indexOf(' ')) == -1 ||
275  d->reply[index + 1] != '2')
276  {
277  setError(NetFailure);
278  return false;
279  }
280 
281  // we've got it
282  resetError();
283  KActiveSocketBase::open(ReadOnly);
284  return true;
285 }
k3socketaddress.h
qint64
KNetwork::KSocketBase::blocking
bool blocking() const
Retrieves this socket's blocking mode.
Definition: k3socketbase.cpp:102
KNetwork::KSocketDevice::writeData
virtual qint64 writeData(const char *data, qint64 len, const KSocketAddress *to=0L)
Writes the given data to the given destination address.
Definition: k3socketdevice.cpp:536
k3httpproxysocketdevice.h
k3socketdevice.h
KNetwork::KHttpProxySocketDevice::proxyServer
const KResolverEntry & proxyServer() const
Retrieves the proxy server address.
Definition: k3httpproxysocketdevice.cpp:82
QByteArray
KNetwork::KHttpProxySocketDevice::KHttpProxySocketDevice
KHttpProxySocketDevice(const KSocketBase *=0L)
Constructor.
Definition: k3httpproxysocketdevice.cpp:57
KNetwork::KResolverEntry
One resolution entry.
Definition: k3resolver.h:68
KNetwork::KActiveSocketBase::resetError
void resetError()
Resets the socket error code and the I/O Device's status.
Definition: k3socketbase.cpp:441
KNetwork::KSocketDevice::connect
virtual bool connect(const KResolverEntry &address, OpenMode mode=ReadWrite)
Connect to a remote host.
Definition: k3socketdevice.cpp:345
KNetwork::KSocketBase::InProgress
Definition: k3socketbase.h:157
KNetwork::KSocketBase::error
SocketError error() const
Retrieves the socket error code.
Definition: k3socketbase.cpp:197
KNetwork::KSocketAddress::nodeName
virtual QString nodeName() const
Returns the node name of this socket.
Definition: k3socketaddress.cpp:560
KNetwork::KSocketAddress
A generic socket address.
Definition: k3socketaddress.h:414
KNetwork::KSocketDevice::CanConnectString
Can connect to hostnames.
Definition: k3socketdevice.h:68
KNetwork::KHttpProxySocketDevice::connect
virtual bool connect(const KResolverEntry &address)
Overrides connection.
Definition: k3httpproxysocketdevice.cpp:111
KNetwork::KSocketDevice::CanNotListen
Can not listen.
Definition: k3socketdevice.h:80
QIODevice::close
virtual void close()
QIODevice::getChar
bool getChar(char *c)
KNetwork::KActiveSocketBase::open
virtual bool open(OpenMode mode)
Reimplemented from QIODevice.
Definition: k3socketbase.cpp:339
QByteArray::resize
void resize(int size)
KNetwork::KSocketBase::WouldBlock
Definition: k3socketbase.h:154
QByteArray::indexOf
int indexOf(char ch, int from) const
KNetwork::KHttpProxySocketDevice::defaultProxy
static KResolverEntry defaultProxy
This is the default proxy server to be used.
Definition: k3httpproxysocketdevice.h:118
KNetwork::KHttpProxySocketDevice::peerAddress
virtual KSocketAddress peerAddress() const
Return the peer address.
Definition: k3httpproxysocketdevice.cpp:99
KNetwork::KHttpProxySocketDevice
The low-level backend for HTTP proxying.
Definition: k3httpproxysocketdevice.h:44
KNetwork::KSocketBase::NoError
Definition: k3socketbase.h:145
QString::isEmpty
bool isEmpty() const
KNetwork::KSocketDevice::readData
virtual qint64 readData(char *data, qint64 maxlen, KSocketAddress *from=0L)
Reads data and the source address from this socket.
Definition: k3socketdevice.cpp:494
KNetwork::KSocketDevice::peekData
virtual qint64 peekData(char *data, qint64 maxlen, KSocketAddress *from=0L)
Peeks the data in the socket and the source address.
Definition: k3socketdevice.cpp:515
QIODevice::isOpen
bool isOpen() const
QString
QByteArray::mid
QByteArray mid(int pos, int len) const
KNetwork::KActiveSocketBase::setError
void setError(SocketError error)
Sets the socket's error code.
Definition: k3socketbase.cpp:435
KNetwork::KSocketAddress::serviceName
virtual QString serviceName() const
Returns the service name for this socket.
Definition: k3socketaddress.cpp:586
KNetwork::KSocketBase::NotSupported
Definition: k3socketbase.h:159
k3resolver.h
KNetwork::KResolverEntry::address
KSocketAddress address() const
Retrieves the socket address associated with this entry.
Definition: k3resolver.cpp:135
QString::contains
bool contains(QChar ch, Qt::CaseSensitivity cs) const
KNetwork::KSocketDevice::CanNotUseDatagrams
Can not use datagrams.
Definition: k3socketdevice.h:91
QLatin1Char
KNetwork::KHttpProxySocketDevice::setProxyServer
void setProxyServer(const KResolverEntry &proxy)
Sets the proxy server address.
Definition: k3httpproxysocketdevice.cpp:87
KNetwork::KHttpProxySocketDevice::capabilities
virtual int capabilities() const
Sets our capabilities.
Definition: k3httpproxysocketdevice.cpp:76
KNetwork::KHttpProxySocketDevice::close
virtual void close()
Closes the socket.
Definition: k3httpproxysocketdevice.cpp:92
KNetwork::KSocketDevice::m_sockfd
int m_sockfd
The socket file descriptor.
Definition: k3socketdevice.h:96
QString::toLatin1
QByteArray toLatin1() const
KNetwork::KSocketDevice::close
virtual void close()
Closes the socket.
Definition: k3socketdevice.cpp:232
QLatin1String
QByteArray::data
char * data()
KNetwork::KHttpProxySocketDevice::externalAddress
virtual KSocketAddress externalAddress() const
Return the externally visible address.
Definition: k3httpproxysocketdevice.cpp:106
KNetwork::KSocketDevice
Low-level socket functionality.
Definition: k3socketdevice.h:51
KNetwork::KHttpProxySocketDevice::~KHttpProxySocketDevice
virtual ~KHttpProxySocketDevice()
Destructor.
Definition: k3httpproxysocketdevice.cpp:68
KNetwork::KSocketBase::NetFailure
Definition: k3socketbase.h:158
KNetwork::KSocketBase
Basic socket functionality.
Definition: k3socketbase.h:85
QIODevice::state
int state() const
QString::arg
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
KNetwork::KSocketDevice::bytesAvailable
virtual qint64 bytesAvailable() const
Returns the number of bytes available for reading without blocking.
Definition: k3socketdevice.cpp:439
KNetwork::KSocketDevice::CanNotBind
Can not bind.
Definition: k3socketdevice.h:76
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:22:10 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KDECore

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

kdelibs API Reference

Skip menu "kdelibs API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal