Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/4l3x777/ehlib
Ehlib: Embedded http(s) library
https://github.com/4l3x777/ehlib
Last synced: about 1 month ago
JSON representation
Ehlib: Embedded http(s) library
- Host: GitHub
- URL: https://github.com/4l3x777/ehlib
- Owner: 4l3x777
- License: mit
- Created: 2023-08-12T15:30:19.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2023-08-12T15:37:46.000Z (over 1 year ago)
- Last Synced: 2023-12-12T22:16:08.455Z (about 1 year ago)
- Language: C
- Size: 519 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
EHLIB: Embedded http(s) library
A tiny, C++ network socket wrapper (based on [Mongoose](https://github.com/cesanta/mongoose.git) and [Mbed-TLS](https://github.com/Mbed-TLS/mbedtls.git)) for http(s) requests especially for embedded devices. Inspired by the excellent [CPR library](https://github.com/whoshuu/cpr), [WNetWrap](https://github.com/hack-tramp/WNetWrap.git), it has mostly identical function names, and will likewise work with random parameter order.
## Features
|Implemented| Upcoming|
|:------------:|:----------:|
|Custom headers|Cookie support|
|Url encoded parameters|Self-signed Root CA support, All well-known Root CA support|
|Multipart upload|Change default dns server|
|File upload|Add auth proxy|
|Custom request methods|
|Basic authentication|
|Bearer authentication|
|Request timeout|
|Non-Auth Proxy support|That is a basic GET request - for detailed examples see the documentation below.
```C++
#include
#include "ehlib.h"
//Tested on Postman Echo
//GET Request
ehlib::Response r = ehlib::request(
ehlib::RequestUrl{"https://postman-echo.com/get"},
ehlib::UrlRequestParams{
{"foo1", "bar1"},
{"foo2", "bar2"}
},
ehlib::RequestMethod{"GET"},
ehlib::RequestUserAgent{"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"}
);std::cout << r.raw << std::endl; // basic parser
std::cout << r.status_code << std::endl; // 200
```## Usage (tested on Linux & Windows)
1. Just copy folders `include`, `lib` into your project.
2. Add static libs and include `ehlib.h` into your build.
3. That's it!
## Documentation
For now it's all here on the readme, but it will eventually be put on a different page to make navigation more user friendly.
To navigate through it use the table of contents dropdown menu.
### GET requests
Making a `GET` request with `Ehlib` is simple - the `GET` method is used by default so doesn't need to be specified:
```C++
#include "ehlib.h"
ehlib::Response r = ehlib::request(
ehlib::RequestUrl{"https://postman-echo.com/get"},
ehlib::RequestUserAgent{"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"}
);
```This gives us a `Response` object which we’ve called r.
There’s a lot of useful stuff in there:
```C++
std::cout << r.url << std::endl; // https://postman-echo.com/getstd::cout << r.status_code << std::endl; // 200
std::cout << r.header["Content-type"] << std::endl; // application/json; charset=utf-8
std::cout << r.raw << std::endl;
/*
{
"args": {},
"headers": {
"x-forwarded-proto": "https",
"x-forwarded-port": "443",
"host": "postman-echo.com",
"x-amzn-trace-id": "Root=1-64d67257-24fc86582562e80206287bbe",
"content-length": "0",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
},
"url": "https://postman-echo.com/get"
}
*/
```To add URL-encoded parameters, add a `UrlRequestParams` object to the `request` call:
```C++
auto r = ehlib::request(
ehlib::RequestUrl{"https://postman-echo.com/get"},
ehlib::UrlRequestParams{
{"foo1", "bar1"},
{"foo2", "bar2"}
},
ehlib::RequestUserAgent{"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"}
);std::cout << r.url << std::endl; // https://postman-echo.com/get?foo1=bar1&foo2=bar2
std::cout << r.raw << std::endl;/*
{
"args": {
"foo1": "bar1",
"foo2": "bar2"
},
"headers": {
"x-forwarded-proto": "https",
"x-forwarded-port": "443",
"host": "postman-echo.com",
"x-amzn-trace-id": "Root=1-64d674e0-26f038a10e869e521dcdbfdc",
"content-length": "0",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
},
"url": "https://postman-echo.com/get?foo1=bar1&foo2=bar2"
}
*/
````UrlRequestParams` is an object with a map-like interface.
You can construct it using a list of key/value pairs inside the `request` or have it outlive `request` by constructing it outside:
```C++
// Constructing it in a place
auto r = ehlib::request(
ehlib::RequestUrl{"http://www.httpbin.org/get"},
ehlib::UrlRequestParams{
{"foo1", "bar1"},
{"foo2", "bar2"}
},
ehlib::RequestUserAgent{"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"}
);std::cout << r.url << std::endl; // https://postman-echo.com/get?foo1=bar1&foo2=bar2
std::cout << r.raw << std::endl;
/*
{
"args": {
"foo1": "bar1",
"foo2": "bar2"
},
"headers": {
"x-forwarded-proto": "https",
"x-forwarded-port": "443",
"host": "postman-echo.com",
"x-amzn-trace-id": "Root=1-64d67627-0f91d09203e69af636c8fcfb",
"content-length": "0",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
},
"url": "https://postman-echo.com/get?foo1=bar1&foo2=bar2"
}
*/// Constructing it an outside
auto parameters = ehlib::UrlRequestParams{
{"foo1", "bar1"},
{"foo2", "bar2"}
};auto r_outside = ehlib::request(
ehlib::RequestUrl{"https://postman-echo.com/get"},
parameters
);std::cout << r_outside.url << std::endl; // https://postman-echo.com/get?foo1=bar1&foo2=bar2
std::cout << r_outside.raw << std::endl; // Same text response as above
```### Download a file
To download the contents of the request you simply add `RequestUrl` to `request`.
File content will return into Response's `raw` field.
For example, to download the CPR library:
```C++
auto r = ehlib::request(
ehlib::RequestUrl{ "https://github.com/whoshuu/cpr/archive/refs/tags/1.10.4.zip" },
ehlib::RequestUserAgent{"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"}
);std::cout << r.raw << std::endl; // print donwloaded file's content (our 1.10.4.zip archive bytes)
```### POST Requests
Making a POST request must use `RequestMethod`:
```C++
auto r = ehlib::request(
ehlib::RequestUrl{"https://postman-echo.com/post"},
ehlib::RequestMethod{"POST"}
);std::cout << r.text << std::endl;
/*
{
"args": {},
"data": {},
"files": {},
"form": {},
"headers": {
"x-forwarded-proto": "https",
"x-forwarded-port": "443",
"host": "postman-echo.com",
"x-amzn-trace-id": "Root=1-64d688e8-1a56cc76092b9abd7de205d9",
"content-length": "0",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
},
"json": null,
"url": "https://postman-echo.com/post"
}
*/
```This sends some data `"This is raw POST data"` with use `PostRequestBody`:
```C++
auto r = ehlib::request(
ehlib::RequestUrl{"https://postman-echo.com/post"},
ehlib::PostRequestBody{"This is raw POST data"},
ehlib::RequestMethod{"POST"}
);std::cout << r.text << std::endl;
/*
{
"args": {},
"data": "This is raw POST data",
"files": {},
"form": {},
"headers": {
"x-forwarded-proto": "https",
"x-forwarded-port": "443",
"host": "postman-echo.com",
"x-amzn-trace-id": "Root=1-64d689c1-3a281bae0158913d6a4f240a",
"content-length": "21",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36",
"content-type": "application/json"
},
"json": null,
"url": "https://postman-echo.com/post"
}
*/
```If the data package is large or contains a file, it’s more appropriate to use a `RequestMultipartUpload` upload.
In this example we are uploading a text files to `https://postman-echo.com/post`:
```C++
auto r = ehlib::request(
ehlib::RequestUrl{"https://postman-echo.com/post"},
ehlib::RequestMultipartUpload{
{"file_path:1.txt", "1.txt"},
{"file_path:C:/Windows/win.ini", "win.ini"},
{"some raw data", "2.txt"}
},
ehlib::RequestMethod{"POST"}
);std::cout << r.text << std::endl;
/*
{
"args": {},
"data": {},
"files": {
"1.txt": "data:application/octet-stream;base64,aGVsbG8gd29ybGQh",
"win.ini": "data:application/octet-stream;base64,OyBmb3IgMTYtYml0IGFwcCBzdXBwb3J0DQpbZm9udHNdDQpbZXh0ZW5zaW9uc10NClttY2kgZXh0ZW5zaW9uc10NCltmaWxlc10NCltNYWlsXQ0KTUFQST0xDQo="
},
"form": {
"some raw data": "2.txt"
},
"headers": {
"x-forwarded-proto": "https",
"x-forwarded-port": "443",
"host": "postman-echo.com",
"x-amzn-trace-id": "Root=1-64d68e5f-0e0b852e32702ddc7806ff31",
"content-length": "513",
"content-type": "multipart/form-data; boundary=1816741701207515830740325151",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
},
"json": null,
"url": "https://postman-echo.com/post"
}
*/
```Notice `file_path:` prefix - this tells that is file on disk and not a key - value pair as form `{"some raw data", "2.txt"}`.
### Authentication
To use [Basic Authentication](https://en.wikipedia.org/wiki/Basic_access_authentication) which uses a username and password, just add `BasicAuth` to the call:
```C++
auto r = ehlib::request(
ehlib::RequestUrl{"https://postman-echo.com/basic-auth"},
ehlib::BasicAuth {"postman", "password"},
ehlib::RequestMethod{"GET"}
);std::cout << r.text << std::endl;
/*
{
"authenticated": true
}
*/```
Authentication via an [OAuth - Bearer Token](https://en.wikipedia.org/wiki/OAuth) can be done using the `BearerAuth` authentication object:
```C++
auto r = ehlib::request(
ehlib::RequestUrl{"http://www.httpbin.org/bearer"},
ehlib::BearerAuth {"ACCESS_TOKEN"},
ehlib::RequestMethod{"GET"}
);
std::cout << r.text << std::endl;/*
{
"authenticated": true,
"token": "ACCESS_TOKEN"
}
*/```
### Response Objects
A `Response` has these public fields and methods:
```C++
std::string status_code; // The HTTP(S) status code for the request
std::string raw; // The data of the HTTP response
std::map header; // A map of the header fields received
std::map sent_headers; // A map of the headers sent
std::string url; // The effective URL of the ultimate request
std::string err; // An error string containing the error code and a message
unsigned long uploaded_bytes; // How many bytes have been sent to the server
unsigned long downloaded_bytes; // How many bytes have been received from the server
unsigned long redirect_count; // How many redirects occurred
void reset(); // Reset Response object to default state
```### Request Headers
Using `RequestHeaders` in your `request` you can specify custom headers:
```C++
auto r = ehlib::request(
ehlib::RequestUrl{"https://postman-echo.com/get"},
ehlib::RequestHeaders{
{"accept", "application/json"},
{"master", "slave"}
},
ehlib::RequestMethod{"GET"},
ehlib::RequestUserAgent{"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"}
);std::cout << r.text << std::endl;
/*
{
"args": {},
"headers": {
"x-forwarded-proto": "https",
"x-forwarded-port": "443",
"host": "postman-echo.com",
"x-amzn-trace-id": "Root=1-64d6950a-387220f76b21c06865853326",
"content-length": "0",
"accept": "application/json",
"master": "slave",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
},
"url": "https://postman-echo.com/get"
}
*/```
### Timeouts
It’s possible to set a timeout for your request if you have strict timing requirements:
```C++
auto r = ehlib::request(
ehlib::RequestUrl{"https://postman-echo.com/get"},
ehlib::RequestTimeout{ 10 },
ehlib::RequestMethod{"GET"},
ehlib::RequestUserAgent{"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"}
);std::cout << r.text << std::endl; // Connection timeout
```Setting the `RequestTimeout` option sets the maximum allowed time the connection or request operation can take in milliseconds. By default a `RequestTimeout` set in 5000 milliseconds
### Using Proxies
Setting up a proxy is easy. For example, we have tor `http proxy` on `localhost` port `9080`.
Try to connect to `https://duckduckgogg42xjoc72x3sjasowoarfbgcmvfimaftt6twagswzczad.onion/`.
This is official `duckduckgo.com` .onion mirror. To do this we will use `RequestProxy`.```C++
auto r = ehlib::request(
ehlib::RequestUrl{"https://duckduckgogg42xjoc72x3sjasowoarfbgcmvfimaftt6twagswzczad.onion/"},
ehlib::RequestTimeout{ 100000 },
ehlib::RequestProxy{ "http://127.0.0.1:9080"},
ehlib::RequestMethod{"GET"},
ehlib::RequestUserAgent{"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"}
);std::cout << r.raw << std::endl;
/*
\n\n\n\n\n\n\n\n\n\t\n\n\n\n\n\n\n\n\n
*/
```### Additional Options
|Allowed options| Upcoming|
|:------------:|:----------:|
|auto-redirect (on/off)|?|The `RequestOptions` constructor allows you to specify additional options for the request. For example, turn `off` auto-redirects (default: `auto-redirect` turn `on`). To enable the option you can use `on`.
```C++
auto r = ehlib::request(
ehlib::RequestUrl{"http://ya.ru"},
ehlib::RequestOptions {
{"auto-redirect", "off"}
},
ehlib::RequestUserAgent{"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"}
);std::cout << r.status_code << std::endl; // 301
```