1 /** HTTP client class. 2 * https://github.com/azadkuh/qhttp 3 * 4 * @author amir zamani 5 * @version 2.0.0 6 * @date 2014-07-11 7 */ 8 9 #ifndef QHTTPCLIENT_HPP 10 #define QHTTPCLIENT_HPP 11 12 /////////////////////////////////////////////////////////////////////////////// 13 #include "qhttpfwd.hpp" 14 15 #include <QTcpSocket> 16 #include <QUrl> 17 18 /////////////////////////////////////////////////////////////////////////////// 19 namespace qhttp { 20 namespace client { 21 /////////////////////////////////////////////////////////////////////////////// 22 using TRequstHandler = std::function<void (QHttpRequest*)>; 23 using TResponseHandler = std::function<void (QHttpResponse*)>; 24 25 /** a simple and async HTTP client class which sends a request to an HTTP server and parses the 26 * corresponding response. 27 * This class internally handles the memory management and life cycle of QHttpRequest and 28 * QHttpResponse instances. you do not have to manually delete or keep their pointers. 29 * in fact the QHttpRequest and QHttpResponse object will be deleted when the internal socket 30 * disconnects. 31 */ 32 class QHttpClient : public QObject 33 { 34 Q_OBJECT 35 36 Q_PROPERTY(quint32 timeOut READ timeOut WRITE setTimeOut) 37 38 public: 39 explicit QHttpClient(QObject *parent = nullptr); 40 41 virtual ~QHttpClient(); 42 43 /** tries to connect to a HTTP server. 44 * when the connection is made, the reqHandler will be called 45 * and when the response is ready, resHandler will be called. 46 * @note httpConnected() and newResponse() won't be emitted. 47 * 48 * @param method an HTTP method, ex: GET, POST, ... 49 * @param url specifies server's address, port and optional path and query strings. 50 * if url starts with socket:// the request will be made on QLocalSocket, otherwise 51 * normal QTcpSocket will be used. 52 * @param resHandler response handler (a lambda, std::function object, ...) 53 * @return true if the url is valid or false (no connection will be made). 54 */ 55 bool request(THttpMethod method, QUrl url, 56 const TRequstHandler& reqHandler, 57 const TResponseHandler& resHandler); 58 59 /** tries to connect to a HTTP server. 60 * when the connection is made, a default request handler is called automatically ( 61 * simply calls req->end()) and when the response is ready, resHandler will be called. 62 * @note httpConnected() and newResponse() won't be emitted. 63 * 64 * @param method an HTTP method, ex: GET, POST, ... 65 * @param url specifies server's address, port and optional path and query strings. 66 * @param resHandler response handler (a lambda, std::function object, ...) 67 * @return true if the url is valid or false (no connection will be made). 68 */ request(THttpMethod method,QUrl url,const TResponseHandler & resHandler)69 inline bool request(THttpMethod method, QUrl url, const TResponseHandler& resHandler) { 70 return request(method, url, nullptr, resHandler); 71 } 72 73 /** tries to connect to a HTTP server. 74 * when the connection is made, creates and emits a QHttpRequest instance 75 * by @sa httpConnected(QHttpRequest*). 76 * @note both httpConnected() and newResponse() may be emitted. 77 * 78 * @param method an HTTP method, ex: GET, POST, ... 79 * @param url specifies server's address, port and optional path and query strings. 80 * @return true if the url is valid or false (no connection will be made). 81 */ request(THttpMethod method,QUrl url)82 inline bool request(THttpMethod method, QUrl url) { 83 return request(method, url, nullptr, nullptr); 84 } 85 86 /** checks if the connetion to the server is open. */ 87 bool isOpen() const; 88 89 /** forcefully close the connection. */ 90 void killConnection(); 91 92 93 /** returns time-out value [mSec] for ESTABLISHED connections (sockets). 94 * @sa setTimeOut(). */ 95 quint32 timeOut()const; 96 97 /** set time-out for ESTABLISHED connections in miliseconds [mSec]. 98 * each (already opened) connection will be forcefully closed after this timeout. 99 * a zero (0) value disables timer for new connections. */ 100 void setTimeOut(quint32); 101 102 /** set a time-out [mSec] for making a new connection (make a request). 103 * if connecting to server takes more than this time-out value, 104 * the @sa timedOut(quint32) signal will be emitted and connection will be killed. 105 * 0 (default) timeout value means to disable this timer. 106 */ 107 void setConnectingTimeOut(quint32); 108 109 template<class Handler> setConnectingTimeOut(quint32 timeout,Handler && func)110 void setConnectingTimeOut(quint32 timeout, Handler&& func) { 111 setConnectingTimeOut(timeout); 112 QObject::connect(this, &QHttpClient::connectingTimeOut, 113 std::forward<Handler&&>(func) 114 ); 115 } 116 117 /** returns the backend type of this client. */ 118 TBackend backendType() const; 119 120 /** returns tcp socket of the connection if backend() == ETcpSocket. */ 121 QTcpSocket* tcpSocket() const; 122 123 /** returns local socket of the connection if backend() == ELocalSocket. */ 124 QLocalSocket* localSocket() const; 125 126 signals: 127 /** emitted when a new HTTP connection to the server is established. 128 * if you overload onRequestReady this signal won't be emitted. 129 * @sa onRequestReady 130 * @sa QHttpRequest 131 */ 132 void httpConnected(QHttpRequest* req); 133 134 /** emitted when a new response is received from the server. 135 * if you overload onResponseReady this signal won't be emitted. 136 * @sa onResponseReady 137 * @sa QHttpResponse 138 */ 139 void newResponse(QHttpResponse* res); 140 141 /** emitted when the HTTP connection drops or being disconnected. */ 142 void disconnected(); 143 144 /// emitted when fails to connect to a HTTP server. @sa setConnectingTimeOut() 145 void connectingTimeOut(); 146 147 148 protected: 149 /** called when a new HTTP connection is established. 150 * you can overload this method, the default implementaion only emits connected(). 151 * @param req use this request instance for assinging the 152 * request headers and sending optional body. 153 * @see httpConnected(QHttpRequest*) 154 */ 155 virtual void onRequestReady(QHttpRequest* req); 156 157 /** called when a new response is received from the server. 158 * you can overload this method, the default implementaion only emits newResponse(). 159 * @param res use this instance for reading incoming response. 160 * @see newResponse(QHttpResponse*) 161 */ 162 virtual void onResponseReady(QHttpResponse* res); 163 164 protected: 165 explicit QHttpClient(QHttpClientPrivate&, QObject*); 166 167 void timerEvent(QTimerEvent*) override; 168 169 Q_DECLARE_PRIVATE(QHttpClient) 170 Q_DISABLE_COPY(QHttpClient) 171 QScopedPointer<QHttpClientPrivate> d_ptr; 172 }; 173 174 /////////////////////////////////////////////////////////////////////////////// 175 } // namespace client 176 } // namespace qhttp 177 /////////////////////////////////////////////////////////////////////////////// 178 #endif // define QHTTPCLIENT_HPP 179