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.
+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.
\ 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;