forked from pEp.foundation/pEpJSONServerAdapter
Revert "Merge branch 'master' into JSON-128" - it was a b0rken merge.
This reverts commitJSON-128a099d13101
, reversing changes made to3eb0e3686b
.
parent
a099d13101
commit
5dd6cba229
@ -1,34 +0,0 @@
|
||||
.DS_Store
|
||||
|
||||
*.o
|
||||
*.Po
|
||||
*.Plo
|
||||
*.pc
|
||||
*~
|
||||
*.d
|
||||
|
||||
server/pep-json-server
|
||||
server/servertest
|
||||
server/unittests
|
||||
server/*.a
|
||||
server/prefix-config.cc
|
||||
server/local.conf
|
||||
server/*.d
|
||||
server/json_spirit/*.d
|
||||
|
||||
build/
|
||||
|
||||
*.vcxproj.user
|
||||
*.obj
|
||||
*.exe
|
||||
*.lib
|
||||
build-windows/libevent/Release/*
|
||||
build-windows/libevent/Debug/*
|
||||
build-windows/pEpJSONServerAdapter/Release/*
|
||||
build-windows/pEpJSONServerAdapter/Debug/*
|
||||
|
||||
server/pEp-mini-json-adapter
|
||||
|
||||
*.d.*
|
||||
.??*.swp
|
||||
tags
|
@ -0,0 +1,65 @@
|
||||
syntax: glob
|
||||
.DS_Store
|
||||
|
||||
*.o
|
||||
*.Po
|
||||
*.Plo
|
||||
*.pc
|
||||
*~
|
||||
|
||||
libevent-*-stable/Makefile
|
||||
libevent-*-stable/config.h
|
||||
libevent-*-stable/config.log
|
||||
libevent-*-stable/config.status
|
||||
libevent-*-stable/include/Makefile
|
||||
libevent-*-stable/libtool
|
||||
libevent-*-stable/sample/Makefile
|
||||
libevent-*-stable/stamp-h1
|
||||
libevent-*-stable/test/Makefile
|
||||
libevent-*-stable/**/.libs/
|
||||
libevent-*-stable/*.lo
|
||||
libevent-*-stable/*.la
|
||||
|
||||
libevent-*-stable/autom4te.cache/
|
||||
libevent-*-stable/include/event2/event-config.h
|
||||
libevent-*-stable/sample/dns-example
|
||||
libevent-*-stable/sample/event-test
|
||||
libevent-*-stable/sample/hello-world
|
||||
libevent-*-stable/sample/http-server
|
||||
libevent-*-stable/sample/le-proxy
|
||||
libevent-*-stable/sample/signal-test
|
||||
libevent-*-stable/sample/time-test
|
||||
libevent-*-stable/test/bench
|
||||
libevent-*-stable/test/bench_cascade
|
||||
libevent-*-stable/test/bench_http
|
||||
libevent-*-stable/test/bench_httpclient
|
||||
libevent-*-stable/test/regress
|
||||
libevent-*-stable/test/rpcgen-attempted
|
||||
libevent-*-stable/test/test-changelist
|
||||
libevent-*-stable/test/test-eof
|
||||
libevent-*-stable/test/test-init
|
||||
libevent-*-stable/test/test-ratelim
|
||||
libevent-*-stable/test/test-time
|
||||
libevent-*-stable/test/test-weof
|
||||
|
||||
libevent-*-stable/build/
|
||||
|
||||
server/pep-json-server
|
||||
server/servertest
|
||||
server/unittests
|
||||
server/*.a
|
||||
server/prefix-config.cc
|
||||
server/local.conf
|
||||
server/*.d
|
||||
server/json_spirit/*.d
|
||||
|
||||
build/
|
||||
|
||||
*.vcxproj.user
|
||||
*.obj
|
||||
*.exe
|
||||
*.lib
|
||||
build-windows/libevent/Release/*
|
||||
build-windows/libevent/Debug/*
|
||||
build-windows/pEpJSONServerAdapter/Release/*
|
||||
build-windows/pEpJSONServerAdapter/Debug/*
|
@ -0,0 +1,65 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>15.0</VCProjectVersion>
|
||||
<ProjectGuid>{8CE78FD7-FE44-4F1F-B9A5-CB34186BBC56}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Makefile</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Makefile</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<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" />
|
||||
</ImportGroup>
|
||||
<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" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<NMakeBuildCommandLine>cd "$(ProjectDir)..\..\libevent-2.0.22-stable\" && nmake -f Makefile.nmake</NMakeBuildCommandLine>
|
||||
<NMakeOutput>libevent.lib</NMakeOutput>
|
||||
<NMakePreprocessorDefinitions>WIN32;_DEBUG;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions>
|
||||
<NMakeCleanCommandLine>cd "$(ProjectDir)..\..\libevent-2.0.22-stable\" && nmake -f Makefile.nmake clean</NMakeCleanCommandLine>
|
||||
<NMakeReBuildCommandLine>cd "$(ProjectDir)..\..\libevent-2.0.22-stable\" && nmake -f Makefile.nmake /a</NMakeReBuildCommandLine>
|
||||
<OutDir>..\..\libevent-2.0.22-stable</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<NMakeBuildCommandLine>cd "$(ProjectDir)..\..\libevent-2.0.22-stable\" && nmake -f Makefile.nmake</NMakeBuildCommandLine>
|
||||
<NMakeOutput>libevent.lib</NMakeOutput>
|
||||
<NMakePreprocessorDefinitions>WIN32;NDEBUG;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions>
|
||||
<NMakeCleanCommandLine>cd "$(ProjectDir)..\..\libevent-2.0.22-stable\" && nmake -f Makefile.nmake clean</NMakeCleanCommandLine>
|
||||
<NMakeReBuildCommandLine>cd "$(ProjectDir)..\..\libevent-2.0.22-stable\" && nmake -f Makefile.nmake /a</NMakeReBuildCommandLine>
|
||||
<OutDir>..\..\libevent-2.0.22-stable</OutDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
@ -1,172 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{0d25734e-a71b-4536-8dc4-60e945382fc5}</ProjectGuid>
|
||||
<RootNamespace>libpEpwebserver</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
<ProjectName>libpEpWebserver</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<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" />
|
||||
</ImportGroup>
|
||||
<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" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<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|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\webserver.cc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\webserver.hh" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\..\pEpEngine\build-windows\pEpEngine.vcxproj">
|
||||
<Project>{146e69f8-e1da-456a-b048-6dd29d9acf6b}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="..\..\..\..\packages\boost.1.72.0.0\build\boost.targets" Condition="Exists('..\..\..\..\packages\boost.1.72.0.0\build\boost.targets')" />
|
||||
<Import Project="..\..\..\..\packages\boost_date_time-vc142.1.72.0.0\build\boost_date_time-vc142.targets" Condition="Exists('..\..\..\..\packages\boost_date_time-vc142.1.72.0.0\build\boost_date_time-vc142.targets')" />
|
||||
<Import Project="..\..\..\..\packages\boost_filesystem-vc142.1.72.0.0\build\boost_filesystem-vc142.targets" Condition="Exists('..\..\..\..\packages\boost_filesystem-vc142.1.72.0.0\build\boost_filesystem-vc142.targets')" />
|
||||
<Import Project="..\..\..\..\packages\boost_regex-vc142.1.72.0.0\build\boost_regex-vc142.targets" Condition="Exists('..\..\..\..\packages\boost_regex-vc142.1.72.0.0\build\boost_regex-vc142.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\..\..\..\packages\boost.1.72.0.0\build\boost.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\boost.1.72.0.0\build\boost.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\boost_date_time-vc142.1.72.0.0\build\boost_date_time-vc142.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\boost_date_time-vc142.1.72.0.0\build\boost_date_time-vc142.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\boost_filesystem-vc142.1.72.0.0\build\boost_filesystem-vc142.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\boost_filesystem-vc142.1.72.0.0\build\boost_filesystem-vc142.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\boost_regex-vc142.1.72.0.0\build\boost_regex-vc142.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\boost_regex-vc142.1.72.0.0\build\boost_regex-vc142.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
@ -1,7 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="boost" version="1.72.0.0" targetFramework="native" />
|
||||
<package id="boost_date_time-vc142" version="1.72.0.0" targetFramework="native" />
|
||||
<package id="boost_filesystem-vc142" version="1.72.0.0" targetFramework="native" />
|
||||
<package id="boost_regex-vc142" version="1.72.0.0" targetFramework="native" />
|
||||
</packages>
|
@ -1,268 +0,0 @@
|
||||
// this file is derived from a boost::beast sample
|
||||
|
||||
#include <boost/beast/core.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
#include "webserver.hh"
|
||||
|
||||
namespace pEp {
|
||||
Webserver::Webserver(net::ip::address addr, unsigned short port, const std::string& doc_root)
|
||||
: _ioc{1}
|
||||
, _acceptor{_ioc, {addr, port}, false}
|
||||
, _doc_root{doc_root}
|
||||
, _generic_handler{}
|
||||
, _port{port}
|
||||
, _running{false}
|
||||
{ }
|
||||
|
||||
beast::string_view Webserver::mime_type(beast::string_view path)
|
||||
{
|
||||
using beast::iequals;
|
||||
auto const ext = [&path]
|
||||
{
|
||||
auto const pos = path.rfind(".");
|
||||
if(pos == beast::string_view::npos)
|
||||
return beast::string_view{};
|
||||
return path.substr(pos);
|
||||
}();
|
||||
if(iequals(ext, ".htm")) return "text/html; charset=utf-8";
|
||||
if(iequals(ext, ".html")) return "text/html; charset=utf-8";
|
||||
if(iequals(ext, ".css")) return "text/css; charset=utf-8";
|
||||
if(iequals(ext, ".txt")) return "text/plain; charset=utf-8";
|
||||
if(iequals(ext, ".js")) return "application/javascript; charset=utf-8";
|
||||
if(iequals(ext, ".json")) return "application/json; charset=utf-8";
|
||||
if(iequals(ext, ".xml")) return "application/xml; charset=utf-8";
|
||||
if(iequals(ext, ".png")) return "image/png";
|
||||
if(iequals(ext, ".jpeg")) return "image/jpeg";
|
||||
if(iequals(ext, ".jpg")) return "image/jpeg";
|
||||
if(iequals(ext, ".gif")) return "image/gif";
|
||||
if(iequals(ext, ".ico")) return "image/vnd.microsoft.icon";
|
||||
if(iequals(ext, ".tiff")) return "image/tiff";
|
||||
if(iequals(ext, ".tif")) return "image/tiff";
|
||||
if(iequals(ext, ".svg")) return "image/svg+xml; charset=utf-8";
|
||||
if(iequals(ext, ".svgz")) return "image/svg+xml";
|
||||
return "application/octet-stream";
|
||||
}
|
||||
|
||||
|
||||
void Webserver::add_url_handler(const std::string& url_regex, handler_t handler)
|
||||
{
|
||||
std::lock_guard< std::mutex > lock(_mtx);
|
||||
_urls.emplace(url_regex, Handling{boost::regex(url_regex), handler});
|
||||
}
|
||||
|
||||
|
||||
void Webserver::remove_url_handler(const std::string& url_regex)
|
||||
{
|
||||
std::lock_guard< std::mutex > lock(_mtx);
|
||||
_urls.erase(url_regex);
|
||||
}
|
||||
|
||||
|
||||
void Webserver::add_generic_url_handler(handler_t handler)
|
||||
{
|
||||
_generic_handler = handler;
|
||||
}
|
||||
|
||||
|
||||
void Webserver::remove_generic_url_handler()
|
||||
{
|
||||
_generic_handler = nullptr;
|
||||
}
|
||||
|
||||
|
||||
Webserver::response Webserver::create_status_response(const request& req, http::status status)
|
||||
{
|
||||
http::response< http::string_body > res{status, req.version()};
|
||||
res.set(http::field::content_type, "text/html; charset=utf-8");
|
||||
res.keep_alive(req.keep_alive());
|
||||
std::stringstream s;
|
||||
s << "<html><body>" << int(status) << " " << status << "</body></html>";
|
||||
res.body() = s.str();
|
||||
res.prepare_payload();
|
||||
if (status != http::status::internal_server_error)
|
||||
res.keep_alive(req.keep_alive());
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
Webserver* Webserver::probing_port_range(net::ip::address addr, unsigned short
|
||||
start, unsigned short end, unsigned short& port, const std::string&
|
||||
doc_root)
|
||||
{
|
||||
pEp::Webserver *web = nullptr;
|
||||
|
||||
for (port = start; port <= end; ++port) {
|
||||
try {
|
||||
web = new pEp::Webserver{addr, port, doc_root};
|
||||
break;
|
||||
}
|
||||
catch (boost::system::system_error& err) {
|
||||
}
|
||||
}
|
||||
|
||||
return web;
|
||||
}
|
||||
|
||||
void Webserver::deliver_status(tcp::socket *socket, const request& req, http::status status)
|
||||
{
|
||||
const response res { create_status_response(req, status) };
|
||||
beast::error_code ec;
|
||||
http::write(*socket, res, ec);
|
||||
}
|
||||
|
||||
|
||||
void Webserver::deliver_file(tcp::socket *socket, const request& req)
|
||||
{
|
||||
static boost::regex file{"/([\\w\\d]{1,100}\\.[\\w\\d]{1,4})"};
|
||||
boost::cmatch m;
|
||||
std::string d{req.target().data(), req.target().length()};
|
||||
if (boost::regex_match(d.c_str(), m, file)) {
|
||||
fs::path p{_doc_root};
|
||||
p /= std::string(m[1]);
|
||||
|
||||
beast::error_code ec;
|
||||
http::file_body::value_type body;
|
||||
body.open(p.string().c_str(), beast::file_mode::scan, ec);
|
||||
if (ec == beast::errc::no_such_file_or_directory) {
|
||||
deliver_status(socket, req, http::status::not_found);
|
||||
}
|
||||
else if (ec) {
|
||||
deliver_status(socket, req, http::status::internal_server_error);
|
||||
}
|
||||
else {
|
||||
auto const size = body.size();
|
||||
http::response<http::file_body> res{
|
||||
std::piecewise_construct,
|
||||
std::make_tuple(std::move(body)),
|
||||
std::make_tuple(http::status::ok, req.version())};
|
||||
res.set(http::field::content_type, mime_type(p.string().c_str()));
|
||||
res.content_length(size);
|
||||
res.keep_alive(req.keep_alive());
|
||||
http::write(*socket, res, ec);
|
||||
}
|
||||
}
|
||||
else {
|
||||
deliver_status(socket, req, http::status::not_found);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Webserver::handler_t Webserver::find_handler(const request& req, boost::cmatch& m)
|
||||
{
|
||||
std::lock_guard< std::mutex > lock(_mtx);
|
||||
|
||||
for (auto it=_urls.begin(); it!=_urls.end(); ++it) {
|
||||
std::string d{req.target().data(), req.target().length()};
|
||||
if (boost::regex_match(d.c_str(), m, it->second.regex))
|
||||
return it->second.handler;
|
||||
}
|
||||
|
||||
return _generic_handler; // might be empty std::function!
|
||||
}
|
||||
|
||||
|
||||
void Webserver::do_session(tcp::socket *socket)
|
||||
{
|
||||
beast::error_code ec;
|
||||
beast::flat_buffer buffer;
|
||||
|
||||
while (_running)
|
||||
{
|
||||
http::request_parser<http::string_body> parser;
|
||||
parser.body_limit((std::numeric_limits<std::int32_t>::max)());
|
||||
|
||||
http::read(*socket, buffer, parser, ec);
|
||||
if (ec) {
|
||||
#ifndef NDEBUG
|
||||
// This will print stuff like ...
|
||||
// - end of stream
|
||||
// - An established connection was aborted by the software in your host machine
|
||||
// ... so don't be alarmed.
|
||||
std::cerr << "pEpWebserver: " << ec.message() << "\n";
|
||||
#endif
|
||||
goto the_end;
|
||||
}
|
||||
|
||||
http::request<http::string_body> req = parser.get();
|
||||
|
||||
const auto method = req.method();
|
||||
switch (method)
|
||||
{
|
||||
case http::verb::post: // fall through
|
||||
case http::verb::get:
|
||||
{
|
||||
boost::cmatch m;
|
||||
Webserver::handler_t handler = find_handler(req, m);
|
||||
|
||||
if (handler) {
|
||||
try{
|
||||
const Webserver::response res = handler(m, req);
|
||||
http::write(*socket, res, ec);
|
||||
}
|
||||
catch(...){
|
||||
deliver_status(socket, req, http::status::internal_server_error);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(method == http::verb::get && !_doc_root.empty())
|
||||
{
|
||||
deliver_file(socket, req);
|
||||
}else{
|
||||
deliver_status(socket, req, http::status::not_found);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
deliver_status(socket, req, http::status::method_not_allowed);
|
||||
};
|
||||
|
||||
if (ec)
|
||||
break;
|
||||
}
|
||||
|
||||
the_end:
|
||||
socket->shutdown(tcp::socket::shutdown_send, ec);
|
||||
delete socket;
|
||||
}
|
||||
|
||||
|
||||
void Webserver::runner(Webserver *me)
|
||||
{
|
||||
while (me->_running)
|
||||
{
|
||||
tcp::socket* socket = new tcp::socket{me->_ioc};
|
||||
me->_acceptor.accept(*socket);
|
||||
|
||||
std::function< void() > tf = [=]()
|
||||
{
|
||||
me->thread_init();
|
||||
me->do_session(socket);
|
||||
me->thread_done();
|
||||
};
|
||||
|
||||
std::thread{tf}.detach();
|
||||
}
|
||||
}
|
||||
|
||||
void Webserver::run()
|
||||
{
|
||||
_running = true;
|
||||
_runner = std::thread(runner, this);
|
||||
}
|
||||
|
||||
void Webserver::shutdown()
|
||||
{
|
||||
_running = false;
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -1,99 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <thread>
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
#include <boost/regex.hpp>
|
||||
#include <boost/beast/http.hpp>
|
||||
|
||||
|
||||
namespace pEp {
|
||||
namespace beast = boost::beast;
|
||||
namespace http = beast::http;
|
||||
namespace net = boost::asio;
|
||||
using tcp = boost::asio::ip::tcp;
|
||||
|
||||
// class Webserver
|
||||
//
|
||||
// when an URL handler is present it is called for each matching URL
|
||||
// otherwise this server is searching for static files in doc_root
|
||||
// only registered file types and no subdirectories are served for
|
||||
// static files
|
||||
//
|
||||
// to deliver 404 return nullptr from handler
|
||||
//
|
||||
// this server is supporting GET for static files and POST for handlers
|
||||
|
||||
class Webserver {
|
||||
public:
|
||||
|
||||
typedef boost::regex url_t;
|
||||
typedef http::request< http::string_body > request;
|
||||
typedef http::response< http::string_body > response;
|
||||
typedef std::function< response(boost::cmatch, const request&) > handler_t;
|
||||
|
||||
private:
|
||||
struct Handling {
|
||||
boost::regex regex;
|
||||
handler_t handler;
|
||||
};
|
||||
|
||||
net::io_context _ioc;
|
||||
tcp::acceptor _acceptor;
|
||||
std::string _doc_root;
|
||||
std::unordered_map< std::string, Handling > _urls;
|
||||
handler_t _generic_handler;
|
||||
unsigned short _port;
|
||||
bool _running;
|
||||
std::mutex _mtx;
|
||||
std::thread _runner;
|
||||
|
||||
public:
|
||||
|
||||
// if doc_root is empty, don't deliver arbitrary files.
|
||||
Webserver(net::ip::address addr, unsigned short port, const std::string& doc_root = "");
|
||||
|
||||
Webserver(const Webserver&) = delete;
|
||||
Webserver& operator=(const Webserver&) = delete;
|
||||
virtual ~Webserver() = default;
|
||||
|
||||
constexpr
|
||||
int port() const noexcept { return _port; }
|
||||
|
||||
void add_url_handler (const std::string& url_regex, handler_t handler);
|
||||
void remove_url_handler(const std::string& url_regex);
|
||||
|
||||
// the generic handler will be called if the URL does not match any registered handlers
|
||||
void add_generic_url_handler (handler_t handler);
|
||||
void remove_generic_url_handler();
|
||||
|
||||
void run();
|
||||
void shutdown();
|
||||
|
||||
static beast::string_view mime_type(beast::string_view path);
|
||||
|
||||
static
|
||||
response create_status_response(const request& req, http::status status);
|
||||
|
||||
static Webserver* probing_port_range(net::ip::address addr,
|
||||
unsigned short start, unsigned short end, unsigned short&
|
||||
port, const std::string& doc_root = "");
|
||||
|
||||
protected:
|
||||
static void runner(Webserver *me);
|
||||
void deliver_status(tcp::socket *socket, const request& req, http::status status);
|
||||
void deliver_file (tcp::socket *socket, const request& req);
|
||||
handler_t find_handler(const request& req, boost::cmatch& m);
|
||||
|
||||
// called at the beginning of a connection thread. Do nothing by default.
|
||||
virtual void thread_init() {}
|
||||
|
||||
// called at the beginning of a connection thread. Do nothing by default.
|
||||
virtual void thread_done() {}
|
||||
|
||||
// is called by run(), in a separate thread.
|
||||
void do_session(tcp::socket *socket);
|
||||
};
|
||||
};
|
||||
|