/** @file @author Stefan Frings */ #ifndef HTTPRESPONSE_H #define HTTPRESPONSE_H #include <QMap> #include <QString> #include <QTcpSocket> #include "httpcookie.h" /** This object represents a HTTP response, in particular the response headers. <p> Example code for proper response generation: <code><pre> response.setStatus(200,"OK"); // optional, because this is the default response.writeBody("Hello"); response.writeBody("World!",true); </pre></code> <p> Example how to return an error: <code><pre> response.setStatus(500,"server error"); response.write("The request cannot be processed because the servers is broken",true); </pre></code> <p> For performance reason, writing a single or few large packets is better than writing many small packets. In case of large responses (e.g. file downloads), a Content-Length header should be set before calling write(). Web Browsers use that information to display a progress bar. */ class HttpResponse { Q_DISABLE_COPY(HttpResponse) public: /** Constructor. @param socket used to write the response */ HttpResponse(QTcpSocket* socket); /** Set a HTTP response header @param name name of the header @param value value of the header */ void setHeader(QByteArray name, QByteArray value); /** Set a HTTP response header @param name name of the header @param value value of the header */ void setHeader(QByteArray name, int value); /** Get the map of HTTP response headers */ QMap<QByteArray,QByteArray>& getHeaders(); /** Get the map of cookies */ QMap<QByteArray,HttpCookie>& getCookies(); /** Set status code and description. The default is 200,OK. */ void setStatus(int statusCode, QByteArray description=QByteArray()); /** Write body data to the socket. <p> The HTTP status line and headers are sent automatically before the first byte of the body gets sent. <p> If the response contains only a single chunk (indicated by lastPart=true), the response is transferred in traditional mode with a Content-Length header, which is automatically added if not already set before. <p> Otherwise, each part is transferred in chunked mode. @param data Data bytes of the body @param lastPart Indicator, if this is the last part of the response. */ void write(QByteArray data, bool lastPart=false); void writeText(QString text, bool lastPart=false); /** Indicates wheter the body has been sent completely. Used by the connection handler to terminate the body automatically when necessary. */ bool hasSentLastPart() const; /** Set a cookie. Cookies are sent together with the headers when the first call to write() occurs. */ void setCookie(const HttpCookie& cookie); private: /** Request headers */ QMap<QByteArray,QByteArray> headers; /** Socket for writing output */ QTcpSocket* socket; /** HTTP status code*/ int statusCode; /** HTTP status code description */ QByteArray statusText; /** Indicator whether headers have been sent */ bool sentHeaders; /** Indicator whether the body has been sent completely */ bool sentLastPart; /** Cookies */ QMap<QByteArray,HttpCookie> cookies; /** Write raw data to the socket. This method blocks until all bytes have been passed to the TCP buffer */ void writeToSocket(QByteArray data); /** Write the response HTTP status and headers to the socket. Calling this method is optional, because writeBody() calls it automatically when required. */ void writeHeaders(); }; #endif // HTTPRESPONSE_H