Skip to content

Commit 0af9372

Browse files
Merge pull request #28 from lk-libs/limiting-bandwidth-usage
Limiting bandwidth usage
2 parents 7437a56 + ba2825b commit 0af9372

File tree

4 files changed

+313
-209
lines changed

4 files changed

+313
-209
lines changed

README.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ Modern, non-blocking and exception free, header-only HTTP Client library for C++
2424
* [POST request with JSON data](#post-request-with-json-data)
2525
* [What about others? (PUT, DELETE, PATCH)](#what-about-others-put-delete-patch)
2626
* [How to ignore SSL certificate errors?](#how-to-ignore-ssl-certificate-errors)
27+
* [How can I limit download and upload bandwidth?](#how-can-i-limit-download-and-upload-bandwidth)
2728
* [Semantic Versioning](#semantic-versioning)
2829
* [Full function list](#full-function-list)
2930
* [License](#license)
@@ -387,6 +388,31 @@ int main() {
387388
```
388389

389390

391+
## How can I limit download and upload bandwidth?
392+
393+
If you do not want the bandwidth to exceed a certain limit during the download and upload process, you can determine the maximum limit that can be used in Bytes with the setDownloadBandwidthLimit and setUploadBandwidthLimit methods.
394+
395+
```cpp
396+
#include <fstream>
397+
#include "libcpp-http-client.hpp"
398+
399+
using namespace lklibs;
400+
401+
int main() {
402+
HttpRequest httpRequest("https://api.myproject.com");
403+
404+
// You can set the download and upload bandwidth limit in bytes per second
405+
auto response = httpRequest
406+
.setDownloadBandwidthLimit(10240) // 10 KB/sec
407+
.setUploadBandwidthLimit(20480) // 20 KB/sec
408+
.send()
409+
.get();
410+
411+
return 0;
412+
}
413+
```
414+
415+
390416
## Semantic Versioning
391417

392418
Versioning of the library is done using conventional semantic versioning. Accordingly,

examples/main.cpp

Lines changed: 73 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,24 @@
1-
#include <fstream>
21
#include "libcpp-http-client.hpp"
32

43
using namespace lklibs;
54

6-
void simpleGet() {
7-
5+
void simpleGet()
6+
{
87
HttpRequest httpRequest("https://httpbun.com/get");
98

109
// The simplest but slowest method if multiple calls will be made
1110
auto response = httpRequest
12-
.setQueryString("param1=7&param2=test")
13-
.send()
14-
.get();
11+
.setQueryString("param1=7&param2=test")
12+
.send()
13+
.get();
1514

1615
std::cout << "Succeed: " << response.succeed << std::endl;
1716
std::cout << "Http Status Code: " << response.statusCode << std::endl;
1817
std::cout << "Data: " << response.textData << std::endl;
1918
}
2019

21-
void nonBlockingGet() {
22-
20+
void nonBlockingGet()
21+
{
2322
HttpRequest httpRequest1("https://httpbun.com/get");
2423
HttpRequest httpRequest2("https://httpbun.com/get");
2524
HttpRequest httpRequest3("https://httpbun.com/get");
@@ -47,15 +46,15 @@ void nonBlockingGet() {
4746
std::cout << "Response3 Data: " << response3.textData << std::endl;
4847
}
4948

50-
void receiveBinaryData() {
51-
49+
void receiveBinaryData()
50+
{
5251
HttpRequest httpRequest("https://httpbun.com/bytes/100");
5352

5453
// If you need to retrieve binary data such as an image, just call the "returnAsBinary" method before send
5554
auto response = httpRequest
56-
.returnAsBinary()
57-
.send()
58-
.get();
55+
.returnAsBinary()
56+
.send()
57+
.get();
5958

6059
std::cout << "Succeed: " << response.succeed << std::endl;
6160
std::cout << "Http Status Code: " << response.statusCode << std::endl;
@@ -64,8 +63,8 @@ void receiveBinaryData() {
6463
std::cout << "Data Size: " << response.binaryData.size() << std::endl;
6564
}
6665

67-
void receiveError() {
68-
66+
void receiveError()
67+
{
6968
HttpRequest httpRequest("https://httpbun.com/not_found");
7069

7170
// This is an exception free library. If an error occurs, no exception is thrown
@@ -81,103 +80,103 @@ void receiveError() {
8180
std::cout << "Error Message: " << response.errorMessage << std::endl;
8281
}
8382

84-
void sendingHttpHeaders() {
85-
83+
void sendingHttpHeaders()
84+
{
8685
HttpRequest httpRequest("https://httpbun.com/get?param1=7&param2=test");
8786

8887
// You can send custom headers as key-value pairs
8988
auto response = httpRequest
90-
.addHeader("Custom-Header1", "value1")
91-
.addHeader("Custom-Header2", "value2")
92-
.send()
93-
.get();
89+
.addHeader("Custom-Header1", "value1")
90+
.addHeader("Custom-Header2", "value2")
91+
.send()
92+
.get();
9493

9594
std::cout << "Succeed: " << response.succeed << std::endl;
9695
}
9796

98-
void simplePostWithFormData() {
99-
97+
void simplePostWithFormData()
98+
{
10099
HttpRequest httpRequest("https://httpbun.com/post");
101100

102101
// You can send a POST request with form data in the payload
103102
auto response = httpRequest
104-
.setMethod(HttpMethod::POST)
105-
.setPayload("param1=7&param2=test")
106-
.send()
107-
.get();
103+
.setMethod(HttpMethod::POST)
104+
.setPayload("param1=7&param2=test")
105+
.send()
106+
.get();
108107

109108
std::cout << "Succeed: " << response.succeed << std::endl;
110109
std::cout << "Http Status Code: " << response.statusCode << std::endl;
111110
std::cout << "Data: " << response.textData << std::endl;
112111
}
113112

114-
void simplePostWithJSONData() {
115-
113+
void simplePostWithJSONData()
114+
{
116115
HttpRequest httpRequest("https://httpbun.com/post");
117116

118117
// You need to send the "Content-Type" as "application/json" in the HTTP Header, if you need to send json data in the payload
119118
auto response = httpRequest
120-
.setMethod(HttpMethod::POST)
121-
.setPayload(R"({"param1": 7, "param2": "test"})")
122-
.addHeader("Content-Type", "application/json")
123-
.send()
124-
.get();
119+
.setMethod(HttpMethod::POST)
120+
.setPayload(R"({"param1": 7, "param2": "test"})")
121+
.addHeader("Content-Type", "application/json")
122+
.send()
123+
.get();
125124

126125
std::cout << "Succeed: " << response.succeed << std::endl;
127126
std::cout << "Http Status Code: " << response.statusCode << std::endl;
128127
std::cout << "Data: " << response.textData << std::endl;
129128
}
130129

131-
void simplePutWithFormData() {
132-
130+
void simplePutWithFormData()
131+
{
133132
HttpRequest httpRequest("https://httpbun.com/put");
134133

135134
// You can send a PUT request with form data in the payload just like POST
136135
auto response = httpRequest
137-
.setMethod(HttpMethod::PUT)
138-
.setPayload("param1=7&param2=test")
139-
.send()
140-
.get();
136+
.setMethod(HttpMethod::PUT)
137+
.setPayload("param1=7&param2=test")
138+
.send()
139+
.get();
141140

142141
std::cout << "Succeed: " << response.succeed << std::endl;
143142
std::cout << "Http Status Code: " << response.statusCode << std::endl;
144143
std::cout << "Data: " << response.textData << std::endl;
145144
}
146145

147-
void simpleDeleteWithFormData() {
148-
146+
void simpleDeleteWithFormData()
147+
{
149148
HttpRequest httpRequest("https://httpbun.com/delete");
150149

151150
// You can send a DELETE request with form data in the payload just like POST
152151
auto response = httpRequest
153-
.setMethod(HttpMethod::DELETE_)
154-
.setPayload("param1=7&param2=test")
155-
.send()
156-
.get();
152+
.setMethod(HttpMethod::DELETE_)
153+
.setPayload("param1=7&param2=test")
154+
.send()
155+
.get();
157156

158157
std::cout << "Succeed: " << response.succeed << std::endl;
159158
std::cout << "Http Status Code: " << response.statusCode << std::endl;
160159
std::cout << "Data: " << response.textData << std::endl;
161160
}
162161

163-
void simplePatch() {
164-
162+
void simplePatch()
163+
{
165164
HttpRequest httpRequest("https://httpbun.com/patch");
166165

167166
// You can send a PATCH request with QueryString just like GET
168167
auto response = httpRequest
169-
.setMethod(HttpMethod::PATCH)
170-
.setQueryString("param1=7&param2=test")
171-
.send()
172-
.get();
168+
.setMethod(HttpMethod::PATCH)
169+
.setQueryString("param1=7&param2=test")
170+
.send()
171+
.get();
173172

174173
std::cout << "Succeed: " << response.succeed << std::endl;
175174
std::cout << "Http Status Code: " << response.statusCode << std::endl;
176175
std::cout << "Data: " << response.textData << std::endl;
177176
}
178177

179-
void ignoreSslErrors() {
180-
178+
void ignoreSslErrors()
179+
{
181180
HttpRequest httpRequest("https://self-signed-cert.httpbun.com");
182181

183182
// If you need to ignore SSL errors, you can call "ignoreSslErrors" method before sending the request
@@ -188,9 +187,25 @@ void ignoreSslErrors() {
188187
std::cout << "Data: " << response.textData << std::endl;
189188
}
190189

190+
void setDownloadAndUploadBandwidthLimit()
191+
{
192+
HttpRequest httpRequest("https://httpbun.com/get");
193+
194+
// You can set the download and upload bandwidth limit in bytes per second
195+
auto response = httpRequest
196+
.setDownloadBandwidthLimit(10240) // 10 KB/sec
197+
.setUploadBandwidthLimit(20480) // 20 KB/sec
198+
.send()
199+
.get();
200+
201+
std::cout << "Succeed: " << response.succeed << std::endl;
202+
std::cout << "Http Status Code: " << response.statusCode << std::endl;
203+
std::cout << "Data: " << response.textData << std::endl;
204+
}
191205

192-
int main() {
193206

207+
int main()
208+
{
194209
simpleGet();
195210

196211
nonBlockingGet();
@@ -213,5 +228,7 @@ int main() {
213228

214229
ignoreSslErrors();
215230

231+
setDownloadAndUploadBandwidthLimit();
232+
216233
return 0;
217-
}
234+
}

src/libcpp-http-client.hpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,30 @@ namespace lklibs {
224224
return *this;
225225
}
226226

227+
/**
228+
* @brief Set the download bandwidth limit for the request
229+
*
230+
* @param limit: Download bandwidth limit in bytes per second (0 for no limit)
231+
*/
232+
HttpRequest &setDownloadBandwidthLimit(int limit) noexcept {
233+
234+
this->downloadBandwidthLimit = limit;
235+
236+
return *this;
237+
}
238+
239+
/**
240+
* @brief Set the upload bandwidth limit for the request
241+
*
242+
* @param limit: Upload bandwidth limit in bytes per second (0 for no limit)
243+
*/
244+
HttpRequest &setUploadBandwidthLimit(int limit) noexcept {
245+
246+
this->uploadBandwidthLimit = limit;
247+
248+
return *this;
249+
}
250+
227251
/**
228252
* @brief Send the HTTP request and return the result as a future
229253
* The result can be obtained by calling the get() method of the future
@@ -258,6 +282,8 @@ namespace lklibs {
258282
bool sslErrorsWillBeIgnored = false;
259283
ReturnFormat returnFormat = ReturnFormat::TEXT;
260284
std::map<std::string, std::string> headers;
285+
int uploadBandwidthLimit = 0;
286+
int downloadBandwidthLimit = 0;
261287

262288
struct CurlDeleter {
263289

@@ -310,6 +336,9 @@ namespace lklibs {
310336
curl_easy_setopt(curl.get(), CURLOPT_CUSTOMREQUEST, this->method.c_str());
311337
curl_easy_setopt(curl.get(), CURLOPT_SSL_VERIFYPEER, this->sslErrorsWillBeIgnored ? 0L : 1L);
312338
curl_easy_setopt(curl.get(), CURLOPT_SSL_VERIFYHOST, this->sslErrorsWillBeIgnored ? 0L : 1L);
339+
curl_easy_setopt(curl.get(), CURLOPT_MAX_SEND_SPEED_LARGE, this->uploadBandwidthLimit);
340+
curl_easy_setopt(curl.get(), CURLOPT_MAX_RECV_SPEED_LARGE, this->downloadBandwidthLimit);
341+
313342

314343
if (!this->payload.empty()) {
315344

0 commit comments

Comments
 (0)