diff options
| author | 2010-12-30 02:45:58 +0000 | |
|---|---|---|
| committer | 2010-12-30 02:45:58 +0000 | |
| commit | d703e48f497a2ae17205373a8345586c693808aa (patch) | |
| tree | 3311c262df9a89e6334259b84b6914fa55b21568 | |
| parent | quick fix (diff) | |
| download | KVIrc-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.cpp | 544 | ||||
| -rw-r--r-- | src/kvilib/net/KviHttpRequest.h | 32 | ||||
| -rw-r--r-- | src/kvilib/net/KviHttpRequestThread.cpp | 619 | ||||
| -rw-r--r-- | src/kvilib/net/KviHttpRequestThread.h | 100 | ||||
| -rw-r--r-- | src/kvilib/net/KviUrl.cpp | 2 | ||||
| -rw-r--r-- | src/kvirc/ui/KviStatusBarApplet.cpp | 2 | ||||
| -rw-r--r-- | src/modules/http/httpfiletransfer.cpp | 12 |
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"; } |
