• Main Page
  • Classes
  • Files
  • File List
  • File Members

lib/bfHttpServer/src/httpconnectionhandler.cpp

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;   // pdiener: it is not busy if it is new
00020     // execute signals in my own thread
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     // Change to the main thread, otherwise deleteLater() would not work
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); // if not, then the handler is already busy
00056     if (!socket.setSocketDescriptor(socketDescriptor)) {
00057         qCritical("HttpConnectionHandler (%p): cannot initialize socket: %s", this,qPrintable(socket.errorString()));
00058         return;
00059     }
00060     // Start timer for read timeout
00061     int readTimeout=settings->value("readTimeout",10000).toInt();
00062     readTimer.start(readTimeout);
00063     currentRequest=0;
00064 }
00065 
00066 
00067 bool HttpConnectionHandler::isBusy() {
00068     //return socket.isOpen();
00069     return busy;    // pdiener: changed this from socket readout to bool variable
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; // pdiener: now we have finished
00093 }
00094 
00095 void HttpConnectionHandler::read() {
00096 #ifdef SUPERVERBOSE
00097     qDebug("HttpConnectionHandler (%x): read input",(unsigned int) this);
00098 #endif
00099 
00100     // Create new HttpRequest object if necessary
00101     if (!currentRequest) {
00102         currentRequest=new HttpRequest(settings);
00103     }
00104 
00105     // Collect data for the request object
00106     while (socket.bytesAvailable() && currentRequest->getStatus()!=HttpRequest::complete && currentRequest->getStatus()!=HttpRequest::abort) {
00107         currentRequest->readFromSocket(socket);
00108         if (currentRequest->getStatus()==HttpRequest::waitForBody) {
00109             // Restart timer for read timeout, otherwise it would
00110             // expire during large file uploads.
00111             int readTimeout=settings->value("readTimeout",10000).toInt();
00112             readTimer.start(readTimeout);
00113         }
00114     }
00115 
00116     // If the request is aborted, return error message and close the connection
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     // If the request is complete, let the request mapper dispatch it
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         // Finalize sending the response if not already done
00138         if (!response.hasSentLastPart()) {
00139             response.write(QByteArray(),true);
00140         }
00141         // Close the connection after delivering the response, if requested
00142         if (QString::compare(currentRequest->getHeader("Connection"),"close",Qt::CaseInsensitive)==0) {
00143             socket.disconnectFromHost();
00144         }
00145         else {
00146             // Start timer for next request
00147             int readTimeout=settings->value("readTimeout",10000).toInt();
00148             readTimer.start(readTimeout);
00149         }
00150         // Prepare for next request
00151         delete currentRequest;
00152         currentRequest=0;
00153     }
00154 }

Generated on Mon Dec 26 2011 12:09:22 for QtWebApp by  doxygen 1.7.1