aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Szymon Tomasz Stefanek2010-12-30 02:45:58 +0000
committerGravatar Szymon Tomasz Stefanek2010-12-30 02:45:58 +0000
commitd703e48f497a2ae17205373a8345586c693808aa (patch)
tree3311c262df9a89e6334259b84b6914fa55b21568
parentquick fix (diff)
downloadKVIrc-d703e48f497a2ae17205373a8345586c693808aa.tar.gz
KVIrc-d703e48f497a2ae17205373a8345586c693808aa.tar.bz2
KVIrc-d703e48f497a2ae17205373a8345586c693808aa.zip
The http request now uses Qt sockets.
git-svn-id: https://svn.kvirc.de/svn/trunk/kvirc@5269 17fca916-40b9-46aa-a4ea-0a15b648b75c
-rw-r--r--src/kvilib/net/KviHttpRequest.cpp544
-rw-r--r--src/kvilib/net/KviHttpRequest.h32
-rw-r--r--src/kvilib/net/KviHttpRequestThread.cpp619
-rw-r--r--src/kvilib/net/KviHttpRequestThread.h100
-rw-r--r--src/kvilib/net/KviUrl.cpp2
-rw-r--r--src/kvirc/ui/KviStatusBarApplet.cpp2
-rw-r--r--src/modules/http/httpfiletransfer.cpp12
7 files changed, 375 insertions, 936 deletions
diff --git a/src/kvilib/net/KviHttpRequest.cpp b/src/kvilib/net/KviHttpRequest.cpp
index 4f605d6c5..14febe034 100644
--- a/src/kvilib/net/KviHttpRequest.cpp
+++ b/src/kvilib/net/KviHttpRequest.cpp
@@ -22,8 +22,6 @@
//
//=============================================================================
-#include <QDir>
-#include <QTimer>
//#include <zlib.h>
#include "KviHttpRequest.h"
@@ -35,17 +33,38 @@
#include "kvi_debug.h"
#include "KviTimeUtils.h"
#include "KviDataBuffer.h"
+#include "KviFile.h"
+
+#include <QTcpSocket>
+#include <QSslSocket>
+#include <QTimer>
+#include <QDir>
+#include <QHostAddress>
+
+class KviHttpRequestPrivate
+{
+public:
+ QTcpSocket * pSocket;
+ bool bIsSSL;
+ KviDataBuffer * pBuffer;
+ QTimer * pConnectTimeoutTimer;
+ KviFile * pFile;
+};
+
KviHttpRequest::KviHttpRequest()
: QObject()
{
- m_pDns = 0;
- m_pThread = 0;
- m_pFile = 0;
+ m_p = new KviHttpRequestPrivate();
+ m_p->pSocket = NULL;
+ m_p->bIsSSL = false;
+ m_p->pConnectTimeoutTimer = NULL;
+ m_p->pBuffer = new KviDataBuffer();
+ m_p->pFile = NULL;
+
m_pPrivateData = 0;
m_bHeaderProcessed = false;
- m_pBuffer = new KviDataBuffer();
m_uConnectionTimeout = 60;
resetStatus();
@@ -55,7 +74,14 @@ KviHttpRequest::KviHttpRequest()
KviHttpRequest::~KviHttpRequest()
{
resetInternalStatus();
- delete m_pBuffer;
+
+ KVI_ASSERT(!(m_p->pSocket));
+ KVI_ASSERT(!(m_p->pFile));
+
+ if(m_p->pBuffer)
+ delete m_p->pBuffer;
+
+ delete m_p;
}
void KviHttpRequest::abort()
@@ -67,18 +93,23 @@ void KviHttpRequest::abort()
void KviHttpRequest::resetInternalStatus()
{
- if(m_pThread)delete m_pThread;
- if(m_pDns)delete m_pDns;
+ if(m_p->pConnectTimeoutTimer)
+ {
+ delete m_p->pConnectTimeoutTimer;
+ m_p->pConnectTimeoutTimer = NULL;
+ }
- m_pDns = 0;
- m_pThread = 0;
+ if(m_p->pSocket)
+ closeSocket();
- if(!m_pFile)return;
- m_pFile->close();
- delete m_pFile;
- m_pFile = 0;
+ if(m_p->pFile)
+ {
+ m_p->pFile->close();
+ delete m_p->pFile;
+ m_p->pFile = NULL;
+ }
- m_pBuffer->clear();
+ m_p->pBuffer->clear();
m_bHeaderProcessed = false;
KviThreadManager::killPendingEvents(this);
@@ -154,73 +185,249 @@ bool KviHttpRequest::start()
return false;
}
- if(!KviQString::equalCI(m_url.protocol(),"http") && !KviQString::equalCI(m_url.protocol(),"https"))
+ m_p->bIsSSL = KviQString::equalCI(m_url.protocol(),"https");
+
+ if(!KviQString::equalCI(m_url.protocol(),"http") && !m_p->bIsSSL)
{
resetInternalStatus();
m_szLastError=__tr2qs("Unsupported protocol %1").arg(m_url.protocol());
return false;
}
- if(KviNetUtils::isValidStringIp(m_url.host()))
+ return doConnect();
+}
+
+void KviHttpRequest::closeSocket()
+{
+ if(!m_p->pSocket)
+ return;
+
+ QObject::disconnect(m_p->pSocket,SIGNAL(connected()),this,SLOT(slotSocketConnected()));
+ QObject::disconnect(m_p->pSocket,SIGNAL(disconnected()),this,SLOT(slotSocketDisconnected()));
+ QObject::disconnect(m_p->pSocket,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(slotSocketError(QAbstractSocket::SocketError)));
+
+ m_p->pSocket->abort();
+ m_p->pSocket->close();
+
+ // This can be called from a socket handler slot
+ m_p->pSocket->deleteLater();
+
+ //delete m_p->pSocket;
+
+ m_p->pSocket = NULL;
+}
+
+void KviHttpRequest::slotSocketDisconnected()
+{
+ switch(m_eProcessingType)
{
- m_szIp = m_url.host();
- QTimer::singleShot(10,this,SLOT(haveServerIp()));
- return true;
+ case WholeFile:
+ // happens always
+ emit binaryData(*m_p->pBuffer);
+ break;
+ case Blocks:
+ // an unprocessed block ?.. should never happend.. but well :D
+ if(m_p->pBuffer->size() > 0)
+ emit binaryData(*m_p->pBuffer);
+ break;
+ case Lines:
+ if(m_p->pBuffer->size() > 0)
+ {
+ // something left in the buffer and has no trailing LF
+ KviCString tmp((const char *)(m_p->pBuffer->data()),m_p->pBuffer->size());
+ emit data(tmp);
+ }
+ break;
+ case StoreToFile:
+ // same as above... should never happen.. but well :D
+ if(m_p->pFile && m_p->pBuffer->size() > 0)
+ m_p->pFile->write((const char *)(m_p->pBuffer->data()),m_p->pBuffer->size());
+ break;
+ default:
+ // nothing... just make gcc happy
+ break;
}
-
- return startDnsLookup();
+ resetInternalStatus();
+ m_szLastError = __tr2qs("Success");
+ emit terminated(true);
}
-bool KviHttpRequest::startDnsLookup()
+void KviHttpRequest::slotSocketConnected()
{
- m_pDns = new KviDnsResolver();
- connect(m_pDns,SIGNAL(lookupDone(KviDnsResolver *)),this,SLOT(dnsLookupDone(KviDnsResolver *)));
+ if(m_p->pConnectTimeoutTimer)
+ {
+ delete m_p->pConnectTimeoutTimer;
+ m_p->pConnectTimeoutTimer = NULL;
+ }
- if(!m_pDns->lookup(m_url.host(),KviDnsResolver::IPv4))
+ emit connectionEstabilished();
+ emit status(
+ __tr2qs("Connected to %1:%2: sending request")
+ .arg(m_p->pSocket->peerAddress().toString())
+ .arg(m_p->pSocket->peerPort())
+ );
+
+ KviCString szMethod;
+
+ bool bIsPost = false;
+
+ if(m_eProcessingType == HeadersOnly)
+ szMethod = "HEAD";
+ else if(m_szPostData.isEmpty())
+ szMethod = "GET";
+ else {
+ szMethod = "POST";
+ bIsPost = true;
+ }
+
+ KviCString szRequest(
+ KviCString::Format,
+ "%s %s HTTP/1.1\r\n" \
+ "Host: %s\r\n" \
+ "Connection: Close\r\n" \
+ "User-Agent: KVIrc-http-slave/1.0.0\r\n" \
+ "Accept: */*\r\n",
+ szMethod.ptr(),
+ KviQString::toUtf8(m_url.path()).data(),
+ KviQString::toUtf8(m_url.host()).data()
+ );
+
+ if(m_uContentOffset > 0)
+ szRequest.append(KviCString::Format,"Range: bytes=%u-\r\n",m_uContentOffset);
+
+ if(bIsPost)
+ {
+ szRequest.append(KviCString::Format,"Content-Type: application/x-www-form-urlencoded\r\n" \
+ "Content-Length: %u\r\n" \
+ "Cache-control: no-cache\r\n" \
+ "Pragma: no-cache\r\n",m_szPostData.length());
+ }
+
+ szRequest += "\r\n";
+
+ if(bIsPost)
+ {
+ if(!m_szPostData.isEmpty())
+ szRequest.append(m_szPostData);
+ szRequest += "\r\n";
+ }
+
+ // FIXME: Handle this better!
+ int written = m_p->pSocket->write(szRequest.ptr(),szRequest.len());
+ if(written < szRequest.len())
{
+ m_szLastError = __tr2qs("Socket write error");
resetInternalStatus();
- m_szLastError = __tr2qs("Unable to start the DNS lookup");
- return false;
+ emit terminated(false);
}
- QString tmp;
- KviQString::sprintf(tmp,__tr2qs("Looking up host %Q"),&(m_url.host()));
- emit status(tmp); // FIXME
+ // FIXME: Handle this better
+ QString req = QString::fromAscii(szRequest.ptr());
+ QStringList sl = req.split("\r\n");
+ emit requestSent(sl);
- emit resolvingHost(m_url.host());
+ // now wait for the response
- return true;
+ // FIXME: Handle read timeouts!
}
-void KviHttpRequest::dnsLookupDone(KviDnsResolver *d)
+void KviHttpRequest::slotSocketReadDataReady()
{
- if(d->state() == KviDnsResolver::Success)
+ KVI_ASSERT(m_p->pSocket);
+
+ int iBytes = m_p->pSocket->bytesAvailable();
+
+ if(iBytes <= 0)
{
- m_szIp = d->firstIpAddress();
- delete m_pDns;
- m_pDns = 0;
- QString tmp;
- KviQString::sprintf(tmp,__tr2qs("Host %Q resolved to %Q"),&(m_url.host()),&m_szIp);
- emit status(tmp);
- haveServerIp();
- } else {
- resetInternalStatus();
- m_szLastError = KviError::getDescription(d->error());
- emit terminated(false);
+ // assume connection closed ?
+ slotSocketDisconnected();
+ return;
}
+
+ // FIXME: Avoid double-buffering here!
+
+ KviDataBuffer oBuffer(iBytes);
+
+ int iRead = m_p->pSocket->read((char *)(oBuffer.data()),iBytes);
+ if(iRead < iBytes)
+ {
+ // hum.... what here ?
+ if(iRead < 1)
+ {
+ slotSocketDisconnected();
+ return;
+ }
+
+ // FIXME
+ // well... otherwise just wait.
+ // FIXME ?
+ oBuffer.resize(iRead);
+ }
+
+ processData(&oBuffer);
+}
+
+void KviHttpRequest::slotSocketError(QAbstractSocket::SocketError eError)
+{
+ KVI_ASSERT(m_p->pSocket);
+
+ if(eError == QAbstractSocket::RemoteHostClosedError)
+ {
+ slotSocketDisconnected();
+ return;
+ }
+
+ m_szLastError = m_p->pSocket->errorString();
+ resetInternalStatus();
+ emit terminated(false);
+}
+
+void KviHttpRequest::slotConnectionTimedOut()
+{
+ resetInternalStatus();
+ m_szLastError = __tr2qs("Connection timed out");
+ emit terminated(false);
}
-void KviHttpRequest::haveServerIp()
+bool KviHttpRequest::doConnect()
{
unsigned short uPort = m_url.port();
- if(uPort == 0)uPort = 80;
+ if(uPort == 0)
+ uPort = m_p->bIsSSL ? 443 : 80;
- QString tmp;
- KviQString::sprintf(tmp,"%Q:%u",&m_szIp,uPort);
- emit contactingHost(tmp);
+ emit contactingHost(QString::fromAscii("%1:%2").arg(m_url.host()).arg(uPort));
+
+ if(m_p->pSocket)
+ closeSocket();
- if(m_pThread)delete m_pThread;
+ m_p->pSocket = m_p->bIsSSL ? new QSslSocket() : new QTcpSocket();
+ QObject::connect(m_p->pSocket,SIGNAL(connected()),this,SLOT(slotSocketConnected()));
+ QObject::connect(m_p->pSocket,SIGNAL(disconnected()),this,SLOT(slotSocketDisconnected()));
+ QObject::connect(m_p->pSocket,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(slotSocketError(QAbstractSocket::SocketError)));
+ QObject::connect(m_p->pSocket,SIGNAL(readyRead()),this,SLOT(slotSocketReadDataReady()));
+
+ if(m_p->bIsSSL)
+ {
+ static_cast<QSslSocket *>(m_p->pSocket)->setProtocol(QSsl::AnyProtocol);
+ static_cast<QSslSocket *>(m_p->pSocket)->connectToHostEncrypted(m_url.host(),uPort);
+ } else {
+ m_p->pSocket->connectToHost(m_url.host(),uPort);
+ }
+
+ if(m_p->pConnectTimeoutTimer)
+ {
+ delete m_p->pConnectTimeoutTimer;
+ m_p->pConnectTimeoutTimer = NULL;
+ }
+
+ m_p->pConnectTimeoutTimer = new QTimer();
+ m_p->pConnectTimeoutTimer->setSingleShot(true);
+ QObject::connect(m_p->pConnectTimeoutTimer,SIGNAL(timeout()),this,SLOT(slotConnectionTimedOut()));
+
+ m_p->pConnectTimeoutTimer->start(m_uConnectionTimeout * 1000);
+
+ /*
m_pThread = new KviHttpRequestThread(
this,
m_url.host(),
@@ -232,109 +439,11 @@ void KviHttpRequest::haveServerIp()
m_szPostData,
m_url.protocol()=="https"
);
+ */
- m_pThread->setConnectionTimeout(m_uConnectionTimeout);
-
- if(!m_pThread->start())
- {
- resetInternalStatus();
- m_szLastError = __tr2qs("Unable to start the request slave thread");
- emit terminated(false);
- return;
- }
-
- KviQString::sprintf(tmp,__tr2qs("Contacting host %Q on port %u"),&m_szIp,uPort);
- emit status(tmp);
-}
-
-bool KviHttpRequest::event(QEvent *e)
-{
- if(e->type() == KVI_THREAD_EVENT)
- {
- switch(((KviThreadEvent *)e)->id())
- {
- case KVI_THREAD_EVENT_BINARYDATA:
- {
- KviDataBuffer * b = ((KviThreadDataEvent<KviDataBuffer> *)e)->getData();
- processData(b);
- delete b;
- return true;
- }
- break;
- case KVI_HTTP_REQUEST_THREAD_EVENT_CONNECTED:
- emit connectionEstabilished();
- emit status(__tr2qs("Connection established, sending request"));
- return true;
- break;
- case KVI_HTTP_REQUEST_THREAD_EVENT_REQUESTSENT:
- {
- QString * req = ((KviThreadDataEvent<QString> *)e)->getData();
- QStringList sl = req->split("\r\n");
- emit requestSent(sl);
- delete req;
- return true;
- }
- break;
- case KVI_THREAD_EVENT_SUCCESS:
- if(!m_pThread && !m_bHeaderProcessed)
- {
- // the thread has already been deleted
- // probably because the response was something like a 404
- // just ignore the event
- return true;
- }
- switch(m_eProcessingType)
- {
- case WholeFile:
- // happens always
- emit binaryData(*m_pBuffer);
- break;
- case Blocks:
- // an unprocessed block ?.. should never happend.. but well :D
- if(m_pBuffer->size() > 0)emit binaryData(*m_pBuffer);
- break;
- case Lines:
- if(m_pBuffer->size() > 0)
- {
- // something left in the buffer and has no trailing LF
- KviCString tmp((const char *)(m_pBuffer->data()),m_pBuffer->size());
- emit data(tmp);
- }
- break;
- case StoreToFile:
- // same as above... should never happen.. but well :D
- if(m_pFile && m_pBuffer->size() > 0)m_pFile->write((const char *)(m_pBuffer->data()),m_pBuffer->size());
- break;
- default:
- // nothing... just make gcc happy
- break;
- }
- resetInternalStatus();
- m_szLastError = __tr2qs("Success");
- emit terminated(true);
- return true;
- break;
- case KVI_THREAD_EVENT_ERROR:
- {
- KviCString * err = ((KviThreadDataEvent<KviCString> *)e)->getData();
- m_szLastError = __tr2qs_no_xgettext(err->ptr());
- delete err;
- resetInternalStatus();
- emit terminated(false);
- return true;
- }
- break;
- case KVI_THREAD_EVENT_MESSAGE:
- {
- KviCString * msg = ((KviThreadDataEvent<KviCString> *)e)->getData();
- emit status(__tr2qs_no_xgettext(msg->ptr()));
- delete msg;
- return true;
- }
- break;
- }
- }
- return QObject::event(e);
+ emit status(__tr2qs("Contacting host %1 on port %2").arg(m_url.host()).arg(uPort));
+
+ return true;
}
void KviHttpRequest::emitLines(KviDataBuffer * pDataBuffer)
@@ -342,7 +451,7 @@ void KviHttpRequest::emitLines(KviDataBuffer * pDataBuffer)
int idx = pDataBuffer->find((const unsigned char *)"\n",1);
while(idx != -1)
{
- KviCString tmp((const char *)(m_pBuffer->data()),idx);
+ KviCString tmp((const char *)(m_p->pBuffer->data()),idx);
tmp.stripRight('\r');
pDataBuffer->remove(idx + 1);
idx = pDataBuffer->find((const unsigned char *)"\n",1);
@@ -430,9 +539,9 @@ bool KviHttpRequest::openFile()
}
}
- m_pFile = new KviFile(m_szFileName);
+ m_p->pFile = new KviFile(m_szFileName);
- if(!m_pFile->open(QFile::WriteOnly | (bAppend ? QFile::Append : QFile::Truncate)))
+ if(!m_p->pFile->open(QFile::WriteOnly | (bAppend ? QFile::Append : QFile::Truncate)))
{
resetInternalStatus();
KviQString::sprintf(m_szLastError,__tr2qs("Can't open file \"%Q\" for writing"),&m_szFileName);
@@ -641,13 +750,13 @@ void KviHttpRequest::processData(KviDataBuffer * data)
if(!m_bHeaderProcessed)
{
// time to process the header
- m_pBuffer->append(*data);
+ m_p->pBuffer->append(*data);
- int idx = m_pBuffer->find((const unsigned char *)"\r\n\r\n",4);
+ int idx = m_p->pBuffer->find((const unsigned char *)"\r\n\r\n",4);
if(idx == -1)
{
// header not complete
- if(m_pBuffer->size() > 4096)
+ if(m_p->pBuffer->size() > 4096)
{
resetInternalStatus();
m_szLastError = __tr2qs("Header too long: exceeded 4096 bytes");
@@ -655,8 +764,8 @@ void KviHttpRequest::processData(KviDataBuffer * data)
}
return;
}
- KviCString szHeader((const char *)(m_pBuffer->data()),idx);
- m_pBuffer->remove(idx + 4);
+ KviCString szHeader((const char *)(m_p->pBuffer->data()),idx);
+ m_p->pBuffer->remove(idx + 4);
if(!processHeader(szHeader))return;
m_bHeaderProcessed = true;
@@ -666,20 +775,20 @@ void KviHttpRequest::processData(KviDataBuffer * data)
if(!openFile())return;
}
- m_uReceivedSize = m_pBuffer->size();
+ m_uReceivedSize = m_p->pBuffer->size();
- // here the header is complete and the eventual remaining data is in m_pBuffer. data has been already used.
+ // here the header is complete and the eventual remaining data is in m_p->pBuffer. data has been already used.
} else {
// header already processed
m_uReceivedSize += data->size();
- // here the header is complete and some data *might* be already in m_pBuffer. data is unused yet.
+ // here the header is complete and some data *might* be already in m_p->pBuffer. data is unused yet.
// Optimisation: If the transfer is NOT chunked (so we don't have to parse it)
// and the requested processing type is either Blocks or StoreToFile
- // then we just can avoid to copy the data to m_pBuffer.
+ // then we just can avoid to copy the data to m_p->pBuffer.
// This is a good optimisation since for large files we can save allocating
// space for and moving megabytes of data...
@@ -692,7 +801,7 @@ void KviHttpRequest::processData(KviDataBuffer * data)
emit binaryData(*data);
break;
case StoreToFile:
- m_pFile->write((const char *)(data->data()),data->size());
+ m_p->pFile->write((const char *)(data->data()),data->size());
break;
default:
break;
@@ -708,11 +817,11 @@ void KviHttpRequest::processData(KviDataBuffer * data)
return;
}
- // need to append to m_pBuffer and process it
- m_pBuffer->append(*data);
+ // need to append to m_p->pBuffer and process it
+ m_p->pBuffer->append(*data);
}
- // we're processing data in m_pBuffer here
+ // we're processing data in m_p->pBuffer here
if(m_bChunkedTransferEncoding)
{
// The transfer encoding is chunked: the buffer contains
@@ -721,45 +830,45 @@ void KviHttpRequest::processData(KviDataBuffer * data)
// The transfer terminates when we read a last chunk of size 0
// that may be followed by optional headers...
// This sux :)
- while(m_pBuffer->size() > 0) // <-- note that we may exit from this loop also for other conditions (there is a goto below)
+ while(m_p->pBuffer->size() > 0) // <-- note that we may exit from this loop also for other conditions (there is a goto below)
{
// we process chunks of parts of chunks at a time.
if(m_uRemainingChunkSize > 0)
{
// process the current chunk data
unsigned int uProcessSize = m_uRemainingChunkSize;
- if(uProcessSize > (unsigned int)m_pBuffer->size())uProcessSize = m_pBuffer->size();
+ if(uProcessSize > (unsigned int)m_p->pBuffer->size())uProcessSize = m_p->pBuffer->size();
m_uRemainingChunkSize -= uProcessSize;
switch(m_eProcessingType)
{
case Blocks:
- if((unsigned int)m_pBuffer->size() == uProcessSize)
+ if((unsigned int)m_p->pBuffer->size() == uProcessSize)
{
// avoid copying to a new buffer
- emit binaryData(*m_pBuffer);
+ emit binaryData(*m_p->pBuffer);
} else {
// must copy
- KviDataBuffer tmp(uProcessSize,m_pBuffer->data());
+ KviDataBuffer tmp(uProcessSize,m_p->pBuffer->data());
emit binaryData(tmp);
- m_pBuffer->remove(uProcessSize);
+ m_p->pBuffer->remove(uProcessSize);
}
break;
case Lines:
- if((unsigned int)m_pBuffer->size() == uProcessSize)
+ if((unsigned int)m_p->pBuffer->size() == uProcessSize)
{
// avoid copying to a new buffer
- emitLines(m_pBuffer);
+ emitLines(m_p->pBuffer);
} else {
// must copy
- KviDataBuffer tmp(uProcessSize,m_pBuffer->data());
+ KviDataBuffer tmp(uProcessSize,m_p->pBuffer->data());
emitLines(&tmp);
- m_pBuffer->remove(uProcessSize);
+ m_p->pBuffer->remove(uProcessSize);
}
break;
case StoreToFile:
- m_pFile->write((const char *)(m_pBuffer->data()),uProcessSize);
- m_pBuffer->remove(uProcessSize);
+ m_p->pFile->write((const char *)(m_p->pBuffer->data()),uProcessSize);
+ m_p->pBuffer->remove(uProcessSize);
break;
default:
// nothing.. just make gcc happy
@@ -770,17 +879,17 @@ void KviHttpRequest::processData(KviDataBuffer * data)
// We're looking for the beginning of a chunk now.
// Note that we might be at the end of a previous chunk that has a CRLF terminator
// we need to skip it.
- int crlf = m_pBuffer->find((const unsigned char *)"\r\n",2);
+ int crlf = m_p->pBuffer->find((const unsigned char *)"\r\n",2);
if(crlf != -1)
{
if(crlf == 0)
{
// This is a plain CRLF at the beginning of the buffer BEFORE a chunk header.
// It comes from the previous chunk terminator. Skip it.
- m_pBuffer->remove(2);
+ m_p->pBuffer->remove(2);
} else {
// got a chunk header
- KviCString szHeader((const char *)(m_pBuffer->data()),crlf);
+ KviCString szHeader((const char *)(m_p->pBuffer->data()),crlf);
szHeader.cutFromFirst(' ');
// now szHeader should contain a hexadecimal chunk length... (why the hell it is hex and not decimal ????)
QString szHexHeader = szHeader.ptr();
@@ -793,20 +902,20 @@ void KviHttpRequest::processData(KviDataBuffer * data)
emit terminated(false);
return;
}
- m_pBuffer->remove(crlf+2);
+ m_p->pBuffer->remove(crlf+2);
if(m_uRemainingChunkSize == 0)
{
// this is the last chunk of data. It may be followed by optional headers
// but we actually don't need them (since we're surely not in HEAD mode)
m_bIgnoreRemainingData = true;
- m_pBuffer->clear();
+ m_p->pBuffer->clear();
goto check_stream_length;
}
}
// the rest is valid data of a non-zero chunk: continue looping
} else {
// chunk header not complete
- if(m_pBuffer->size() > 4096)
+ if(m_p->pBuffer->size() > 4096)
{
resetInternalStatus();
m_szLastError = __tr2qs("Chunk header too long: exceeded 4096 bytes");
@@ -818,19 +927,19 @@ void KviHttpRequest::processData(KviDataBuffer * data)
}
}
} else {
- // the transfer encoding is not chunked: m_pBuffer contains only valid data
+ // the transfer encoding is not chunked: m_p->pBuffer contains only valid data
switch(m_eProcessingType)
{
case Blocks:
- if(m_pBuffer->size() > 0)emit binaryData(*m_pBuffer);
- m_pBuffer->clear();
+ if(m_p->pBuffer->size() > 0)emit binaryData(*m_p->pBuffer);
+ m_p->pBuffer->clear();
break;
case Lines:
- if(m_pBuffer->size() > 0)emitLines(m_pBuffer);
+ if(m_p->pBuffer->size() > 0)emitLines(m_p->pBuffer);
break;
case StoreToFile:
- m_pFile->write((const char *)(m_pBuffer->data()),m_pBuffer->size());
- m_pBuffer->clear();
+ m_p->pFile->write((const char *)(m_p->pBuffer->data()),m_p->pBuffer->size());
+ m_p->pBuffer->clear();
break;
default:
// nothing.. just make gcc happy
@@ -849,3 +958,48 @@ check_stream_length:
return;
}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#if 0
+
+bool KviHttpRequest::startDnsLookup()
+{
+ m_pDns = new KviDnsResolver();
+ connect(m_pDns,SIGNAL(lookupDone(KviDnsResolver *)),this,SLOT(dnsLookupDone(KviDnsResolver *)));
+
+ if(!m_pDns->lookup(m_url.host(),KviDnsResolver::IPv4))
+ {
+ resetInternalStatus();
+ m_szLastError = __tr2qs("Unable to start the DNS lookup");
+ return false;
+ }
+
+ QString tmp;
+ KviQString::sprintf(tmp,__tr2qs("Looking up host %Q"),&(m_url.host()));
+ emit status(tmp); // FIXME
+
+ emit resolvingHost(m_url.host());
+
+ return true;
+}
+
+void KviHttpRequest::dnsLookupDone(KviDnsResolver *d)
+{
+ if(d->state() == KviDnsResolver::Success)
+ {
+ m_szIp = d->firstIpAddress();
+ delete m_pDns;
+ m_pDns = 0;
+ QString tmp;
+ KviQString::sprintf(tmp,__tr2qs("Host %Q resolved to %Q"),&(m_url.host()),&m_szIp);
+ emit status(tmp);
+ haveServerIp();
+ } else {
+ int iErr = d->error();
+ resetInternalStatus();
+ m_szLastError = KviError::getDescription(iErr);
+ emit terminated(false);
+ }
+}
+#endif
diff --git a/src/kvilib/net/KviHttpRequest.h b/src/kvilib/net/KviHttpRequest.h
index 3dfd2811c..637790448 100644
--- a/src/kvilib/net/KviHttpRequest.h
+++ b/src/kvilib/net/KviHttpRequest.h
@@ -31,15 +31,15 @@
#include "KviCString.h"
#include "KviUrl.h"
#include "KviPointerHashTable.h"
-#include "KviFile.h"
#include <QObject>
#include <QStringList>
+#include <QAbstractSocket>
+
class KviDnsResolver;
class KviDataBuffer;
-class KviSSL;
-class KviHttpRequestThread;
+
//
// This class implements a HTTP protocol client.
@@ -49,6 +49,8 @@ class KviHttpRequestThread;
// FIXME: Document and hide internals.
+class KviHttpRequestPrivate;
+
class KVILIB_API KviHttpRequest : public QObject, public KviHeapObject
{
Q_OBJECT
@@ -86,20 +88,16 @@ protected:
unsigned int m_uTotalSize;
unsigned int m_uReceivedSize;
// internal status
- QString m_szIp;
- KviDnsResolver * m_pDns;
- KviHttpRequestThread * m_pThread;
- KviDataBuffer * m_pBuffer;
bool m_bHeaderProcessed;
bool m_bChunkedTransferEncoding;
bool m_bGzip;
unsigned int m_uRemainingChunkSize;
bool m_bIgnoreRemainingData; // used in chunked transfer after the last chunk has been seen
- KviFile * m_pFile;
unsigned int m_uConnectionTimeout; // in seconds, 60 secs by default
+private:
+ KviHttpRequestPrivate * m_p;
protected:
- bool startDnsLookup();
- virtual bool event(QEvent *e);
+
void processData(KviDataBuffer * data);
bool processHeader(KviCString &szHeader);
bool openFile();
@@ -108,9 +106,6 @@ protected:
void resetStatus();
void resetData();
void resetInternalStatus();
-protected slots:
- void dnsLookupDone(KviDnsResolver *d);
- void haveServerIp();
public:
void setConnectionTimeout(unsigned int uConnectionTimeout)
{
@@ -163,6 +158,17 @@ signals:
void binaryData(const KviDataBuffer &data);
void header(KviPointerHashTable<const char *,KviCString> * hdr);
void requestSent(const QStringList &request);
+
+private:
+ void closeSocket();
+ bool doConnect();
+
+private slots:
+ void slotSocketReadDataReady();
+ void slotSocketDisconnected();
+ void slotSocketConnected();
+ void slotSocketError(QAbstractSocket::SocketError socketError);
+ void slotConnectionTimedOut();
};
diff --git a/src/kvilib/net/KviHttpRequestThread.cpp b/src/kvilib/net/KviHttpRequestThread.cpp
deleted file mode 100644
index 88258dde5..000000000
--- a/src/kvilib/net/KviHttpRequestThread.cpp
+++ /dev/null
@@ -1,619 +0,0 @@
-//=============================================================================
-//
-// File : KviHttpRequestThread.cpp
-// Creation date : Sat Aug 17 13:43:32 2002 GMT by Szymon Stefanek
-//
-// This file is part of the KVIrc irc client distribution
-// Copyright (C) 2002-2010 Szymon Stefanek (pragma at kvirc dot net)
-//
-// This program is FREE software. You can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your opinion) any later version.
-//
-// This program 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 General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, write to the Free Software Foundation,
-// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-//
-//=============================================================================
-
-#include "KviHttpRequestThread.h"
-#include "KviHttpRequest.h"
-
-#include "KviLocale.h"
-#include "KviNetUtils.h"
-#include "KviError.h"
-#include "KviTimeUtils.h"
-#include "KviDataBuffer.h"
-
-#include "kvi_debug.h"
-#include "kvi_socket.h"
-
-#ifdef COMPILE_SSL_SUPPORT
- #include "KviSSL.h"
-#endif
-
-//#include <zlib.h>
-
-
-KviHttpRequestThread::KviHttpRequestThread(
- KviHttpRequest * r,
- const QString &szHost,
- const QString &szIp,
- unsigned short uPort,
- const QString & szPath,
- unsigned int uContentOffset,
- RequestMethod m,
- const QString &szPostData,
- bool bUseSSL
- ) : KviSensitiveThread()
-{
- m_pRequest = r;
- m_szHost = szHost;
- m_szIp = szIp;
- m_szPath = szPath;
- m_uPort = uPort > 0 ? uPort : 80;
- m_uContentOffset = uContentOffset;
- m_eRequestMethod = m;
- m_szPostData = szPostData;
- m_sock = KVI_INVALID_SOCKET;
- m_bUseSSL = bUseSSL;
- m_uConnectionTimeout = 60;
-#ifdef COMPILE_SSL_SUPPORT
- m_pSSL = 0;
-#endif
-}
-
-KviHttpRequestThread::~KviHttpRequestThread()
-{
-}
-
-bool KviHttpRequestThread::processInternalEvents()
-{
- while(KviThreadEvent *e = dequeueEvent())
- {
- switch(e->id())
- {
- case KVI_THREAD_EVENT_TERMINATE:
- {
- delete e;
- return false;
- }
- break;
- default:
- qDebug("Unrecognized event in http thread");
- delete e;
- return false;
- break;
- }
- }
-
- return true;
-}
-
-bool KviHttpRequestThread::failure(const char *error)
-{
- if(error)
- {
- postEvent(m_pRequest,new KviThreadDataEvent<KviCString>(KVI_THREAD_EVENT_ERROR,new KviCString(error)));
- } /*else {
- postEvent(m_pRequest,new KviThreadDataEvent<KviCString>(KVI_THREAD_EVENT_ERROR,new KviCString(__tr2qs("Aborted"))));
- }*/
- return false;
-}
-
-bool KviHttpRequestThread::selectForWrite(int iTimeoutInSecs)
-{
-
- kvi_time_t startTime = kvi_unixTime();
-
- for(;;)
- {
- if(!processInternalEvents())
- {
- return failure(0);
- }
-
- fd_set writeSet;
-
- FD_ZERO(&writeSet);
-
- FD_SET(m_sock,&writeSet);
-
- struct timeval tmv;
- tmv.tv_sec = 0;
- tmv.tv_usec = 1000; // we wait 1000 usecs for an event
-
-
- int nRet = kvi_socket_select(m_sock + 1,0,&writeSet,0,&tmv);
-
- if(nRet > 0)
- {
- if(FD_ISSET(m_sock,&writeSet))
- {
- // connected!
- return true;
- }
- } else {
- if(nRet < 0)
- {
- int err = kvi_socket_error();
-#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW)
- if((err != EAGAIN) && (err != EINTR) && (err != WSAEWOULDBLOCK))
-#else
- if((err != EAGAIN) && (err != EINTR))
-#endif
- {
- return failure(KviError::getUntranslatedDescription(KviError::translateSystemError(err)));
- }
- }
- }
-
-
- if((time(0) - startTime) > iTimeoutInSecs)
- return failure(__tr_no_lookup("Operation timed out"));
-
- usleep(100000); // 1/10 sec
- }
-
- return false;
-}
-
-bool KviHttpRequestThread::sslFailure()
-{
-#ifdef COMPILE_SSL_SUPPORT
- KviCString buffer;
- if(m_pSSL->getLastErrorString(buffer))
- {
- failure(buffer.ptr());
- } else {
- failure(__tr_no_lookup("Unexpected SSL error"));
- }
-#endif
- return false;
-}
-
-bool KviHttpRequestThread::connectToRemoteHost()
-{
- m_sock = kvi_socket_create(KVI_SOCKET_PF_INET,KVI_SOCKET_TYPE_STREAM,0); //tcp
- if(m_sock == KVI_INVALID_SOCKET)
- return failure(__tr_no_lookup("Failed to create the socket"));
-
- if(!kvi_socket_setNonBlocking(m_sock))
- return failure(__tr_no_lookup("Failed to enter non blocking mode"));
-
- sockaddr_in saddr;
-
- if(!KviNetUtils::stringIpToBinaryIp(m_szIp,&(saddr.sin_addr)))
- return failure(__tr_no_lookup("Invalid target address"));
-
- saddr.sin_port = htons(m_uPort);
- saddr.sin_family = AF_INET;
-
- if(!kvi_socket_connect(m_sock,(struct sockaddr *)&saddr,sizeof(saddr)))
- {
- int err = kvi_socket_error();
- if(!kvi_socket_recoverableConnectError(err))
- {
- return failure(KviError::getUntranslatedDescription(KviError::translateSystemError(err)));
- }
- }
-
- // now loop selecting for write
-
- if(!selectForWrite(m_uConnectionTimeout))
- return false;
-
- int sockError;
- int iSize = sizeof(sockError);
- if(!kvi_socket_getsockopt(m_sock,SOL_SOCKET,SO_ERROR,(void *)&sockError,&iSize))sockError = -1;
- if(sockError != 0)
- {
- //failed
- KviError::Code eError;
- if(sockError > 0)
- eError = KviError::translateSystemError(sockError);
- else
- eError = KviError::UnknownError;
- return failure(KviError::getUntranslatedDescription(eError));
- }
-
-#ifdef COMPILE_SSL_SUPPORT
- if(m_bUseSSL)
- {
- m_pSSL = new KviSSL();
- if(!m_pSSL->initContext(KviSSL::Client))
- return failure(__tr_no_lookup("Failed to initialize the SSL context"));
- if(!m_pSSL->initSocket(m_sock))
- return failure(__tr_no_lookup("Failed to initialize the SSL connection"));
-
- for(;;)
- {
- switch(m_pSSL->connect())
- {
- case KviSSL::Success:
- // done: connected.
- return true;
- break;
- case KviSSL::WantRead:
- if(!selectForRead(m_uConnectionTimeout))
- return false;
- break;
- case KviSSL::WantWrite:
- if(!selectForWrite(m_uConnectionTimeout))
- return false;
- break;
- case KviSSL::RemoteEndClosedConnection:
- return failure(__tr_no_lookup("Remote end has closed the connection"));
- break;
- case KviSSL::SSLError:
- return sslFailure();
- break;
- case KviSSL::SyscallError:
- {
- // syscall problem
- int err = kvi_socket_error();
- if(!kvi_socket_recoverableError(err))
- {
- // Declare problems :)
- return failure(__tr_no_lookup("Unrecoverable SSL error during handshake"));
- } // else can recover ? (EAGAIN, EINTR ?) ... should select for read or for write
- }
- break;
- default:
- return sslFailure();
- break;
- }
- }
-
- // never here
- return true;
- }
-#endif
-
- return true;
-}
-
-
-bool KviHttpRequestThread::sendBuffer(const char * buffer,int bufLen,int iTimeoutInSecs)
-{
- const char * ptr = buffer;
- int curLen = bufLen;
-
- time_t startTime = time(0);
-
- for(;;)
- {
- if(!processInternalEvents())
- return failure();
-
- int wrtn;
-#ifdef COMPILE_SSL_SUPPORT
- if(m_pSSL)
- {
- wrtn = m_pSSL->write((char *)ptr,curLen);
- } else {
-#endif
- wrtn = kvi_socket_send(m_sock,ptr,curLen);
-#ifdef COMPILE_SSL_SUPPORT
- }
-#endif
-
- if(wrtn > 0)
- {
- curLen -= wrtn;
-
- if(curLen <= 0)
- break;
-
- ptr += wrtn;
- } else {
- if(wrtn < 0)
- {
-#ifdef COMPILE_SSL_SUPPORT
- if(m_pSSL)
- {
- // ops...might be an SSL error
- switch(m_pSSL->getProtocolError(wrtn))
- {
- case KviSSL::WantWrite:
- if(!selectForWrite(m_uConnectionTimeout))
- return false;
- break;
- case KviSSL::WantRead:
- if(!selectForRead(m_uConnectionTimeout))
- return false;
- break;
- case KviSSL::SyscallError:
- if(wrtn == 0)
- {
- return failure(__tr_no_lookup("Remote end has closed the connection"));
- } else {
- int iSSLErr = m_pSSL->getLastError(true);
- if(iSSLErr != 0)
- {
- return sslFailure();
- } else {
- goto handle_system_error;
- }
- }
- break;
- case KviSSL::SSLError:
- return sslFailure();
- break;
- default:
- return sslFailure();
- break;
- }
- } else {
-#endif //COMPILE_SSL_SUPPORT
-
-handle_system_error:
- int err = kvi_socket_error();
-#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW)
- if((err != EAGAIN) && (err != EINTR) && (err != WSAEWOULDBLOCK))
-#else
- if((err != EAGAIN) && (err != EINTR))
-#endif
- {
- return failure(KviError::getUntranslatedDescription(KviError::translateSystemError(err)));
- }
-#ifdef COMPILE_SSL_SUPPORT
- }
-#endif
- }
- }
-
- int diff = time(0) - startTime;
- if(diff > iTimeoutInSecs)
- return failure(__tr_no_lookup("Operation timed out"));
-
- usleep(10000);
- }
-
- return true;
-}
-
-int KviHttpRequestThread::selectForReadStep()
-{
- // calls select on the main socket
- // returns 1 if there is data available for reading
- // returns 0 if there is no data available but there was no error
- // returns -1 if there was a critical error (socket closed)
- fd_set readSet;
-
- FD_ZERO(&readSet);
-
- FD_SET(m_sock,&readSet);
-
- struct timeval tmv;
- tmv.tv_sec = 0;
- tmv.tv_usec = 1000; // we wait 1000 usecs for an event
-
-
- int nRet = kvi_socket_select(m_sock + 1,&readSet,0,0,&tmv);
-
- if(nRet > 0)
- {
- if(FD_ISSET(m_sock,&readSet))
- {
- // ok
- return 1;
- }
- } else {
- if(nRet < 0)
- {
- int err = kvi_socket_error();
-#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW)
- if((err != EAGAIN) && (err != EINTR) && (err != WSAEWOULDBLOCK))
-#else
- if((err != EAGAIN) && (err != EINTR))
-#endif
- {
- failure(KviError::getUntranslatedDescription(KviError::translateSystemError(err)));
- return -1;
- }
- }
- }
-
- return 0;
-}
-
-bool KviHttpRequestThread::selectForRead(int iTimeoutInSecs)
-{
- // waits for some data to arrive on the socket
- // up to iTimeoutInSecs seconds
- // returns true if data is available on the socket
- // or false if there was a select() error or no data
- // was available in the specified amount of time
-
- time_t startTime = time(0);
-
- for(;;)
- {
- if(!processInternalEvents())
- {
- return failure(); // ensure that the socket is closed
- }
-
- int nRet = selectForReadStep();
-
- if(nRet < 0)return false;
- if(nRet > 0)return true;
-
- int diff = time(0) - startTime;
- if(diff > iTimeoutInSecs)
- return failure(__tr_no_lookup("Operation timed out (while selecting for read)"));
-
- usleep(100000); // 1/10 sec
- }
-
- return false;
-}
-
-bool KviHttpRequestThread::readDataStep()
-{
- unsigned char buffer[2048];
- int readed;
-
-
-#ifdef COMPILE_SSL_SUPPORT
- if(m_pSSL)
- {
- readed = m_pSSL->read((char *)buffer,2048);
- if(readed <= 0)
- {
- // ssl error....?
- switch(m_pSSL->getProtocolError(readed))
- {
- case KviSSL::ZeroReturn:
- readed = 0;
- break;
- case KviSSL::WantRead:
- return selectForRead(m_uConnectionTimeout);
- break;
- case KviSSL::WantWrite:
- return selectForWrite(m_uConnectionTimeout);
- break;
- case KviSSL::SyscallError:
- {
- int iE = m_pSSL->getLastError(true);
- if(iE != 0)return sslFailure();
- }
- break;
- case KviSSL::SSLError:
- return sslFailure();
- break;
- default:
- return sslFailure();
- break;
- }
- }
- } else {
-#endif
- readed = kvi_socket_read(m_sock,buffer,2048);
-#ifdef COMPILE_SSL_SUPPORT
- }
-#endif
-
- if(readed > 0)
- {
- postEvent(m_pRequest,new KviThreadDataEvent<KviDataBuffer>(KVI_THREAD_EVENT_BINARYDATA,new KviDataBuffer(readed,buffer)));
- } else {
- if(readed < 0)
- {
- // Read error ?
- int err = kvi_socket_error();
-#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW)
- if((err != EAGAIN) && (err != EINTR) && (err != WSAEWOULDBLOCK))
-#else
- if((err != EAGAIN) && (err != EINTR))
-#endif
- {
- // yes...read error
- return failure(KviError::getUntranslatedDescription(KviError::translateSystemError(err)));
- }
- return selectForRead(m_uConnectionTimeout); // EINTR or EAGAIN...transient problem
- } else {
- // readed == 0
- // Connection closed by remote host
- postEvent(m_pRequest,new KviThreadEvent(KVI_THREAD_EVENT_SUCCESS));
- return false;
- }
- }
- return selectForRead(m_uConnectionTimeout);
-}
-
-void KviHttpRequestThread::run()
-{
- // setup:
- // nothing needed
-
- // run:
- runInternal();
-
- // cleanup:
-#ifdef COMPILE_SSL_SUPPORT
- if(m_pSSL)
- {
- delete m_pSSL;
- m_pSSL = 0;
- }
-#endif
-
- if(kvi_socket_isValid(m_sock))
- {
- kvi_socket_close(m_sock);
- m_sock = KVI_INVALID_SOCKET;
- }
-}
-
-void KviHttpRequestThread::runInternal()
-{
-#ifndef COMPILE_SSL_SUPPORT
- if(m_bUseSSL)
- {
- failure(__tr_no_lookup("This KVIrc executable has no SSL support"));
- return;
- }
-#endif
-
- if(!connectToRemoteHost())return;
-
- postEvent(m_pRequest,new KviThreadEvent(KVI_HTTP_REQUEST_THREAD_EVENT_CONNECTED));
-
- // FIXME: Other headers ?
-
- KviCString szMethod;
- switch(m_eRequestMethod)
- {
- case Head: szMethod = "HEAD"; break;
- case Post: szMethod = "POST"; break;
- case Get: szMethod = "GET"; break;
- }
-
- KviCString szRequest(KviCString::Format,"%s %s HTTP/1.1\r\n" \
- "Host: %s\r\n" \
- "Connection: Close\r\n" \
- "User-Agent: KVIrc-http-slave/1.0.0\r\n" \
- "Accept: */*\r\n",
- szMethod.ptr(),KviQString::toUtf8(m_szPath).data(),KviQString::toUtf8(m_szHost).data());
-
- if(m_uContentOffset > 0)
- szRequest.append(KviCString::Format,"Range: bytes=%u-\r\n",m_uContentOffset);
-
- if(m_eRequestMethod == Post)
- {
- szRequest.append(KviCString::Format,"Content-Type: application/x-www-form-urlencoded\r\n" \
- "Content-Length: %u\r\n" \
- "Cache-control: no-cache\r\n" \
- "Pragma: no-cache\r\n",m_szPostData.length());
- }
-
- szRequest += "\r\n";
-
- if(m_eRequestMethod == Post)
- {
- if(!m_szPostData.isEmpty())
- szRequest.append(m_szPostData);
- szRequest += "\r\n";
- }
-
- //qDebug("SENDING REQUEST:\n%s",szRequest.ptr());
-
- if(!sendBuffer(szRequest.ptr(),szRequest.len(),60))return;
-
- // now loop reading data
- postEvent(m_pRequest,new KviThreadDataEvent<QString>(KVI_HTTP_REQUEST_THREAD_EVENT_REQUESTSENT,new QString(szRequest)));
-
- for(;;)
- {
- if(!readDataStep())return;
- }
-}
-
diff --git a/src/kvilib/net/KviHttpRequestThread.h b/src/kvilib/net/KviHttpRequestThread.h
deleted file mode 100644
index b1c024c6e..000000000
--- a/src/kvilib/net/KviHttpRequestThread.h
+++ /dev/null
@@ -1,100 +0,0 @@
-#ifndef _KviHttpRequestThread_h_
-#define _KviHttpRequestThread_h_
-//=============================================================================
-//
-// File : KviHttpRequestThread.h
-// Creation date : Sat Aug 17 13:43:31 2002 GMT by Szymon Stefanek
-//
-// This file is part of the KVIrc irc client distribution
-// Copyright (C) 2002-2010 Szymon Stefanek (pragma at kvirc dot net)
-//
-// This program is FREE software. You can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your opinion) any later version.
-//
-// This program 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 General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, write to the Free Software Foundation,
-// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-//
-//=============================================================================
-
-#include "kvi_settings.h"
-
-#include "KviQString.h"
-#include "KviThread.h"
-#include "kvi_sockettype.h"
-
-#ifdef COMPILE_SSL_SUPPORT
- class KviSSL;
-#endif //COMPILE_SSL_SUPPORT
-
-class KviHttpRequest;
-
-class KviHttpRequestThread : public KviSensitiveThread
-{
- friend class KviHttpRequest;
-public:
- enum RequestMethod { Post, Get, Head };
-protected:
- KviHttpRequestThread(KviHttpRequest * r,
- const QString &szHost,
- const QString &szIp,
- unsigned short uPort,
- const QString &szPath,
- unsigned int uContentOffset,
- RequestMethod m,
- const QString &szPostData = QString(),
- bool bUseSSL = false
- );
-
-public:
- ~KviHttpRequestThread();
-protected:
- KviHttpRequest * m_pRequest;
-
- QString m_szHost;
- QString m_szIp;
- QString m_szPath;
- unsigned int m_uContentOffset;
- RequestMethod m_eRequestMethod;
- QString m_szPostData;
-
- unsigned short m_uPort;
- kvi_socket_t m_sock;
- bool m_bUseSSL;
- unsigned int m_uConnectionTimeout;
-#ifdef COMPILE_SSL_SUPPORT
- KviSSL * m_pSSL;
-#endif //COMPILE_SSL_SUPPORT
-protected:
- void setConnectionTimeout(unsigned int uTimeout)
- {
- m_uConnectionTimeout = uTimeout;
- if(m_uConnectionTimeout < 5)
- m_uConnectionTimeout = 5; // keep it sane
- }
- int selectForReadStep();
- bool selectForRead(int iTimeoutInSecs);
- bool readDataStep();
- bool sendBuffer(const char *buffer,int bufLen,int iTimeoutInSecs);
- bool failure(const char *error=0);
- bool sslFailure();
- bool selectForWrite(int iTimeoutInSecs);
- bool connectToRemoteHost();
- bool processInternalEvents();
- void runInternal();
- virtual void run();
-}; // class KviHttpRequestThread
-
-
-#define KVI_HTTP_REQUEST_THREAD_EVENT_CONNECTED (KVI_THREAD_USER_EVENT_BASE + 0xCAFE)
-#define KVI_HTTP_REQUEST_THREAD_EVENT_REQUESTSENT (KVI_THREAD_USER_EVENT_BASE + 0xCAFF)
-
-
-#endif //_KviHttpRequestThread_h_
diff --git a/src/kvilib/net/KviUrl.cpp b/src/kvilib/net/KviUrl.cpp
index bea2acfa7..2f9f4a4cf 100644
--- a/src/kvilib/net/KviUrl.cpp
+++ b/src/kvilib/net/KviUrl.cpp
@@ -67,7 +67,7 @@ void KviUrl::parse()
if(m_szPath.isEmpty()) m_szPath=QString("/");
m_szUser = url.userName();
m_szPass = url.password();
- m_uPort = url.port() > 0 ? url.port() : 80 ;
+ m_uPort = url.port(0);
}
diff --git a/src/kvirc/ui/KviStatusBarApplet.cpp b/src/kvirc/ui/KviStatusBarApplet.cpp
index 533a1ad05..54c694371 100644
--- a/src/kvirc/ui/KviStatusBarApplet.cpp
+++ b/src/kvirc/ui/KviStatusBarApplet.cpp
@@ -23,8 +23,6 @@
//
//=============================================================================
-
-
#include "KviStatusBarApplet.h"
#include "KviMainWindow.h"
#include "KviIconManager.h"
diff --git a/src/modules/http/httpfiletransfer.cpp b/src/modules/http/httpfiletransfer.cpp
index 5a3359888..2c48b49c2 100644
--- a/src/modules/http/httpfiletransfer.cpp
+++ b/src/modules/http/httpfiletransfer.cpp
@@ -261,17 +261,17 @@ void KviHttpFileTransfer::displayPaint(QPainter * p,int column, QRect rect)
{
KviTimeUtils::secondsToDaysHoursMinsSecs(kvi_timeSpan(m_tTransferEndTime,m_tTransferStartTime),&uD,&uH,&uM,&uS);
txt = "TOT: ";
- if(uD > 0)txt += QString(__tr2qs_ctx("%1d %2h %3m %4s","http")).arg(uD).arg(uH).arg(uM).arg(uS);
- else if(uH > 0)txt += QString(__tr2qs_ctx("%1h %2m %3s","http")).arg(uH).arg(uM).arg(uS);
- else txt += QString(__tr2qs_ctx("%1m %2s","http")).arg(uM, uS);
+ if(uD > 0)txt += __tr2qs_ctx("%1d %2h %3m %4s","http").arg(uD).arg(uH).arg(uM).arg(uS);
+ else if(uH > 0)txt += __tr2qs_ctx("%1h %2m %3s","http").arg(uH).arg(uM).arg(uS);
+ else txt += __tr2qs_ctx("%1m %2s","http").arg(uM).arg(uS);
} else {
if(iEta >= 0)
{
KviTimeUtils::secondsToDaysHoursMinsSecs(iEta,&uD,&uH,&uM,&uS);
txt = "ETA: ";
- if(uD > 0)txt += QString(__tr2qs_ctx("%1d %2h %3m %4s","http")).arg(uD).arg(uH).arg(uM).arg(uS);
- else if(uH > 0)txt += QString(__tr2qs_ctx("%1h %2m %3s","http")).arg(uH).arg(uM).arg(uS);
- else txt += QString(__tr2qs_ctx("%1m %2s","http")).arg(uM, uS);
+ if(uD > 0)txt += __tr2qs_ctx("%1d %2h %3m %4s","http").arg(uD).arg(uH).arg(uM).arg(uS);
+ else if(uH > 0)txt += __tr2qs_ctx("%1h %2m %3s","http").arg(uH).arg(uM).arg(uS);
+ else txt += __tr2qs_ctx("%1m %2s","http").arg(uM).arg(uS);
} else {
txt = "ETA: Unknown";
}