diff --git a/.githooks/commit-msg b/.githooks/commit-msg
deleted file mode 100755
index 52e7a30..0000000
--- a/.githooks/commit-msg
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/bin/bash
-
-format() {
- sed -e 's/^fix:/доза:/' \
- -e '/^# ------------------------ >8 ------------------------$/,$d' \
- -e '/^#/d'
-}
-
-translated="$(curl -s \
- http://localhost:9000/translate \
- -H 'Content-Type: text/html' \
- --data-binary @- -o- < <(format < "$1") | \
- tail -n +2 | \
- perl -pe 's,(.*?),\1,g')"
-
-[ -n "$translated" ] && echo "$translated" > "$1"
diff --git a/.gitignore b/.gitignore
index f364d66..b50f60d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,6 @@
-build/
.cache/
+/test
+build/
+cache/
cmake-build*/
compile_commands.json
diff --git a/.gitmodules b/.gitmodules
deleted file mode 100644
index 79d1dc3..0000000
--- a/.gitmodules
+++ /dev/null
@@ -1,3 +0,0 @@
-[submodule "puppy/include/http"]
- path = puppy/include/http
- url = https://github.com/yhirose/cpp-httplib
diff --git a/README.md b/README.md
deleted file mode 100644
index 69b2b44..0000000
--- a/README.md
+++ /dev/null
@@ -1,34 +0,0 @@
-# promty
-
-## Собирание
-
-Чтобы строить проект, Вы нуждаетесь:
-1. Получить **законную копию** "X-переводчика ПРОМТ Magic Gooddy 6.0.0.205" (да, мы фактически имеем эти DVD),
-2. Установите это на вашей машине "Окна"
-3. Бегите сервером SSH на той машине
-4. Управляемый `puppy/scripts/prepare_environment.sh "WINDOWS_USER@WINDOWS_IP"`. Это будет тянуть все необходимые файлы и ключи регистр
-5. Управляемый `docker compose up -d --build`
-
-## Вклад
-
-### Передайте Стиль
-
-Эти использования проекта, для которых "обычное передает формат", передают сообщения.
-
-```
-напечатайте [возможности]: передайте описание
-
-дополнительное тело
-
-дополнительная нижняя
-```
-
-Мы используем только известный, стандартизированный передают типы как определено спецификацией:
-
-| Напечатать | Описание |
-|------------------------|-----------------------------------------------------------------------------------------------------------|
-| `подвиг` | Добавляет, что новая особенность к codebase |
-| `доза` | Залатать неполадки в codebase |
-| `доктора` | Изменения только для докторов |
-| `тест` | Сменить испытания |
-| `хозяйственная работа` | Изменения, которые непосредственно не затрагивают кодекс, типа ударов версии или обновлений иждивенчества |
diff --git a/caddy/Caddyfile b/caddy/Caddyfile
index 3be3842..38827b2 100644
--- a/caddy/Caddyfile
+++ b/caddy/Caddyfile
@@ -14,10 +14,6 @@ http://ядро.орг, http://*.ядро.орг {
# we don't want to flood the upstream from the same IP
mode bypass
ttl 30m
-
- timeout {
- backend 10m
- }
}
import Caddyfile.yadro proxy:80
@@ -27,24 +23,13 @@ http://ядро.орг, http://*.ядро.орг {
reverse_proxy {
dynamic a puppy 80
lb_policy least_conn
-
- transport http {
- response_header_timeout 10m
- read_timeout 10m
- write_timeout 10m
- }
}
cache {
allowed_http_verbs POST
ttl 7d
-
- key {
- headers X-Translation-Direction
- }
-
timeout {
- backend 10m
+ backend 1m
}
}
}
diff --git a/caddy/Caddyfile.yadro b/caddy/Caddyfile.yadro
index c8a7c6d..c8244f5 100644
--- a/caddy/Caddyfile.yadro
+++ b/caddy/Caddyfile.yadro
@@ -75,6 +75,6 @@ handle @surely_static {
redir @known_host https://{kernel}{uri} permanent
}
-# TODO: cache by path for 30 minutes
+# TOOO: cache by path for 30 minutes
reverse_proxy {args[0]}
diff --git a/caddy/Dockerfile b/caddy/Dockerfile
index a2e47ee..3d21c17 100644
--- a/caddy/Dockerfile
+++ b/caddy/Dockerfile
@@ -1,6 +1,8 @@
FROM caddy:builder AS builder
+
RUN --mount=type=cache,target=/go/pkg/mod xcaddy build \
--with github.com/caddyserver/cache-handler
FROM caddy:latest
+
COPY --from=builder /usr/bin/caddy /usr/bin/caddy
diff --git a/docker-compose.yml b/docker-compose.yml
index 45428e3..1bb0852 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,35 +1,33 @@
services:
puppies:
- networks: [promty]
+ networks:
+ - promty
build: puppy
hostname: puppy
+ stop_signal: SIGINT
volumes:
- /dev/shm/puppy-temp:/tmpfs
+ - ./cache:/cache
deploy:
mode: replicated
- replicas: 3
+ replicas: 1
endpoint_mode: vip
- update_config:
- order: start-first
proxy:
- networks: [promty]
+ networks:
+ - promty
container_name: proxy
build: proxy
- depends_on:
- puppies:
- condition: service_healthy
caddy:
- networks: [promty]
+ networks:
+ - promty
container_name: caddy
build: caddy
volumes:
- ./caddy:/etc/caddy
- depends_on: [proxy]
ports:
- 80:80
- - 9000:9000
networks:
promty:
diff --git a/domains b/domains
index b993a5b..110ffcf 100644
--- a/domains
+++ b/domains
@@ -25,7 +25,7 @@
линукс.ядро.орг linux.kernel.org
саял.ядро.орг lkml.kernel.org
уздечка.ядро.орг lore.kernel.org
-кольчуга.ядро.орг mail.kernel.org
+почта.ядро.орг mail.kernel.org
социальные.сми.ядро.орг media.social.kernel.org
край.зеркал.ядро.орг mirrors.edge.kernel.org
зеркала.ядро.орг mirrors.kernel.org
@@ -33,7 +33,7 @@
уздечка.сппн.ядро.орг nntp.lore.kernel.org
нью-йоркские.зеркала.ядро.орг ny.mirrors.kernel.org
источник.нук.ядро.орг nyc.source.kernel.org
-прокладка.ядро.орг pad.kernel.org
+клавиатура.ядро.орг pad.kernel.org
доктора.париж.ядро.орг parisc.docs.kernel.org
путаница.ядро.орг patchwork.kernel.org
люди.ядро.орг people.kernel.org
@@ -43,13 +43,13 @@
источник.греха.ядро.орг sin.source.kernel.org
пппп.ядро.орг smtp.kernel.org
уздечка.пппп.ядро.орг smtp.lore.kernel.org
-подпространство.пппп.ядро.орг smtp.subspace.kernel.org
+подместо.пппп.ядро.орг smtp.subspace.kernel.org
пппп1.ядро.орг smtp1.kernel.org
пппп2.ядро.орг smtp2.kernel.org
пппп3.ядро.орг smtp3.kernel.org
-социальное.ядро.орг social.kernel.org
+социальный.ядро.орг social.kernel.org
редкие.доктора.ядро.орг sparse.docs.kernel.org
-подпространство.ядро.орг subspace.kernel.org
+подместо.ядро.орг subspace.kernel.org
зеркала.резюме.ядро.орг sv.mirrors.kernel.org
сай.отражает.ядро.орг sy.mirrors.kernel.org
мпук.ядро.орг vger.kernel.org
diff --git a/proxy/Dockerfile b/proxy/Dockerfile
index 5e46401..52f9945 100644
--- a/proxy/Dockerfile
+++ b/proxy/Dockerfile
@@ -1,15 +1,10 @@
FROM golang:1.23-alpine AS builder
-
WORKDIR /build
COPY . .
-
-RUN --mount=type=cache,target=/go/pkg/mod go build;
-
+RUN --mount=type=cache,target=/go/pkg/mod go build
FROM alpine AS runner
-
WORKDIR /app
COPY --from=builder /build/proxy .
-
EXPOSE 80/tcp
CMD ./proxy
diff --git a/proxy/main.go b/proxy/main.go
index 7d01449..51f9d5a 100644
--- a/proxy/main.go
+++ b/proxy/main.go
@@ -23,7 +23,6 @@ func main() {
// We only support gzip decoding
r.Out.Header.Set("Accept-Encoding", "gzip")
- r.Out.Header.Set("User-Agent", "ядро.орг/1.0")
},
ModifyResponse: func(r *http.Response) error {
// Disable security policy because of the domain restrictions.
@@ -68,7 +67,7 @@ func main() {
return original_raw
}
- return []byte("https://" + yadro + "/")
+ return []byte("http://" + yadro + "/") // TODO: https
})))
}
@@ -88,15 +87,11 @@ func main() {
http.ListenAndServe("0.0.0.0:80", proxy)
}
-func replaceDomains(response string) string {
+func replaceDomains(response []byte) []byte {
re := regexp.MustCompile(`(?i)[A-Za-z\-\.]*\.?kernel\.org`)
- response = strings.NewReplacer(
- "%3F", "?",
- "%26", "&",
- ).Replace(response)
- response = re.ReplaceAllStringFunc(response, func(original_raw string) string {
- kernel := strings.ToLower(original_raw)
+ response = re.ReplaceAllFunc(response, func(original_raw []byte) []byte {
+ kernel := strings.ToLower(string(original_raw))
// Strip `www.`
kernel = strings.TrimPrefix(kernel, "www.")
@@ -108,46 +103,42 @@ func replaceDomains(response string) string {
return original_raw
}
- return yadro
+ return []byte(yadro)
})
+ response = bytes.ReplaceAll(response, []byte("%3F"), []byte("?"))
+ response = bytes.ReplaceAll(response, []byte("%26"), []byte("&"))
+ response = bytes.ReplaceAll(response, []byte("https"), []byte("http")) // TODO: TEMP
+
return response
}
-func translateWithPromtPuppies(response string) string {
+func translateWithPromtPuppies(response []byte) []byte {
// Don't try to translate empty body (30x, etc)
if len(response) == 0 {
return response
}
- req, _ := http.NewRequest("POST", "http://caddy:9000/translate", strings.NewReader(response))
+ req, _ := http.NewRequest("POST", "http://caddy:9000/translate", bytes.NewReader(response))
req.Header.Add("Content-Type", "text/html")
resp, err := http.DefaultClient.Do(req)
if err != nil {
- fmt.Fprintln(os.Stderr, "Error in while translating", err)
- return ""
+ fmt.Fprintln(os.Stderr, "Error in first", err)
+ return []byte{0}
}
- var translated strings.Builder
- io.Copy(&translated, resp.Body)
+ response, _ = io.ReadAll(resp.Body)
+
resp.Body.Close()
- return translated.String()
-}
-
-func enfunnify(response string) string {
- return strings.NewReplacer(
- "tarball", "tar ball",
- ).Replace(response)
+ return response
}
func modifyResponse(response []byte) []byte {
- s := string(response)
- s = enfunnify(s)
- s = translateWithPromtPuppies(s)
- s = replaceDomains(s)
- return []byte(s)
+ response = translateWithPromtPuppies(response)
+ response = replaceDomains(response)
+ return response
}
diff --git a/puppy/Dockerfile b/puppy/Dockerfile
index b235ad9..c539092 100644
--- a/puppy/Dockerfile
+++ b/puppy/Dockerfile
@@ -1,47 +1,41 @@
#check=skip=JSONArgsRecommended
-
-FROM debian:13-slim AS builder
+FROM debian:12-slim AS builder
RUN apt-get update && DEBIAN_FRONTEND=noninteracive apt-get install -y \
--no-install-recommends cmake g++-mingw-w64-i686-posix g++ make && \
- apt-get clean && rm -rf /var/lib/apt/lists/*;
+ apt-get clean && rm -rf /var/lib/apt/lists/*
WORKDIR /build
-
-COPY app/healthcheck.cpp app/healthcheck.cpp
-COPY include/http include/http
-RUN g++ -o healthcheck -I./include ./app/healthcheck.cpp;
-
-COPY app app
-COPY include include
-COPY src src
-COPY CMakeLists.txt .
+COPY . .
+RUN g++ -o healthcheck -I./include ./app/healthcheck.cpp
RUN --mount=type=cache,target=cmake-build cmake -B cmake-build \
-DCMAKE_CXX_COMPILER=i686-w64-mingw32-g++ && cmake --build cmake-build -j$(nproc) && \
- cp cmake-build/promt-puppy.exe .;
+ cp cmake-build/promt-puppy.exe .
-
-FROM debian:13-slim AS runner
+FROM debian:12-slim AS runner
ENV WINEPREFIX=/wineprefix \
- XDG_RUNTIME_DIR=/tmp/ \
- DEBIAN_FRONTEND=noninteracive \
- WINEDEBUG=-all
-
+ DEBIAN_FRONTEND=noninteracive
RUN dpkg --add-architecture i386 && apt-get update && \
apt-get install -y --no-install-recommends \
wine wine64 wine32:i386 && \
apt-get clean && rm -rf /var/lib/apt/lists/* && \
- mkdir -p /tmpfs $WINEPREFIX/drive_c && ln -sf /tmpfs $WINEPREFIX/drive_c/tmpfs;
+ wineboot -i && echo "Sleeping for 15 seconds..." && sleep 15 && \
+ mkdir /tmpfs && ln -sf /tmpfs $WINEPREFIX/drive_c/tmpfs
+
COPY build/ $WINEPREFIX/drive_c
+RUN wine regedit $WINEPREFIX/drive_c/registry.reg && \
+ echo "Sleeping for 15 seconds" && sleep 15
WORKDIR /app
+
COPY --from=builder /build/promt-puppy.exe /build/healthcheck .
-HEALTHCHECK --start-period=30s --start-interval=1s CMD ./healthcheck;
+
+HEALTHCHECK CMD ./healthcheck
EXPOSE 80/tcp
VOLUME /cache
-STOPSIGNAL SIGINT
-COPY docker-entrypoint.sh /entrypoint.sh
-ENTRYPOINT ["/entrypoint.sh"]
+ENV WINEDEBUG=-all
+
+CMD exec wine promt-puppy.exe
diff --git a/puppy/app/healthcheck.cpp b/puppy/app/healthcheck.cpp
index 110bc3e..f5e023f 100644
--- a/puppy/app/healthcheck.cpp
+++ b/puppy/app/healthcheck.cpp
@@ -1,4 +1,4 @@
-#include "http/httplib.h"
+#include "httplib.hpp"
int main() {
auto res = httplib::Client("127.0.0.1", 80).Get("/health");
diff --git a/puppy/app/main.cpp b/puppy/app/main.cpp
index 13a52b2..1acb218 100644
--- a/puppy/app/main.cpp
+++ b/puppy/app/main.cpp
@@ -1,62 +1,18 @@
-#include "http/httplib.h"
+#include "httplib.hpp"
-#include
-#include
-#include
#include
#include
-#include
#include
#include
-#include
-#include
#include "PromtCtlDocument.hpp"
#include "PromtFTManager.hpp"
-#define EPOCH_DIFF 116444736000000000LL
-#define TICKS_PER_SEC 10000000LL
-
-static LARGE_INTEGER fake_time;
-
-static NTSTATUS WINAPI HookedNtQuerySystemTime(PLARGE_INTEGER time)
-{
- if (time)
- time->QuadPart = fake_time.QuadPart;
-
- fake_time.QuadPart += TICKS_PER_SEC;
- return 0;
-}
-
-static void InstallTimeHook()
-{
- HMODULE ntdll = GetModuleHandleA("ntdll.dll");
- if (!ntdll)
- return;
-
- auto target = (BYTE *)GetProcAddress(ntdll, "NtQuerySystemTime");
- if (!target)
- return;
-
- DWORD old;
- VirtualProtect(target, 5, PAGE_EXECUTE_READWRITE, &old);
-
- intptr_t rel = (BYTE *)HookedNtQuerySystemTime - target - 5;
- target[0] = 0xE9; // jmp rel32
- *(int32_t *)(target + 1) = (int32_t)rel;
-
- VirtualProtect(target, 5, old, &old);
-
- const char *env = std::getenv("FAKETIME");
- long long unix_ts = env ? std::strtoll(env, nullptr, 10) : 0;
- fake_time.QuadPart = unix_ts * TICKS_PER_SEC + EPOCH_DIFF;
-}
-
static inline std::string random_filename(int len = 65) {
static const char ASCII_PRINTABLE[] = "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
- static std::random_device random_device;
- static std::mt19937 generator(random_device());
- static std::uniform_int_distribution distribution(0, static_cast(strlen(ASCII_PRINTABLE) - 1));
+ std::random_device random_device;
+ std::mt19937 generator(random_device());
+ std::uniform_int_distribution distribution(0, static_cast(strlen(ASCII_PRINTABLE) - 1));
std::string random_string;
random_string.reserve(len);
for (int i = 0; i < len; ++i)
@@ -105,20 +61,11 @@ static inline auto read_file(const std::string &filename) {
size = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, 0, 0);
std::string out;
- out.resize(size - 1);
- WideCharToMultiByte(CP_UTF8, 0, wstr, -1, out.data(), size - 1, 0, 0);
+ out.resize(size);
+ WideCharToMultiByte(CP_UTF8, 0, wstr, -1, out.data(), size, 0, 0);
delete[] wstr;
- std::string out_lf;
- out_lf.reserve(out.size());
-
- for (auto c : out) {
- if (c == '\r')
- continue;
- out_lf.push_back(c);
- }
-
- return out_lf;
+ return out;
}
class WebServer {
@@ -195,8 +142,7 @@ class WebServer {
public:
WebServer() {
- if (!std::filesystem::exists(TMP_FOLDER))
- std::filesystem::create_directory(TMP_FOLDER);
+ if (!std::filesystem::exists(TMP_FOLDER)) std::filesystem::create_directory(TMP_FOLDER);
m_svr.Post("/translate", [this](const httplib::Request &req, httplib::Response &res) {
TranslateHandler(req, res);
@@ -213,7 +159,6 @@ class WebServer {
}
void listen(const char *host = "0.0.0.0", unsigned short port = 80) {
- print("started!");
m_svr.listen(host, port);
}
@@ -224,23 +169,12 @@ class WebServer {
}
};
-static std::function signal_action;
-
-void signal_handler(int signal) {
- signal_action(signal);
-}
-
int main() {
- InstallTimeHook();
+ print("Starting...");
CoInitializeEx(NULL, COINIT_MULTITHREADED);
CoInitializeSecurity(nullptr, -1, nullptr, nullptr, RPC_C_AUTHN_LEVEL_NONE, RPC_C_IMP_LEVEL_IDENTIFY, nullptr, EOAC_NONE, nullptr);
WebServer ws;
-
- signal_action = [&](int x) { ws.stop(); };
- std::signal(SIGTERM, signal_handler);
- std::signal(SIGINT, signal_handler);
-
ws.listen();
}
diff --git a/puppy/docker-entrypoint.sh b/puppy/docker-entrypoint.sh
deleted file mode 100755
index 82cd9b6..0000000
--- a/puppy/docker-entrypoint.sh
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/bin/bash
-# shellcheck disable=SC2155
-
-echo 'initializing wine...'
-wineboot -i
-
-echo 'copying registy values...'
-wine regedit "$WINEPREFIX"/drive_c/registry.reg
-
-export FAKETIME="$(cat "$WINEPREFIX"/drive_c/build-date)"
-echo "starting with date $(date -d @"$FAKETIME")..."
-exec wine /app/promt-puppy.exe
diff --git a/puppy/include/http b/puppy/include/http
deleted file mode 160000
index adf58bf..0000000
--- a/puppy/include/http
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit adf58bf474fac638160592d6c3f67da4ebc7df20
diff --git a/puppy/include/httplib.hpp b/puppy/include/httplib.hpp
new file mode 100644
index 0000000..cae875c
--- /dev/null
+++ b/puppy/include/httplib.hpp
@@ -0,0 +1,10243 @@
+//
+// https://github.com/yhirose/cpp-httplib
+// Copyright (c) 2024 Yuji Hirose. All rights reserved.
+// MIT License
+//
+
+#ifndef CPPHTTPLIB_HTTPLIB_H
+#define CPPHTTPLIB_HTTPLIB_H
+
+#define CPPHTTPLIB_VERSION "0.18.1"
+
+/*
+ * Configuration
+ */
+
+#ifndef CPPHTTPLIB_KEEPALIVE_TIMEOUT_SECOND
+#define CPPHTTPLIB_KEEPALIVE_TIMEOUT_SECOND 5
+#endif
+
+#ifndef CPPHTTPLIB_KEEPALIVE_TIMEOUT_CHECK_INTERVAL_USECOND
+#define CPPHTTPLIB_KEEPALIVE_TIMEOUT_CHECK_INTERVAL_USECOND 10000
+#endif
+
+#ifndef CPPHTTPLIB_KEEPALIVE_MAX_COUNT
+#define CPPHTTPLIB_KEEPALIVE_MAX_COUNT 100
+#endif
+
+#ifndef CPPHTTPLIB_CONNECTION_TIMEOUT_SECOND
+#define CPPHTTPLIB_CONNECTION_TIMEOUT_SECOND 300
+#endif
+
+#ifndef CPPHTTPLIB_CONNECTION_TIMEOUT_USECOND
+#define CPPHTTPLIB_CONNECTION_TIMEOUT_USECOND 0
+#endif
+
+#ifndef CPPHTTPLIB_SERVER_READ_TIMEOUT_SECOND
+#define CPPHTTPLIB_SERVER_READ_TIMEOUT_SECOND 5
+#endif
+
+#ifndef CPPHTTPLIB_SERVER_READ_TIMEOUT_USECOND
+#define CPPHTTPLIB_SERVER_READ_TIMEOUT_USECOND 0
+#endif
+
+#ifndef CPPHTTPLIB_SERVER_WRITE_TIMEOUT_SECOND
+#define CPPHTTPLIB_SERVER_WRITE_TIMEOUT_SECOND 5
+#endif
+
+#ifndef CPPHTTPLIB_SERVER_WRITE_TIMEOUT_USECOND
+#define CPPHTTPLIB_SERVER_WRITE_TIMEOUT_USECOND 0
+#endif
+
+#ifndef CPPHTTPLIB_CLIENT_READ_TIMEOUT_SECOND
+#define CPPHTTPLIB_CLIENT_READ_TIMEOUT_SECOND 300
+#endif
+
+#ifndef CPPHTTPLIB_CLIENT_READ_TIMEOUT_USECOND
+#define CPPHTTPLIB_CLIENT_READ_TIMEOUT_USECOND 0
+#endif
+
+#ifndef CPPHTTPLIB_CLIENT_WRITE_TIMEOUT_SECOND
+#define CPPHTTPLIB_CLIENT_WRITE_TIMEOUT_SECOND 5
+#endif
+
+#ifndef CPPHTTPLIB_CLIENT_WRITE_TIMEOUT_USECOND
+#define CPPHTTPLIB_CLIENT_WRITE_TIMEOUT_USECOND 0
+#endif
+
+#ifndef CPPHTTPLIB_IDLE_INTERVAL_SECOND
+#define CPPHTTPLIB_IDLE_INTERVAL_SECOND 0
+#endif
+
+#ifndef CPPHTTPLIB_IDLE_INTERVAL_USECOND
+#ifdef _WIN32
+#define CPPHTTPLIB_IDLE_INTERVAL_USECOND 10000
+#else
+#define CPPHTTPLIB_IDLE_INTERVAL_USECOND 0
+#endif
+#endif
+
+#ifndef CPPHTTPLIB_REQUEST_URI_MAX_LENGTH
+#define CPPHTTPLIB_REQUEST_URI_MAX_LENGTH 8192
+#endif
+
+#ifndef CPPHTTPLIB_HEADER_MAX_LENGTH
+#define CPPHTTPLIB_HEADER_MAX_LENGTH 8192
+#endif
+
+#ifndef CPPHTTPLIB_REDIRECT_MAX_COUNT
+#define CPPHTTPLIB_REDIRECT_MAX_COUNT 20
+#endif
+
+#ifndef CPPHTTPLIB_MULTIPART_FORM_DATA_FILE_MAX_COUNT
+#define CPPHTTPLIB_MULTIPART_FORM_DATA_FILE_MAX_COUNT 1024
+#endif
+
+#ifndef CPPHTTPLIB_PAYLOAD_MAX_LENGTH
+#define CPPHTTPLIB_PAYLOAD_MAX_LENGTH ((std::numeric_limits::max)())
+#endif
+
+#ifndef CPPHTTPLIB_FORM_URL_ENCODED_PAYLOAD_MAX_LENGTH
+#define CPPHTTPLIB_FORM_URL_ENCODED_PAYLOAD_MAX_LENGTH 8192
+#endif
+
+#ifndef CPPHTTPLIB_RANGE_MAX_COUNT
+#define CPPHTTPLIB_RANGE_MAX_COUNT 1024
+#endif
+
+#ifndef CPPHTTPLIB_TCP_NODELAY
+#define CPPHTTPLIB_TCP_NODELAY false
+#endif
+
+#ifndef CPPHTTPLIB_IPV6_V6ONLY
+#define CPPHTTPLIB_IPV6_V6ONLY false
+#endif
+
+#ifndef CPPHTTPLIB_RECV_BUFSIZ
+#define CPPHTTPLIB_RECV_BUFSIZ size_t(16384u)
+#endif
+
+#ifndef CPPHTTPLIB_COMPRESSION_BUFSIZ
+#define CPPHTTPLIB_COMPRESSION_BUFSIZ size_t(16384u)
+#endif
+
+#ifndef CPPHTTPLIB_THREAD_POOL_COUNT
+#define CPPHTTPLIB_THREAD_POOL_COUNT \
+ ((std::max)(8u, std::thread::hardware_concurrency() > 0 \
+ ? std::thread::hardware_concurrency() - 1 \
+ : 0))
+#endif
+
+#ifndef CPPHTTPLIB_RECV_FLAGS
+#define CPPHTTPLIB_RECV_FLAGS 0
+#endif
+
+#ifndef CPPHTTPLIB_SEND_FLAGS
+#define CPPHTTPLIB_SEND_FLAGS 0
+#endif
+
+#ifndef CPPHTTPLIB_LISTEN_BACKLOG
+#define CPPHTTPLIB_LISTEN_BACKLOG 5
+#endif
+
+/*
+ * Headers
+ */
+
+#ifdef _WIN32
+#ifndef _CRT_SECURE_NO_WARNINGS
+#define _CRT_SECURE_NO_WARNINGS
+#endif //_CRT_SECURE_NO_WARNINGS
+
+#ifndef _CRT_NONSTDC_NO_DEPRECATE
+#define _CRT_NONSTDC_NO_DEPRECATE
+#endif //_CRT_NONSTDC_NO_DEPRECATE
+
+#if defined(_MSC_VER)
+#if _MSC_VER < 1900
+#error Sorry, Visual Studio versions prior to 2015 are not supported
+#endif
+
+#pragma comment(lib, "ws2_32.lib")
+
+#ifdef _WIN64
+using ssize_t = __int64;
+#else
+using ssize_t = long;
+#endif
+#endif // _MSC_VER
+
+#ifndef S_ISREG
+#define S_ISREG(m) (((m) & S_IFREG) == S_IFREG)
+#endif // S_ISREG
+
+#ifndef S_ISDIR
+#define S_ISDIR(m) (((m) & S_IFDIR) == S_IFDIR)
+#endif // S_ISDIR
+
+#ifndef NOMINMAX
+#define NOMINMAX
+#endif // NOMINMAX
+
+#include
+#include
+#include
+
+#ifndef WSA_FLAG_NO_HANDLE_INHERIT
+#define WSA_FLAG_NO_HANDLE_INHERIT 0x80
+#endif
+
+using socket_t = SOCKET;
+#ifdef CPPHTTPLIB_USE_POLL
+#define poll(fds, nfds, timeout) WSAPoll(fds, nfds, timeout)
+#endif
+
+#else // not _WIN32
+
+#include
+#if !defined(_AIX) && !defined(__MVS__)
+#include
+#endif
+#ifdef __MVS__
+#include
+#ifndef NI_MAXHOST
+#define NI_MAXHOST 1025
+#endif
+#endif
+#include
+#include
+#include
+#ifdef __linux__
+#include
+#endif
+#include
+#ifdef CPPHTTPLIB_USE_POLL
+#include
+#endif
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+using socket_t = int;
+#ifndef INVALID_SOCKET
+#define INVALID_SOCKET (-1)
+#endif
+#endif //_WIN32
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include