1# A wrapper for the Qt Network Access API 2 3This is just a wrapper around Qt's QNetworkAccessManager and friends. I use it in my apps at https://flavio.tordini.org . It has a simpler, higher-level API and some functionality not found in Qt: 4 5- Throttling (as required by many web APIs nowadays) 6- Automatic retries 7- User agent and request header defaults 8- Partial requests 9- Easier POST requests 10- Read timeouts (don't let your requests get stuck forever). (now supported by Qt >= 5.15) 11- Redirection support (now supported by Qt >= 5.6) 12- Disk-based cache implementation similar to Qt's but not strictly a HTTP cache, i.e. it ignores HTTP headers. This is good if want to cache successful requests irrespective of what the origin server says you should do. The cache also fallbacks to stale content when the server returns an error. 13 14## Design 15 16This library uses the [Decorator design pattern](https://en.wikipedia.org/wiki/Decorator_pattern) to modularize features and make it easy to add them and use them as needed. The main class is [Http](https://github.com/flaviotordini/http/blob/master/src/http.h), which implements the base features of a HTTP client. More specialized classes are: 17 18- [CachedHttp](https://github.com/flaviotordini/http/blob/master/src/cachedhttp.h), a simple disk-based cache 19- [ThrottledHttp](https://github.com/flaviotordini/http/blob/master/src/throttledhttp.h), implements request throttling (aka limiting) 20 21The constructor of these classes takes another Http instance for which they will act as a proxy. (See examples below). Following this design you can create your own Http subclass. For example, a different caching mechanism, an event dispatcher, custom request logging, etc. 22 23 24## Build Instructions 25In order to build this library you can use either `qmake` or `cmake`. 26 27### qmake 28``` 29mkdir build 30cd build 31qmake .. 32make 33``` 34 35### CMake 36``` 37mkdir build 38cd build 39cmake .. 40make 41``` 42 43## Integration 44 45You can use this library as a git submodule. For example, add it to your project inside a lib subdirectory: 46 47``` 48git submodule add -b master https://github.com/flaviotordini/http lib/http 49``` 50 51Then you can update your git submodules like this: 52 53``` 54git submodule update --init --recursive --remote 55``` 56 57To integrate the library in your qmake based project just add this to your .pro file: 58 59``` 60include(lib/http/http.pri) 61``` 62 63qmake builds all object files in the same directory. In order to avoid filename clashes use: 64 65``` 66CONFIG += object_parallel_to_source 67``` 68 69If you are using CMake you can integrate the library by adding the following lines to your CMakeLists.txt: 70 71``` 72add_subdirectory(lib/http) 73... 74target_link_library(your_super_cool_project <other libraries> http) 75``` 76or if you have installed http you can find it via: 77 78``` 79find_library(http REQUIRED) 80... 81target_link_library(your_super_cool_project <other libraries> http) 82``` 83 84 85## Examples 86 87A basic C++14 example: 88 89``` 90#include "http.h" 91 92auto reply = Http::instance().get("https://google.com/"); 93connect(reply, &HttpReply::finished, this, [](auto &reply) { 94 if (reply.isSuccessful()) { 95 qDebug() << "Feel the bytes!" << reply.body(); 96 } else { 97 qDebug() << "Something's wrong here" << reply.statusCode() << reply.reasonPhrase(); 98 } 99}); 100``` 101 102Or using two separate signals for success and failure: 103``` 104#include "http.h" 105 106auto reply = Http::instance().get("https://google.com/"); 107connect(reply, &HttpReply::data, this, [](auto &bytes) { 108 qDebug() << "Feel the bytes!" << bytes; 109}); 110connect(reply, &HttpReply::error, this, [](auto &msg) { 111 qDebug() << "Something's wrong here" << msg; 112}); 113``` 114 115This is a real-world example of building a Http object with more complex features. It throttles requests, uses a custom user agent and caches results: 116 117``` 118#include "http.h" 119#include "cachedhttp.h" 120#include "throttledhttp.h" 121 122Http &myHttp() { 123 static Http *http = [] { 124 Http *http = new Http; 125 http->addRequestHeader("User-Agent", userAgent()); 126 127 ThrottledHttp *throttledHttp = new ThrottledHttp(*http); 128 throttledHttp->setMilliseconds(1000); 129 130 CachedHttp *cachedHttp = new CachedHttp(*throttledHttp, "mycache"); 131 cachedHttp->setMaxSeconds(86400 * 30); 132 133 return cachedHttp; 134 }(); 135 return *http; 136} 137``` 138 139If the full power (and complexity) of QNetworkReply is needed you can always fallback to it: 140 141``` 142#include "http.h" 143 144HttpRequest req; 145req.url = "https://flavio.tordini.org/"; 146QNetworkReply *reply = Http::instance().networkReply(req); 147// Use QNetworkReply as needed... 148``` 149 150Note that features like redirection, retries and read timeouts won't work in this mode. 151 152## License 153 154You can use this library under the MIT license and at your own risk. If you do, you're welcome contributing your changes and fixes. 155