mirror of
https://github.com/yhirose/cpp-httplib
synced 2026-06-08 18:30:49 +00:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3e906a9b8c | |||
| 110393eadb | |||
| 98caa8c058 | |||
| ef65f09608 | |||
| e130cf3a3b | |||
| 8a348f17fd | |||
| 797d1f27e8 | |||
| 6cde600922 |
@@ -8,10 +8,31 @@ jobs:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macOS-latest, ubuntu-latest]
|
||||
os: [macOS-latest, ubuntu-latest, windows-latest]
|
||||
|
||||
steps:
|
||||
- name: prepare git for checkout on windows
|
||||
if: matrix.os == 'windows-latest'
|
||||
run: |
|
||||
git config --global core.autocrlf false
|
||||
git config --global core.eol lf
|
||||
- name: checkout
|
||||
uses: actions/checkout@v1
|
||||
uses: actions/checkout@v2
|
||||
- name: install brotli library on ubuntu
|
||||
if: matrix.os == 'ubuntu-latest'
|
||||
run: sudo apt-get install -y libbrotli-dev
|
||||
- name: install brotli library on macOS
|
||||
if: matrix.os == 'macOS-latest'
|
||||
run: brew install brotli
|
||||
- name: make
|
||||
if: matrix.os != 'windows-latest'
|
||||
run: cd test && make
|
||||
- name: setup msbuild on windows
|
||||
if: matrix.os == 'windows-latest'
|
||||
uses: warrenbuckley/Setup-MSBuild@v1
|
||||
- name: make-windows
|
||||
if: matrix.os == 'windows-latest'
|
||||
run: |
|
||||
cd test
|
||||
msbuild.exe test.sln /verbosity:minimal /t:Build "/p:Configuration=Release;Platform=x64"
|
||||
x64\Release\test.exe
|
||||
|
||||
@@ -2,14 +2,11 @@ cpp-httplib
|
||||
===========
|
||||
|
||||
[](https://github.com/yhirose/cpp-httplib/actions)
|
||||
[](https://ci.appveyor.com/project/yhirose/cpp-httplib)
|
||||
|
||||
A C++11 single-file header-only cross platform HTTP/HTTPS library.
|
||||
|
||||
It's extremely easy to setup. Just include **httplib.h** file in your code!
|
||||
|
||||
For Windows users: Please read [this note](https://github.com/yhirose/cpp-httplib#windows).
|
||||
|
||||
Server Example
|
||||
--------------
|
||||
|
||||
@@ -287,7 +284,6 @@ Client Example
|
||||
|
||||
int main(void)
|
||||
{
|
||||
// IMPORTANT: 1st parameter must be a hostname or an IP address string.
|
||||
httplib::Client cli("localhost", 1234);
|
||||
|
||||
auto res = cli.Get("/hi");
|
||||
@@ -297,6 +293,16 @@ int main(void)
|
||||
}
|
||||
```
|
||||
|
||||
NOTE: Constructor with scheme-host-port string is now supported!
|
||||
|
||||
```c++
|
||||
httplib::Client cli("localhost");
|
||||
httplib::Client cli("localhost:8080");
|
||||
httplib::Client cli("http://localhost");
|
||||
httplib::Client cli("http://localhost:8080");
|
||||
httplib::Client cli("https://localhost");
|
||||
```
|
||||
|
||||
### GET with HTTP headers
|
||||
|
||||
```c++
|
||||
@@ -517,7 +523,7 @@ OpenSSL Support
|
||||
|
||||
SSL support is available with `CPPHTTPLIB_OPENSSL_SUPPORT`. `libssl` and `libcrypto` should be linked.
|
||||
|
||||
NOTE: cpp-httplib supports 1.1.1 (until 2023-09-11) and 1.0.2 (2019-12-31).
|
||||
NOTE: cpp-httplib currently supports only version 1.1.1.
|
||||
|
||||
```c++
|
||||
#define CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
image:
|
||||
- Visual Studio 2019
|
||||
|
||||
platform:
|
||||
- x64
|
||||
|
||||
build_script:
|
||||
- cmd: >-
|
||||
cd test
|
||||
|
||||
msbuild.exe test.sln /verbosity:minimal /t:Build /p:Configuration=Release;Platform=%PLATFORM%
|
||||
|
||||
test_script:
|
||||
- cmd: x64\Release\test.exe
|
||||
@@ -8,20 +8,17 @@
|
||||
#include <httplib.h>
|
||||
#include <iostream>
|
||||
|
||||
#define CA_CERT_FILE "./ca-bundle.crt"
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main(void) {
|
||||
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
auto res = httplib::Client2("https://localhost:8080")
|
||||
.set_ca_cert_path(CA_CERT_FILE)
|
||||
// .enable_server_certificate_verification(true)
|
||||
.Get("/hi");
|
||||
auto scheme_host_port = "https://localhost:8080";
|
||||
#else
|
||||
auto res = httplib::Client2("http://localhost:8080").Get("/hi");
|
||||
auto scheme_host_port = "http://localhost:8080";
|
||||
#endif
|
||||
|
||||
auto res = httplib::Client2(scheme_host_port).Get("/hi");
|
||||
|
||||
if (res) {
|
||||
cout << res->status << endl;
|
||||
cout << res->get_header_value("Content-Type") << endl;
|
||||
|
||||
+2
-2
@@ -2,13 +2,13 @@
|
||||
#CXX = clang++
|
||||
CXXFLAGS = -ggdb -O0 -std=c++11 -DGTEST_USE_OWN_TR1_TUPLE -I.. -I. -Wall -Wextra -Wtype-limits -Wconversion
|
||||
|
||||
OPENSSL_DIR = /usr/local/opt/openssl
|
||||
OPENSSL_DIR = /usr/local/opt/openssl@1.1
|
||||
OPENSSL_SUPPORT = -DCPPHTTPLIB_OPENSSL_SUPPORT -I$(OPENSSL_DIR)/include -L$(OPENSSL_DIR)/lib -lssl -lcrypto
|
||||
|
||||
ZLIB_SUPPORT = -DCPPHTTPLIB_ZLIB_SUPPORT -lz
|
||||
|
||||
BROTLI_DIR = /usr/local/opt/brotli
|
||||
# BROTLI_SUPPORT = -DCPPHTTPLIB_BROTLI_SUPPORT -I$(BROTLI_DIR)/include -L$(BROTLI_DIR)/lib -lbrotlicommon-static -lbrotlienc-static -lbrotlidec-static
|
||||
BROTLI_SUPPORT = -DCPPHTTPLIB_BROTLI_SUPPORT -I$(BROTLI_DIR)/include -L$(BROTLI_DIR)/lib -lbrotlicommon -lbrotlienc -lbrotlidec
|
||||
|
||||
all : test
|
||||
./test
|
||||
|
||||
+51
-7
@@ -2720,6 +2720,43 @@ TEST(ExceptionTest, ThrowExceptionInHandler) {
|
||||
ASSERT_FALSE(svr.is_running());
|
||||
}
|
||||
|
||||
TEST(KeepAliveTest, ReadTimeout) {
|
||||
Server svr;
|
||||
|
||||
svr.Get("/a", [&](const Request & /*req*/, Response &res) {
|
||||
std::this_thread::sleep_for(std::chrono::seconds(2));
|
||||
res.set_content("a", "text/plain");
|
||||
});
|
||||
|
||||
svr.Get("/b", [&](const Request & /*req*/, Response &res) {
|
||||
res.set_content("b", "text/plain");
|
||||
});
|
||||
|
||||
auto listen_thread = std::thread([&svr]() { svr.listen("localhost", PORT); });
|
||||
while (!svr.is_running()) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
}
|
||||
|
||||
// Give GET time to get a few messages.
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
|
||||
Client cli("localhost", PORT);
|
||||
cli.set_keep_alive(true);
|
||||
cli.set_read_timeout(1);
|
||||
|
||||
auto resa = cli.Get("/a");
|
||||
ASSERT_TRUE(resa == nullptr);
|
||||
|
||||
auto resb = cli.Get("/b");
|
||||
ASSERT_TRUE(resb != nullptr);
|
||||
EXPECT_EQ(200, resb->status);
|
||||
EXPECT_EQ("b", resb->body);
|
||||
|
||||
svr.stop();
|
||||
listen_thread.join();
|
||||
ASSERT_FALSE(svr.is_running());
|
||||
}
|
||||
|
||||
class ServerTestWithAI_PASSIVE : public ::testing::Test {
|
||||
protected:
|
||||
ServerTestWithAI_PASSIVE()
|
||||
@@ -3065,19 +3102,26 @@ TEST(CleanupTest, WSACleanup) {
|
||||
}
|
||||
#endif
|
||||
|
||||
// #ifndef CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
// TEST(NoSSLSupport, SimpleInterface) {
|
||||
// httplib::Client cli("https://yahoo.com");
|
||||
// ASSERT_FALSE(cli.is_valid());
|
||||
// }
|
||||
// #endif
|
||||
|
||||
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
TEST(InvalidScheme, SimpleInterface) {
|
||||
httplib::Client2 cli("scheme://yahoo.com");
|
||||
httplib::Client cli("scheme://yahoo.com");
|
||||
ASSERT_FALSE(cli.is_valid());
|
||||
}
|
||||
|
||||
TEST(NoScheme, SimpleInterface) {
|
||||
httplib::Client2 cli("yahoo.com");
|
||||
ASSERT_FALSE(cli.is_valid());
|
||||
httplib::Client cli("yahoo.com:80");
|
||||
ASSERT_TRUE(cli.is_valid());
|
||||
}
|
||||
|
||||
TEST(YahooRedirectTest2, SimpleInterface) {
|
||||
httplib::Client2 cli("http://yahoo.com");
|
||||
httplib::Client cli("http://yahoo.com");
|
||||
|
||||
auto res = cli.Get("/");
|
||||
ASSERT_TRUE(res != nullptr);
|
||||
@@ -3090,7 +3134,7 @@ TEST(YahooRedirectTest2, SimpleInterface) {
|
||||
}
|
||||
|
||||
TEST(YahooRedirectTest3, SimpleInterface) {
|
||||
httplib::Client2 cli("https://yahoo.com");
|
||||
httplib::Client cli("https://yahoo.com");
|
||||
|
||||
auto res = cli.Get("/");
|
||||
ASSERT_TRUE(res != nullptr);
|
||||
@@ -3104,7 +3148,7 @@ TEST(YahooRedirectTest3, SimpleInterface) {
|
||||
|
||||
#ifdef CPPHTTPLIB_BROTLI_SUPPORT
|
||||
TEST(DecodeWithChunkedEncoding, BrotliEncoding) {
|
||||
httplib::Client2 cli("https://cdnjs.cloudflare.com");
|
||||
httplib::Client cli("https://cdnjs.cloudflare.com");
|
||||
auto res = cli.Get("/ajax/libs/jquery/3.5.1/jquery.js", {{"Accept-Encoding", "brotli"}});
|
||||
|
||||
ASSERT_TRUE(res != nullptr);
|
||||
@@ -3117,7 +3161,7 @@ TEST(DecodeWithChunkedEncoding, BrotliEncoding) {
|
||||
#if 0
|
||||
TEST(HttpsToHttpRedirectTest2, SimpleInterface) {
|
||||
auto res =
|
||||
httplib::Client2("https://httpbin.org")
|
||||
httplib::Client("https://httpbin.org")
|
||||
.set_follow_location(true)
|
||||
.Get("/redirect-to?url=http%3A%2F%2Fwww.google.com&status_code=302");
|
||||
|
||||
|
||||
+6
-2
@@ -22,7 +22,7 @@
|
||||
<ProjectGuid>{6B3E6769-052D-4BC0-9D2C-E9127C3DBB26}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>test</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
@@ -97,6 +97,7 @@
|
||||
<AdditionalIncludeDirectories>./;../</AdditionalIncludeDirectories>
|
||||
<AdditionalUsingDirectories>
|
||||
</AdditionalUsingDirectories>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@@ -114,6 +115,7 @@
|
||||
<AdditionalIncludeDirectories>./;../</AdditionalIncludeDirectories>
|
||||
<AdditionalUsingDirectories>
|
||||
</AdditionalUsingDirectories>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@@ -133,6 +135,7 @@
|
||||
<AdditionalIncludeDirectories>./;../</AdditionalIncludeDirectories>
|
||||
<AdditionalUsingDirectories>
|
||||
</AdditionalUsingDirectories>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@@ -154,6 +157,7 @@
|
||||
<AdditionalIncludeDirectories>./;../</AdditionalIncludeDirectories>
|
||||
<AdditionalUsingDirectories>
|
||||
</AdditionalUsingDirectories>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@@ -171,4 +175,4 @@
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
+8
-4
@@ -5,7 +5,8 @@
|
||||
using namespace std;
|
||||
using namespace httplib;
|
||||
|
||||
void ProxyTest(Client& cli, bool basic) {
|
||||
template <typename T>
|
||||
void ProxyTest(T& cli, bool basic) {
|
||||
cli.set_proxy("localhost", basic ? 3128 : 3129);
|
||||
auto res = cli.Get("/get");
|
||||
ASSERT_TRUE(res != nullptr);
|
||||
@@ -36,7 +37,8 @@ TEST(ProxyTest, SSLDigest) {
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void RedirectProxyText(Client& cli, const char *path, bool basic) {
|
||||
template <typename T>
|
||||
void RedirectProxyText(T& cli, const char *path, bool basic) {
|
||||
cli.set_proxy("localhost", basic ? 3128 : 3129);
|
||||
if (basic) {
|
||||
cli.set_proxy_basic_auth("hello", "world");
|
||||
@@ -100,7 +102,8 @@ TEST(RedirectTest, YouTubeSSLDigest) {
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void BaseAuthTestFromHTTPWatch(Client& cli) {
|
||||
template <typename T>
|
||||
void BaseAuthTestFromHTTPWatch(T& cli) {
|
||||
cli.set_proxy("localhost", 3128);
|
||||
cli.set_proxy_basic_auth("hello", "world");
|
||||
|
||||
@@ -157,7 +160,8 @@ TEST(BaseAuthTest, SSL) {
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
void DigestAuthTestFromHTTPWatch(Client& cli) {
|
||||
template <typename T>
|
||||
void DigestAuthTestFromHTTPWatch(T& cli) {
|
||||
cli.set_proxy("localhost", 3129);
|
||||
cli.set_proxy_digest_auth("hello", "world");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user