File indexing completed on 2025-02-02 04:36:32
0001 /* 0002 * Copyright 2011 Nikhil Marathe <nsm.nikhil@gmail.com> 0003 * 0004 * Permission is hereby granted, free of charge, to any person obtaining a copy 0005 * of this software and associated documentation files (the "Software"), to 0006 * deal in the Software without restriction, including without limitation the 0007 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 0008 * sell copies of the Software, and to permit persons to whom the Software is 0009 * furnished to do so, subject to the following conditions: 0010 * 0011 * The above copyright notice and this permission notice shall be included in 0012 * all copies or substantial portions of the Software. 0013 * 0014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 0015 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 0016 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 0017 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 0018 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 0019 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 0020 * IN THE SOFTWARE. 0021 */ 0022 0023 #ifndef Q_HTTP_RESPONSE 0024 #define Q_HTTP_RESPONSE 0025 0026 #include <QObject> 0027 #include <QHash> 0028 0029 // 0030 class QTcpSocket; 0031 0032 class QHttpConnection; 0033 0034 typedef QHash<QString, QString> HeaderHash; 0035 0036 /*! 0037 * The QHttpResponse class handles sending 0038 * data back to the client in response to a request. 0039 * 0040 * The way to respond is to: 0041 * <ol> 0042 * <li>Set headers (optional).</li> 0043 * <li>Call writeHead() with the HTTP status code.</li> 0044 * <li>Call write() zero or more times.</li> 0045 * <li>Call end() when you are ready to end the request.</li> 0046 * </ol> 0047 * 0048 */ 0049 class QHttpResponse : public QObject 0050 { 0051 Q_OBJECT 0052 0053 public: 0054 enum StatusCode { 0055 STATUS_CONTINUE = 100, 0056 STATUS_SWITCH_PROTOCOLS = 101, 0057 STATUS_OK = 200, 0058 STATUS_CREATED = 201, 0059 STATUS_ACCEPTED = 202, 0060 STATUS_NON_AUTHORITATIVE_INFORMATION = 203, 0061 STATUS_NO_CONTENT = 204, 0062 STATUS_RESET_CONTENT = 205, 0063 STATUS_PARTIAL_CONTENT = 206, 0064 STATUS_MULTIPLE_CHOICES = 300, 0065 STATUS_MOVED_PERMANENTLY = 301, 0066 STATUS_FOUND = 302, 0067 STATUS_SEE_OTHER = 303, 0068 STATUS_NOT_MODIFIED = 304, 0069 STATUS_USE_PROXY = 305, 0070 STATUS_TEMPORARY_REDIRECT = 307, 0071 STATUS_BAD_REQUEST = 400, 0072 STATUS_UNAUTHORIZED = 401, 0073 STATUS_PAYMENT_REQUIRED = 402, 0074 STATUS_FORBIDDEN = 403, 0075 STATUS_NOT_FOUND = 404, 0076 STATUS_METHOD_NOT_ALLOWED = 405, 0077 STATUS_NOT_ACCEPTABLE = 406, 0078 STATUS_PROXY_AUTHENTICATION_REQUIRED = 407, 0079 STATUS_REQUEST_TIMEOUT = 408, 0080 STATUS_CONFLICT = 409, 0081 STATUS_GONE = 410, 0082 STATUS_LENGTH_REQUIRED = 411, 0083 STATUS_PRECONDITION_FAILED = 412, 0084 STATUS_REQUEST_ENTITY_TOO_LARGE = 413, 0085 STATUS_REQUEST_URI_TOO_LONG = 414, 0086 STATUS_REQUEST_UNSUPPORTED_MEDIA_TYPE = 415, 0087 STATUS_REQUESTED_RANGE_NOT_SATISFIABLE = 416, 0088 STATUS_EXPECTATION_FAILED = 417, 0089 STATUS_INTERNAL_SERVER_ERROR = 500, 0090 STATUS_NOT_IMPLEMENTED = 501, 0091 STATUS_BAD_GATEWAY = 502, 0092 STATUS_SERVICE_UNAVAILABLE = 503, 0093 STATUS_GATEWAY_TIMEOUT = 504, 0094 STATUS_HTTP_VERSION_NOT_SUPPORTED = 505 0095 }; 0096 0097 virtual ~QHttpResponse(); 0098 0099 public Q_SLOTS: 0100 /*! 0101 * Write the header of the response 0102 * using @c status as the response status 0103 * code. Any headers should be set before this 0104 * is called. 0105 */ 0106 Q_INVOKABLE void writeHead(int status); 0107 0108 /*! 0109 * Write the block of data to the client. 0110 * 0111 * \note 0112 * writeHead() has to be called before write(), otherwise the call will 0113 * fail. 0114 */ 0115 Q_INVOKABLE void write(const QByteArray &data); 0116 0117 /*! 0118 * Write a QString instead of a QByteArray. 0119 * \see write(const QByteArray &); 0120 */ 0121 Q_INVOKABLE void write(const QString &data); 0122 0123 /*! 0124 * Write data that has been encoded in base64. 0125 */ 0126 Q_INVOKABLE void write_b64(const QByteArray &data); 0127 0128 /*! 0129 * End the response. Data will be flushed 0130 * to the underlying socket and the connection 0131 * itself will be closed if this is the last 0132 * response. 0133 * 0134 * This will Q_EMIT done() and queue this object 0135 * for deletion. For details see \ref memorymanagement 0136 */ 0137 Q_INVOKABLE void end(const QString &data=QString()); 0138 0139 /*! 0140 * Set a response header @c field to @c value 0141 */ 0142 Q_INVOKABLE void setHeader(const QString &field, const QString &value); 0143 0144 Q: 0145 /*! 0146 * Emitted once the response is finished. 0147 * You should NOT interact with this object 0148 * after done() has been emitted as the object 0149 * is scheduled for deletion at any time. 0150 */ 0151 void done(); 0152 0153 private: 0154 QHttpResponse(QHttpConnection *connection); 0155 0156 void writeHeaders(); 0157 void writeHeader(const char *field, const QString &value); 0158 0159 QHttpConnection *m_connection; 0160 0161 bool m_headerWritten; 0162 HeaderHash m_headers; 0163 friend class QHttpConnection; 0164 0165 bool m_sentConnectionHeader; 0166 bool m_sentContentLengthHeader; 0167 bool m_sentTransferEncodingHeader; 0168 bool m_sentDate; 0169 bool m_keepAlive; 0170 bool m_last; 0171 bool m_useChunkedEncoding; 0172 bool m_finished; 0173 0174 private Q_SLOTS: 0175 void connectionClosed(); 0176 0177 }; 0178 0179 #endif