qhttpresponse.h 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. /*
  2. * Copyright 2011-2014 Nikhil Marathe <nsm.nikhil@gmail.com>
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a copy
  5. * of this software and associated documentation files (the "Software"), to
  6. * deal in the Software without restriction, including without limitation the
  7. * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. * sell copies of the Software, and to permit persons to whom the Software is
  9. * furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. * IN THE SOFTWARE.
  21. */
  22. #ifndef Q_HTTP_RESPONSE
  23. #define Q_HTTP_RESPONSE
  24. #include "qhttpserverapi.h"
  25. #include "qhttpserverfwd.h"
  26. #include <QObject>
  27. /// The QHttpResponse class handles sending data back to the client as a response to a request.
  28. /** The steps to respond correctly are
  29. <ol>
  30. <li>Call setHeader() to set headers [optional]</li>
  31. <li>Call writeHead() with the HTTP status code</li>
  32. <li>Call write() zero or more times for body data.</li>
  33. <li>Call end() when the resonse can be sent back</li>
  34. </ol> */
  35. class QHTTPSERVER_API QHttpResponse : public QObject
  36. {
  37. Q_OBJECT
  38. public:
  39. /// HTTP status code.
  40. enum StatusCode {
  41. STATUS_CONTINUE = 100,
  42. STATUS_SWITCH_PROTOCOLS = 101,
  43. STATUS_OK = 200,
  44. STATUS_CREATED = 201,
  45. STATUS_ACCEPTED = 202,
  46. STATUS_NON_AUTHORITATIVE_INFORMATION = 203,
  47. STATUS_NO_CONTENT = 204,
  48. STATUS_RESET_CONTENT = 205,
  49. STATUS_PARTIAL_CONTENT = 206,
  50. STATUS_MULTIPLE_CHOICES = 300,
  51. STATUS_MOVED_PERMANENTLY = 301,
  52. STATUS_FOUND = 302,
  53. STATUS_SEE_OTHER = 303,
  54. STATUS_NOT_MODIFIED = 304,
  55. STATUS_USE_PROXY = 305,
  56. STATUS_TEMPORARY_REDIRECT = 307,
  57. STATUS_BAD_REQUEST = 400,
  58. STATUS_UNAUTHORIZED = 401,
  59. STATUS_PAYMENT_REQUIRED = 402,
  60. STATUS_FORBIDDEN = 403,
  61. STATUS_NOT_FOUND = 404,
  62. STATUS_METHOD_NOT_ALLOWED = 405,
  63. STATUS_NOT_ACCEPTABLE = 406,
  64. STATUS_PROXY_AUTHENTICATION_REQUIRED = 407,
  65. STATUS_REQUEST_TIMEOUT = 408,
  66. STATUS_CONFLICT = 409,
  67. STATUS_GONE = 410,
  68. STATUS_LENGTH_REQUIRED = 411,
  69. STATUS_PRECONDITION_FAILED = 412,
  70. STATUS_REQUEST_ENTITY_TOO_LARGE = 413,
  71. STATUS_REQUEST_URI_TOO_LONG = 414,
  72. STATUS_REQUEST_UNSUPPORTED_MEDIA_TYPE = 415,
  73. STATUS_REQUESTED_RANGE_NOT_SATISFIABLE = 416,
  74. STATUS_EXPECTATION_FAILED = 417,
  75. STATUS_INTERNAL_SERVER_ERROR = 500,
  76. STATUS_NOT_IMPLEMENTED = 501,
  77. STATUS_BAD_GATEWAY = 502,
  78. STATUS_SERVICE_UNAVAILABLE = 503,
  79. STATUS_GATEWAY_TIMEOUT = 504,
  80. STATUS_HTTP_VERSION_NOT_SUPPORTED = 505
  81. };
  82. virtual ~QHttpResponse();
  83. /// @cond nodoc
  84. friend class QHttpConnection;
  85. /// @endcond
  86. public Q_SLOTS:
  87. /// Sets a response header @c field to @c value.
  88. /** @note You must call this with all your custom headers
  89. before calling writeHead(), write() or end().
  90. @param field Header field to be set.
  91. @param value Header value to be set. */
  92. void setHeader(const QString &field, const QString &value);
  93. /// Writes the header section of the response
  94. /// using @c status as the response status code.
  95. /** @param statusCode Status code for the response.
  96. @note Any headers should be set before
  97. invoking this function with setHeader(). */
  98. void writeHead(int statusCode);
  99. /** @overload */
  100. void writeHead(StatusCode statusCode);
  101. /// Writes a block of @c data to the client.
  102. /** @note writeHead() must be called before this function. */
  103. void write(const QByteArray &data);
  104. /// Flushes the written data to the client.
  105. /** @note writeHead() must be called before this function. */
  106. void flush();
  107. /// Waiting for bytes to be written. See QAbstractSocket::waitForBytesWritten in the Qt documentation
  108. /** @note writeHead() must be called before this function. */
  109. void waitForBytesWritten();
  110. /// End/finish the response.
  111. /** Data will be flushed to the underlying socket
  112. and the connection itself will be closed if
  113. this is the last response.
  114. This will emit done() and queue this object
  115. for deletion. For details see \ref memorymanagement.
  116. @param data Optional data to be written before finishing. */
  117. void end(const QByteArray &data = "");
  118. Q_SIGNALS:
  119. /// Emitted when all the data has been sent
  120. /** This signal indicates that the underlaying socket has transmitted all
  121. of it's buffered data. It is possible to implement memory-efficient
  122. file transfers by calling \ref write() for a block of data only after
  123. receiving this signal. */
  124. void allBytesWritten();
  125. /// Emitted when the response is finished.
  126. /** You should <b>not</b> interact with this object
  127. after done() has been emitted as the object
  128. has already been scheduled for deletion. */
  129. void done();
  130. private:
  131. QHttpResponse(QHttpConnection *connection);
  132. void writeHeaders();
  133. void writeHeader(const char *field, const QString &value);
  134. QHttpConnection *m_connection;
  135. HeaderHash m_headers;
  136. bool m_headerWritten;
  137. bool m_sentConnectionHeader;
  138. bool m_sentContentLengthHeader;
  139. bool m_sentTransferEncodingHeader;
  140. bool m_sentDate;
  141. bool m_keepAlive;
  142. bool m_last;
  143. bool m_useChunkedEncoding;
  144. bool m_finished;
  145. private Q_SLOTS:
  146. void connectionClosed();
  147. };
  148. #endif