initial commit
This commit is contained in:
commit
9d20827c46
2469 changed files with 470994 additions and 0 deletions
32
iris-legacy/cutestuff/cutestuff.pri
Normal file
32
iris-legacy/cutestuff/cutestuff.pri
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
INCLUDEPATH += $$PWD/util $$PWD/network
|
||||
DEPENDPATH += $$PWD/util $$PWD/network
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/util/bytestream.h \
|
||||
$$PWD/network/bsocket.h \
|
||||
$$PWD/network/httpconnect.h \
|
||||
$$PWD/network/httppoll.h \
|
||||
$$PWD/network/socks.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/util/bytestream.cpp \
|
||||
$$PWD/network/bsocket.cpp \
|
||||
$$PWD/network/httpconnect.cpp \
|
||||
$$PWD/network/httppoll.cpp \
|
||||
$$PWD/network/socks.cpp
|
||||
|
||||
!irisnet {
|
||||
INCLUDEPATH += $$PWD/legacy
|
||||
HEADERS += \
|
||||
$$PWD/legacy/safedelete.h \
|
||||
$$PWD/legacy/ndns.h \
|
||||
$$PWD/legacy/srvresolver.h \
|
||||
$$PWD/legacy/servsock.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/legacy/safedelete.cpp \
|
||||
$$PWD/legacy/ndns.cpp \
|
||||
$$PWD/legacy/srvresolver.cpp \
|
||||
$$PWD/legacy/servsock.cpp
|
||||
}
|
||||
|
||||
393
iris-legacy/cutestuff/legacy/ndns.cpp
Normal file
393
iris-legacy/cutestuff/legacy/ndns.cpp
Normal file
|
|
@ -0,0 +1,393 @@
|
|||
/*
|
||||
* ndns.cpp - native DNS resolution
|
||||
* Copyright (C) 2001, 2002 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
//! \class NDns ndns.h
|
||||
//! \brief Simple DNS resolution using native system calls
|
||||
//!
|
||||
//! This class is to be used when Qt's QDns is not good enough. Because QDns
|
||||
//! does not use threads, it cannot make a system call asyncronously. Thus,
|
||||
//! QDns tries to imitate the behavior of each platform's native behavior, and
|
||||
//! generally falls short.
|
||||
//!
|
||||
//! NDns uses a thread to make the system call happen in the background. This
|
||||
//! gives your program native DNS behavior, at the cost of requiring threads
|
||||
//! to build.
|
||||
//!
|
||||
//! \code
|
||||
//! #include "ndns.h"
|
||||
//!
|
||||
//! ...
|
||||
//!
|
||||
//! NDns dns;
|
||||
//! dns.resolve("psi.affinix.com");
|
||||
//!
|
||||
//! // The class will emit the resultsReady() signal when the resolution
|
||||
//! // is finished. You may then retrieve the results:
|
||||
//!
|
||||
//! QHostAddress ip_address = dns.result();
|
||||
//!
|
||||
//! // or if you want to get the IP address as a string:
|
||||
//!
|
||||
//! QString ip_address = dns.resultString();
|
||||
//! \endcode
|
||||
|
||||
#include "ndns.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <q3socketdevice.h>
|
||||
#include <q3ptrlist.h>
|
||||
#include <qeventloop.h>
|
||||
//Added by qt3to4:
|
||||
#include <QCustomEvent>
|
||||
#include <QEvent>
|
||||
#include <Q3CString>
|
||||
#include <QPointer>
|
||||
|
||||
#ifdef Q_OS_UNIX
|
||||
#include <netdb.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "psilogger.h"
|
||||
|
||||
// CS_NAMESPACE_BEGIN
|
||||
|
||||
//! \if _hide_doc_
|
||||
class NDnsWorker : public QThread
|
||||
{
|
||||
public:
|
||||
NDnsWorker(QObject *, const Q3CString &);
|
||||
~NDnsWorker();
|
||||
|
||||
bool success;
|
||||
bool cancelled;
|
||||
QHostAddress addr;
|
||||
|
||||
protected:
|
||||
void run();
|
||||
|
||||
private:
|
||||
Q3CString host;
|
||||
};
|
||||
//! \endif
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// NDnsManager
|
||||
//----------------------------------------------------------------------------
|
||||
#ifndef HAVE_GETHOSTBYNAME_R
|
||||
#ifndef Q_WS_WIN
|
||||
static QMutex *workerMutex = 0;
|
||||
static QMutex *workerCancelled = 0;
|
||||
#endif
|
||||
#endif
|
||||
static NDnsManager *manager_instance = 0;
|
||||
bool winsock_init = false;
|
||||
|
||||
class NDnsManager::Item
|
||||
{
|
||||
public:
|
||||
NDns *ndns;
|
||||
NDnsWorker *worker;
|
||||
};
|
||||
|
||||
class NDnsManager::Private
|
||||
{
|
||||
public:
|
||||
Item *find(const NDns *n)
|
||||
{
|
||||
Q3PtrListIterator<Item> it(list);
|
||||
for(Item *i; (i = it.current()); ++it) {
|
||||
if(i->ndns == n)
|
||||
return i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Item *find(const NDnsWorker *w)
|
||||
{
|
||||
Q3PtrListIterator<Item> it(list);
|
||||
for(Item *i; (i = it.current()); ++it) {
|
||||
if(i->worker == w)
|
||||
return i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Q3PtrList<Item> list;
|
||||
};
|
||||
|
||||
NDnsManager::NDnsManager()
|
||||
: QObject(QCoreApplication::instance())
|
||||
{
|
||||
#ifndef HAVE_GETHOSTBYNAME_R
|
||||
#ifndef Q_WS_WIN
|
||||
workerMutex = new QMutex;
|
||||
workerCancelled = new QMutex;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_WIN32
|
||||
if(!winsock_init) {
|
||||
winsock_init = true;
|
||||
Q3SocketDevice *sd = new Q3SocketDevice;
|
||||
delete sd;
|
||||
}
|
||||
#endif
|
||||
|
||||
d = new Private;
|
||||
d->list.setAutoDelete(true);
|
||||
|
||||
connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), SLOT(app_aboutToQuit()));
|
||||
}
|
||||
|
||||
NDnsManager::~NDnsManager()
|
||||
{
|
||||
delete d;
|
||||
|
||||
#ifndef HAVE_GETHOSTBYNAME_R
|
||||
#ifndef Q_WS_WIN
|
||||
delete workerMutex;
|
||||
workerMutex = 0;
|
||||
delete workerCancelled;
|
||||
workerCancelled = 0;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void NDnsManager::resolve(NDns *self, const QString &name)
|
||||
{
|
||||
Item *i = new Item;
|
||||
i->ndns = self;
|
||||
i->worker = new NDnsWorker(this, name.utf8());
|
||||
connect(i->worker, SIGNAL(finished()), SLOT(workerFinished()));
|
||||
d->list.append(i);
|
||||
|
||||
i->worker->start();
|
||||
}
|
||||
|
||||
void NDnsManager::stop(NDns *self)
|
||||
{
|
||||
Item *i = d->find(self);
|
||||
if(!i)
|
||||
return;
|
||||
// disassociate
|
||||
i->ndns = 0;
|
||||
|
||||
#ifndef HAVE_GETHOSTBYNAME_R
|
||||
#ifndef Q_WS_WIN
|
||||
// cancel
|
||||
workerCancelled->lock();
|
||||
i->worker->cancelled = true;
|
||||
workerCancelled->unlock();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
d->list.removeRef(i);
|
||||
}
|
||||
|
||||
bool NDnsManager::isBusy(const NDns *self) const
|
||||
{
|
||||
Item *i = d->find(self);
|
||||
return (i ? true: false);
|
||||
}
|
||||
|
||||
void NDnsManager::workerFinished()
|
||||
{
|
||||
NDnsWorker* worker = dynamic_cast<NDnsWorker*>(sender());
|
||||
Q_ASSERT(worker);
|
||||
if (!worker)
|
||||
return;
|
||||
worker->wait(); // ensure that the thread is terminated
|
||||
|
||||
Item *i = d->find(worker);
|
||||
if(i) {
|
||||
QHostAddress addr = i->worker->addr;
|
||||
QPointer<NDns> ndns = i->ndns;
|
||||
d->list.removeRef(i);
|
||||
|
||||
// nuke manager if no longer needed (code that follows MUST BE SAFE!)
|
||||
tryDestroy();
|
||||
|
||||
// requestor still around?
|
||||
if(ndns) {
|
||||
ndns->finished(addr);
|
||||
}
|
||||
}
|
||||
|
||||
worker->deleteLater();
|
||||
}
|
||||
|
||||
void NDnsManager::tryDestroy()
|
||||
{
|
||||
// mblsha: NDnsManager is now singleton
|
||||
#if 0
|
||||
if(d->list.isEmpty()) {
|
||||
manager_instance = 0;
|
||||
deleteLater();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void NDnsManager::app_aboutToQuit()
|
||||
{
|
||||
// mblsha: NDnsManager is now singleton
|
||||
#if 0
|
||||
while(man) {
|
||||
QCoreApplication::instance()->processEvents(QEventLoop::WaitForMoreEvents);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// NDns
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//! \fn void NDns::resultsReady()
|
||||
//! This signal is emitted when the DNS resolution succeeds or fails.
|
||||
|
||||
//!
|
||||
//! Constructs an NDns object with parent \a parent.
|
||||
NDns::NDns(QObject *parent)
|
||||
:QObject(parent)
|
||||
{
|
||||
}
|
||||
|
||||
//!
|
||||
//! Destroys the object and frees allocated resources.
|
||||
NDns::~NDns()
|
||||
{
|
||||
stop();
|
||||
PsiLogger::instance()->log(QString("%1 NDns::~NDns()").arg(LOG_THIS));
|
||||
}
|
||||
|
||||
//!
|
||||
//! Resolves hostname \a host (eg. psi.affinix.com)
|
||||
void NDns::resolve(const QString &host)
|
||||
{
|
||||
PsiLogger::instance()->log(QString("%1 NDns::resolve(%2)").arg(LOG_THIS).arg(host));
|
||||
stop();
|
||||
if(!manager_instance)
|
||||
manager_instance = new NDnsManager;
|
||||
manager_instance->resolve(this, host);
|
||||
}
|
||||
|
||||
//!
|
||||
//! Cancels the lookup action.
|
||||
//! \note This will not stop the underlying system call, which must finish before the next lookup will proceed.
|
||||
void NDns::stop()
|
||||
{
|
||||
PsiLogger::instance()->log(QString("%1 NDns::stop()").arg(LOG_THIS));
|
||||
if(manager_instance)
|
||||
manager_instance->stop(this);
|
||||
}
|
||||
|
||||
//!
|
||||
//! Returns the IP address as QHostAddress. This will be a Null QHostAddress if the lookup failed.
|
||||
//! \sa resultsReady()
|
||||
QHostAddress NDns::result() const
|
||||
{
|
||||
return addr;
|
||||
}
|
||||
|
||||
//!
|
||||
//! Returns the IP address as a string. This will be an empty string if the lookup failed.
|
||||
//! \sa resultsReady()
|
||||
QString NDns::resultString() const
|
||||
{
|
||||
if (addr.isNull())
|
||||
return QString();
|
||||
else
|
||||
return addr.toString();
|
||||
}
|
||||
|
||||
//!
|
||||
//! Returns TRUE if busy resolving a hostname.
|
||||
bool NDns::isBusy() const
|
||||
{
|
||||
if(!manager_instance)
|
||||
return false;
|
||||
return manager_instance->isBusy(this);
|
||||
}
|
||||
|
||||
void NDns::finished(const QHostAddress &a)
|
||||
{
|
||||
PsiLogger::instance()->log(QString("%1 NDns::finished(%2)").arg(LOG_THIS).arg(a.toString()));
|
||||
addr = a;
|
||||
resultsReady();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// NDnsWorker
|
||||
//----------------------------------------------------------------------------
|
||||
NDnsWorker::NDnsWorker(QObject *_par, const Q3CString &_host)
|
||||
: QThread(_par)
|
||||
{
|
||||
success = cancelled = false;
|
||||
host = _host.copy(); // do we need this to avoid sharing across threads?
|
||||
}
|
||||
|
||||
NDnsWorker::~NDnsWorker()
|
||||
{
|
||||
}
|
||||
|
||||
void NDnsWorker::run()
|
||||
{
|
||||
hostent *h = 0;
|
||||
|
||||
#ifdef HAVE_GETHOSTBYNAME_R
|
||||
hostent buf;
|
||||
char char_buf[1024];
|
||||
int err;
|
||||
gethostbyname_r(host.data(), &buf, char_buf, sizeof(char_buf), &h, &err);
|
||||
#else
|
||||
#ifndef Q_WS_WIN
|
||||
// lock for gethostbyname
|
||||
QMutexLocker locker(workerMutex);
|
||||
|
||||
// check for cancel
|
||||
workerCancelled->lock();
|
||||
bool cancel = cancelled;
|
||||
workerCancelled->unlock();
|
||||
|
||||
if(!cancel)
|
||||
#endif
|
||||
h = gethostbyname(host.data());
|
||||
#endif
|
||||
|
||||
// FIXME: not ipv6 clean, currently.
|
||||
if(!h || h->h_addrtype != AF_INET) {
|
||||
success = false;
|
||||
return;
|
||||
}
|
||||
|
||||
in_addr a = *((struct in_addr *)h->h_addr_list[0]);
|
||||
addr.setAddress(ntohl(a.s_addr));
|
||||
success = true;
|
||||
}
|
||||
|
||||
// CS_NAMESPACE_END
|
||||
90
iris-legacy/cutestuff/legacy/ndns.h
Normal file
90
iris-legacy/cutestuff/legacy/ndns.h
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* ndns.h - native DNS resolution
|
||||
* Copyright (C) 2001, 2002 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CS_NDNS_H
|
||||
#define CS_NDNS_H
|
||||
|
||||
#include <qobject.h>
|
||||
#include <q3cstring.h>
|
||||
#include <qthread.h>
|
||||
#include <qmutex.h>
|
||||
#include <qhostaddress.h>
|
||||
//Added by qt3to4:
|
||||
#include <QEvent>
|
||||
|
||||
// CS_NAMESPACE_BEGIN
|
||||
|
||||
class NDnsWorker;
|
||||
class NDnsManager;
|
||||
|
||||
class NDns : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
NDns(QObject *parent=0);
|
||||
~NDns();
|
||||
|
||||
void resolve(const QString &);
|
||||
void stop();
|
||||
bool isBusy() const;
|
||||
|
||||
QHostAddress result() const;
|
||||
QString resultString() const;
|
||||
|
||||
signals:
|
||||
void resultsReady();
|
||||
|
||||
private:
|
||||
QHostAddress addr;
|
||||
|
||||
friend class NDnsManager;
|
||||
void finished(const QHostAddress &);
|
||||
};
|
||||
|
||||
class NDnsManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
~NDnsManager();
|
||||
class Item;
|
||||
|
||||
//! \if _hide_doc_
|
||||
protected slots:
|
||||
void workerFinished();
|
||||
//! \endif
|
||||
|
||||
private slots:
|
||||
void app_aboutToQuit();
|
||||
|
||||
private:
|
||||
class Private;
|
||||
Private *d;
|
||||
|
||||
friend class NDns;
|
||||
NDnsManager();
|
||||
void resolve(NDns *self, const QString &name);
|
||||
void stop(NDns *self);
|
||||
bool isBusy(const NDns *self) const;
|
||||
void tryDestroy();
|
||||
};
|
||||
|
||||
// CS_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
111
iris-legacy/cutestuff/legacy/safedelete.cpp
Normal file
111
iris-legacy/cutestuff/legacy/safedelete.cpp
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
#include "safedelete.h"
|
||||
|
||||
#include <qtimer.h>
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// SafeDelete
|
||||
//----------------------------------------------------------------------------
|
||||
SafeDelete::SafeDelete()
|
||||
{
|
||||
lock = 0;
|
||||
}
|
||||
|
||||
SafeDelete::~SafeDelete()
|
||||
{
|
||||
if(lock)
|
||||
lock->dying();
|
||||
}
|
||||
|
||||
void SafeDelete::deleteLater(QObject *o)
|
||||
{
|
||||
if(!lock)
|
||||
deleteSingle(o);
|
||||
else
|
||||
list.append(o);
|
||||
}
|
||||
|
||||
void SafeDelete::unlock()
|
||||
{
|
||||
lock = 0;
|
||||
deleteAll();
|
||||
}
|
||||
|
||||
void SafeDelete::deleteAll()
|
||||
{
|
||||
if(list.isEmpty())
|
||||
return;
|
||||
|
||||
QObjectList::Iterator it = list.begin();
|
||||
for(QObjectList::Iterator it = list.begin(); it != list.end(); ++it)
|
||||
deleteSingle(*it);
|
||||
list.clear();
|
||||
}
|
||||
|
||||
void SafeDelete::deleteSingle(QObject *o)
|
||||
{
|
||||
o->deleteLater();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// SafeDeleteLock
|
||||
//----------------------------------------------------------------------------
|
||||
SafeDeleteLock::SafeDeleteLock(SafeDelete *sd)
|
||||
{
|
||||
own = false;
|
||||
if(!sd->lock) {
|
||||
_sd = sd;
|
||||
_sd->lock = this;
|
||||
}
|
||||
else
|
||||
_sd = 0;
|
||||
}
|
||||
|
||||
SafeDeleteLock::~SafeDeleteLock()
|
||||
{
|
||||
if(_sd) {
|
||||
_sd->unlock();
|
||||
if(own)
|
||||
delete _sd;
|
||||
}
|
||||
}
|
||||
|
||||
void SafeDeleteLock::dying()
|
||||
{
|
||||
_sd = new SafeDelete(*_sd);
|
||||
own = true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// SafeDeleteLater
|
||||
//----------------------------------------------------------------------------
|
||||
SafeDeleteLater *SafeDeleteLater::self = 0;
|
||||
|
||||
SafeDeleteLater *SafeDeleteLater::ensureExists()
|
||||
{
|
||||
if(!self)
|
||||
new SafeDeleteLater();
|
||||
return self;
|
||||
}
|
||||
|
||||
SafeDeleteLater::SafeDeleteLater()
|
||||
{
|
||||
self = this;
|
||||
QTimer::singleShot(0, this, SLOT(explode()));
|
||||
}
|
||||
|
||||
SafeDeleteLater::~SafeDeleteLater()
|
||||
{
|
||||
while (!list.isEmpty())
|
||||
delete list.takeFirst();
|
||||
self = 0;
|
||||
}
|
||||
|
||||
void SafeDeleteLater::deleteItLater(QObject *o)
|
||||
{
|
||||
list.append(o);
|
||||
}
|
||||
|
||||
void SafeDeleteLater::explode()
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
60
iris-legacy/cutestuff/legacy/safedelete.h
Normal file
60
iris-legacy/cutestuff/legacy/safedelete.h
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
#ifndef SAFEDELETE_H
|
||||
#define SAFEDELETE_H
|
||||
|
||||
#include <qobject.h>
|
||||
#include <qobject.h>
|
||||
|
||||
class SafeDelete;
|
||||
class SafeDeleteLock
|
||||
{
|
||||
public:
|
||||
SafeDeleteLock(SafeDelete *sd);
|
||||
~SafeDeleteLock();
|
||||
|
||||
private:
|
||||
SafeDelete *_sd;
|
||||
bool own;
|
||||
friend class SafeDelete;
|
||||
void dying();
|
||||
};
|
||||
|
||||
class SafeDelete
|
||||
{
|
||||
public:
|
||||
SafeDelete();
|
||||
~SafeDelete();
|
||||
|
||||
void deleteLater(QObject *o);
|
||||
|
||||
// same as QObject::deleteLater()
|
||||
static void deleteSingle(QObject *o);
|
||||
|
||||
private:
|
||||
QObjectList list;
|
||||
void deleteAll();
|
||||
|
||||
friend class SafeDeleteLock;
|
||||
SafeDeleteLock *lock;
|
||||
void unlock();
|
||||
};
|
||||
|
||||
class SafeDeleteLater : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
static SafeDeleteLater *ensureExists();
|
||||
void deleteItLater(QObject *o);
|
||||
|
||||
private slots:
|
||||
void explode();
|
||||
|
||||
private:
|
||||
SafeDeleteLater();
|
||||
~SafeDeleteLater();
|
||||
|
||||
QObjectList list;
|
||||
friend class SafeDelete;
|
||||
static SafeDeleteLater *self;
|
||||
};
|
||||
|
||||
#endif
|
||||
111
iris-legacy/cutestuff/legacy/servsock.cpp
Normal file
111
iris-legacy/cutestuff/legacy/servsock.cpp
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* servsock.cpp - simple wrapper to QServerSocket
|
||||
* Copyright (C) 2003 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "servsock.h"
|
||||
|
||||
// CS_NAMESPACE_BEGIN
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// ServSock
|
||||
//----------------------------------------------------------------------------
|
||||
class ServSock::Private
|
||||
{
|
||||
public:
|
||||
Private() {}
|
||||
|
||||
ServSockSignal *serv;
|
||||
};
|
||||
|
||||
ServSock::ServSock(QObject *parent)
|
||||
:QObject(parent)
|
||||
{
|
||||
d = new Private;
|
||||
d->serv = 0;
|
||||
}
|
||||
|
||||
ServSock::~ServSock()
|
||||
{
|
||||
stop();
|
||||
delete d;
|
||||
}
|
||||
|
||||
bool ServSock::isActive() const
|
||||
{
|
||||
return (d->serv ? true: false);
|
||||
}
|
||||
|
||||
bool ServSock::listen(quint16 port)
|
||||
{
|
||||
stop();
|
||||
|
||||
d->serv = new ServSockSignal(this);
|
||||
if(!d->serv->listen(QHostAddress::Any, port)) {
|
||||
delete d->serv;
|
||||
d->serv = 0;
|
||||
return false;
|
||||
}
|
||||
connect(d->serv, SIGNAL(connectionReady(int)), SLOT(sss_connectionReady(int)));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ServSock::stop()
|
||||
{
|
||||
delete d->serv;
|
||||
d->serv = 0;
|
||||
}
|
||||
|
||||
int ServSock::port() const
|
||||
{
|
||||
if(d->serv)
|
||||
return d->serv->serverPort();
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
QHostAddress ServSock::address() const
|
||||
{
|
||||
if(d->serv)
|
||||
return d->serv->serverAddress();
|
||||
else
|
||||
return QHostAddress();
|
||||
}
|
||||
|
||||
void ServSock::sss_connectionReady(int s)
|
||||
{
|
||||
connectionReady(s);
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// ServSockSignal
|
||||
//----------------------------------------------------------------------------
|
||||
ServSockSignal::ServSockSignal(QObject *parent)
|
||||
:QTcpServer(parent)
|
||||
{
|
||||
setMaxPendingConnections(16);
|
||||
}
|
||||
|
||||
void ServSockSignal::incomingConnection(int socketDescriptor)
|
||||
{
|
||||
connectionReady(socketDescriptor);
|
||||
}
|
||||
|
||||
// CS_NAMESPACE_END
|
||||
68
iris-legacy/cutestuff/legacy/servsock.h
Normal file
68
iris-legacy/cutestuff/legacy/servsock.h
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* servsock.h - simple wrapper to QServerSocket
|
||||
* Copyright (C) 2003 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CS_SERVSOCK_H
|
||||
#define CS_SERVSOCK_H
|
||||
|
||||
#include <QTcpServer>
|
||||
|
||||
// CS_NAMESPACE_BEGIN
|
||||
|
||||
class ServSock : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ServSock(QObject *parent=0);
|
||||
~ServSock();
|
||||
|
||||
bool isActive() const;
|
||||
bool listen(quint16 port);
|
||||
void stop();
|
||||
int port() const;
|
||||
QHostAddress address() const;
|
||||
|
||||
signals:
|
||||
void connectionReady(int);
|
||||
|
||||
private slots:
|
||||
void sss_connectionReady(int);
|
||||
|
||||
private:
|
||||
class Private;
|
||||
Private *d;
|
||||
};
|
||||
|
||||
class ServSockSignal : public QTcpServer
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ServSockSignal(QObject *parent = 0);
|
||||
|
||||
signals:
|
||||
void connectionReady(int);
|
||||
|
||||
protected:
|
||||
// reimplemented
|
||||
void incomingConnection(int socketDescriptor);
|
||||
};
|
||||
|
||||
// CS_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
313
iris-legacy/cutestuff/legacy/srvresolver.cpp
Normal file
313
iris-legacy/cutestuff/legacy/srvresolver.cpp
Normal file
|
|
@ -0,0 +1,313 @@
|
|||
/*
|
||||
* srvresolver.cpp - class to simplify SRV lookups
|
||||
* Copyright (C) 2003 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "srvresolver.h"
|
||||
|
||||
#include <q3cstring.h>
|
||||
#include <qtimer.h>
|
||||
#include <q3dns.h>
|
||||
//Added by qt3to4:
|
||||
#include <QList>
|
||||
#include <QtAlgorithms>
|
||||
#include "safedelete.h"
|
||||
#include "psilogger.h"
|
||||
|
||||
#ifndef NO_NDNS
|
||||
#include "ndns.h"
|
||||
#endif
|
||||
|
||||
// CS_NAMESPACE_BEGIN
|
||||
|
||||
bool serverLessThan(const Q3Dns::Server &s1, const Q3Dns::Server &s2)
|
||||
{
|
||||
int a = s1.priority;
|
||||
int b = s2.priority;
|
||||
int j = s1.weight;
|
||||
int k = s2.weight;
|
||||
return a < b || (a == b && j < k);
|
||||
}
|
||||
|
||||
static void sortSRVList(QList<Q3Dns::Server> &list)
|
||||
{
|
||||
qStableSort(list.begin(), list.end(), serverLessThan);
|
||||
}
|
||||
|
||||
class SrvResolver::Private
|
||||
{
|
||||
public:
|
||||
Private() {}
|
||||
|
||||
Q3Dns *qdns;
|
||||
#ifndef NO_NDNS
|
||||
NDns ndns;
|
||||
#endif
|
||||
|
||||
bool failed;
|
||||
QHostAddress resultAddress;
|
||||
Q_UINT16 resultPort;
|
||||
|
||||
bool srvonly;
|
||||
QString srv;
|
||||
QList<Q3Dns::Server> servers;
|
||||
bool aaaa;
|
||||
|
||||
QTimer t;
|
||||
SafeDelete sd;
|
||||
};
|
||||
|
||||
SrvResolver::SrvResolver(QObject *parent)
|
||||
:QObject(parent)
|
||||
{
|
||||
d = new Private;
|
||||
d->qdns = 0;
|
||||
|
||||
#ifndef NO_NDNS
|
||||
connect(&d->ndns, SIGNAL(resultsReady()), SLOT(ndns_done()));
|
||||
#endif
|
||||
connect(&d->t, SIGNAL(timeout()), SLOT(t_timeout()));
|
||||
stop();
|
||||
}
|
||||
|
||||
SrvResolver::~SrvResolver()
|
||||
{
|
||||
stop();
|
||||
delete d;
|
||||
}
|
||||
|
||||
void SrvResolver::resolve(const QString &server, const QString &type, const QString &proto, bool srvOnly)
|
||||
{
|
||||
PsiLogger::instance()->log(QString("SrvResolver::resolve(%1, %2, %3, %4)").arg(server).arg(type).arg(proto).arg(srvOnly));
|
||||
stop();
|
||||
|
||||
d->failed = false;
|
||||
d->srvonly = srvOnly;
|
||||
d->srv = QString("_") + type + "._" + proto + '.' + server;
|
||||
d->t.start(15000, true);
|
||||
d->qdns = new Q3Dns;
|
||||
connect(d->qdns, SIGNAL(resultsReady()), SLOT(qdns_done()));
|
||||
d->qdns->setRecordType(Q3Dns::Srv);
|
||||
d->qdns->setLabel(d->srv);
|
||||
}
|
||||
|
||||
void SrvResolver::resolve(const QString &server, const QString &type, const QString &proto)
|
||||
{
|
||||
resolve(server, type, proto, false);
|
||||
}
|
||||
|
||||
void SrvResolver::resolveSrvOnly(const QString &server, const QString &type, const QString &proto)
|
||||
{
|
||||
resolve(server, type, proto, true);
|
||||
}
|
||||
|
||||
void SrvResolver::next()
|
||||
{
|
||||
if(d->servers.isEmpty())
|
||||
return;
|
||||
|
||||
tryNext();
|
||||
}
|
||||
|
||||
void SrvResolver::stop()
|
||||
{
|
||||
if(d->t.isActive())
|
||||
d->t.stop();
|
||||
if(d->qdns) {
|
||||
d->qdns->disconnect(this);
|
||||
d->sd.deleteLater(d->qdns);
|
||||
d->qdns = 0;
|
||||
}
|
||||
#ifndef NO_NDNS
|
||||
if(d->ndns.isBusy())
|
||||
d->ndns.stop();
|
||||
#endif
|
||||
d->resultAddress = QHostAddress();
|
||||
d->resultPort = 0;
|
||||
d->servers.clear();
|
||||
d->srv = "";
|
||||
d->failed = true;
|
||||
}
|
||||
|
||||
bool SrvResolver::isBusy() const
|
||||
{
|
||||
#ifndef NO_NDNS
|
||||
if(d->qdns || d->ndns.isBusy())
|
||||
#else
|
||||
if(d->qdns)
|
||||
#endif
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
QList<Q3Dns::Server> SrvResolver::servers() const
|
||||
{
|
||||
return d->servers;
|
||||
}
|
||||
|
||||
bool SrvResolver::failed() const
|
||||
{
|
||||
return d->failed;
|
||||
}
|
||||
|
||||
QHostAddress SrvResolver::resultAddress() const
|
||||
{
|
||||
return d->resultAddress;
|
||||
}
|
||||
|
||||
Q_UINT16 SrvResolver::resultPort() const
|
||||
{
|
||||
return d->resultPort;
|
||||
}
|
||||
|
||||
void SrvResolver::tryNext()
|
||||
{
|
||||
#ifndef NO_NDNS
|
||||
PsiLogger::instance()->log(QString("SrvResolver(%1)::tryNext() d->ndns.resolve(%2)").arg(d->srv).arg(d->servers.first().name));
|
||||
d->ndns.resolve(d->servers.first().name);
|
||||
#else
|
||||
d->qdns = new Q3Dns;
|
||||
connect(d->qdns, SIGNAL(resultsReady()), SLOT(ndns_done()));
|
||||
if(d->aaaa)
|
||||
d->qdns->setRecordType(Q3Dns::Aaaa); // IPv6
|
||||
else
|
||||
d->qdns->setRecordType(Q3Dns::A); // IPv4
|
||||
d->qdns->setLabel(d->servers.first().name);
|
||||
#endif
|
||||
}
|
||||
|
||||
void SrvResolver::qdns_done()
|
||||
{
|
||||
PsiLogger::instance()->log(QString("SrvResolver(%1)::qdns_done() d->qdns = %2; d->qdns->isWorking() = %3; d->qdns->servers().count() = %4").arg(d->srv).arg((long)d->qdns).arg(d->qdns ? d->qdns->isWorking() : 0).arg(d->qdns ? d->qdns->servers().count() : 0));
|
||||
if(!d->qdns)
|
||||
return;
|
||||
|
||||
// apparently we sometimes get this signal even though the results aren't ready
|
||||
if(d->qdns->isWorking())
|
||||
return;
|
||||
d->t.stop();
|
||||
|
||||
SafeDeleteLock s(&d->sd);
|
||||
|
||||
// grab the server list and destroy the qdns object
|
||||
QList<Q3Dns::Server> list;
|
||||
if(d->qdns->recordType() == Q3Dns::Srv)
|
||||
list = d->qdns->servers();
|
||||
d->qdns->disconnect(this);
|
||||
d->sd.deleteLater(d->qdns);
|
||||
d->qdns = 0;
|
||||
|
||||
if(list.isEmpty()) {
|
||||
stop();
|
||||
resultsReady();
|
||||
return;
|
||||
}
|
||||
sortSRVList(list);
|
||||
d->servers = list;
|
||||
|
||||
if(d->srvonly)
|
||||
resultsReady();
|
||||
else {
|
||||
// kick it off
|
||||
d->aaaa = true;
|
||||
tryNext();
|
||||
}
|
||||
}
|
||||
|
||||
void SrvResolver::ndns_done()
|
||||
{
|
||||
#ifndef NO_NDNS
|
||||
SafeDeleteLock s(&d->sd);
|
||||
|
||||
QHostAddress r = d->ndns.result();
|
||||
int port = d->servers.first().port;
|
||||
d->servers.remove(d->servers.begin());
|
||||
|
||||
PsiLogger::instance()->log(QString("SrvResolver(%1)::ndns_done() r.isNull = %2, r = %3, port = %4").arg(d->srv).arg(r.isNull()).arg(r.toString()).arg(port));
|
||||
|
||||
if(!r.isNull()) {
|
||||
d->resultAddress = r;
|
||||
d->resultPort = port;
|
||||
resultsReady();
|
||||
}
|
||||
else {
|
||||
// failed? bail if last one
|
||||
if(d->servers.isEmpty()) {
|
||||
stop();
|
||||
resultsReady();
|
||||
return;
|
||||
}
|
||||
|
||||
// otherwise try the next
|
||||
tryNext();
|
||||
}
|
||||
#else
|
||||
if(!d->qdns)
|
||||
return;
|
||||
|
||||
// apparently we sometimes get this signal even though the results aren't ready
|
||||
if(d->qdns->isWorking())
|
||||
return;
|
||||
|
||||
SafeDeleteLock s(&d->sd);
|
||||
|
||||
// grab the address list and destroy the qdns object
|
||||
QList<QHostAddress> list;
|
||||
if(d->qdns->recordType() == Q3Dns::A || d->qdns->recordType() == Q3Dns::Aaaa)
|
||||
list = d->qdns->addresses();
|
||||
d->qdns->disconnect(this);
|
||||
d->sd.deleteLater(d->qdns);
|
||||
d->qdns = 0;
|
||||
|
||||
if(!list.isEmpty()) {
|
||||
int port = d->servers.first().port;
|
||||
d->servers.remove(d->servers.begin());
|
||||
d->aaaa = true;
|
||||
|
||||
d->resultAddress = list.first();
|
||||
d->resultPort = port;
|
||||
resultsReady();
|
||||
}
|
||||
else {
|
||||
if(!d->aaaa)
|
||||
d->servers.remove(d->servers.begin());
|
||||
d->aaaa = !d->aaaa;
|
||||
|
||||
// failed? bail if last one
|
||||
if(d->servers.isEmpty()) {
|
||||
stop();
|
||||
resultsReady();
|
||||
return;
|
||||
}
|
||||
|
||||
// otherwise try the next
|
||||
tryNext();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void SrvResolver::t_timeout()
|
||||
{
|
||||
SafeDeleteLock s(&d->sd);
|
||||
|
||||
stop();
|
||||
resultsReady();
|
||||
}
|
||||
|
||||
// CS_NAMESPACE_END
|
||||
66
iris-legacy/cutestuff/legacy/srvresolver.h
Normal file
66
iris-legacy/cutestuff/legacy/srvresolver.h
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* srvresolver.h - class to simplify SRV lookups
|
||||
* Copyright (C) 2003 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CS_SRVRESOLVER_H
|
||||
#define CS_SRVRESOLVER_H
|
||||
|
||||
#include <QList>
|
||||
#include <q3dns.h>
|
||||
|
||||
// CS_NAMESPACE_BEGIN
|
||||
|
||||
class SrvResolver : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SrvResolver(QObject *parent=0);
|
||||
~SrvResolver();
|
||||
|
||||
void resolve(const QString &server, const QString &type, const QString &proto);
|
||||
void resolveSrvOnly(const QString &server, const QString &type, const QString &proto);
|
||||
void next();
|
||||
void stop();
|
||||
bool isBusy() const;
|
||||
|
||||
QList<Q3Dns::Server> servers() const;
|
||||
|
||||
bool failed() const;
|
||||
QHostAddress resultAddress() const;
|
||||
Q_UINT16 resultPort() const;
|
||||
|
||||
signals:
|
||||
void resultsReady();
|
||||
|
||||
private slots:
|
||||
void qdns_done();
|
||||
void ndns_done();
|
||||
void t_timeout();
|
||||
|
||||
private:
|
||||
class Private;
|
||||
Private *d;
|
||||
|
||||
void tryNext();
|
||||
void resolve(const QString &server, const QString &type, const QString &proto, bool srvOnly);
|
||||
};
|
||||
|
||||
// CS_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
474
iris-legacy/cutestuff/network/bsocket.cpp
Normal file
474
iris-legacy/cutestuff/network/bsocket.cpp
Normal file
|
|
@ -0,0 +1,474 @@
|
|||
/*
|
||||
* bsocket.cpp - QSocket wrapper based on Bytestream with SRV DNS support
|
||||
* Copyright (C) 2003 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <QTcpSocket>
|
||||
#include <QHostAddress>
|
||||
#include <QMetaType>
|
||||
|
||||
#include "bsocket.h"
|
||||
|
||||
//#include "safedelete.h"
|
||||
#ifndef NO_NDNS
|
||||
#include "ndns.h"
|
||||
#endif
|
||||
#include "srvresolver.h"
|
||||
|
||||
//#define BS_DEBUG
|
||||
|
||||
#ifdef BS_DEBUG
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#define READBUFSIZE 65536
|
||||
|
||||
// CS_NAMESPACE_BEGIN
|
||||
|
||||
#include "psilogger.h"
|
||||
|
||||
class QTcpSocketSignalRelay : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QTcpSocketSignalRelay(QTcpSocket *sock, QObject *parent = 0)
|
||||
:QObject(parent)
|
||||
{
|
||||
qRegisterMetaType<QAbstractSocket::SocketError>("QAbstractSocket::SocketError");
|
||||
connect(sock, SIGNAL(hostFound()), SLOT(sock_hostFound()), Qt::QueuedConnection);
|
||||
connect(sock, SIGNAL(connected()), SLOT(sock_connected()), Qt::QueuedConnection);
|
||||
connect(sock, SIGNAL(disconnected()), SLOT(sock_disconnected()), Qt::QueuedConnection);
|
||||
connect(sock, SIGNAL(readyRead()), SLOT(sock_readyRead()), Qt::QueuedConnection);
|
||||
connect(sock, SIGNAL(bytesWritten(qint64)), SLOT(sock_bytesWritten(qint64)), Qt::QueuedConnection);
|
||||
connect(sock, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(sock_error(QAbstractSocket::SocketError)), Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
signals:
|
||||
void hostFound();
|
||||
void connected();
|
||||
void disconnected();
|
||||
void readyRead();
|
||||
void bytesWritten(qint64);
|
||||
void error(QAbstractSocket::SocketError);
|
||||
|
||||
public slots:
|
||||
void sock_hostFound()
|
||||
{
|
||||
emit hostFound();
|
||||
}
|
||||
|
||||
void sock_connected()
|
||||
{
|
||||
emit connected();
|
||||
}
|
||||
|
||||
void sock_disconnected()
|
||||
{
|
||||
emit disconnected();
|
||||
}
|
||||
|
||||
void sock_readyRead()
|
||||
{
|
||||
emit readyRead();
|
||||
}
|
||||
|
||||
void sock_bytesWritten(qint64 x)
|
||||
{
|
||||
emit bytesWritten(x);
|
||||
}
|
||||
|
||||
void sock_error(QAbstractSocket::SocketError x)
|
||||
{
|
||||
emit error(x);
|
||||
}
|
||||
};
|
||||
|
||||
class BSocket::Private
|
||||
{
|
||||
public:
|
||||
Private()
|
||||
{
|
||||
qsock = 0;
|
||||
qsock_relay = 0;
|
||||
}
|
||||
|
||||
QTcpSocket *qsock;
|
||||
QTcpSocketSignalRelay *qsock_relay;
|
||||
int state;
|
||||
|
||||
#ifndef NO_NDNS
|
||||
NDns ndns;
|
||||
#endif
|
||||
SrvResolver srv;
|
||||
QString host;
|
||||
int port;
|
||||
//SafeDelete sd;
|
||||
};
|
||||
|
||||
BSocket::BSocket(QObject *parent)
|
||||
:ByteStream(parent)
|
||||
{
|
||||
d = new Private;
|
||||
#ifndef NO_NDNS
|
||||
connect(&d->ndns, SIGNAL(resultsReady()), SLOT(ndns_done()));
|
||||
#endif
|
||||
connect(&d->srv, SIGNAL(resultsReady()), SLOT(srv_done()));
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
BSocket::~BSocket()
|
||||
{
|
||||
reset(true);
|
||||
delete d;
|
||||
PsiLogger::instance()->log(QString("%1 BSocket::~BSocket()").arg(LOG_THIS));
|
||||
}
|
||||
|
||||
void BSocket::reset(bool clear)
|
||||
{
|
||||
PsiLogger::instance()->log(QString("%1 BSocket::reset()").arg(LOG_THIS));
|
||||
|
||||
if(d->qsock) {
|
||||
delete d->qsock_relay;
|
||||
d->qsock_relay = 0;
|
||||
|
||||
/*d->qsock->disconnect(this);
|
||||
|
||||
if(!clear && d->qsock->isOpen() && d->qsock->isValid()) {*/
|
||||
// move remaining into the local queue
|
||||
QByteArray block(d->qsock->bytesAvailable(), 0);
|
||||
d->qsock->read(block.data(), block.size());
|
||||
appendRead(block);
|
||||
//}
|
||||
|
||||
//d->sd.deleteLater(d->qsock);
|
||||
// delete d->qsock;
|
||||
d->qsock->deleteLater();
|
||||
d->qsock = 0;
|
||||
}
|
||||
else {
|
||||
if(clear)
|
||||
clearReadBuffer();
|
||||
}
|
||||
|
||||
if(d->srv.isBusy())
|
||||
d->srv.stop();
|
||||
#ifndef NO_NDNS
|
||||
if(d->ndns.isBusy())
|
||||
d->ndns.stop();
|
||||
#endif
|
||||
d->state = Idle;
|
||||
}
|
||||
|
||||
void BSocket::ensureSocket()
|
||||
{
|
||||
PsiLogger::instance()->log(QString("%1 BSocket::ensureSocket()").arg(LOG_THIS));
|
||||
if(!d->qsock) {
|
||||
d->qsock = new QTcpSocket;
|
||||
#if QT_VERSION >= 0x030200
|
||||
d->qsock->setReadBufferSize(READBUFSIZE);
|
||||
#endif
|
||||
d->qsock_relay = new QTcpSocketSignalRelay(d->qsock);
|
||||
connect(d->qsock_relay, SIGNAL(hostFound()), SLOT(qs_hostFound()));
|
||||
connect(d->qsock_relay, SIGNAL(connected()), SLOT(qs_connected()));
|
||||
connect(d->qsock_relay, SIGNAL(disconnected()), SLOT(qs_closed()));
|
||||
connect(d->qsock_relay, SIGNAL(readyRead()), SLOT(qs_readyRead()));
|
||||
connect(d->qsock_relay, SIGNAL(bytesWritten(qint64)), SLOT(qs_bytesWritten(qint64)));
|
||||
connect(d->qsock_relay, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(qs_error(QAbstractSocket::SocketError)));
|
||||
}
|
||||
}
|
||||
|
||||
void BSocket::connectToHost(const QString &host, quint16 port)
|
||||
{
|
||||
PsiLogger::instance()->log(QString("%1 BSocket::connectToHost(%2, %3)").arg(LOG_THIS).arg(host).arg(port));
|
||||
reset(true);
|
||||
d->host = host;
|
||||
d->port = port;
|
||||
#ifdef NO_NDNS
|
||||
d->state = Connecting;
|
||||
do_connect();
|
||||
#else
|
||||
d->state = HostLookup;
|
||||
d->ndns.resolve(d->host);
|
||||
#endif
|
||||
}
|
||||
|
||||
void BSocket::connectToServer(const QString &srv, const QString &type)
|
||||
{
|
||||
PsiLogger::instance()->log(QString("%1 BSocket::connectToServer(%2, %3)").arg(LOG_THIS).arg(srv).arg(type));
|
||||
reset(true);
|
||||
d->state = HostLookup;
|
||||
d->srv.resolve(srv, type, "tcp");
|
||||
}
|
||||
|
||||
int BSocket::socket() const
|
||||
{
|
||||
if(d->qsock)
|
||||
return d->qsock->socketDescriptor();
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
void BSocket::setSocket(int s)
|
||||
{
|
||||
PsiLogger::instance()->log(QString("%1 BSocket::setSocket(%2)").arg(LOG_THIS).arg(s));
|
||||
reset(true);
|
||||
ensureSocket();
|
||||
d->state = Connected;
|
||||
d->qsock->setSocketDescriptor(s);
|
||||
}
|
||||
|
||||
int BSocket::state() const
|
||||
{
|
||||
return d->state;
|
||||
}
|
||||
|
||||
bool BSocket::isOpen() const
|
||||
{
|
||||
if(d->state == Connected)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void BSocket::close()
|
||||
{
|
||||
PsiLogger::instance()->log(QString("%1 BSocket::close()").arg(LOG_THIS));
|
||||
if(d->state == Idle)
|
||||
return;
|
||||
|
||||
if(d->qsock) {
|
||||
d->qsock->close();
|
||||
d->state = Closing;
|
||||
if(d->qsock->bytesToWrite() == 0)
|
||||
reset();
|
||||
}
|
||||
else {
|
||||
reset();
|
||||
}
|
||||
}
|
||||
|
||||
void BSocket::write(const QByteArray &a)
|
||||
{
|
||||
if(d->state != Connected)
|
||||
return;
|
||||
#ifdef BS_DEBUG
|
||||
QString s = QString::fromUtf8(a);
|
||||
fprintf(stderr, "BSocket: writing [%d]: {%s}\n", a.size(), s.latin1());
|
||||
#endif
|
||||
d->qsock->write(a.data(), a.size());
|
||||
}
|
||||
|
||||
QByteArray BSocket::read(int bytes)
|
||||
{
|
||||
QByteArray block;
|
||||
if(d->qsock) {
|
||||
int max = bytesAvailable();
|
||||
if(bytes <= 0 || bytes > max)
|
||||
bytes = max;
|
||||
block.resize(bytes);
|
||||
d->qsock->read(block.data(), block.size());
|
||||
}
|
||||
else
|
||||
block = ByteStream::read(bytes);
|
||||
|
||||
#ifdef BS_DEBUG
|
||||
QString s = QString::fromUtf8(block);
|
||||
fprintf(stderr, "BSocket: read [%d]: {%s}\n", block.size(), s.latin1());
|
||||
#endif
|
||||
return block;
|
||||
}
|
||||
|
||||
int BSocket::bytesAvailable() const
|
||||
{
|
||||
if(d->qsock)
|
||||
return d->qsock->bytesAvailable();
|
||||
else
|
||||
return ByteStream::bytesAvailable();
|
||||
}
|
||||
|
||||
int BSocket::bytesToWrite() const
|
||||
{
|
||||
if(!d->qsock)
|
||||
return 0;
|
||||
return d->qsock->bytesToWrite();
|
||||
}
|
||||
|
||||
QHostAddress BSocket::address() const
|
||||
{
|
||||
if(d->qsock)
|
||||
return d->qsock->localAddress();
|
||||
else
|
||||
return QHostAddress();
|
||||
}
|
||||
|
||||
quint16 BSocket::port() const
|
||||
{
|
||||
if(d->qsock)
|
||||
return d->qsock->localPort();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
QHostAddress BSocket::peerAddress() const
|
||||
{
|
||||
if(d->qsock)
|
||||
return d->qsock->peerAddress();
|
||||
else
|
||||
return QHostAddress();
|
||||
}
|
||||
|
||||
quint16 BSocket::peerPort() const
|
||||
{
|
||||
if(d->qsock)
|
||||
return d->qsock->peerPort();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void BSocket::srv_done()
|
||||
{
|
||||
PsiLogger::instance()->log(QString("%1 BSocket::srv_done()").arg(LOG_THIS));
|
||||
if(d->srv.failed()) {
|
||||
#ifdef BS_DEBUG
|
||||
fprintf(stderr, "BSocket: Error resolving hostname.\n");
|
||||
#endif
|
||||
error(ErrHostNotFound);
|
||||
return;
|
||||
}
|
||||
|
||||
d->host = d->srv.resultAddress().toString();
|
||||
d->port = d->srv.resultPort();
|
||||
do_connect();
|
||||
//QTimer::singleShot(0, this, SLOT(do_connect()));
|
||||
//hostFound();
|
||||
}
|
||||
|
||||
void BSocket::ndns_done()
|
||||
{
|
||||
PsiLogger::instance()->log(QString("%1 BSocket::ndns_done()").arg(LOG_THIS));
|
||||
#ifndef NO_NDNS
|
||||
if(!d->ndns.result().isNull()) {
|
||||
d->host = d->ndns.resultString();
|
||||
d->state = Connecting;
|
||||
do_connect();
|
||||
//QTimer::singleShot(0, this, SLOT(do_connect()));
|
||||
//hostFound();
|
||||
}
|
||||
else {
|
||||
#ifdef BS_DEBUG
|
||||
fprintf(stderr, "BSocket: Error resolving hostname.\n");
|
||||
#endif
|
||||
error(ErrHostNotFound);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void BSocket::do_connect()
|
||||
{
|
||||
PsiLogger::instance()->log(QString("%1 BSocket::do_connect()").arg(LOG_THIS));
|
||||
#ifdef BS_DEBUG
|
||||
fprintf(stderr, "BSocket: Connecting to %s:%d\n", d->host.latin1(), d->port);
|
||||
#endif
|
||||
ensureSocket();
|
||||
d->qsock->connectToHost(d->host, d->port);
|
||||
}
|
||||
|
||||
void BSocket::qs_hostFound()
|
||||
{
|
||||
PsiLogger::instance()->log(QString("%1 BSocket::qs_hostFound()").arg(LOG_THIS));
|
||||
//SafeDeleteLock s(&d->sd);
|
||||
}
|
||||
|
||||
void BSocket::qs_connected()
|
||||
{
|
||||
PsiLogger::instance()->log(QString("%1 BSocket::qs_connected()").arg(LOG_THIS));
|
||||
d->state = Connected;
|
||||
#ifdef BS_DEBUG
|
||||
fprintf(stderr, "BSocket: Connected.\n");
|
||||
#endif
|
||||
//SafeDeleteLock s(&d->sd);
|
||||
connected();
|
||||
}
|
||||
|
||||
void BSocket::qs_closed()
|
||||
{
|
||||
PsiLogger::instance()->log(QString("%1 BSocket::qs_closed()").arg(LOG_THIS));
|
||||
if(d->state == Closing)
|
||||
{
|
||||
#ifdef BS_DEBUG
|
||||
fprintf(stderr, "BSocket: Delayed Close Finished.\n");
|
||||
#endif
|
||||
//SafeDeleteLock s(&d->sd);
|
||||
reset();
|
||||
delayedCloseFinished();
|
||||
}
|
||||
}
|
||||
|
||||
void BSocket::qs_readyRead()
|
||||
{
|
||||
//SafeDeleteLock s(&d->sd);
|
||||
readyRead();
|
||||
}
|
||||
|
||||
void BSocket::qs_bytesWritten(qint64 x64)
|
||||
{
|
||||
int x = x64;
|
||||
#ifdef BS_DEBUG
|
||||
fprintf(stderr, "BSocket: BytesWritten [%d].\n", x);
|
||||
#endif
|
||||
//SafeDeleteLock s(&d->sd);
|
||||
bytesWritten(x);
|
||||
}
|
||||
|
||||
void BSocket::qs_error(QAbstractSocket::SocketError x)
|
||||
{
|
||||
PsiLogger::instance()->log(QString("%1 BSocket::qs_error(%2)").arg(LOG_THIS).arg(x));
|
||||
if(x == QTcpSocket::RemoteHostClosedError) {
|
||||
#ifdef BS_DEBUG
|
||||
fprintf(stderr, "BSocket: Connection Closed.\n");
|
||||
#endif
|
||||
//SafeDeleteLock s(&d->sd);
|
||||
reset();
|
||||
connectionClosed();
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef BS_DEBUG
|
||||
fprintf(stderr, "BSocket: Error.\n");
|
||||
#endif
|
||||
//SafeDeleteLock s(&d->sd);
|
||||
|
||||
// connection error during SRV host connect? try next
|
||||
if(d->state == HostLookup && (x == QTcpSocket::ConnectionRefusedError || x == QTcpSocket::HostNotFoundError)) {
|
||||
d->srv.next();
|
||||
return;
|
||||
}
|
||||
|
||||
reset();
|
||||
if(x == QTcpSocket::ConnectionRefusedError)
|
||||
error(ErrConnectionRefused);
|
||||
else if(x == QTcpSocket::HostNotFoundError)
|
||||
error(ErrHostNotFound);
|
||||
else
|
||||
error(ErrRead);
|
||||
}
|
||||
|
||||
#include "bsocket.moc"
|
||||
|
||||
// CS_NAMESPACE_END
|
||||
90
iris-legacy/cutestuff/network/bsocket.h
Normal file
90
iris-legacy/cutestuff/network/bsocket.h
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* bsocket.h - QSocket wrapper based on Bytestream with SRV DNS support
|
||||
* Copyright (C) 2003 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CS_BSOCKET_H
|
||||
#define CS_BSOCKET_H
|
||||
|
||||
#include <QAbstractSocket>
|
||||
|
||||
#include "bytestream.h"
|
||||
|
||||
class QString;
|
||||
class QObject;
|
||||
class QByteArray;
|
||||
|
||||
// CS_NAMESPACE_BEGIN
|
||||
|
||||
class BSocket : public ByteStream
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum Error { ErrConnectionRefused = ErrCustom, ErrHostNotFound };
|
||||
enum State { Idle, HostLookup, Connecting, Connected, Closing };
|
||||
BSocket(QObject *parent=0);
|
||||
~BSocket();
|
||||
|
||||
void connectToHost(const QString &host, quint16 port);
|
||||
void connectToServer(const QString &srv, const QString &type);
|
||||
int socket() const;
|
||||
void setSocket(int);
|
||||
int state() const;
|
||||
|
||||
// from ByteStream
|
||||
bool isOpen() const;
|
||||
void close();
|
||||
void write(const QByteArray &);
|
||||
QByteArray read(int bytes=0);
|
||||
int bytesAvailable() const;
|
||||
int bytesToWrite() const;
|
||||
|
||||
// local
|
||||
QHostAddress address() const;
|
||||
quint16 port() const;
|
||||
|
||||
// remote
|
||||
QHostAddress peerAddress() const;
|
||||
quint16 peerPort() const;
|
||||
|
||||
signals:
|
||||
void hostFound();
|
||||
void connected();
|
||||
|
||||
private slots:
|
||||
void qs_hostFound();
|
||||
void qs_connected();
|
||||
void qs_closed();
|
||||
void qs_readyRead();
|
||||
void qs_bytesWritten(qint64);
|
||||
void qs_error(QAbstractSocket::SocketError);
|
||||
void srv_done();
|
||||
void ndns_done();
|
||||
void do_connect();
|
||||
|
||||
private:
|
||||
class Private;
|
||||
Private *d;
|
||||
|
||||
void reset(bool clear=false);
|
||||
void ensureSocket();
|
||||
};
|
||||
|
||||
// CS_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
363
iris-legacy/cutestuff/network/httpconnect.cpp
Normal file
363
iris-legacy/cutestuff/network/httpconnect.cpp
Normal file
|
|
@ -0,0 +1,363 @@
|
|||
/*
|
||||
* httpconnect.cpp - HTTP "CONNECT" proxy
|
||||
* Copyright (C) 2003 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "httpconnect.h"
|
||||
|
||||
#include <qstringlist.h>
|
||||
//Added by qt3to4:
|
||||
#include <Q3CString>
|
||||
#include "bsocket.h"
|
||||
#include <QtCrypto>
|
||||
|
||||
#ifdef PROX_DEBUG
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
// CS_NAMESPACE_BEGIN
|
||||
|
||||
static QString extractLine(QByteArray *buf, bool *found)
|
||||
{
|
||||
// Scan for newline
|
||||
int index = buf->indexOf ("\r\n");
|
||||
if (index == -1) {
|
||||
// Newline not found
|
||||
if (found)
|
||||
*found = false;
|
||||
return "";
|
||||
}
|
||||
else {
|
||||
// Found newline
|
||||
QString s = QString::fromAscii(buf->left(index));
|
||||
buf->remove(0, index + 2);
|
||||
|
||||
if (found)
|
||||
*found = true;
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
static bool extractMainHeader(const QString &line, QString *proto, int *code, QString *msg)
|
||||
{
|
||||
int n = line.find(' ');
|
||||
if(n == -1)
|
||||
return false;
|
||||
if(proto)
|
||||
*proto = line.mid(0, n);
|
||||
++n;
|
||||
int n2 = line.find(' ', n);
|
||||
if(n2 == -1)
|
||||
return false;
|
||||
if(code)
|
||||
*code = line.mid(n, n2-n).toInt();
|
||||
n = n2+1;
|
||||
if(msg)
|
||||
*msg = line.mid(n);
|
||||
return true;
|
||||
}
|
||||
|
||||
class HttpConnect::Private
|
||||
{
|
||||
public:
|
||||
Private() {}
|
||||
|
||||
BSocket sock;
|
||||
QString host;
|
||||
int port;
|
||||
QString user, pass;
|
||||
QString real_host;
|
||||
int real_port;
|
||||
|
||||
QByteArray recvBuf;
|
||||
|
||||
bool inHeader;
|
||||
QStringList headerLines;
|
||||
|
||||
int toWrite;
|
||||
bool active;
|
||||
};
|
||||
|
||||
HttpConnect::HttpConnect(QObject *parent)
|
||||
:ByteStream(parent)
|
||||
{
|
||||
d = new Private;
|
||||
connect(&d->sock, SIGNAL(connected()), SLOT(sock_connected()));
|
||||
connect(&d->sock, SIGNAL(connectionClosed()), SLOT(sock_connectionClosed()));
|
||||
connect(&d->sock, SIGNAL(delayedCloseFinished()), SLOT(sock_delayedCloseFinished()));
|
||||
connect(&d->sock, SIGNAL(readyRead()), SLOT(sock_readyRead()));
|
||||
connect(&d->sock, SIGNAL(bytesWritten(int)), SLOT(sock_bytesWritten(int)));
|
||||
connect(&d->sock, SIGNAL(error(int)), SLOT(sock_error(int)));
|
||||
|
||||
reset(true);
|
||||
}
|
||||
|
||||
HttpConnect::~HttpConnect()
|
||||
{
|
||||
reset(true);
|
||||
delete d;
|
||||
}
|
||||
|
||||
void HttpConnect::reset(bool clear)
|
||||
{
|
||||
if(d->sock.state() != BSocket::Idle)
|
||||
d->sock.close();
|
||||
if(clear) {
|
||||
clearReadBuffer();
|
||||
d->recvBuf.resize(0);
|
||||
}
|
||||
d->active = false;
|
||||
}
|
||||
|
||||
void HttpConnect::setAuth(const QString &user, const QString &pass)
|
||||
{
|
||||
d->user = user;
|
||||
d->pass = pass;
|
||||
}
|
||||
|
||||
void HttpConnect::connectToHost(const QString &proxyHost, int proxyPort, const QString &host, int port)
|
||||
{
|
||||
reset(true);
|
||||
|
||||
d->host = proxyHost;
|
||||
d->port = proxyPort;
|
||||
d->real_host = host;
|
||||
d->real_port = port;
|
||||
|
||||
#ifdef PROX_DEBUG
|
||||
fprintf(stderr, "HttpConnect: Connecting to %s:%d", proxyHost.latin1(), proxyPort);
|
||||
if(d->user.isEmpty())
|
||||
fprintf(stderr, "\n");
|
||||
else
|
||||
fprintf(stderr, ", auth {%s,%s}\n", d->user.latin1(), d->pass.latin1());
|
||||
#endif
|
||||
d->sock.connectToHost(d->host, d->port);
|
||||
}
|
||||
|
||||
bool HttpConnect::isOpen() const
|
||||
{
|
||||
return d->active;
|
||||
}
|
||||
|
||||
void HttpConnect::close()
|
||||
{
|
||||
d->sock.close();
|
||||
if(d->sock.bytesToWrite() == 0)
|
||||
reset();
|
||||
}
|
||||
|
||||
void HttpConnect::write(const QByteArray &buf)
|
||||
{
|
||||
if(d->active)
|
||||
d->sock.write(buf);
|
||||
}
|
||||
|
||||
QByteArray HttpConnect::read(int bytes)
|
||||
{
|
||||
return ByteStream::read(bytes);
|
||||
}
|
||||
|
||||
int HttpConnect::bytesAvailable() const
|
||||
{
|
||||
return ByteStream::bytesAvailable();
|
||||
}
|
||||
|
||||
int HttpConnect::bytesToWrite() const
|
||||
{
|
||||
if(d->active)
|
||||
return d->sock.bytesToWrite();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void HttpConnect::sock_connected()
|
||||
{
|
||||
#ifdef PROX_DEBUG
|
||||
fprintf(stderr, "HttpConnect: Connected\n");
|
||||
#endif
|
||||
d->inHeader = true;
|
||||
d->headerLines.clear();
|
||||
|
||||
// connected, now send the request
|
||||
QString s;
|
||||
s += QString("CONNECT ") + d->real_host + ':' + QString::number(d->real_port) + " HTTP/1.0\r\n";
|
||||
if(!d->user.isEmpty()) {
|
||||
QString str = d->user + ':' + d->pass;
|
||||
s += QString("Proxy-Authorization: Basic ") + QCA::Base64().encodeString(str) + "\r\n";
|
||||
}
|
||||
s += "Pragma: no-cache\r\n";
|
||||
s += "\r\n";
|
||||
|
||||
Q3CString cs = s.utf8();
|
||||
QByteArray block(cs.length());
|
||||
memcpy(block.data(), cs.data(), block.size());
|
||||
d->toWrite = block.size();
|
||||
d->sock.write(block);
|
||||
}
|
||||
|
||||
void HttpConnect::sock_connectionClosed()
|
||||
{
|
||||
if(d->active) {
|
||||
reset();
|
||||
connectionClosed();
|
||||
}
|
||||
else {
|
||||
error(ErrProxyNeg);
|
||||
}
|
||||
}
|
||||
|
||||
void HttpConnect::sock_delayedCloseFinished()
|
||||
{
|
||||
if(d->active) {
|
||||
reset();
|
||||
delayedCloseFinished();
|
||||
}
|
||||
}
|
||||
|
||||
void HttpConnect::sock_readyRead()
|
||||
{
|
||||
QByteArray block = d->sock.read();
|
||||
|
||||
if(!d->active) {
|
||||
ByteStream::appendArray(&d->recvBuf, block);
|
||||
|
||||
if(d->inHeader) {
|
||||
// grab available lines
|
||||
while(1) {
|
||||
bool found;
|
||||
QString line = extractLine(&d->recvBuf, &found);
|
||||
if(!found)
|
||||
break;
|
||||
if(line.isEmpty()) {
|
||||
d->inHeader = false;
|
||||
break;
|
||||
}
|
||||
d->headerLines += line;
|
||||
}
|
||||
|
||||
// done with grabbing the header?
|
||||
if(!d->inHeader) {
|
||||
QString str = d->headerLines.first();
|
||||
d->headerLines.remove(d->headerLines.begin());
|
||||
|
||||
QString proto;
|
||||
int code;
|
||||
QString msg;
|
||||
if(!extractMainHeader(str, &proto, &code, &msg)) {
|
||||
#ifdef PROX_DEBUG
|
||||
fprintf(stderr, "HttpConnect: invalid header!\n");
|
||||
#endif
|
||||
reset(true);
|
||||
error(ErrProxyNeg);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
#ifdef PROX_DEBUG
|
||||
fprintf(stderr, "HttpConnect: header proto=[%s] code=[%d] msg=[%s]\n", proto.latin1(), code, msg.latin1());
|
||||
for(QStringList::ConstIterator it = d->headerLines.begin(); it != d->headerLines.end(); ++it)
|
||||
fprintf(stderr, "HttpConnect: * [%s]\n", (*it).latin1());
|
||||
#endif
|
||||
}
|
||||
|
||||
if(code == 200) { // OK
|
||||
#ifdef PROX_DEBUG
|
||||
fprintf(stderr, "HttpConnect: << Success >>\n");
|
||||
#endif
|
||||
d->active = true;
|
||||
connected();
|
||||
|
||||
if(!d->recvBuf.isEmpty()) {
|
||||
appendRead(d->recvBuf);
|
||||
d->recvBuf.resize(0);
|
||||
readyRead();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
int err;
|
||||
QString errStr;
|
||||
if(code == 407) { // Authentication failed
|
||||
err = ErrProxyAuth;
|
||||
errStr = tr("Authentication failed");
|
||||
}
|
||||
else if(code == 404) { // Host not found
|
||||
err = ErrHostNotFound;
|
||||
errStr = tr("Host not found");
|
||||
}
|
||||
else if(code == 403) { // Access denied
|
||||
err = ErrProxyNeg;
|
||||
errStr = tr("Access denied");
|
||||
}
|
||||
else if(code == 503) { // Connection refused
|
||||
err = ErrConnectionRefused;
|
||||
errStr = tr("Connection refused");
|
||||
}
|
||||
else { // invalid reply
|
||||
err = ErrProxyNeg;
|
||||
errStr = tr("Invalid reply");
|
||||
}
|
||||
|
||||
#ifdef PROX_DEBUG
|
||||
fprintf(stderr, "HttpConnect: << Error >> [%s]\n", errStr.latin1());
|
||||
#endif
|
||||
reset(true);
|
||||
error(err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
appendRead(block);
|
||||
readyRead();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void HttpConnect::sock_bytesWritten(int x)
|
||||
{
|
||||
if(d->toWrite > 0) {
|
||||
int size = x;
|
||||
if(d->toWrite < x)
|
||||
size = d->toWrite;
|
||||
d->toWrite -= size;
|
||||
x -= size;
|
||||
}
|
||||
|
||||
if(d->active && x > 0)
|
||||
bytesWritten(x);
|
||||
}
|
||||
|
||||
void HttpConnect::sock_error(int x)
|
||||
{
|
||||
if(d->active) {
|
||||
reset();
|
||||
error(ErrRead);
|
||||
}
|
||||
else {
|
||||
reset(true);
|
||||
if(x == BSocket::ErrHostNotFound)
|
||||
error(ErrProxyConnect);
|
||||
else if(x == BSocket::ErrConnectionRefused)
|
||||
error(ErrProxyConnect);
|
||||
else if(x == BSocket::ErrRead)
|
||||
error(ErrProxyNeg);
|
||||
}
|
||||
}
|
||||
|
||||
// CS_NAMESPACE_END
|
||||
67
iris-legacy/cutestuff/network/httpconnect.h
Normal file
67
iris-legacy/cutestuff/network/httpconnect.h
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* httpconnect.h - HTTP "CONNECT" proxy
|
||||
* Copyright (C) 2003 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CS_HTTPCONNECT_H
|
||||
#define CS_HTTPCONNECT_H
|
||||
|
||||
#include "bytestream.h"
|
||||
|
||||
// CS_NAMESPACE_BEGIN
|
||||
|
||||
class HttpConnect : public ByteStream
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum Error { ErrConnectionRefused = ErrCustom, ErrHostNotFound, ErrProxyConnect, ErrProxyNeg, ErrProxyAuth };
|
||||
HttpConnect(QObject *parent=0);
|
||||
~HttpConnect();
|
||||
|
||||
void setAuth(const QString &user, const QString &pass="");
|
||||
void connectToHost(const QString &proxyHost, int proxyPort, const QString &host, int port);
|
||||
|
||||
// from ByteStream
|
||||
bool isOpen() const;
|
||||
void close();
|
||||
void write(const QByteArray &);
|
||||
QByteArray read(int bytes=0);
|
||||
int bytesAvailable() const;
|
||||
int bytesToWrite() const;
|
||||
|
||||
signals:
|
||||
void connected();
|
||||
|
||||
private slots:
|
||||
void sock_connected();
|
||||
void sock_connectionClosed();
|
||||
void sock_delayedCloseFinished();
|
||||
void sock_readyRead();
|
||||
void sock_bytesWritten(int);
|
||||
void sock_error(int);
|
||||
|
||||
private:
|
||||
class Private;
|
||||
Private *d;
|
||||
|
||||
void reset(bool clear=false);
|
||||
};
|
||||
|
||||
// CS_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
666
iris-legacy/cutestuff/network/httppoll.cpp
Normal file
666
iris-legacy/cutestuff/network/httppoll.cpp
Normal file
|
|
@ -0,0 +1,666 @@
|
|||
/*
|
||||
* httppoll.cpp - HTTP polling proxy
|
||||
* Copyright (C) 2003 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "httppoll.h"
|
||||
|
||||
#include <qstringlist.h>
|
||||
#include <q3url.h>
|
||||
#include <qtimer.h>
|
||||
#include <qpointer.h>
|
||||
#include <QtCrypto>
|
||||
//Added by qt3to4:
|
||||
#include <Q3CString>
|
||||
#include <stdlib.h>
|
||||
#include "bsocket.h"
|
||||
|
||||
#ifdef PROX_DEBUG
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#define POLL_KEYS 64
|
||||
|
||||
// CS_NAMESPACE_BEGIN
|
||||
|
||||
static QByteArray randomArray(int size)
|
||||
{
|
||||
QByteArray a(size);
|
||||
for(int n = 0; n < size; ++n)
|
||||
a[n] = (char)(256.0*rand()/(RAND_MAX+1.0));
|
||||
return a;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// HttpPoll
|
||||
//----------------------------------------------------------------------------
|
||||
static QString hpk(int n, const QString &s)
|
||||
{
|
||||
if(n == 0)
|
||||
return s;
|
||||
else
|
||||
return QCA::Base64().arrayToString( QCA::Hash("sha1").hash( Q3CString(hpk(n - 1, s).latin1()) ).toByteArray() );
|
||||
}
|
||||
|
||||
class HttpPoll::Private
|
||||
{
|
||||
public:
|
||||
Private() {}
|
||||
|
||||
HttpProxyPost http;
|
||||
QString host;
|
||||
int port;
|
||||
QString user, pass;
|
||||
QString url;
|
||||
bool use_proxy;
|
||||
|
||||
QByteArray out;
|
||||
|
||||
int state;
|
||||
bool closing;
|
||||
QString ident;
|
||||
|
||||
QTimer *t;
|
||||
|
||||
QString key[POLL_KEYS];
|
||||
int key_n;
|
||||
|
||||
int polltime;
|
||||
};
|
||||
|
||||
HttpPoll::HttpPoll(QObject *parent)
|
||||
:ByteStream(parent)
|
||||
{
|
||||
d = new Private;
|
||||
|
||||
d->polltime = 30;
|
||||
d->t = new QTimer;
|
||||
connect(d->t, SIGNAL(timeout()), SLOT(do_sync()));
|
||||
|
||||
connect(&d->http, SIGNAL(result()), SLOT(http_result()));
|
||||
connect(&d->http, SIGNAL(error(int)), SLOT(http_error(int)));
|
||||
|
||||
reset(true);
|
||||
}
|
||||
|
||||
HttpPoll::~HttpPoll()
|
||||
{
|
||||
reset(true);
|
||||
delete d->t;
|
||||
delete d;
|
||||
}
|
||||
|
||||
void HttpPoll::reset(bool clear)
|
||||
{
|
||||
if(d->http.isActive())
|
||||
d->http.stop();
|
||||
if(clear)
|
||||
clearReadBuffer();
|
||||
clearWriteBuffer();
|
||||
d->out.resize(0);
|
||||
d->state = 0;
|
||||
d->closing = false;
|
||||
d->t->stop();
|
||||
}
|
||||
|
||||
void HttpPoll::setAuth(const QString &user, const QString &pass)
|
||||
{
|
||||
d->user = user;
|
||||
d->pass = pass;
|
||||
}
|
||||
|
||||
void HttpPoll::connectToUrl(const QString &url)
|
||||
{
|
||||
connectToHost("", 0, url);
|
||||
}
|
||||
|
||||
void HttpPoll::connectToHost(const QString &proxyHost, int proxyPort, const QString &url)
|
||||
{
|
||||
reset(true);
|
||||
|
||||
// using proxy?
|
||||
if(!proxyHost.isEmpty()) {
|
||||
d->host = proxyHost;
|
||||
d->port = proxyPort;
|
||||
d->url = url;
|
||||
d->use_proxy = true;
|
||||
}
|
||||
else {
|
||||
Q3Url u = url;
|
||||
d->host = u.host();
|
||||
if(u.hasPort())
|
||||
d->port = u.port();
|
||||
else
|
||||
d->port = 80;
|
||||
d->url = u.encodedPathAndQuery();
|
||||
d->use_proxy = false;
|
||||
}
|
||||
|
||||
resetKey();
|
||||
bool last;
|
||||
QString key = getKey(&last);
|
||||
|
||||
#ifdef PROX_DEBUG
|
||||
fprintf(stderr, "HttpPoll: Connecting to %s:%d [%s]", d->host.latin1(), d->port, d->url.latin1());
|
||||
if(d->user.isEmpty())
|
||||
fprintf(stderr, "\n");
|
||||
else
|
||||
fprintf(stderr, ", auth {%s,%s}\n", d->user.latin1(), d->pass.latin1());
|
||||
#endif
|
||||
QPointer<QObject> self = this;
|
||||
syncStarted();
|
||||
if(!self)
|
||||
return;
|
||||
|
||||
d->state = 1;
|
||||
d->http.setAuth(d->user, d->pass);
|
||||
d->http.post(d->host, d->port, d->url, makePacket("0", key, "", QByteArray()), d->use_proxy);
|
||||
}
|
||||
|
||||
QByteArray HttpPoll::makePacket(const QString &ident, const QString &key, const QString &newkey, const QByteArray &block)
|
||||
{
|
||||
QString str = ident;
|
||||
if(!key.isEmpty()) {
|
||||
str += ';';
|
||||
str += key;
|
||||
}
|
||||
if(!newkey.isEmpty()) {
|
||||
str += ';';
|
||||
str += newkey;
|
||||
}
|
||||
str += ',';
|
||||
Q3CString cs = str.latin1();
|
||||
int len = cs.length();
|
||||
|
||||
QByteArray a(len + block.size());
|
||||
memcpy(a.data(), cs.data(), len);
|
||||
memcpy(a.data() + len, block.data(), block.size());
|
||||
return a;
|
||||
}
|
||||
|
||||
int HttpPoll::pollInterval() const
|
||||
{
|
||||
return d->polltime;
|
||||
}
|
||||
|
||||
void HttpPoll::setPollInterval(int seconds)
|
||||
{
|
||||
d->polltime = seconds;
|
||||
}
|
||||
|
||||
bool HttpPoll::isOpen() const
|
||||
{
|
||||
return (d->state == 2 ? true: false);
|
||||
}
|
||||
|
||||
void HttpPoll::close()
|
||||
{
|
||||
if(d->state == 0 || d->closing)
|
||||
return;
|
||||
|
||||
if(bytesToWrite() == 0)
|
||||
reset();
|
||||
else
|
||||
d->closing = true;
|
||||
}
|
||||
|
||||
void HttpPoll::http_result()
|
||||
{
|
||||
// check for death :)
|
||||
QPointer<QObject> self = this;
|
||||
syncFinished();
|
||||
if(!self)
|
||||
return;
|
||||
|
||||
// get id and packet
|
||||
QString id;
|
||||
QString cookie = d->http.getHeader("Set-Cookie");
|
||||
int n = cookie.find("ID=");
|
||||
if(n == -1) {
|
||||
reset();
|
||||
error(ErrRead);
|
||||
return;
|
||||
}
|
||||
n += 3;
|
||||
int n2 = cookie.find(';', n);
|
||||
if(n2 != -1)
|
||||
id = cookie.mid(n, n2-n);
|
||||
else
|
||||
id = cookie.mid(n);
|
||||
QByteArray block = d->http.body();
|
||||
|
||||
// session error?
|
||||
if(id.right(2) == ":0") {
|
||||
if(id == "0:0" && d->state == 2) {
|
||||
reset();
|
||||
connectionClosed();
|
||||
return;
|
||||
}
|
||||
else {
|
||||
reset();
|
||||
error(ErrRead);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
d->ident = id;
|
||||
bool justNowConnected = false;
|
||||
if(d->state == 1) {
|
||||
d->state = 2;
|
||||
justNowConnected = true;
|
||||
}
|
||||
|
||||
// sync up again soon
|
||||
if(bytesToWrite() > 0 || !d->closing)
|
||||
d->t->start(d->polltime * 1000, true);
|
||||
|
||||
// connecting
|
||||
if(justNowConnected) {
|
||||
connected();
|
||||
}
|
||||
else {
|
||||
if(!d->out.isEmpty()) {
|
||||
int x = d->out.size();
|
||||
d->out.resize(0);
|
||||
takeWrite(x);
|
||||
bytesWritten(x);
|
||||
}
|
||||
}
|
||||
|
||||
if(!self)
|
||||
return;
|
||||
|
||||
if(!block.isEmpty()) {
|
||||
appendRead(block);
|
||||
readyRead();
|
||||
}
|
||||
|
||||
if(!self)
|
||||
return;
|
||||
|
||||
if(bytesToWrite() > 0) {
|
||||
do_sync();
|
||||
}
|
||||
else {
|
||||
if(d->closing) {
|
||||
reset();
|
||||
delayedCloseFinished();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HttpPoll::http_error(int x)
|
||||
{
|
||||
reset();
|
||||
if(x == HttpProxyPost::ErrConnectionRefused)
|
||||
error(ErrConnectionRefused);
|
||||
else if(x == HttpProxyPost::ErrHostNotFound)
|
||||
error(ErrHostNotFound);
|
||||
else if(x == HttpProxyPost::ErrSocket)
|
||||
error(ErrRead);
|
||||
else if(x == HttpProxyPost::ErrProxyConnect)
|
||||
error(ErrProxyConnect);
|
||||
else if(x == HttpProxyPost::ErrProxyNeg)
|
||||
error(ErrProxyNeg);
|
||||
else if(x == HttpProxyPost::ErrProxyAuth)
|
||||
error(ErrProxyAuth);
|
||||
}
|
||||
|
||||
int HttpPoll::tryWrite()
|
||||
{
|
||||
if(!d->http.isActive())
|
||||
do_sync();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void HttpPoll::do_sync()
|
||||
{
|
||||
if(d->http.isActive())
|
||||
return;
|
||||
|
||||
d->t->stop();
|
||||
d->out = takeWrite(0, false);
|
||||
|
||||
bool last;
|
||||
QString key = getKey(&last);
|
||||
QString newkey;
|
||||
if(last) {
|
||||
resetKey();
|
||||
newkey = getKey(&last);
|
||||
}
|
||||
|
||||
QPointer<QObject> self = this;
|
||||
syncStarted();
|
||||
if(!self)
|
||||
return;
|
||||
|
||||
d->http.post(d->host, d->port, d->url, makePacket(d->ident, key, newkey, d->out), d->use_proxy);
|
||||
}
|
||||
|
||||
void HttpPoll::resetKey()
|
||||
{
|
||||
#ifdef PROX_DEBUG
|
||||
fprintf(stderr, "HttpPoll: reset key!\n");
|
||||
#endif
|
||||
QByteArray a = randomArray(64);
|
||||
QString str = QString::fromLatin1(a.data(), a.size());
|
||||
|
||||
d->key_n = POLL_KEYS;
|
||||
for(int n = 0; n < POLL_KEYS; ++n)
|
||||
d->key[n] = hpk(n+1, str);
|
||||
}
|
||||
|
||||
const QString & HttpPoll::getKey(bool *last)
|
||||
{
|
||||
*last = false;
|
||||
--(d->key_n);
|
||||
if(d->key_n == 0)
|
||||
*last = true;
|
||||
return d->key[d->key_n];
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// HttpProxyPost
|
||||
//----------------------------------------------------------------------------
|
||||
static QString extractLine(QByteArray *buf, bool *found)
|
||||
{
|
||||
// scan for newline
|
||||
int n;
|
||||
for(n = 0; n < (int)buf->size()-1; ++n) {
|
||||
if(buf->at(n) == '\r' && buf->at(n+1) == '\n') {
|
||||
//Q3CString cstr;
|
||||
//cstr.resize(n+1);
|
||||
QByteArray cstr;
|
||||
cstr.resize(n);
|
||||
memcpy(cstr.data(), buf->data(), n);
|
||||
n += 2; // hack off CR/LF
|
||||
|
||||
memmove(buf->data(), buf->data() + n, buf->size() - n);
|
||||
buf->resize(buf->size() - n);
|
||||
QString s = QString::fromUtf8(cstr);
|
||||
|
||||
if(found)
|
||||
*found = true;
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
if(found)
|
||||
*found = false;
|
||||
return "";
|
||||
}
|
||||
|
||||
static bool extractMainHeader(const QString &line, QString *proto, int *code, QString *msg)
|
||||
{
|
||||
int n = line.find(' ');
|
||||
if(n == -1)
|
||||
return false;
|
||||
if(proto)
|
||||
*proto = line.mid(0, n);
|
||||
++n;
|
||||
int n2 = line.find(' ', n);
|
||||
if(n2 == -1)
|
||||
return false;
|
||||
if(code)
|
||||
*code = line.mid(n, n2-n).toInt();
|
||||
n = n2+1;
|
||||
if(msg)
|
||||
*msg = line.mid(n);
|
||||
return true;
|
||||
}
|
||||
|
||||
class HttpProxyPost::Private
|
||||
{
|
||||
public:
|
||||
Private() {}
|
||||
|
||||
BSocket sock;
|
||||
QByteArray postdata, recvBuf, body;
|
||||
QString url;
|
||||
QString user, pass;
|
||||
bool inHeader;
|
||||
QStringList headerLines;
|
||||
bool asProxy;
|
||||
QString host;
|
||||
};
|
||||
|
||||
HttpProxyPost::HttpProxyPost(QObject *parent)
|
||||
:QObject(parent)
|
||||
{
|
||||
d = new Private;
|
||||
connect(&d->sock, SIGNAL(connected()), SLOT(sock_connected()));
|
||||
connect(&d->sock, SIGNAL(connectionClosed()), SLOT(sock_connectionClosed()));
|
||||
connect(&d->sock, SIGNAL(readyRead()), SLOT(sock_readyRead()));
|
||||
connect(&d->sock, SIGNAL(error(int)), SLOT(sock_error(int)));
|
||||
reset(true);
|
||||
}
|
||||
|
||||
HttpProxyPost::~HttpProxyPost()
|
||||
{
|
||||
reset(true);
|
||||
delete d;
|
||||
}
|
||||
|
||||
void HttpProxyPost::reset(bool clear)
|
||||
{
|
||||
if(d->sock.state() != BSocket::Idle)
|
||||
d->sock.close();
|
||||
d->recvBuf.resize(0);
|
||||
if(clear)
|
||||
d->body.resize(0);
|
||||
}
|
||||
|
||||
void HttpProxyPost::setAuth(const QString &user, const QString &pass)
|
||||
{
|
||||
d->user = user;
|
||||
d->pass = pass;
|
||||
}
|
||||
|
||||
bool HttpProxyPost::isActive() const
|
||||
{
|
||||
return (d->sock.state() == BSocket::Idle ? false: true);
|
||||
}
|
||||
|
||||
void HttpProxyPost::post(const QString &proxyHost, int proxyPort, const QString &url, const QByteArray &data, bool asProxy)
|
||||
{
|
||||
reset(true);
|
||||
|
||||
d->host = proxyHost;
|
||||
d->url = url;
|
||||
d->postdata = data;
|
||||
d->asProxy = asProxy;
|
||||
|
||||
#ifdef PROX_DEBUG
|
||||
fprintf(stderr, "HttpProxyPost: Connecting to %s:%d", proxyHost.latin1(), proxyPort);
|
||||
if(d->user.isEmpty())
|
||||
fprintf(stderr, "\n");
|
||||
else
|
||||
fprintf(stderr, ", auth {%s,%s}\n", d->user.latin1(), d->pass.latin1());
|
||||
#endif
|
||||
d->sock.connectToHost(proxyHost, proxyPort);
|
||||
}
|
||||
|
||||
void HttpProxyPost::stop()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
QByteArray HttpProxyPost::body() const
|
||||
{
|
||||
return d->body;
|
||||
}
|
||||
|
||||
QString HttpProxyPost::getHeader(const QString &var) const
|
||||
{
|
||||
for(QStringList::ConstIterator it = d->headerLines.begin(); it != d->headerLines.end(); ++it) {
|
||||
const QString &s = *it;
|
||||
int n = s.find(": ");
|
||||
if(n == -1)
|
||||
continue;
|
||||
QString v = s.mid(0, n);
|
||||
if(v == var)
|
||||
return s.mid(n+2);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
void HttpProxyPost::sock_connected()
|
||||
{
|
||||
#ifdef PROX_DEBUG
|
||||
fprintf(stderr, "HttpProxyPost: Connected\n");
|
||||
#endif
|
||||
d->inHeader = true;
|
||||
d->headerLines.clear();
|
||||
|
||||
Q3Url u = d->url;
|
||||
|
||||
// connected, now send the request
|
||||
QString s;
|
||||
s += QString("POST ") + d->url + " HTTP/1.0\r\n";
|
||||
if(d->asProxy) {
|
||||
if(!d->user.isEmpty()) {
|
||||
QString str = d->user + ':' + d->pass;
|
||||
s += QString("Proxy-Authorization: Basic ") + QCA::Base64().encodeString(str) + "\r\n";
|
||||
}
|
||||
s += "Pragma: no-cache\r\n";
|
||||
s += QString("Host: ") + u.host() + "\r\n";
|
||||
}
|
||||
else {
|
||||
s += QString("Host: ") + d->host + "\r\n";
|
||||
}
|
||||
s += "Content-Type: application/x-www-form-urlencoded\r\n";
|
||||
s += QString("Content-Length: ") + QString::number(d->postdata.size()) + "\r\n";
|
||||
s += "\r\n";
|
||||
|
||||
// write request
|
||||
Q3CString cs = s.utf8();
|
||||
QByteArray block(cs.length());
|
||||
memcpy(block.data(), cs.data(), block.size());
|
||||
d->sock.write(block);
|
||||
|
||||
// write postdata
|
||||
d->sock.write(d->postdata);
|
||||
}
|
||||
|
||||
void HttpProxyPost::sock_connectionClosed()
|
||||
{
|
||||
d->body = d->recvBuf;
|
||||
reset();
|
||||
result();
|
||||
}
|
||||
|
||||
void HttpProxyPost::sock_readyRead()
|
||||
{
|
||||
QByteArray block = d->sock.read();
|
||||
ByteStream::appendArray(&d->recvBuf, block);
|
||||
|
||||
if(d->inHeader) {
|
||||
// grab available lines
|
||||
while(1) {
|
||||
bool found;
|
||||
QString line = extractLine(&d->recvBuf, &found);
|
||||
if(!found)
|
||||
break;
|
||||
if(line.isEmpty()) {
|
||||
d->inHeader = false;
|
||||
break;
|
||||
}
|
||||
d->headerLines += line;
|
||||
}
|
||||
|
||||
// done with grabbing the header?
|
||||
if(!d->inHeader) {
|
||||
QString str = d->headerLines.first();
|
||||
d->headerLines.remove(d->headerLines.begin());
|
||||
|
||||
QString proto;
|
||||
int code;
|
||||
QString msg;
|
||||
if(!extractMainHeader(str, &proto, &code, &msg)) {
|
||||
#ifdef PROX_DEBUG
|
||||
fprintf(stderr, "HttpProxyPost: invalid header!\n");
|
||||
#endif
|
||||
reset(true);
|
||||
error(ErrProxyNeg);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
#ifdef PROX_DEBUG
|
||||
fprintf(stderr, "HttpProxyPost: header proto=[%s] code=[%d] msg=[%s]\n", proto.latin1(), code, msg.latin1());
|
||||
for(QStringList::ConstIterator it = d->headerLines.begin(); it != d->headerLines.end(); ++it)
|
||||
fprintf(stderr, "HttpProxyPost: * [%s]\n", (*it).latin1());
|
||||
#endif
|
||||
}
|
||||
|
||||
if(code == 200) { // OK
|
||||
#ifdef PROX_DEBUG
|
||||
fprintf(stderr, "HttpProxyPost: << Success >>\n");
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
int err;
|
||||
QString errStr;
|
||||
if(code == 407) { // Authentication failed
|
||||
err = ErrProxyAuth;
|
||||
errStr = tr("Authentication failed");
|
||||
}
|
||||
else if(code == 404) { // Host not found
|
||||
err = ErrHostNotFound;
|
||||
errStr = tr("Host not found");
|
||||
}
|
||||
else if(code == 403) { // Access denied
|
||||
err = ErrProxyNeg;
|
||||
errStr = tr("Access denied");
|
||||
}
|
||||
else if(code == 503) { // Connection refused
|
||||
err = ErrConnectionRefused;
|
||||
errStr = tr("Connection refused");
|
||||
}
|
||||
else { // invalid reply
|
||||
err = ErrProxyNeg;
|
||||
errStr = tr("Invalid reply");
|
||||
}
|
||||
|
||||
#ifdef PROX_DEBUG
|
||||
fprintf(stderr, "HttpProxyPost: << Error >> [%s]\n", errStr.latin1());
|
||||
#endif
|
||||
reset(true);
|
||||
error(err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HttpProxyPost::sock_error(int x)
|
||||
{
|
||||
#ifdef PROX_DEBUG
|
||||
fprintf(stderr, "HttpProxyPost: socket error: %d\n", x);
|
||||
#endif
|
||||
reset(true);
|
||||
if(x == BSocket::ErrHostNotFound)
|
||||
error(ErrProxyConnect);
|
||||
else if(x == BSocket::ErrConnectionRefused)
|
||||
error(ErrProxyConnect);
|
||||
else if(x == BSocket::ErrRead)
|
||||
error(ErrProxyNeg);
|
||||
}
|
||||
|
||||
// CS_NAMESPACE_END
|
||||
104
iris-legacy/cutestuff/network/httppoll.h
Normal file
104
iris-legacy/cutestuff/network/httppoll.h
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* httppoll.h - HTTP polling proxy
|
||||
* Copyright (C) 2003 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CS_HTTPPOLL_H
|
||||
#define CS_HTTPPOLL_H
|
||||
|
||||
#include "bytestream.h"
|
||||
|
||||
// CS_NAMESPACE_BEGIN
|
||||
|
||||
class HttpPoll : public ByteStream
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum Error { ErrConnectionRefused = ErrCustom, ErrHostNotFound, ErrProxyConnect, ErrProxyNeg, ErrProxyAuth };
|
||||
HttpPoll(QObject *parent=0);
|
||||
~HttpPoll();
|
||||
|
||||
void setAuth(const QString &user, const QString &pass="");
|
||||
void connectToUrl(const QString &url);
|
||||
void connectToHost(const QString &proxyHost, int proxyPort, const QString &url);
|
||||
|
||||
int pollInterval() const;
|
||||
void setPollInterval(int seconds);
|
||||
|
||||
// from ByteStream
|
||||
bool isOpen() const;
|
||||
void close();
|
||||
|
||||
signals:
|
||||
void connected();
|
||||
void syncStarted();
|
||||
void syncFinished();
|
||||
|
||||
protected:
|
||||
int tryWrite();
|
||||
|
||||
private slots:
|
||||
void http_result();
|
||||
void http_error(int);
|
||||
void do_sync();
|
||||
|
||||
private:
|
||||
class Private;
|
||||
Private *d;
|
||||
|
||||
void reset(bool clear=false);
|
||||
QByteArray makePacket(const QString &ident, const QString &key, const QString &newkey, const QByteArray &block);
|
||||
void resetKey();
|
||||
const QString & getKey(bool *);
|
||||
};
|
||||
|
||||
class HttpProxyPost : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum Error { ErrConnectionRefused, ErrHostNotFound, ErrSocket, ErrProxyConnect, ErrProxyNeg, ErrProxyAuth };
|
||||
HttpProxyPost(QObject *parent=0);
|
||||
~HttpProxyPost();
|
||||
|
||||
void setAuth(const QString &user, const QString &pass="");
|
||||
bool isActive() const;
|
||||
void post(const QString &proxyHost, int proxyPort, const QString &url, const QByteArray &data, bool asProxy=true);
|
||||
void stop();
|
||||
QByteArray body() const;
|
||||
QString getHeader(const QString &) const;
|
||||
|
||||
signals:
|
||||
void result();
|
||||
void error(int);
|
||||
|
||||
private slots:
|
||||
void sock_connected();
|
||||
void sock_connectionClosed();
|
||||
void sock_readyRead();
|
||||
void sock_error(int);
|
||||
|
||||
private:
|
||||
class Private;
|
||||
Private *d;
|
||||
|
||||
void reset(bool clear=false);
|
||||
};
|
||||
|
||||
// CS_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
1231
iris-legacy/cutestuff/network/socks.cpp
Normal file
1231
iris-legacy/cutestuff/network/socks.cpp
Normal file
File diff suppressed because it is too large
Load diff
160
iris-legacy/cutestuff/network/socks.h
Normal file
160
iris-legacy/cutestuff/network/socks.h
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
/*
|
||||
* socks.h - SOCKS5 TCP proxy client/server
|
||||
* Copyright (C) 2003 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CS_SOCKS_H
|
||||
#define CS_SOCKS_H
|
||||
|
||||
#include "bytestream.h"
|
||||
|
||||
// CS_NAMESPACE_BEGIN
|
||||
|
||||
class QHostAddress;
|
||||
class SocksClient;
|
||||
class SocksServer;
|
||||
|
||||
class SocksUDP : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
~SocksUDP();
|
||||
|
||||
void change(const QString &host, int port);
|
||||
void write(const QByteArray &data);
|
||||
|
||||
signals:
|
||||
void packetReady(const QByteArray &data);
|
||||
|
||||
private slots:
|
||||
void sn_activated(int);
|
||||
|
||||
private:
|
||||
class Private;
|
||||
Private *d;
|
||||
|
||||
friend class SocksClient;
|
||||
SocksUDP(SocksClient *sc, const QString &host, int port, const QHostAddress &routeAddr, int routePort);
|
||||
};
|
||||
|
||||
class SocksClient : public ByteStream
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum Error { ErrConnectionRefused = ErrCustom, ErrHostNotFound, ErrProxyConnect, ErrProxyNeg, ErrProxyAuth };
|
||||
enum Method { AuthNone=0x0001, AuthUsername=0x0002 };
|
||||
enum Request { ReqConnect, ReqUDPAssociate };
|
||||
SocksClient(QObject *parent=0);
|
||||
SocksClient(int, QObject *parent=0);
|
||||
~SocksClient();
|
||||
|
||||
bool isIncoming() const;
|
||||
|
||||
// outgoing
|
||||
void setAuth(const QString &user, const QString &pass="");
|
||||
void connectToHost(const QString &proxyHost, int proxyPort, const QString &host, int port, bool udpMode=false);
|
||||
|
||||
// incoming
|
||||
void chooseMethod(int);
|
||||
void authGrant(bool);
|
||||
void requestDeny();
|
||||
void grantConnect();
|
||||
void grantUDPAssociate(const QString &relayHost, int relayPort);
|
||||
|
||||
// from ByteStream
|
||||
bool isOpen() const;
|
||||
void close();
|
||||
void write(const QByteArray &);
|
||||
QByteArray read(int bytes=0);
|
||||
int bytesAvailable() const;
|
||||
int bytesToWrite() const;
|
||||
|
||||
// remote address
|
||||
QHostAddress peerAddress() const;
|
||||
Q_UINT16 peerPort() const;
|
||||
|
||||
// udp
|
||||
QString udpAddress() const;
|
||||
Q_UINT16 udpPort() const;
|
||||
SocksUDP *createUDP(const QString &host, int port, const QHostAddress &routeAddr, int routePort);
|
||||
|
||||
signals:
|
||||
// outgoing
|
||||
void connected();
|
||||
|
||||
// incoming
|
||||
void incomingMethods(int);
|
||||
void incomingAuth(const QString &user, const QString &pass);
|
||||
void incomingConnectRequest(const QString &host, int port);
|
||||
void incomingUDPAssociateRequest();
|
||||
|
||||
private slots:
|
||||
void sock_connected();
|
||||
void sock_connectionClosed();
|
||||
void sock_delayedCloseFinished();
|
||||
void sock_readyRead();
|
||||
void sock_bytesWritten(int);
|
||||
void sock_error(int);
|
||||
void serve();
|
||||
|
||||
private:
|
||||
class Private;
|
||||
Private *d;
|
||||
|
||||
void init();
|
||||
void reset(bool clear=false);
|
||||
void do_request();
|
||||
void processOutgoing(const QByteArray &);
|
||||
void processIncoming(const QByteArray &);
|
||||
void continueIncoming();
|
||||
void writeData(const QByteArray &a);
|
||||
};
|
||||
|
||||
class SocksServer : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SocksServer(QObject *parent=0);
|
||||
~SocksServer();
|
||||
|
||||
bool isActive() const;
|
||||
bool listen(Q_UINT16 port, bool udp=false);
|
||||
void stop();
|
||||
int port() const;
|
||||
QHostAddress address() const;
|
||||
SocksClient *takeIncoming();
|
||||
|
||||
void writeUDP(const QHostAddress &addr, int port, const QByteArray &data);
|
||||
|
||||
signals:
|
||||
void incomingReady();
|
||||
void incomingUDP(const QString &host, int port, const QHostAddress &addr, int sourcePort, const QByteArray &data);
|
||||
|
||||
private slots:
|
||||
void connectionReady(int);
|
||||
void connectionError();
|
||||
void sn_activated(int);
|
||||
|
||||
private:
|
||||
class Private;
|
||||
Private *d;
|
||||
};
|
||||
|
||||
// CS_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
269
iris-legacy/cutestuff/util/bytestream.cpp
Normal file
269
iris-legacy/cutestuff/util/bytestream.cpp
Normal file
|
|
@ -0,0 +1,269 @@
|
|||
/*
|
||||
* bytestream.cpp - base class for bytestreams
|
||||
* Copyright (C) 2003 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "bytestream.h"
|
||||
//Added by qt3to4:
|
||||
#include <Q3CString>
|
||||
|
||||
// CS_NAMESPACE_BEGIN
|
||||
|
||||
//! \class ByteStream bytestream.h
|
||||
//! \brief Base class for "bytestreams"
|
||||
//!
|
||||
//! This class provides a basic framework for a "bytestream", here defined
|
||||
//! as a bi-directional, asynchronous pipe of data. It can be used to create
|
||||
//! several different kinds of bytestream-applications, such as a console or
|
||||
//! TCP connection, or something more abstract like a security layer or tunnel,
|
||||
//! all with the same interface. The provided functions make creating such
|
||||
//! classes simpler. ByteStream is a pure-virtual class, so you do not use it
|
||||
//! on its own, but instead through a subclass such as \a BSocket.
|
||||
//!
|
||||
//! The signals connectionClosed(), delayedCloseFinished(), readyRead(),
|
||||
//! bytesWritten(), and error() serve the exact same function as those from
|
||||
//! <A HREF="http://doc.trolltech.com/3.1/qsocket.html">QSocket</A>.
|
||||
//!
|
||||
//! The simplest way to create a ByteStream is to reimplement isOpen(), close(),
|
||||
//! and tryWrite(). Call appendRead() whenever you want to make data available for
|
||||
//! reading. ByteStream will take care of the buffers with regards to the caller,
|
||||
//! and will call tryWrite() when the write buffer gains data. It will be your
|
||||
//! job to call tryWrite() whenever it is acceptable to write more data to
|
||||
//! the underlying system.
|
||||
//!
|
||||
//! If you need more advanced control, reimplement read(), write(), bytesAvailable(),
|
||||
//! and/or bytesToWrite() as necessary.
|
||||
//!
|
||||
//! Use appendRead(), appendWrite(), takeRead(), and takeWrite() to modify the
|
||||
//! buffers. If you have more advanced requirements, the buffers can be accessed
|
||||
//! directly with readBuf() and writeBuf().
|
||||
//!
|
||||
//! Also available are the static convenience functions ByteStream::appendArray()
|
||||
//! and ByteStream::takeArray(), which make dealing with byte queues very easy.
|
||||
|
||||
class ByteStream::Private
|
||||
{
|
||||
public:
|
||||
Private() {}
|
||||
|
||||
QByteArray readBuf, writeBuf;
|
||||
};
|
||||
|
||||
//!
|
||||
//! Constructs a ByteStream object with parent \a parent.
|
||||
ByteStream::ByteStream(QObject *parent)
|
||||
:QObject(parent)
|
||||
{
|
||||
d = new Private;
|
||||
}
|
||||
|
||||
//!
|
||||
//! Destroys the object and frees allocated resources.
|
||||
ByteStream::~ByteStream()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
//!
|
||||
//! Returns TRUE if the stream is open, meaning that you can write to it.
|
||||
bool ByteStream::isOpen() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//!
|
||||
//! Closes the stream. If there is data in the write buffer then it will be
|
||||
//! written before actually closing the stream. Once all data has been written,
|
||||
//! the delayedCloseFinished() signal will be emitted.
|
||||
//! \sa delayedCloseFinished()
|
||||
void ByteStream::close()
|
||||
{
|
||||
}
|
||||
|
||||
//!
|
||||
//! Writes array \a a to the stream.
|
||||
void ByteStream::write(const QByteArray &a)
|
||||
{
|
||||
if(!isOpen())
|
||||
return;
|
||||
|
||||
bool doWrite = bytesToWrite() == 0 ? true: false;
|
||||
appendWrite(a);
|
||||
if(doWrite)
|
||||
tryWrite();
|
||||
}
|
||||
|
||||
//!
|
||||
//! Reads bytes \a bytes of data from the stream and returns them as an array. If \a bytes is 0, then
|
||||
//! \a read will return all available data.
|
||||
QByteArray ByteStream::read(int bytes)
|
||||
{
|
||||
return takeRead(bytes);
|
||||
}
|
||||
|
||||
//!
|
||||
//! Returns the number of bytes available for reading.
|
||||
int ByteStream::bytesAvailable() const
|
||||
{
|
||||
return d->readBuf.size();
|
||||
}
|
||||
|
||||
//!
|
||||
//! Returns the number of bytes that are waiting to be written.
|
||||
int ByteStream::bytesToWrite() const
|
||||
{
|
||||
return d->writeBuf.size();
|
||||
}
|
||||
|
||||
//!
|
||||
//! Writes string \a cs to the stream.
|
||||
void ByteStream::write(const Q3CString &cs)
|
||||
{
|
||||
QByteArray block(cs.length());
|
||||
memcpy(block.data(), cs.data(), block.size());
|
||||
write(block);
|
||||
}
|
||||
|
||||
//!
|
||||
//! Clears the read buffer.
|
||||
void ByteStream::clearReadBuffer()
|
||||
{
|
||||
d->readBuf.resize(0);
|
||||
}
|
||||
|
||||
//!
|
||||
//! Clears the write buffer.
|
||||
void ByteStream::clearWriteBuffer()
|
||||
{
|
||||
d->writeBuf.resize(0);
|
||||
}
|
||||
|
||||
//!
|
||||
//! Appends \a block to the end of the read buffer.
|
||||
void ByteStream::appendRead(const QByteArray &block)
|
||||
{
|
||||
appendArray(&d->readBuf, block);
|
||||
}
|
||||
|
||||
//!
|
||||
//! Appends \a block to the end of the write buffer.
|
||||
void ByteStream::appendWrite(const QByteArray &block)
|
||||
{
|
||||
appendArray(&d->writeBuf, block);
|
||||
}
|
||||
|
||||
//!
|
||||
//! Returns \a size bytes from the start of the read buffer.
|
||||
//! If \a size is 0, then all available data will be returned.
|
||||
//! If \a del is TRUE, then the bytes are also removed.
|
||||
QByteArray ByteStream::takeRead(int size, bool del)
|
||||
{
|
||||
return takeArray(&d->readBuf, size, del);
|
||||
}
|
||||
|
||||
//!
|
||||
//! Returns \a size bytes from the start of the write buffer.
|
||||
//! If \a size is 0, then all available data will be returned.
|
||||
//! If \a del is TRUE, then the bytes are also removed.
|
||||
QByteArray ByteStream::takeWrite(int size, bool del)
|
||||
{
|
||||
return takeArray(&d->writeBuf, size, del);
|
||||
}
|
||||
|
||||
//!
|
||||
//! Returns a reference to the read buffer.
|
||||
QByteArray & ByteStream::readBuf()
|
||||
{
|
||||
return d->readBuf;
|
||||
}
|
||||
|
||||
//!
|
||||
//! Returns a reference to the write buffer.
|
||||
QByteArray & ByteStream::writeBuf()
|
||||
{
|
||||
return d->writeBuf;
|
||||
}
|
||||
|
||||
//!
|
||||
//! Attempts to try and write some bytes from the write buffer, and returns the number
|
||||
//! successfully written or -1 on error. The default implementation returns -1.
|
||||
int ByteStream::tryWrite()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
//!
|
||||
//! Append array \a b to the end of the array pointed to by \a a.
|
||||
void ByteStream::appendArray(QByteArray *a, const QByteArray &b)
|
||||
{
|
||||
int oldsize = a->size();
|
||||
a->resize(oldsize + b.size());
|
||||
memcpy(a->data() + oldsize, b.data(), b.size());
|
||||
}
|
||||
|
||||
//!
|
||||
//! Returns \a size bytes from the start of the array pointed to by \a from.
|
||||
//! If \a size is 0, then all available data will be returned.
|
||||
//! If \a del is TRUE, then the bytes are also removed.
|
||||
QByteArray ByteStream::takeArray(QByteArray *from, int size, bool del)
|
||||
{
|
||||
QByteArray a;
|
||||
if(size == 0) {
|
||||
a = *from;
|
||||
if(del)
|
||||
from->resize(0);
|
||||
}
|
||||
else {
|
||||
if(size > (int)from->size())
|
||||
size = from->size();
|
||||
a.resize(size);
|
||||
char *r = from->data();
|
||||
memcpy(a.data(), r, size);
|
||||
if(del) {
|
||||
int newsize = from->size()-size;
|
||||
memmove(r, r+size, newsize);
|
||||
from->resize(newsize);
|
||||
}
|
||||
}
|
||||
return a;
|
||||
}
|
||||
void connectionClosed();
|
||||
void delayedCloseFinished();
|
||||
void readyRead();
|
||||
void bytesWritten(int);
|
||||
void error(int);
|
||||
|
||||
//! \fn void ByteStream::connectionClosed()
|
||||
//! This signal is emitted when the remote end of the stream closes.
|
||||
|
||||
//! \fn void ByteStream::delayedCloseFinished()
|
||||
//! This signal is emitted when all pending data has been written to the stream
|
||||
//! after an attempt to close.
|
||||
|
||||
//! \fn void ByteStream::readyRead()
|
||||
//! This signal is emitted when data is available to be read.
|
||||
|
||||
//! \fn void ByteStream::bytesWritten(int x);
|
||||
//! This signal is emitted when data has been successfully written to the stream.
|
||||
//! \a x is the number of bytes written.
|
||||
|
||||
//! \fn void ByteStream::error(int code)
|
||||
//! This signal is emitted when an error occurs in the stream. The reason for
|
||||
//! error is indicated by \a code.
|
||||
|
||||
// CS_NAMESPACE_END
|
||||
78
iris-legacy/cutestuff/util/bytestream.h
Normal file
78
iris-legacy/cutestuff/util/bytestream.h
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* bytestream.h - base class for bytestreams
|
||||
* Copyright (C) 2003 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CS_BYTESTREAM_H
|
||||
#define CS_BYTESTREAM_H
|
||||
|
||||
#include <qobject.h>
|
||||
#include <q3cstring.h>
|
||||
|
||||
// CS_NAMESPACE_BEGIN
|
||||
|
||||
// CS_EXPORT_BEGIN
|
||||
class ByteStream : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum Error { ErrRead, ErrWrite, ErrCustom = 10 };
|
||||
ByteStream(QObject *parent=0);
|
||||
virtual ~ByteStream()=0;
|
||||
|
||||
virtual bool isOpen() const;
|
||||
virtual void close();
|
||||
virtual void write(const QByteArray &);
|
||||
virtual QByteArray read(int bytes=0);
|
||||
virtual int bytesAvailable() const;
|
||||
virtual int bytesToWrite() const;
|
||||
|
||||
void write(const Q3CString &);
|
||||
|
||||
static void appendArray(QByteArray *a, const QByteArray &b);
|
||||
static QByteArray takeArray(QByteArray *from, int size=0, bool del=true);
|
||||
|
||||
signals:
|
||||
void connectionClosed();
|
||||
void delayedCloseFinished();
|
||||
void readyRead();
|
||||
void bytesWritten(int);
|
||||
void error(int);
|
||||
|
||||
protected:
|
||||
void clearReadBuffer();
|
||||
void clearWriteBuffer();
|
||||
void appendRead(const QByteArray &);
|
||||
void appendWrite(const QByteArray &);
|
||||
QByteArray takeRead(int size=0, bool del=true);
|
||||
QByteArray takeWrite(int size=0, bool del=true);
|
||||
QByteArray & readBuf();
|
||||
QByteArray & writeBuf();
|
||||
virtual int tryWrite();
|
||||
|
||||
private:
|
||||
//! \if _hide_doc_
|
||||
class Private;
|
||||
Private *d;
|
||||
//! \endif
|
||||
};
|
||||
// CS_EXPORT_END
|
||||
|
||||
// CS_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
Reference in a new issue