Go to the documentation of this file.00001
00006 #include "httpconnectionhandler.h"
00007 #include "httpresponse.h"
00008 #include <QTimer>
00009 #include <QCoreApplication>
00010
00011 HttpConnectionHandler::HttpConnectionHandler(QSettings* settings, HttpRequestHandler* requestHandler)
00012 : QThread()
00013 {
00014 Q_ASSERT(settings!=0);
00015 Q_ASSERT(requestHandler!=0);
00016 this->settings=settings;
00017 this->requestHandler=requestHandler;
00018 currentRequest=0;
00019 busy = false;
00020
00021 moveToThread(this);
00022 socket.moveToThread(this);
00023 readTimer.moveToThread(this);
00024 connect(&socket, SIGNAL(readyRead()), SLOT(read()));
00025 connect(&socket, SIGNAL(disconnected()), SLOT(disconnected()));
00026 connect(&readTimer, SIGNAL(timeout()), SLOT(readTimeout()));
00027 readTimer.setSingleShot(true);
00028 qDebug("HttpConnectionHandler (%p): constructed", this);
00029 this->start();
00030 }
00031
00032
00033 HttpConnectionHandler::~HttpConnectionHandler() {
00034 qDebug("HttpConnectionHandler (%p): destroyed", this);
00035 }
00036
00037
00038 void HttpConnectionHandler::run() {
00039 qDebug("HttpConnectionHandler (%p): thread started", this);
00040 try {
00041 exec();
00042 }
00043 catch (...) {
00044 qCritical("HttpConnectionHandler (%p): an uncatched exception occured in the thread",this);
00045 }
00046 qDebug("HttpConnectionHandler (%p): thread stopped", this);
00047
00048 moveToThread(QCoreApplication::instance()->thread());
00049 }
00050
00051
00052 void HttpConnectionHandler::handleConnection(int socketDescriptor) {
00053 qDebug("HttpConnectionHandler (%p): handle new connection", this);
00054 busy = true;
00055 Q_ASSERT(socket.isOpen()==false);
00056 if (!socket.setSocketDescriptor(socketDescriptor)) {
00057 qCritical("HttpConnectionHandler (%p): cannot initialize socket: %s", this,qPrintable(socket.errorString()));
00058 return;
00059 }
00060
00061 int readTimeout=settings->value("readTimeout",10000).toInt();
00062 readTimer.start(readTimeout);
00063 currentRequest=0;
00064 }
00065
00066
00067 bool HttpConnectionHandler::isBusy() {
00068
00069 return busy;
00070 }
00071
00072 void HttpConnectionHandler::setBusy() {
00073 this->busy = true;
00074 }
00075
00076
00077 void HttpConnectionHandler::readTimeout() {
00078 qDebug("HttpConnectionHandler (%p): read timeout occured",this);
00079 socket.write("HTTP/1.1 408 request timeout\r\nConnection: close\r\n\r\n408 request timeout\r\n");
00080 socket.disconnectFromHost();
00081 delete currentRequest;
00082 currentRequest=0;
00083 }
00084
00085
00086 void HttpConnectionHandler::disconnected() {
00087 qDebug("HttpConnectionHandler (%p): disconnected", this);
00088 socket.close();
00089 delete currentRequest;
00090 currentRequest=0;
00091 readTimer.stop();
00092 busy = false;
00093 }
00094
00095 void HttpConnectionHandler::read() {
00096 #ifdef SUPERVERBOSE
00097 qDebug("HttpConnectionHandler (%x): read input",(unsigned int) this);
00098 #endif
00099
00100
00101 if (!currentRequest) {
00102 currentRequest=new HttpRequest(settings);
00103 }
00104
00105
00106 while (socket.bytesAvailable() && currentRequest->getStatus()!=HttpRequest::complete && currentRequest->getStatus()!=HttpRequest::abort) {
00107 currentRequest->readFromSocket(socket);
00108 if (currentRequest->getStatus()==HttpRequest::waitForBody) {
00109
00110
00111 int readTimeout=settings->value("readTimeout",10000).toInt();
00112 readTimer.start(readTimeout);
00113 }
00114 }
00115
00116
00117 if (currentRequest->getStatus()==HttpRequest::abort) {
00118 socket.write("HTTP/1.1 413 entity too large\r\nConnection: close\r\n\r\n413 Entity too large\r\n");
00119 socket.disconnectFromHost();
00120 delete currentRequest;
00121 currentRequest=0;
00122 return;
00123 }
00124
00125
00126 if (currentRequest->getStatus()==HttpRequest::complete) {
00127 readTimer.stop();
00128 qDebug("HttpConnectionHandler (%p): received request",this);
00129 HttpResponse response(&socket);
00130 try {
00131 requestHandler->service(*currentRequest, response);
00132 }
00133 catch (...) {
00134 qCritical("HttpConnectionHandler (%p): An uncatched exception occured in the request handler",this);
00135 }
00136
00137
00138 if (!response.hasSentLastPart()) {
00139 response.write(QByteArray(),true);
00140 }
00141
00142 if (QString::compare(currentRequest->getHeader("Connection"),"close",Qt::CaseInsensitive)==0) {
00143 socket.disconnectFromHost();
00144 }
00145 else {
00146
00147 int readTimeout=settings->value("readTimeout",10000).toInt();
00148 readTimer.start(readTimeout);
00149 }
00150
00151 delete currentRequest;
00152 currentRequest=0;
00153 }
00154 }