aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGravatar Szymon Tomasz Stefanek2010-12-29 06:15:12 +0000
committerGravatar Szymon Tomasz Stefanek2010-12-29 06:15:12 +0000
commit9b907f837d93dec1c98bb8f33e70414aac0dab8e (patch)
tree5d43468bd3f2701700ac6a244a593d8c50667832 /src
parentKill the 'extern' specifier which is optional and actually confusing here (diff)
downloadKVIrc-9b907f837d93dec1c98bb8f33e70414aac0dab8e.tar.gz
KVIrc-9b907f837d93dec1c98bb8f33e70414aac0dab8e.tar.bz2
KVIrc-9b907f837d93dec1c98bb8f33e70414aac0dab8e.zip
More file splitting
git-svn-id: https://svn.kvirc.de/svn/trunk/kvirc@5259 17fca916-40b9-46aa-a4ea-0a15b648b75c
Diffstat (limited to 'src')
-rw-r--r--src/kvilib/CMakeLists.txt1
-rw-r--r--src/kvilib/net/KviHttpRequest.cpp584
-rw-r--r--src/kvilib/net/KviHttpRequest.h72
-rw-r--r--src/kvirc/ui/KviStatusBarApplet.cpp1
4 files changed, 12 insertions, 646 deletions
diff --git a/src/kvilib/CMakeLists.txt b/src/kvilib/CMakeLists.txt
index cc1438229..b63d7c3c6 100644
--- a/src/kvilib/CMakeLists.txt
+++ b/src/kvilib/CMakeLists.txt
@@ -106,6 +106,7 @@ SET(kvilib_SRCS
irc/KviUserIdentity.cpp
net/KviDnsResolver.cpp
net/KviHttpRequest.cpp
+ net/KviHttpRequestThread.cpp
net/KviNetUtils.cpp
net/KviSASL.cpp
net/kvi_socket.cpp
diff --git a/src/kvilib/net/KviHttpRequest.cpp b/src/kvilib/net/KviHttpRequest.cpp
index 3f73da337..30f97887d 100644
--- a/src/kvilib/net/KviHttpRequest.cpp
+++ b/src/kvilib/net/KviHttpRequest.cpp
@@ -22,28 +22,20 @@
//
//=============================================================================
-
-
#include <QDir>
#include <QTimer>
//#include <zlib.h>
#include "KviHttpRequest.h"
+#include "KviHttpRequestThread.h"
#include "KviLocale.h"
#include "KviNetUtils.h"
#include "KviDnsResolver.h"
#include "KviError.h"
#include "kvi_debug.h"
-#include "kvi_socket.h"
#include "KviTimeUtils.h"
+#include "KviDataBuffer.h"
-#ifdef COMPILE_SSL_SUPPORT
- #include "KviSSL.h"
-#endif
-
-
-#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)
KviHttpRequest::KviHttpRequest()
: QObject()
@@ -858,575 +850,3 @@ check_stream_length:
return;
}
-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
- if(sockError > 0)sockError = KviError::translateSystemError(sockError);
- else sockError = KviError_unknownError;
- return failure(KviError::getUntranslatedDescription(sockError));
- }
-
-#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/KviHttpRequest.h b/src/kvilib/net/KviHttpRequest.h
index 39f6b0e4a..3dfd2811c 100644
--- a/src/kvilib/net/KviHttpRequest.h
+++ b/src/kvilib/net/KviHttpRequest.h
@@ -1,5 +1,5 @@
-#ifndef _KVI_HTTP_H_
-#define _KVI_HTTP_H_
+#ifndef _KviHttpRequest_h_
+#define _KviHttpRequest_h_
//=============================================================================
//
// File : KviHttpRequest.h
@@ -25,12 +25,10 @@
//=============================================================================
#include "kvi_settings.h"
+#include "kvi_inttypes.h"
+
#include "KviHeapObject.h"
#include "KviCString.h"
-#include "KviThread.h"
-#include "kvi_sockettype.h"
-#include "KviDataBuffer.h"
-#include "kvi_inttypes.h"
#include "KviUrl.h"
#include "KviPointerHashTable.h"
#include "KviFile.h"
@@ -39,6 +37,7 @@
#include <QStringList>
class KviDnsResolver;
+class KviDataBuffer;
class KviSSL;
class KviHttpRequestThread;
@@ -48,6 +47,8 @@ class KviHttpRequestThread;
// download stuff to a file or to a qt SLOT().
//
+// FIXME: Document and hide internals.
+
class KVILIB_API KviHttpRequest : public QObject, public KviHeapObject
{
Q_OBJECT
@@ -165,61 +166,4 @@ signals:
};
-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
-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();
-};
-
-
-#endif //_KVI_HTTP_H_
+#endif //_KviHttpRequest_h_
diff --git a/src/kvirc/ui/KviStatusBarApplet.cpp b/src/kvirc/ui/KviStatusBarApplet.cpp
index aec1290c9..533a1ad05 100644
--- a/src/kvirc/ui/KviStatusBarApplet.cpp
+++ b/src/kvirc/ui/KviStatusBarApplet.cpp
@@ -50,6 +50,7 @@
#include "KviUrl.h"
#include "KviTalPopupMenu.h"
#include "KviTalToolTip.h"
+#include "KviDataBuffer.h"
#include <QPainter>
#include <QStyle>