diff --git a/README.md b/README.md index ef6ffbe..fa84578 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ AI scrapers are everywhere. This will stop them. `robots.txt` won't. - Protect your endpoint from AI bots with a cryptographic challenge - Easy configuration in jsonc - Support for cloudflare -- Minimal. The waiting page is a single file with no links that weighs 4kB +- Minimal. The waiting page is tiny and light on network usage. ### Planned features - Dynamic challenge amount (aka difficulty) diff --git a/html/NotoSans.woff b/html/NotoSans.woff new file mode 100644 index 0000000..4d87b9b Binary files /dev/null and b/html/NotoSans.woff differ diff --git a/html/index.html b/html/index.html index d1b8296..a821fd3 100644 --- a/html/index.html +++ b/html/index.html @@ -7,8 +7,13 @@

🛑

STOP!


Verifying that you are not a bot. This might take a short moment.

You do not need to do anything.

Why am I seeing this?


This website protects itself from AI bots and scrapers by asking you to complete a cryptographic challenge before allowing you entry.

Difficulty {{ tl:text challengeDifficulty }}, elapsed 0ms, 0h, 0h/s

Powered by checkpoint v{{ tl:text checkpointVersion }}
+STOP! - Checkpoint

🛑

STOP!


Verifying that you are not a bot. This might take a short moment.

You do not need to do anything.

Why am I seeing this?


This website protects itself from AI bots and scrapers by asking you to complete a cryptographic challenge before allowing you entry.

Difficulty {{ tl:text challengeDifficulty }}, elapsed 0ms, 0h, 0h/s

Powered by checkpoint v{{ tl:text checkpointVersion }}
\ No newline at end of file diff --git a/src/core/Handler.cpp b/src/core/Handler.cpp index 7f6f0b0..b5128c9 100644 --- a/src/core/Handler.cpp +++ b/src/core/Handler.cpp @@ -145,6 +145,10 @@ std::string CServerHandler::fingerprintForRequest(const Pistache::Http::Request& return sha256(input); } +bool CServerHandler::isResourceCheckpoint(const std::string_view& res) { + return res == "/checkpoint/NotoSans.woff"; +} + void CServerHandler::onRequest(const Pistache::Http::Request& req, Pistache::Http::ResponseWriter response) { const auto HEADERS = req.headers(); std::shared_ptr hostHeader; @@ -218,6 +222,12 @@ void CServerHandler::onRequest(const Pistache::Http::Request& req, Pistache::Htt return; } + if (isResourceCheckpoint(req.resource())) { + response.send(Pistache::Http::Code::Ok, + readFileAsText(g_pGlobalState->cwd + "/" + g_pConfig->m_config.html_dir + "/" + req.resource().substr(req.resource().find("checkpoint/") + 11))); + return; + } + if (g_pConfig->m_config.git_host) { // TODO: ratelimit this, probably. diff --git a/src/core/Handler.hpp b/src/core/Handler.hpp index a7c36b1..c5512f5 100644 --- a/src/core/Handler.hpp +++ b/src/core/Handler.hpp @@ -24,6 +24,8 @@ class CServerHandler : public Pistache::Http::Handler { void challengeSubmitted(const Pistache::Http::Request& req, Pistache::Http::ResponseWriter& response); std::string fingerprintForRequest(const Pistache::Http::Request& req); + bool isResourceCheckpoint(const std::string_view& res); + struct SChallengeResponse { std::string challenge; unsigned long int solution = 0;