qhttprequest.h 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  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_REQUEST
  23. #define Q_HTTP_REQUEST
  24. #include "qhttpserverapi.h"
  25. #include "qhttpserverfwd.h"
  26. #include <QObject>
  27. #include <QMetaEnum>
  28. #include <QMetaType>
  29. #include <QUrl>
  30. /// The QHttpRequest class represents the header and body data sent by the client.
  31. /** The requests header data is available immediately. Body data is streamed as
  32. it comes in via the data() signal. As a consequence the application's request
  33. callback should ensure that it connects to the data() signal before control
  34. returns back to the event loop. Otherwise there is a risk of some data never
  35. being received by the application.
  36. The class is <b>read-only</b>. */
  37. class QHTTPSERVER_API QHttpRequest : public QObject
  38. {
  39. Q_OBJECT
  40. Q_PROPERTY(HeaderHash headers READ headers)
  41. Q_PROPERTY(QString remoteAddress READ remoteAddress)
  42. Q_PROPERTY(quint16 remotePort READ remotePort)
  43. Q_PROPERTY(QString method READ method)
  44. Q_PROPERTY(QUrl url READ url)
  45. Q_PROPERTY(QString path READ path)
  46. Q_PROPERTY(QString httpVersion READ httpVersion)
  47. Q_ENUMS(HttpMethod)
  48. /// @cond nodoc
  49. friend class QHttpConnection;
  50. /// @endcond
  51. public:
  52. virtual ~QHttpRequest();
  53. /// Request method enumeration.
  54. /** @note Taken from http_parser.h -- make sure to keep synced */
  55. enum HttpMethod {
  56. HTTP_DELETE = 0,
  57. HTTP_GET,
  58. HTTP_HEAD,
  59. HTTP_POST,
  60. HTTP_PUT,
  61. // pathological
  62. HTTP_CONNECT,
  63. HTTP_OPTIONS,
  64. HTTP_TRACE,
  65. // webdav
  66. HTTP_COPY,
  67. HTTP_LOCK,
  68. HTTP_MKCOL,
  69. HTTP_MOVE,
  70. HTTP_PROPFIND,
  71. HTTP_PROPPATCH,
  72. HTTP_SEARCH,
  73. HTTP_UNLOCK,
  74. // subversion
  75. HTTP_REPORT,
  76. HTTP_MKACTIVITY,
  77. HTTP_CHECKOUT,
  78. HTTP_MERGE,
  79. // upnp
  80. HTTP_MSEARCH,
  81. HTTP_NOTIFY,
  82. HTTP_SUBSCRIBE,
  83. HTTP_UNSUBSCRIBE,
  84. // RFC-5789
  85. HTTP_PATCH,
  86. HTTP_PURGE
  87. };
  88. /// The method used for the request.
  89. HttpMethod method() const;
  90. /// Returns the method string for the request.
  91. /** @note This will plainly transform the enum into a string HTTP_GET -> "HTTP_GET". */
  92. const QString methodString() const;
  93. /// The complete URL for the request.
  94. /** This includes the path and query string.
  95. @sa path() */
  96. const QUrl &url() const;
  97. /// The path portion of the query URL.
  98. /** @sa url() */
  99. const QString path() const;
  100. /// The HTTP version of the request.
  101. /** @return A string in the form of "x.x" */
  102. const QString &httpVersion() const;
  103. /// Return all the headers sent by the client.
  104. /** This returns a reference. If you want to store headers
  105. somewhere else, where the request may be deleted,
  106. make sure you store them as a copy.
  107. @note All header names are <b>lowercase</b>
  108. so that Content-Length becomes content-length etc. */
  109. const HeaderHash &headers() const;
  110. /// Get the value of a header.
  111. /** Headers are stored as lowercase so the input @c field will be lowercased.
  112. @param field Name of the header field
  113. @return Value of the header or empty string if not found. */
  114. QString header(const QString &field);
  115. /// IP Address of the client in dotted decimal format.
  116. const QString &remoteAddress() const;
  117. /// Outbound connection port for the client.
  118. quint16 remotePort() const;
  119. /// Request body data, empty for non POST/PUT requests.
  120. /** @sa storeBody() */
  121. const QByteArray &body() const
  122. {
  123. return m_body;
  124. }
  125. /// If this request was successfully received.
  126. /** Set before end() has been emitted, stating whether
  127. the message was properly received. This is false
  128. until the receiving the full request has completed. */
  129. bool successful() const
  130. {
  131. return m_success;
  132. }
  133. /// Utility function to make this request store all body data internally.
  134. /** If you call this when the request is received via QHttpServer::newRequest()
  135. the request will take care of storing the body data for you.
  136. Once the end() signal is emitted you can access the body data with
  137. the body() function.
  138. If you wish to handle incoming data yourself don't call this function
  139. and see the data() signal.
  140. @sa data() body() */
  141. void storeBody();
  142. Q_SIGNALS:
  143. /// Emitted when new body data has been received.
  144. /** @note This may be emitted zero or more times
  145. depending on the request type.
  146. @param data Received data. */
  147. void data(const QByteArray &data);
  148. /// Emitted when the request has been fully received.
  149. /** @note The no more data() signals will be emitted after this. */
  150. void end();
  151. private Q_SLOTS:
  152. void appendBody(const QByteArray &body);
  153. private:
  154. QHttpRequest(QHttpConnection *connection, QObject *parent = 0);
  155. static QString MethodToString(HttpMethod method);
  156. void setMethod(HttpMethod method) { m_method = method; }
  157. void setVersion(const QString &version) { m_version = version; }
  158. void setUrl(const QUrl &url) { m_url = url; }
  159. void setHeaders(const HeaderHash headers) { m_headers = headers; }
  160. void setSuccessful(bool success) { m_success = success; }
  161. QHttpConnection *m_connection;
  162. HeaderHash m_headers;
  163. HttpMethod m_method;
  164. QUrl m_url;
  165. QString m_version;
  166. QString m_remoteAddress;
  167. quint16 m_remotePort;
  168. QByteArray m_body;
  169. bool m_success;
  170. };
  171. #endif