SkillAgentSearch skills...

WNetWrap

WinINet wrapper - tiny windows HTTPS library, no dependencies. 封装了WinInet的强大http请求库 make POST and GET requests

Install / Use

/learn @hack-tramp/WNetWrap

README

<p align="center"> <img width="200" src="https://github.com/hack-tramp/WNetWrap/blob/main/logo.png?raw=true"> <h1 align="center">WNetWrap <br> <img align="center" src="https://img.shields.io/badge/c%2B%2B-14-blue" href="https://github.com/topics/c-plus-plus-14"> <img align="center" src="https://github.com/hack-tramp/wnetwrap/actions/workflows/msbuild.yml/badge.svg" href="https://github.com/hack-tramp/wnetwrap/actions/workflows/msbuild.yml"> <img align="center" src="https://img.shields.io/badge/License-MIT-green.svg" href="https://opensource.org/licenses/MIT"> <img align="center" src="https://img.badgesize.io/hack-tramp/WNetWrap/main/wnetwrap.cpp?label=source size"> </h1> </p>

A tiny, dependency-free wrapper around WinINet for developers targeting Windows only, who need a lightweight native solution. Inspired by the excellent CPR library, it has mostly identical function names, and will likewise work with random parameter order.

Below is a basic GET request - for detailed examples see the documentation below.

#include <iostream>
#include "wnetwrap.h"

int main()
{	//GET method and firefox user agent used by default
	wrap::Response r = wrap::HttpsRequest(wrap::Url{"https://www.example.com/"}); 
	std::cout << r.text << std::endl; // basic parser
	std::cout << r.status_code << std::endl; // 200
 }

Features

|Implemented| Upcoming| |:------------:|:----------:| |Custom headers|Asynchronous requests| |Url encoded parameters|Callbacks| |Url encoded POST values|NTLM authentication| |Multipart form POST upload|Digest authentication| |File POST upload|PUT, PATCH and DELETE methods| |Basic authentication| |Bearer authentication| |Connection and request timeout| |Cookie support| |Proxy support|

Usage

Just put wnetwrap.h and wnetwrap.cpp in your project folder. 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 WNetWrap is simple - the GET method is used by default so doesn't need to be specified:

#include <wnetwrap.h>
wrap::Response r = wrap::HttpsRequest(wrap::Url{"http://www.httpbin.org/get"});

This gives us a Response object which we’ve called r. There’s a lot of useful stuff in there:

std::cout << r.url << std::endl; // http://www.httpbin.org/get
std::cout << r.status_code << std::endl; // 200
std::cout << r.header["content-type"] << std::endl; // application/json
std::cout << r.text << std::endl;

/*
 * {
 *   "args": {},
 *   "headers": {
 *     ..
 *   },
 *   "url": "http://httpbin.org/get"
 * }
 */

To add URL-encoded parameters, add a Parameters object to the HttpsRequest call:

wrap::Response r = wrap::HttpsRequest(wrap::Url{"http://www.httpbin.org/get"},
                  wrap::Parameters{{"hello", "world"}});
std::cout << r.url << std::endl; // http://www.httpbin.org/get?hello=world
std::cout << r.text << std::endl;

/*
 * {
 *   "args": {
 *     "hello": "world"
 *   },
 *   "headers": {
 *     ..
 *   },
 *   "url": "http://httpbin.org/get?hello=world"
 * }
 */

Parameters is an object with a map-like interface. You can construct it using a list of key/value pairs inside the HttpsRequest or have it outlive HttpsRequest by constructing it outside:

// Constructing it in place
wrap::Response r = wrap::HttpsRequest(wrap::Url{"http://www.httpbin.org/get"},
                  wrap::Parameters{{"hello", "world"}, {"stay", "cool"}});
std::cout << r.url << std::endl; // http://www.httpbin.org/get?hello=world&stay=cool
std::cout << r.text << std::endl;

/*
 * {
 *   "args": {
 *     "hello": "world"
 *     "stay": "cool"
 *   },
 *   "headers": {
 *     ..
 *   },
 *   "url": "http://httpbin.org/get?hello=world&stay=cool"
 * }
 */

 // Constructing it outside
wrap::Parameters parameters = wrap::Parameters{{"hello", "world"}, {"stay", "cool"}};
wrap::Response r_outside = wrap::HttpsRequest(wrap::Url{"http://www.httpbin.org/get"}, parameters);
std::cout << r_outside.url << std::endl; // http://www.httpbin.org/get?hello=world&stay=cool
std::cout << r_outside.text << std::endl; // Same text response as above

Downloading a file

To download the contents of the request you simply add a Download parameter to HttpsRequest. If this parameter's value is blank then the file is downloaded with its original filename, otherwise the value provided will be the new file's name. For example, to download the CPR library: <br>

wrap::HttpsRequest(wrap::Url{ "https://github.com/whoshuu/cpr/archive/refs/tags/1.6.0.zip" }, wrap::Download{});

When you download a file, the .raw and .text properties of the response object will be returned empty.

POST Requests

Making a POST request is just a matter of specifying the HTTP method:

wrap::Response r = wrap::HttpsRequest(wrap::Url{"http://www.httpbin.org/post"},
                   wrap::Payload{{"key", "value"}}, 
		   wrap::Method{"POST"});
std::cout << r.text << std::endl;

/*
 * {
 *   "args": {},
 *   "data": "",
 *   "files": {},
 *   "form": {
 *     "key": "value"
 *   },
 *   "headers": {
 *     ..
 *     "Content-Type": "application/x-www-form-urlencoded",
 *     ..
 *   },
 *   "json": null,
 *   "url": "http://www.httpbin.org/post"
 * }
 */

This sends up "key=value" as a "x-www-form-urlencoded" pair in the POST request. To send data raw and unencoded, use Body instead of Payload:

wrap::Response r = wrap::HttpsRequest(wrap::Url{"http://www.httpbin.org/post"},
                   wrap::Body{"This is raw POST data"},
                   wrap::Header{{"Content-Type", "text/plain"}},
		   wrap::Method{"POST"});
std::cout << r.text << std::endl;

/*
 * {
 *   "args": {},
 *   "data": "This is raw POST data",
 *   "files": {},
 *   "form": {},
 *   "headers": {
 *     ..
 *     "Content-Type": "text/plain",
 *     ..
 *   },
 *   "json": null,
 *   "url": "http://www.httpbin.org/post"
 * }
 */

Here you will notice that the "Content-Type" is being set explicitly to "text/plain". This is because by default, "x-www-form-urlencoded" is used for raw data POSTs. For cases where the data being sent up is small, either "x-www-form-urlencoded" or "text/plain" is suitable. If the data package is large or contains a file, it’s more appropriate to use a Multipart upload. In this example we are uploading a textfile to file.io:

wrap::Response r = wrap::HttpsRequest(wrap::Url{ "file.io" },
				      wrap::Multipart{ {"file:sample1","sample.txt"} }, 
			              wrap::Method{ "POST" });
std::cout << r.text << std::endl;

/*
{"success":true,"status":200,"id":"0a1dc4a0-d056-11eb-b8a8-95e106f75f99","key":"JBDaFwjAneQH","name":"sample.txt","link":"https://
file.io/JBDaFwjAneQH","private":false,"expires":"2021-07-02T16:55:52.042Z","downloads":0,"maxDownloads":1,"autoDelete":true,"size"
:53,"mimeType":"text/plain","created":"2021-06-18T16:55:52.042Z","modified":"2021-06-18T16:55:52.042Z"}
 */

Notice how the text file, which in this case was passed as sample1, had file: prefixed before it - this tells WNetWrap that this is a file and not a key - value pair.

Authentication

To use Basic Authentication which uses a username and password, just add Authentication to the call:

wrap::Response r = wrap::HttpsRequest(wrap::Url{"http://www.httpbin.org/basic-auth/user/pass"},
                  wrap::Authentication{"user", "pass"});
std::cout << r.text << std::endl;

/*
 * {
 *   "authenticated": true,
 *   "user": "user"
 * }
 */

Authentication via an OAuth - Bearer Token can be done using the Bearer authentication object:

wrap::Response r = wrap::HttpsRequest(wrap::Url{"http://www.httpbin.org/bearer"},
                  wrap::Bearer{"ACCESS_TOKEN"});
std::cout << r.text << std::endl;

/*
 * {
 *   "authenticated": true,
 *   "token": "ACCESS_TOKEN"
 * }
 */

Response Objects

A Response has these public fields and methods:

std::string status_code;        // The HTTP status code for the request
std::string raw;                // The body of the HTTP response
std::string text;               // The text body in case of HTML response - if not HTML, same as raw above
std::map header;                // A map of the header fields received
std::map sent_headers;          // A map of the headers sent
std::map secinfo;               // A map of certificate information strings (HTTPS only)
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

The header is a map with an important modification. Its keys are case insensitive as required by RFC 7230:

wrap::Response r = wrap::HttpsRequest(wrap::Url{"http://www.httpbin.org/get"});
std::cout << r.header["content-type"] << std::endl;
std::cout << r.header["Content-Type"] << std::endl;
std::cout << r.header["CoNtEnT-tYpE"] << std::endl;

All of these should print the same value, "application/json".

Request Headers

Using Header in your HttpsRequest you can specify custom headers:

wrap::Response r = wrap::HttpsRequest(wrap::Url{"http://www.httpbin.org/headers"},
                  wrap::Header{{"accept", "application/json"}});
std::cout << r.text << std::endl;

/*
 * "headers": {
 *   "Accept": "applicat

Related Skills

View on GitHub
GitHub Stars40
CategoryCustomer
Updated3mo ago
Forks10

Languages

C++

Security Score

92/100

Audited on Dec 30, 2025

No findings