qhttpabstracts.hpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /** interfaces of QHttp' incomming and outgoing classes.
  2. * https://github.com/azadkuh/qhttp
  3. *
  4. * @author amir zamani
  5. * @version 2.0.0
  6. * @date 2014-07-11
  7. */
  8. #ifndef QHTTPABSTRACTS_HPP
  9. #define QHTTPABSTRACTS_HPP
  10. ///////////////////////////////////////////////////////////////////////////////
  11. #include "qhttpfwd.hpp"
  12. #include <QObject>
  13. #include <functional>
  14. ///////////////////////////////////////////////////////////////////////////////
  15. namespace qhttp {
  16. ///////////////////////////////////////////////////////////////////////////////
  17. /** a utility class to give the string representation of qhttp types. */
  18. class QHTTP_API Stringify
  19. {
  20. public:
  21. /** returns the standard message for an HTTP status code. */
  22. static const char* toString(TStatusCode);
  23. /** returns the standars name of an HTTP method. */
  24. static const char* toString(THttpMethod);
  25. };
  26. ///////////////////////////////////////////////////////////////////////////////
  27. typedef std::function<void (QByteArray)> TDataHandler;
  28. typedef std::function<void (void)> TEndHandler;
  29. ///////////////////////////////////////////////////////////////////////////////
  30. /** an interface for input (incoming) HTTP packets.
  31. * server::QHttpRequest or client::QHttpResponse inherit from this class. */
  32. class QHTTP_API QHttpAbstractInput : public QObject
  33. {
  34. Q_OBJECT
  35. public:
  36. /** Return all the headers in the incomming packet.
  37. * This returns a reference. If you want to store headers
  38. * somewhere else, where the request may be deleted,
  39. * make sure you store them as a copy.
  40. * @note All header names are <b>lowercase</b> . */
  41. virtual const THeaderHash& headers() const=0;
  42. /** The HTTP version of the packet.
  43. * @return A string in the form of "x.x" */
  44. virtual const QString& httpVersion() const=0;
  45. /** If this packet was successfully received.
  46. * Set before end() has been emitted, stating whether
  47. * the message was properly received. This is false
  48. * until the receiving the full request has completed. */
  49. virtual bool isSuccessful() const=0;
  50. signals:
  51. /** Emitted when new body data has been received.
  52. * @param data Received data.
  53. * @note This may be emitted zero or more times depending on the transfer type.
  54. * @see onData();
  55. */
  56. void data(QByteArray data);
  57. /** Emitted when the incomming packet has been fully received.
  58. * @note The no more data() signals will be emitted after this.
  59. * @see onEnd();
  60. */
  61. void end();
  62. public:
  63. /** optionally set a handler for data() signal.
  64. * @param dataHandler a std::function or lambda handler to receive incoming data.
  65. * @note if you set this handler, the data() signal won't be emitted anymore.
  66. */
  67. void onData(const TDataHandler& dataHandler) {
  68. QObject::connect(this, &QHttpAbstractInput::data, [dataHandler](QByteArray data){
  69. dataHandler(data);
  70. });
  71. }
  72. /** optionally set a handler for end() signal.
  73. * @param endHandler a std::function or lambda handler to receive end notification.
  74. * @note if you set this handler, the end() signal won't be emitted anymore.
  75. */
  76. void onEnd(const TEndHandler& endHandler) {
  77. QObject::connect(this, &QHttpAbstractInput::end, [endHandler](){
  78. endHandler();
  79. });
  80. }
  81. public:
  82. /** tries to collect all the incoming data internally.
  83. * @note if you call this method, data() signal won't be emitted and
  84. * onData() will have no effect.
  85. *
  86. * @param atMost maximum acceptable incoming data. if the incoming data
  87. * exceeds this value, the connection won't read any more data and
  88. * end() signal will be emitted. -1 means unlimited.
  89. */
  90. virtual void collectData(int atMost = -1) =0;
  91. /** returns the collected data requested by collectData(). */
  92. virtual const QByteArray& collectedData()const =0;
  93. public:
  94. virtual ~QHttpAbstractInput() = default;
  95. explicit QHttpAbstractInput(QObject* parent);
  96. Q_DISABLE_COPY(QHttpAbstractInput)
  97. };
  98. ///////////////////////////////////////////////////////////////////////////////
  99. /** an interface for output (outgoing) HTTP packets.
  100. * server::QHttpResponse or client::QHttpRequest inherit from this class. */
  101. class QHTTP_API QHttpAbstractOutput : public QObject
  102. {
  103. Q_OBJECT
  104. public:
  105. /** changes the HTTP version string ex: "1.1" or "1.0".
  106. * version is "1.1" set by default. */
  107. virtual void setVersion(const QString& versionString)=0;
  108. /** helper function. @sa addHeader */
  109. template<typename T>
  110. void addHeaderValue(const QByteArray &field, T value);
  111. /** adds an HTTP header to the packet.
  112. * @note this method does not actually write anything to socket, just prepares the headers(). */
  113. virtual void addHeader(const QByteArray& field, const QByteArray& value)=0;
  114. /** returns all the headers that already been set. */
  115. virtual THeaderHash& headers()=0;
  116. /** writes a block of data into the HTTP packet.
  117. * @note headers are written (flushed) before any data.
  118. * @warning after calling this method add a new header, set staus code, set Url have no effect! */
  119. virtual void write(const QByteArray &data)=0;
  120. /** ends (finishes) the outgoing packet by calling write().
  121. * headers and data will be flushed to the underlying socket.
  122. *
  123. * @sa write() */
  124. virtual void end(const QByteArray &data = QByteArray())=0;
  125. signals:
  126. /** Emitted when all the data has been sent.
  127. * this signal indicates that the underlaying socket has transmitted all
  128. * of it's buffered data. */
  129. void allBytesWritten();
  130. /** Emitted when the packet is finished and reports if it was the last packet.
  131. * if it was the last packet (google for "Connection: keep-alive / close")
  132. * the http connection (socket) will be closed automatically. */
  133. void done(bool wasTheLastPacket);
  134. public:
  135. virtual ~QHttpAbstractOutput() = default;
  136. protected:
  137. explicit QHttpAbstractOutput(QObject* parent);
  138. Q_DISABLE_COPY(QHttpAbstractOutput)
  139. };
  140. template<> inline void
  141. QHttpAbstractOutput::addHeaderValue<int>(const QByteArray &field, int value) {
  142. addHeader(field, QString::number(value).toLatin1());
  143. }
  144. template<> inline void
  145. QHttpAbstractOutput::addHeaderValue<size_t>(const QByteArray &field, size_t value) {
  146. addHeader(field, QString::number(value).toLatin1());
  147. }
  148. template<> inline void
  149. QHttpAbstractOutput::addHeaderValue<QString>(const QByteArray &field, QString value) {
  150. addHeader(field, value.toUtf8());
  151. }
  152. ///////////////////////////////////////////////////////////////////////////////
  153. } // namespace qhttp
  154. ///////////////////////////////////////////////////////////////////////////////
  155. #endif // QHTTPABSTRACTS_HPP