Merge pull request #1 from yhirose/master

Merging to latest version
This commit is contained in:
Constantin 2019-01-30 12:08:48 +09:00 committed by GitHub
commit 86df5fb901
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 2951 additions and 764 deletions

6
.gitignore vendored
View File

@ -4,9 +4,12 @@ example/server
example/client example/client
example/hello example/hello
example/simplesvr example/simplesvr
example/benchmark
example/*.pem
test/test test/test
test/test.xcodeproj/xcuser* test/test.xcodeproj/xcuser*
test/test.xcodeproj/*/xcuser* test/test.xcodeproj/*/xcuser*
test/*.pem
*.swp *.swp
@ -16,5 +19,8 @@ Release
*.sdf *.sdf
*.suo *.suo
*.opensdf *.opensdf
*.db
ipch ipch
*.dSYM *.dSYM
.*
!/.travis.yml

12
.travis.yml Normal file
View File

@ -0,0 +1,12 @@
# Environment
language: cpp
os: osx
# Compiler selection
compiler:
- clang
# Build/test steps
script:
- cd ${TRAVIS_BUILD_DIR}/test
- make all

22
LICENSE Normal file
View File

@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2017 yhirose
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

184
README.md
View File

@ -1,17 +1,18 @@
cpp-httplib cpp-httplib
=========== ===========
A C++11 header-only HTTP library. [![Build Status](https://travis-ci.org/yhirose/cpp-httplib.svg?branch=master)](https://travis-ci.org/yhirose/cpp-httplib)
[![Bulid Status](https://ci.appveyor.com/api/projects/status/github/yhirose/cpp-httplib?branch=master&svg=true)](https://ci.appveyor.com/project/yhirose/cpp-httplib)
[The Boost Software License 1.0](http://www.boost.org/LICENSE_1_0.txt) A C++11 header-only HTTP library.
It's extremely easy to setup. Just include **httplib.h** file in your code! It's extremely easy to setup. Just include **httplib.h** file in your code!
Inspired by [Sinatra](http://www.sinatrarb.com/) and [express](https://github.com/visionmedia/express).
Server Example Server Example
-------------- --------------
Inspired by [Sinatra](http://www.sinatrarb.com/) and [express](https://github.com/visionmedia/express).
```c++ ```c++
#include <httplib.h> #include <httplib.h>
@ -21,11 +22,11 @@ int main(void)
Server svr; Server svr;
svr.get("/hi", [](const Request& req, const Response& res) { svr.Get("/hi", [](const Request& req, Response& res) {
res.set_content("Hello World!", "text/plain"); res.set_content("Hello World!", "text/plain");
}); });
svr.get(R"(/numbers/(\d+))", [&](const Request& req, const Response& res) { svr.Get(R"(/numbers/(\d+))", [&](const Request& req, Response& res) {
auto numbers = req.matches[1]; auto numbers = req.matches[1];
res.set_content(numbers, "text/plain"); res.set_content(numbers, "text/plain");
}); });
@ -34,9 +35,70 @@ int main(void)
} }
``` ```
`Post`, `Put`, `Delete` and `Options` methods are also supported.
### Bind a socket to multiple interfaces and any available port
```cpp
int port = svr.bind_to_any_port("0.0.0.0");
svr.listen_after_bind();
```
### Method Chain
```cpp
svr.Get("/get", [](const auto& req, auto& res) {
res.set_content("get", "text/plain");
})
.Post("/post", [](const auto& req, auto& res) {
res.set_content(req.body(), "text/plain");
})
.listen("localhost", 1234);
```
### Static File Server
```cpp
svr.set_base_dir("./www");
```
### Logging
```cpp
svr.set_logger([](const auto& req, const auto& res) {
your_logger(req, res);
});
```
### Error Handler
```cpp
svr.set_error_handler([](const auto& req, auto& res) {
const char* fmt = "<p>Error Status: <span style='color:red;'>%d</span></p>";
char buf[BUFSIZ];
snprintf(buf, sizeof(buf), fmt, res.status);
res.set_content(buf, "text/html");
});
```
### 'multipart/form-data' POST data
```cpp
svr.Post("/multipart", [&](const auto& req, auto& res) {
auto size = req.files.size();
auto ret = req.has_file("name1"));
const auto& file = req.get_file_value("name1");
// file.filename;
// file.content_type;
auto body = req.body.substr(file.offset, file.length));
})
```
Client Example Client Example
-------------- --------------
### GET
```c++ ```c++
#include <httplib.h> #include <httplib.h>
#include <iostream> #include <iostream>
@ -45,13 +107,97 @@ int main(void)
{ {
httplib::Client cli("localhost", 1234); httplib::Client cli("localhost", 1234);
auto res = cli.get("/hi"); auto res = cli.Get("/hi");
if (res && res->status == 200) { if (res && res->status == 200) {
std::cout << res->body << std::endl; std::cout << res->body << std::endl;
} }
} }
``` ```
### POST
```c++
res = cli.Post("/post", "text", "text/plain");
res = cli.Post("/person", "name=john1&note=coder", "application/x-www-form-urlencoded");
```
### POST with parameters
```c++
httplib::Params params;
params.emplace("name", "john");
params.emplace("note", "coder");
auto res = cli.Post("/post", params);
```
or
```c++
httplib::Params params{
{ "name", "john" },
{ "note", "coder" }
};
auto res = cli.Post("/post", params);
```
### PUT
```c++
res = cli.Put("/resource/foo", "text", "text/plain");
```
### DELETE
```c++
res = cli.Delete("/resource/foo");
```
### OPTIONS
```c++
res = cli.Options("*");
res = cli.Options("/resource/foo");
```
### Connection Timeout
```c++
httplib::Client cli("localhost", 8080, 5); // timeouts in 5 seconds
```
### With Progress Callback
```cpp
httplib::Client client(url, port);
// prints: 0 / 000 bytes => 50% complete
std::shared_ptr<httplib::Response> res =
cli.Get("/", [](uint64_t len, uint64_t total) {
printf("%lld / %lld bytes => %d%% complete\n",
len, total,
(int)((len/total)*100));
return true; // return 'false' if you want to cancel the request.
}
);
```
![progress](https://user-images.githubusercontent.com/236374/33138910-495c4ecc-cf86-11e7-8693-2fc6d09615c4.gif)
This feature was contributed by [underscorediscovery](https://github.com/yhirose/cpp-httplib/pull/23).
### Range
```cpp
httplib::Client cli("httpbin.org", 80);
// 'Range: bytes=1-10'
httplib::Headers headers = { httplib::make_range_header(1, 10) };
auto res = cli.Get("/range/32", headers);
// res->status should be 206.
// res->body should be "bcdefghijk".
```
OpenSSL Support OpenSSL Support
--------------- ---------------
@ -65,4 +211,26 @@ SSLServer svr("./cert.pem", "./key.pem");
SSLClient cli("localhost", 8080); SSLClient cli("localhost", 8080);
``` ```
Copyright (c) 2017 Yuji Hirose. All rights reserved. Zlib Support
------------
'gzip' compression is available with `CPPHTTPLIB_ZLIB_SUPPORT`.
The server applies gzip compression to the following MIME type contents:
* all text types
* image/svg+xml
* application/javascript
* application/json
* application/xml
* application/xhtml+xml
NOTE
----
g++ 4.8 cannot build this library since `<regex>` in g++4.8 is [broken](https://stackoverflow.com/questions/12530406/is-gcc-4-8-or-earlier-buggy-about-regular-expressions).
License
-------
MIT license (© 2019 Yuji Hirose)

9
appveyor.yml Normal file
View File

@ -0,0 +1,9 @@
version: 1.0.{build}
image: Visual Studio 2017
build_script:
- cmd: >-
cd test
msbuild.exe test.sln /verbosity:minimal /t:Build /p:Configuration=Debug;Platform=Win32
test_script:
- cmd: Debug\test.exe

View File

@ -1,21 +1,25 @@
CC = clang++ CC = clang++
CFLAGS = -std=c++14 -I.. CFLAGS = -std=c++14 -I.. -Wall -Wextra -lpthread
OPENSSL_SUPPORT = -DCPPHTTPLIB_OPENSSL_SUPPORT -I/usr/local/opt/openssl/include -L/usr/local/opt/openssl/lib -lssl -lcrypto #OPENSSL_SUPPORT = -DCPPHTTPLIB_OPENSSL_SUPPORT -I/usr/local/opt/openssl/include -L/usr/local/opt/openssl/lib -lssl -lcrypto
ZLIB_SUPPORT = -DCPPHTTPLIB_ZLIB_SUPPORT -lz
all: server client hello simplesvr all: server client hello simplesvr benchmark
server : server.cc ../httplib.h server : server.cc ../httplib.h Makefile
$(CC) -o server $(CFLAGS) server.cc $(OPENSSL_SUPPORT) $(CC) -o server $(CFLAGS) server.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT)
client : client.cc ../httplib.h client : client.cc ../httplib.h Makefile
$(CC) -o client $(CFLAGS) client.cc $(OPENSSL_SUPPORT) $(CC) -o client $(CFLAGS) client.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT)
hello : hello.cc ../httplib.h hello : hello.cc ../httplib.h Makefile
$(CC) -o hello $(CFLAGS) hello.cc $(OPENSSL_SUPPORT) $(CC) -o hello $(CFLAGS) hello.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT)
simplesvr : simplesvr.cc ../httplib.h simplesvr : simplesvr.cc ../httplib.h Makefile
$(CC) -o simplesvr $(CFLAGS) simplesvr.cc $(OPENSSL_SUPPORT) $(CC) -o simplesvr $(CFLAGS) simplesvr.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT)
benchmark : benchmark.cc ../httplib.h Makefile
$(CC) -o benchmark $(CFLAGS) benchmark.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT)
pem: pem:
openssl genrsa 2048 > key.pem openssl genrsa 2048 > key.pem

33
example/benchmark.cc Normal file
View File

@ -0,0 +1,33 @@
#include <httplib.h>
#include <chrono>
#include <iostream>
using namespace std;
struct StopWatch {
StopWatch(const string& label) : label_(label) {
start_ = chrono::system_clock::now();
}
~StopWatch() {
auto end = chrono::system_clock::now();
auto diff = end - start_;
auto count = chrono::duration_cast<chrono::milliseconds>(diff).count();
cout << label_ << ": " << count << " millisec." << endl;
}
string label_;
chrono::system_clock::time_point start_;
};
int main(void) {
string body(1024 * 5, 'a');
httplib::Client cli("httpbin.org", 80);
for (int i = 0; i < 3; i++) {
StopWatch sw(to_string(i).c_str());
auto res = cli.Post("/post", body, "application/octet-stream");
assert(res->status == 200);
}
return 0;
}

View File

@ -18,7 +18,7 @@ int main(void)
httplib::Client cli("localhost", 8080); httplib::Client cli("localhost", 8080);
#endif #endif
auto res = cli.get("/hi"); auto res = cli.Get("/hi");
if (res) { if (res) {
cout << res->status << endl; cout << res->status << endl;
cout << res->get_header_value("Content-Type") << endl; cout << res->get_header_value("Content-Type") << endl;

View File

@ -1,33 +1,55 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations"> <ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32"> <ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration> <Configuration>Debug</Configuration>
<Platform>Win32</Platform> <Platform>Win32</Platform>
</ProjectConfiguration> </ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32"> <ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration> <Configuration>Release</Configuration>
<Platform>Win32</Platform> <Platform>Win32</Platform>
</ProjectConfiguration> </ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup> </ItemGroup>
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<ProjectGuid>{6DB1FC63-B153-4279-92B7-D8A11AF285D6}</ProjectGuid> <ProjectGuid>{6DB1FC63-B153-4279-92B7-D8A11AF285D6}</ProjectGuid>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
<RootNamespace>client</RootNamespace> <RootNamespace>client</RootNamespace>
<WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings"> <ImportGroup Label="ExtensionSettings">
@ -35,15 +57,31 @@
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup> </ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup> </ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" /> <PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental> <LinkIncremental>true</LinkIncremental>
<IntDir>$(Configuration)\$(ProjectName)_obj\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<IntDir>$(Platform)\$(Configuration)\$(ProjectName)_obj\</IntDir>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental> <LinkIncremental>false</LinkIncremental>
<IntDir>$(Configuration)\$(ProjectName)_obj\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<IntDir>$(Platform)\$(Configuration)\$(ProjectName)_obj\</IntDir>
</PropertyGroup> </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile> <ClCompile>
@ -60,6 +98,21 @@
<AdditionalDependencies>Ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>Ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>Ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile> <ClCompile>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
@ -79,6 +132,25 @@
<AdditionalDependencies>Ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>Ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>Ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="client.cc" /> <ClCompile Include="client.cc" />
</ItemGroup> </ItemGroup>

View File

@ -1,6 +1,8 @@
 
Microsoft Visual Studio Solution File, Format Version 11.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2010 # Visual Studio 15
VisualStudioVersion = 15.0.27703.2047
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "server", "server.vcxproj", "{864CD288-050A-4C8B-9BEF-3048BD876C5B}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "server", "server.vcxproj", "{864CD288-050A-4C8B-9BEF-3048BD876C5B}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "client", "client.vcxproj", "{6DB1FC63-B153-4279-92B7-D8A11AF285D6}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "client", "client.vcxproj", "{6DB1FC63-B153-4279-92B7-D8A11AF285D6}"
@ -13,19 +15,32 @@ EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32 Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32 Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{864CD288-050A-4C8B-9BEF-3048BD876C5B}.Debug|Win32.ActiveCfg = Debug|Win32 {864CD288-050A-4C8B-9BEF-3048BD876C5B}.Debug|Win32.ActiveCfg = Debug|Win32
{864CD288-050A-4C8B-9BEF-3048BD876C5B}.Debug|Win32.Build.0 = Debug|Win32 {864CD288-050A-4C8B-9BEF-3048BD876C5B}.Debug|Win32.Build.0 = Debug|Win32
{864CD288-050A-4C8B-9BEF-3048BD876C5B}.Debug|x64.ActiveCfg = Debug|x64
{864CD288-050A-4C8B-9BEF-3048BD876C5B}.Debug|x64.Build.0 = Debug|x64
{864CD288-050A-4C8B-9BEF-3048BD876C5B}.Release|Win32.ActiveCfg = Release|Win32 {864CD288-050A-4C8B-9BEF-3048BD876C5B}.Release|Win32.ActiveCfg = Release|Win32
{864CD288-050A-4C8B-9BEF-3048BD876C5B}.Release|Win32.Build.0 = Release|Win32 {864CD288-050A-4C8B-9BEF-3048BD876C5B}.Release|Win32.Build.0 = Release|Win32
{864CD288-050A-4C8B-9BEF-3048BD876C5B}.Release|x64.ActiveCfg = Release|x64
{864CD288-050A-4C8B-9BEF-3048BD876C5B}.Release|x64.Build.0 = Release|x64
{6DB1FC63-B153-4279-92B7-D8A11AF285D6}.Debug|Win32.ActiveCfg = Debug|Win32 {6DB1FC63-B153-4279-92B7-D8A11AF285D6}.Debug|Win32.ActiveCfg = Debug|Win32
{6DB1FC63-B153-4279-92B7-D8A11AF285D6}.Debug|Win32.Build.0 = Debug|Win32 {6DB1FC63-B153-4279-92B7-D8A11AF285D6}.Debug|Win32.Build.0 = Debug|Win32
{6DB1FC63-B153-4279-92B7-D8A11AF285D6}.Debug|x64.ActiveCfg = Debug|x64
{6DB1FC63-B153-4279-92B7-D8A11AF285D6}.Debug|x64.Build.0 = Debug|x64
{6DB1FC63-B153-4279-92B7-D8A11AF285D6}.Release|Win32.ActiveCfg = Release|Win32 {6DB1FC63-B153-4279-92B7-D8A11AF285D6}.Release|Win32.ActiveCfg = Release|Win32
{6DB1FC63-B153-4279-92B7-D8A11AF285D6}.Release|Win32.Build.0 = Release|Win32 {6DB1FC63-B153-4279-92B7-D8A11AF285D6}.Release|Win32.Build.0 = Release|Win32
{6DB1FC63-B153-4279-92B7-D8A11AF285D6}.Release|x64.ActiveCfg = Release|x64
{6DB1FC63-B153-4279-92B7-D8A11AF285D6}.Release|x64.Build.0 = Release|x64
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {7097C9E4-07F8-48C6-A888-BBA9EBB5D17D}
EndGlobalSection
EndGlobal EndGlobal

View File

@ -12,7 +12,7 @@ int main(void)
{ {
Server svr; Server svr;
svr.get("/hi", [](const auto& req, auto& res) { svr.Get("/hi", [](const Request& /*req*/, Response& res) {
res.set_content("Hello World!", "text/plain"); res.set_content("Hello World!", "text/plain");
}); });

View File

@ -7,13 +7,14 @@
#include <httplib.h> #include <httplib.h>
#include <cstdio> #include <cstdio>
#include <chrono>
#define SERVER_CERT_FILE "./cert.pem" #define SERVER_CERT_FILE "./cert.pem"
#define SERVER_PRIVATE_KEY_FILE "./key.pem" #define SERVER_PRIVATE_KEY_FILE "./key.pem"
using namespace httplib; using namespace httplib;
std::string dump_headers(const MultiMap& headers) std::string dump_headers(const Headers& headers)
{ {
std::string s; std::string s;
char buf[BUFSIZ]; char buf[BUFSIZ];
@ -34,7 +35,7 @@ std::string log(const Request& req, const Response& res)
s += "================================\n"; s += "================================\n";
snprintf(buf, sizeof(buf), "%s %s", req.method.c_str(), req.path.c_str()); snprintf(buf, sizeof(buf), "%s %s %s", req.method.c_str(), req.version.c_str(), req.path.c_str());
s += buf; s += buf;
std::string query; std::string query;
@ -51,9 +52,10 @@ std::string log(const Request& req, const Response& res)
s += "--------------------------------\n"; s += "--------------------------------\n";
snprintf(buf, sizeof(buf), "%d\n", res.status); snprintf(buf, sizeof(buf), "%d %s\n", res.status, res.version.c_str());
s += buf; s += buf;
s += dump_headers(res.headers); s += dump_headers(res.headers);
s += "\n";
if (!res.body.empty()) { if (!res.body.empty()) {
s += res.body; s += res.body;
@ -72,30 +74,40 @@ int main(void)
Server svr; Server svr;
#endif #endif
svr.get("/", [=](const auto& req, auto& res) { if (!svr.is_valid()) {
printf("server has an error...\n");
return -1;
}
svr.Get("/", [=](const Request& /*req*/, Response& res) {
res.set_redirect("/hi"); res.set_redirect("/hi");
}); });
svr.get("/hi", [](const auto& req, auto& res) { svr.Get("/hi", [](const Request& /*req*/, Response& res) {
res.set_content("Hello World!", "text/plain"); res.set_content("Hello World!\n", "text/plain");
}); });
svr.get("/dump", [](const auto& req, auto& res) { svr.Get("/slow", [](const Request& /*req*/, Response& res) {
std::this_thread::sleep_for(std::chrono::seconds(2));
res.set_content("Slow...\n", "text/plain");
});
svr.Get("/dump", [](const Request& req, Response& res) {
res.set_content(dump_headers(req.headers), "text/plain"); res.set_content(dump_headers(req.headers), "text/plain");
}); });
svr.get("/stop", [&](const auto& req, auto& res) { svr.Get("/stop", [&](const Request& /*req*/, Response& /*res*/) {
svr.stop(); svr.stop();
}); });
svr.set_error_handler([](const auto& req, auto& res) { svr.set_error_handler([](const Request& /*req*/, Response& res) {
const char* fmt = "<p>Error Status: <span style='color:red;'>%d</span></p>"; const char* fmt = "<p>Error Status: <span style='color:red;'>%d</span></p>";
char buf[BUFSIZ]; char buf[BUFSIZ];
snprintf(buf, sizeof(buf), fmt, res.status); snprintf(buf, sizeof(buf), fmt, res.status);
res.set_content(buf, "text/html"); res.set_content(buf, "text/html");
}); });
svr.set_logger([](const auto& req, const auto& res) { svr.set_logger([](const Request& req, const Response& res) {
printf("%s", log(req, res).c_str()); printf("%s", log(req, res).c_str());
}); });

View File

@ -1,33 +1,55 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations"> <ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32"> <ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration> <Configuration>Debug</Configuration>
<Platform>Win32</Platform> <Platform>Win32</Platform>
</ProjectConfiguration> </ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32"> <ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration> <Configuration>Release</Configuration>
<Platform>Win32</Platform> <Platform>Win32</Platform>
</ProjectConfiguration> </ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup> </ItemGroup>
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<ProjectGuid>{864CD288-050A-4C8B-9BEF-3048BD876C5B}</ProjectGuid> <ProjectGuid>{864CD288-050A-4C8B-9BEF-3048BD876C5B}</ProjectGuid>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
<RootNamespace>sample</RootNamespace> <RootNamespace>sample</RootNamespace>
<WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings"> <ImportGroup Label="ExtensionSettings">
@ -35,15 +57,31 @@
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup> </ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup> </ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" /> <PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental> <LinkIncremental>true</LinkIncremental>
<IntDir>$(Configuration)\$(ProjectName)_obj\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<IntDir>$(Platform)\$(Configuration)\$(ProjectName)_obj\</IntDir>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental> <LinkIncremental>false</LinkIncremental>
<IntDir>$(Configuration)\$(ProjectName)_obj\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<IntDir>$(Platform)\$(Configuration)\$(ProjectName)_obj\</IntDir>
</PropertyGroup> </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile> <ClCompile>
@ -60,6 +98,21 @@
<AdditionalDependencies>Ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>Ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>Ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile> <ClCompile>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
@ -79,6 +132,25 @@
<AdditionalDependencies>Ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>Ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>Ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="server.cc" /> <ClCompile Include="server.cc" />
</ItemGroup> </ItemGroup>

View File

@ -15,7 +15,7 @@
using namespace httplib; using namespace httplib;
using namespace std; using namespace std;
string dump_headers(const MultiMap& headers) string dump_headers(const Headers& headers)
{ {
string s; string s;
char buf[BUFSIZ]; char buf[BUFSIZ];
@ -28,6 +28,38 @@ string dump_headers(const MultiMap& headers)
return s; return s;
} }
string dump_multipart_files(const MultipartFiles& files)
{
string s;
char buf[BUFSIZ];
s += "--------------------------------\n";
for (const auto& x: files) {
const auto& name = x.first;
const auto& file = x.second;
snprintf(buf, sizeof(buf), "name: %s\n", name.c_str());
s += buf;
snprintf(buf, sizeof(buf), "filename: %s\n", file.filename.c_str());
s += buf;
snprintf(buf, sizeof(buf), "content type: %s\n", file.content_type.c_str());
s += buf;
snprintf(buf, sizeof(buf), "text offset: %lu\n", file.offset);
s += buf;
snprintf(buf, sizeof(buf), "text length: %lu\n", file.length);
s += buf;
s += "----------------\n";
}
return s;
}
string log(const Request& req, const Response& res) string log(const Request& req, const Response& res)
{ {
string s; string s;
@ -35,7 +67,7 @@ string log(const Request& req, const Response& res)
s += "================================\n"; s += "================================\n";
snprintf(buf, sizeof(buf), "%s %s", req.method.c_str(), req.path.c_str()); snprintf(buf, sizeof(buf), "%s %s %s", req.method.c_str(), req.version.c_str(), req.path.c_str());
s += buf; s += buf;
string query; string query;
@ -49,6 +81,7 @@ string log(const Request& req, const Response& res)
s += buf; s += buf;
s += dump_headers(req.headers); s += dump_headers(req.headers);
s += dump_multipart_files(req.files);
s += "--------------------------------\n"; s += "--------------------------------\n";
@ -72,18 +105,26 @@ int main(int argc, const char** argv)
Server svr; Server svr;
#endif #endif
svr.set_error_handler([](const auto& req, auto& res) { svr.Post("/multipart", [](const Request& req, Response& res) {
auto body =
dump_headers(req.headers) +
dump_multipart_files(req.files);
res.set_content(body, "text/plain");
});
svr.set_error_handler([](const Request& /*req*/, Response& res) {
const char* fmt = "<p>Error Status: <span style='color:red;'>%d</span></p>"; const char* fmt = "<p>Error Status: <span style='color:red;'>%d</span></p>";
char buf[BUFSIZ]; char buf[BUFSIZ];
snprintf(buf, sizeof(buf), fmt, res.status); snprintf(buf, sizeof(buf), fmt, res.status);
res.set_content(buf, "text/html"); res.set_content(buf, "text/html");
}); });
svr.set_logger([](const auto& req, const auto& res) { svr.set_logger([](const Request& req, const Response& res) {
cout << log(req, res); cout << log(req, res);
}); });
auto port = 80; auto port = 8080;
if (argc > 1) { if (argc > 1) {
port = atoi(argv[1]); port = atoi(argv[1]);
} }

1836
httplib.h

File diff suppressed because it is too large Load Diff

View File

@ -1,17 +1,20 @@
CC = clang++ CC = clang++
CFLAGS = -std=c++14 -DGTEST_USE_OWN_TR1_TUPLE -I.. -I. #CC = g++
#OPENSSL_SUPPORT = -DCPPHTTPLIB_OPENSSL_SUPPORT -I/usr/local/opt/openssl/include -L/usr/local/opt/openssl/lib -lssl -lcrypto
CFLAGS = -ggdb -O0 -std=c++11 -DGTEST_USE_OWN_TR1_TUPLE -I.. -I. -Wall -Wextra -Wtype-limits
OPENSSL_SUPPORT = -DCPPHTTPLIB_OPENSSL_SUPPORT -I/usr/local/opt/openssl/include -L/usr/local/opt/openssl/lib -lssl -lcrypto
ZLIB_SUPPORT = -DCPPHTTPLIB_ZLIB_SUPPORT -lz
all : test all : test
./test ./test
test : test.cc ../httplib.h test : test.cc ../httplib.h Makefile cert.pem
$(CC) -o test $(CFLAGS) test.cc gtest/gtest-all.cc gtest/gtest_main.cc $(OPENSSL_SUPPORT) $(CC) -o test $(CFLAGS) test.cc gtest/gtest-all.cc gtest/gtest_main.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT) -lpthread
pem: cert.pem:
openssl genrsa 2048 > key.pem openssl genrsa 2048 > key.pem
openssl req -new -key key.pem | openssl x509 -days 3650 -req -signkey key.pem > cert.pem openssl req -new -batch -config test.conf -key key.pem | openssl x509 -days 3650 -req -signkey key.pem > cert.pem
clean: clean:
rm test *.pem rm -f test *.pem

BIN
test/image.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

File diff suppressed because it is too large Load Diff

18
test/test.conf Normal file
View File

@ -0,0 +1,18 @@
[req]
default_bits = 2048
distinguished_name = req_distinguished_name
attributes = req_attributes
prompt = no
output_password = mypass
[req_distinguished_name]
C = US
ST = Test State or Province
L = Test Locality
O = Organization Name
OU = Organizational Unit Name
CN = Common Name
emailAddress = test@email.address
[req_attributes]
challengePassword = 1234

View File

@ -22,31 +22,32 @@
<ProjectGuid>{6B3E6769-052D-4BC0-9D2C-E9127C3DBB26}</ProjectGuid> <ProjectGuid>{6B3E6769-052D-4BC0-9D2C-E9127C3DBB26}</ProjectGuid>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
<RootNamespace>test</RootNamespace> <RootNamespace>test</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>

View File

@ -1,248 +0,0 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
BAA4BF2517280236003EF6AD /* test.cc in Sources */ = {isa = PBXBuildFile; fileRef = BAA4BF2417280236003EF6AD /* test.cc */; };
BAF46809172813BB0069D928 /* gtest-all.cc in Sources */ = {isa = PBXBuildFile; fileRef = BAF46806172813BB0069D928 /* gtest-all.cc */; };
BAF4680A172813BB0069D928 /* gtest_main.cc in Sources */ = {isa = PBXBuildFile; fileRef = BAF46808172813BB0069D928 /* gtest_main.cc */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
BAE5F9C51727F08F001D0075 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = /usr/share/man/man1/;
dstSubfolderSpec = 0;
files = (
);
runOnlyForDeploymentPostprocessing = 1;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
BAA4BF2417280236003EF6AD /* test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = test.cc; sourceTree = SOURCE_ROOT; };
BAE5F9C71727F08F001D0075 /* test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = test; sourceTree = BUILT_PRODUCTS_DIR; };
BAF46806172813BB0069D928 /* gtest-all.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "gtest-all.cc"; sourceTree = "<group>"; };
BAF46807172813BB0069D928 /* gtest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gtest.h; sourceTree = "<group>"; };
BAF46808172813BB0069D928 /* gtest_main.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gtest_main.cc; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
BAE5F9C41727F08F001D0075 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
BAE5F9BE1727F08F001D0075 = {
isa = PBXGroup;
children = (
BAE5F9C91727F08F001D0075 /* test */,
BAE5F9C81727F08F001D0075 /* Products */,
);
sourceTree = "<group>";
};
BAE5F9C81727F08F001D0075 /* Products */ = {
isa = PBXGroup;
children = (
BAE5F9C71727F08F001D0075 /* test */,
);
name = Products;
sourceTree = "<group>";
};
BAE5F9C91727F08F001D0075 /* test */ = {
isa = PBXGroup;
children = (
BAF46805172813BB0069D928 /* gtest */,
BAA4BF2417280236003EF6AD /* test.cc */,
);
path = test;
sourceTree = "<group>";
};
BAF46805172813BB0069D928 /* gtest */ = {
isa = PBXGroup;
children = (
BAF46806172813BB0069D928 /* gtest-all.cc */,
BAF46807172813BB0069D928 /* gtest.h */,
BAF46808172813BB0069D928 /* gtest_main.cc */,
);
path = gtest;
sourceTree = SOURCE_ROOT;
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
BAE5F9C61727F08F001D0075 /* test */ = {
isa = PBXNativeTarget;
buildConfigurationList = BAE5F9D01727F08F001D0075 /* Build configuration list for PBXNativeTarget "test" */;
buildPhases = (
BAE5F9C31727F08F001D0075 /* Sources */,
BAE5F9C41727F08F001D0075 /* Frameworks */,
BAE5F9C51727F08F001D0075 /* CopyFiles */,
);
buildRules = (
);
dependencies = (
);
name = test;
productName = test;
productReference = BAE5F9C71727F08F001D0075 /* test */;
productType = "com.apple.product-type.tool";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
BAE5F9BF1727F08F001D0075 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0460;
ORGANIZATIONNAME = "Yuji Hirose";
};
buildConfigurationList = BAE5F9C21727F08F001D0075 /* Build configuration list for PBXProject "test" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
);
mainGroup = BAE5F9BE1727F08F001D0075;
productRefGroup = BAE5F9C81727F08F001D0075 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
BAE5F9C61727F08F001D0075 /* test */,
);
};
/* End PBXProject section */
/* Begin PBXSourcesBuildPhase section */
BAE5F9C31727F08F001D0075 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
BAA4BF2517280236003EF6AD /* test.cc in Sources */,
BAF46809172813BB0069D928 /* gtest-all.cc in Sources */,
BAF4680A172813BB0069D928 /* gtest_main.cc in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
BAE5F9CE1727F08F001D0075 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ARCHS = "$(ARCHS_STANDARD_64_BIT)";
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
GTEST_USE_OWN_TR1_TUPLE,
"DEBUG=1",
"$(inherited)",
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = (
"../**",
"./**",
);
MACOSX_DEPLOYMENT_TARGET = 10.7;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
USER_HEADER_SEARCH_PATHS = "";
};
name = Debug;
};
BAE5F9CF1727F08F001D0075 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ARCHS = "$(ARCHS_STANDARD_64_BIT)";
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_PREPROCESSOR_DEFINITIONS = GTEST_USE_OWN_TR1_TUPLE;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = (
"../**",
"./**",
);
MACOSX_DEPLOYMENT_TARGET = 10.7;
SDKROOT = macosx;
USER_HEADER_SEARCH_PATHS = "";
};
name = Release;
};
BAE5F9D11727F08F001D0075 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
};
BAE5F9D21727F08F001D0075 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
BAE5F9C21727F08F001D0075 /* Build configuration list for PBXProject "test" */ = {
isa = XCConfigurationList;
buildConfigurations = (
BAE5F9CE1727F08F001D0075 /* Debug */,
BAE5F9CF1727F08F001D0075 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
BAE5F9D01727F08F001D0075 /* Build configuration list for PBXNativeTarget "test" */ = {
isa = XCConfigurationList;
buildConfigurations = (
BAE5F9D11727F08F001D0075 /* Debug */,
BAE5F9D21727F08F001D0075 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = BAE5F9BF1727F08F001D0075 /* Project object */;
}

View File

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:test.xcodeproj">
</FileRef>
</Workspace>