650 lines
27 KiB
HTML
650 lines
27 KiB
HTML
{% extends "base.html" %}
|
|
|
|
{% block title %}API Documentation - {{ app_name }}{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="container mt-4 api-card">
|
|
<div class="row">
|
|
<div class="col-lg-10 mx-auto">
|
|
|
|
<div class="mb-4">
|
|
<h2>API Documentation</h2>
|
|
<p class="lead">REST API for geo-blocking configuration generation.</p>
|
|
|
|
<div class="alert alert-info mb-2">
|
|
<i class="fas fa-info-circle me-2"></i>
|
|
<strong>Base URL:</strong> <code id="baseUrl"></code>
|
|
</div>
|
|
|
|
<!-- Usage Guidelines -->
|
|
<div class="alert alert-primary mt-3">
|
|
<h5 class="fw-bold mb-2">
|
|
<i class="fas fa-compass me-2"></i>API Usage Guidelines
|
|
</h5>
|
|
|
|
<p class="mb-2">
|
|
Choose the endpoint based on your integration needs.
|
|
</p>
|
|
|
|
<table class="table table-sm mb-2">
|
|
<thead>
|
|
<tr>
|
|
<th>Use Case</th>
|
|
<th>Recommended Endpoint</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td>Programmatic CIDR integration (TXT / CSV / JSON / JS)</td>
|
|
<td><code>POST /api/generate/raw</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td>Download ready-to-use application config (nginx / apache / haproxy)</td>
|
|
<td><code>POST /api/generate</code></td>
|
|
</tr>
|
|
<tr>
|
|
<td>Web UI preview (admin panel)</td>
|
|
<td><code>POST /api/generate/preview</code></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<div class="alert alert-warning mb-2">
|
|
<strong>UI-only:</strong> <code>/api/generate/preview</code> is intended for internal web UI usage.
|
|
It returns JSON with a <em>raw config string</em> + metadata and is not recommended for external production integrations.
|
|
</div>
|
|
|
|
<div class="alert alert-warning mb-0">
|
|
<strong>Recommendation:</strong> Avoid <code>nginx</code> + <code>map</code> for production.
|
|
Prefer <code>nginx</code> variants <code>geo</code> or <code>deny</code>.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Health -->
|
|
<div class="card mb-3">
|
|
<div class="card-header api-header-get" onclick="toggleEndpoint('ep-health')">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<div>
|
|
<span class="badge bg-info me-2 api-badge">GET</span>
|
|
<code class="api-path">/health</code>
|
|
<span class="ms-3 api-muted">Service health check</span>
|
|
</div>
|
|
<i class="fas fa-chevron-down"></i>
|
|
</div>
|
|
</div>
|
|
<div class="card-body collapse" id="ep-health">
|
|
<p class="mb-2">Simple liveness probe.</p>
|
|
|
|
<div class="api-trybox">
|
|
<div class="d-flex gap-2 align-items-center flex-wrap">
|
|
<button class="btn btn-sm btn-primary" onclick="tryPath('/health')">
|
|
<i class="fas fa-play me-1"></i>Execute
|
|
</button>
|
|
<span class="api-muted">Returns JSON.</span>
|
|
</div>
|
|
|
|
<div id="response-health" class="mt-3" style="display:none;">
|
|
<h6 class="fw-bold">Response</h6>
|
|
<pre><code id="response-health-body"></code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Countries -->
|
|
<div class="card mb-3">
|
|
<div class="card-header api-header-get" onclick="toggleEndpoint('ep-countries')">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<div>
|
|
<span class="badge bg-info me-2 api-badge">GET</span>
|
|
<code class="api-path">/api/countries</code>
|
|
<span class="ms-3 api-muted">Get available countries</span>
|
|
</div>
|
|
<i class="fas fa-chevron-down"></i>
|
|
</div>
|
|
</div>
|
|
<div class="card-body collapse" id="ep-countries">
|
|
<p class="mb-2">Returns list of countries with ISO codes and flag emojis.</p>
|
|
|
|
<h6 class="fw-bold mt-3">Response Schema</h6>
|
|
<pre><code>{
|
|
"success": true,
|
|
"countries": [
|
|
{"code": "CN", "name": "China", "flag": "🇨🇳"}
|
|
]
|
|
}</code></pre>
|
|
|
|
<div class="api-trybox">
|
|
<button class="btn btn-sm btn-primary" onclick="tryApi('countries')">
|
|
<i class="fas fa-play me-1"></i>Execute
|
|
</button>
|
|
|
|
<div id="response-countries" class="mt-3" style="display:none;">
|
|
<h6 class="fw-bold">Response</h6>
|
|
<pre><code id="response-countries-body"></code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Database Status -->
|
|
<div class="card mb-3">
|
|
<div class="card-header api-header-get" onclick="toggleEndpoint('ep-db-status')">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<div>
|
|
<span class="badge bg-info me-2 api-badge">GET</span>
|
|
<code class="api-path">/api/database/status</code>
|
|
<span class="ms-3 api-muted">Check MaxMind DB status</span>
|
|
</div>
|
|
<i class="fas fa-chevron-down"></i>
|
|
</div>
|
|
</div>
|
|
<div class="card-body collapse" id="ep-db-status">
|
|
<p class="mb-2">Database status including update need and timestamps.</p>
|
|
|
|
<h6 class="fw-bold mt-3">Response Schema</h6>
|
|
<pre><code>{
|
|
"success": true,
|
|
"exists": true,
|
|
"needs_update": false,
|
|
"last_update": "2026-02-10T08:00:00",
|
|
"file_size": 5242880,
|
|
"auto_update": true
|
|
}</code></pre>
|
|
|
|
<div class="api-trybox">
|
|
<button class="btn btn-sm btn-primary" onclick="tryApi('database/status')">
|
|
<i class="fas fa-play me-1"></i>Execute
|
|
</button>
|
|
|
|
<div id="response-database-status" class="mt-3" style="display:none;">
|
|
<h6 class="fw-bold">Response</h6>
|
|
<pre><code id="response-database-status-body"></code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Database Update -->
|
|
<div class="card mb-3">
|
|
<div class="card-header api-header-post" onclick="toggleEndpoint('ep-db-update')">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<div>
|
|
<span class="badge bg-success me-2 api-badge">POST</span>
|
|
<code class="api-path">/api/database/update</code>
|
|
<span class="ms-3 api-muted">Trigger MaxMind DB update</span>
|
|
</div>
|
|
<i class="fas fa-chevron-down"></i>
|
|
</div>
|
|
</div>
|
|
<div class="card-body collapse" id="ep-db-update">
|
|
<p class="mb-2">Manual database update (download + replace).</p>
|
|
|
|
<h6 class="fw-bold mt-3">Response Schema</h6>
|
|
<pre><code>{
|
|
"success": true,
|
|
"url": "https://github.com/...",
|
|
"size": 5242880
|
|
}</code></pre>
|
|
|
|
<div class="api-trybox">
|
|
<button class="btn btn-sm btn-success" onclick="tryApi('database/update', 'POST', {})">
|
|
<i class="fas fa-play me-1"></i>Execute
|
|
</button>
|
|
|
|
<div id="response-database-update" class="mt-3" style="display:none;">
|
|
<h6 class="fw-bold">Response</h6>
|
|
<pre><code id="response-database-update-body"></code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Redis Status -->
|
|
<div class="card mb-3">
|
|
<div class="card-header api-header-get" onclick="toggleEndpoint('ep-redis')">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<div>
|
|
<span class="badge bg-info me-2 api-badge">GET</span>
|
|
<code class="api-path">/api/cache/redis/status</code>
|
|
<span class="ms-3 api-muted">Redis L1 status</span>
|
|
</div>
|
|
<i class="fas fa-chevron-down"></i>
|
|
</div>
|
|
</div>
|
|
<div class="card-body collapse" id="ep-redis">
|
|
<p class="mb-2">Redis health + key stats.</p>
|
|
|
|
<div class="api-trybox">
|
|
<button class="btn btn-sm btn-primary" onclick="tryApi('cache/redis/status')">
|
|
<i class="fas fa-play me-1"></i>Execute
|
|
</button>
|
|
|
|
<div id="response-cache-redis-status" class="mt-3" style="display:none;">
|
|
<h6 class="fw-bold">Response</h6>
|
|
<pre><code id="response-cache-redis-status-body"></code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- SQLite Status -->
|
|
<div class="card mb-3">
|
|
<div class="card-header api-header-get" onclick="toggleEndpoint('ep-sqlite')">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<div>
|
|
<span class="badge bg-info me-2 api-badge">GET</span>
|
|
<code class="api-path">/api/cache/sqlite/status</code>
|
|
<span class="ms-3 api-muted">SQLite L2 status</span>
|
|
</div>
|
|
<i class="fas fa-chevron-down"></i>
|
|
</div>
|
|
</div>
|
|
<div class="card-body collapse" id="ep-sqlite">
|
|
<p class="mb-2">SQLite cache file stats and top countries.</p>
|
|
|
|
<div class="api-trybox">
|
|
<button class="btn btn-sm btn-primary" onclick="tryApi('cache/sqlite/status')">
|
|
<i class="fas fa-play me-1"></i>Execute
|
|
</button>
|
|
|
|
<div id="response-cache-sqlite-status" class="mt-3" style="display:none;">
|
|
<h6 class="fw-bold">Response</h6>
|
|
<pre><code id="response-cache-sqlite-status-body"></code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Cache Invalidate -->
|
|
<div class="card mb-3">
|
|
<div class="card-header api-header-post" onclick="toggleEndpoint('ep-invalidate')">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<div>
|
|
<span class="badge bg-success me-2 api-badge">POST</span>
|
|
<code class="api-path">/api/cache/invalidate/<country_code></code>
|
|
<span class="ms-3 api-muted">Invalidate a single country</span>
|
|
</div>
|
|
<i class="fas fa-chevron-down"></i>
|
|
</div>
|
|
</div>
|
|
<div class="card-body collapse" id="ep-invalidate">
|
|
<p class="mb-2">Clears Redis networks for a country + related cached configs.</p>
|
|
|
|
<div class="api-trybox">
|
|
<div class="d-flex gap-2 align-items-center flex-wrap">
|
|
<input type="text" id="invalidateCountry" class="form-control form-control-sm d-inline w-auto" maxlength="2" placeholder="CN">
|
|
<button class="btn btn-sm btn-warning" onclick="tryInvalidateCountry()">
|
|
<i class="fas fa-trash me-1"></i>Invalidate
|
|
</button>
|
|
<span class="api-muted">ISO 3166-1 alpha-2</span>
|
|
</div>
|
|
|
|
<div id="response-cache-invalidate" class="mt-3" style="display:none;">
|
|
<h6 class="fw-bold">Response</h6>
|
|
<pre><code id="response-cache-invalidate-body"></code></pre>
|
|
</div>
|
|
|
|
<h6 class="fw-bold mt-3">cURL</h6>
|
|
<pre><code class="language-bash">curl -X POST <span id="curlUrl-invalidate"></span>/api/cache/invalidate/CN</code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Cache Flush -->
|
|
<div class="card mb-3">
|
|
<div class="card-header api-header-post" onclick="toggleEndpoint('ep-flush')">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<div>
|
|
<span class="badge bg-success me-2 api-badge">POST</span>
|
|
<code class="api-path">/api/cache/flush</code>
|
|
<span class="ms-3 api-muted">Flush Redis cache (all keys)</span>
|
|
</div>
|
|
<i class="fas fa-chevron-down"></i>
|
|
</div>
|
|
</div>
|
|
<div class="card-body collapse" id="ep-flush">
|
|
<p class="mb-2">Flushes all Redis keys used by the application.</p>
|
|
|
|
<div class="api-trybox">
|
|
<button class="btn btn-sm btn-warning" onclick="tryApi('cache/flush', 'POST', {})">
|
|
<i class="fas fa-trash me-1"></i>Execute
|
|
</button>
|
|
|
|
<div id="response-cache-flush" class="mt-3" style="display:none;">
|
|
<h6 class="fw-bold">Response</h6>
|
|
<pre><code id="response-cache-flush-body"></code></pre>
|
|
</div>
|
|
|
|
<h6 class="fw-bold mt-3">cURL</h6>
|
|
<pre><code class="language-bash">curl -X POST <span id="curlUrl-flush"></span>/api/cache/flush</code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Progress -->
|
|
<div class="card mb-3">
|
|
<div class="card-header api-header-get" onclick="toggleEndpoint('ep-progress')">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<div>
|
|
<span class="badge bg-info me-2 api-badge">GET</span>
|
|
<code class="api-path">/api/progress</code>
|
|
<span class="ms-3 api-muted">Generation progress</span>
|
|
</div>
|
|
<i class="fas fa-chevron-down"></i>
|
|
</div>
|
|
</div>
|
|
<div class="card-body collapse" id="ep-progress">
|
|
<p class="mb-2">Poll this endpoint during generation.</p>
|
|
|
|
<div class="api-trybox">
|
|
<button class="btn btn-sm btn-primary" onclick="tryApi('progress')">
|
|
<i class="fas fa-play me-1"></i>Execute
|
|
</button>
|
|
|
|
<div id="response-progress" class="mt-3" style="display:none;">
|
|
<h6 class="fw-bold">Response</h6>
|
|
<pre><code id="response-progress-body"></code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Stats Summary -->
|
|
<div class="card mb-3">
|
|
<div class="card-header api-header-get" onclick="toggleEndpoint('ep-stats')">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<div>
|
|
<span class="badge bg-info me-2 api-badge">GET</span>
|
|
<code class="api-path">/api/stats/summary</code>
|
|
<span class="ms-3 api-muted">Combined status summary</span>
|
|
</div>
|
|
<i class="fas fa-chevron-down"></i>
|
|
</div>
|
|
</div>
|
|
<div class="card-body collapse" id="ep-stats">
|
|
<p class="mb-2">Aggregated status of MaxMind + SQLite + Redis.</p>
|
|
|
|
<div class="api-trybox">
|
|
<button class="btn btn-sm btn-primary" onclick="tryApi('stats/summary')">
|
|
<i class="fas fa-play me-1"></i>Execute
|
|
</button>
|
|
|
|
<div id="response-stats-summary" class="mt-3" style="display:none;">
|
|
<h6 class="fw-bold">Response</h6>
|
|
<pre><code id="response-stats-summary-body"></code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Preview (UI JSON wrapper) -->
|
|
<div class="card mb-3">
|
|
<div class="card-header api-header-post" onclick="toggleEndpoint('ep-preview')">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<div>
|
|
<span class="badge bg-success me-2 api-badge">POST</span>
|
|
<code class="api-path">/api/generate/preview</code>
|
|
<span class="ms-3 api-muted">UI preview (JSON wrapper)</span>
|
|
</div>
|
|
<i class="fas fa-chevron-down"></i>
|
|
</div>
|
|
</div>
|
|
<div class="card-body collapse" id="ep-preview">
|
|
<div class="alert alert-warning">
|
|
<strong>UI-only:</strong> Intended for internal web UI. Response is JSON, but <code>config</code> contains raw text.
|
|
</div>
|
|
|
|
<h6 class="fw-bold mt-2">Request Body</h6>
|
|
<pre><code>{
|
|
"countries": ["SG"],
|
|
"app_type": "haproxy",
|
|
"app_variant": "map",
|
|
"aggregate": true,
|
|
"use_cache": true
|
|
}</code></pre>
|
|
|
|
<div class="api-trybox">
|
|
<div class="row g-2">
|
|
<div class="col-12 col-md-8">
|
|
<label class="form-label mb-1 api-muted">Try body (JSON)</label>
|
|
<textarea id="previewBody" class="form-control form-control-sm" rows="6">{
|
|
"countries": ["SG"],
|
|
"app_type": "haproxy",
|
|
"app_variant": "map",
|
|
"aggregate": true,
|
|
"use_cache": true
|
|
}</textarea>
|
|
</div>
|
|
<div class="col-12 col-md-4">
|
|
<label class="form-label mb-1 api-muted">Action</label>
|
|
<div class="d-grid gap-2">
|
|
<button class="btn btn-sm btn-success" onclick="tryApiJsonTextarea('generate/preview','previewBody')">
|
|
<i class="fas fa-play me-1"></i>Execute
|
|
</button>
|
|
<small class="api-muted">Shows headers + JSON response.</small>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="response-generate-preview" class="mt-3" style="display:none;">
|
|
<h6 class="fw-bold">Response</h6>
|
|
<pre><code id="response-generate-preview-body"></code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- RAW -->
|
|
<div class="card mb-3">
|
|
<div class="card-header api-header-post" onclick="toggleEndpoint('ep-raw')">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<div>
|
|
<span class="badge bg-success me-2 api-badge">POST</span>
|
|
<code class="api-path">/api/generate/raw</code>
|
|
<span class="ms-3 api-muted">Raw blocklist (TXT / CSV / JSON / JS)</span>
|
|
</div>
|
|
<i class="fas fa-chevron-down"></i>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card-body collapse" id="ep-raw">
|
|
<p class="mb-2">
|
|
Output format is selected by <code>app_type</code>.
|
|
Cache metadata is returned via response headers.
|
|
</p>
|
|
|
|
<h6 class="fw-bold mt-3">Supported Modes</h6>
|
|
<table class="table table-sm">
|
|
<thead>
|
|
<tr><th>app_type</th><th>Content-Type</th><th>Notes</th></tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr><td><code class="text-success">raw-cidr_txt</code></td><td><code>text/plain</code></td><td>default</td></tr>
|
|
<tr><td><code class="text-success">raw-cidr_csv</code></td><td><code>text/csv</code></td><td>CSV export</td></tr>
|
|
<tr><td><code class="text-success">raw-cidr_json</code></td><td><code>application/json</code></td><td><code>{countries, networks, count, aggregated}</code></td></tr>
|
|
<tr><td><code class="text-success">raw-cidr_json</code> + <code>as_js=true</code></td><td><code>application/javascript</code></td><td><code>const <js_var> = {...};</code></td></tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<h6 class="fw-bold mt-3">Example JSON Schema (raw-cidr_json)</h6>
|
|
<pre><code>{
|
|
"countries": ["SG"],
|
|
"networks": ["1.2.3.0/24", "..."],
|
|
"count": 123,
|
|
"aggregated": true
|
|
}</code></pre>
|
|
|
|
<div class="api-trybox">
|
|
<div class="row g-2">
|
|
<div class="col-12 col-md-8">
|
|
<label class="form-label mb-1 api-muted">Try body (JSON)</label>
|
|
<textarea id="rawBody" class="form-control form-control-sm" rows="10">{
|
|
"countries": ["PL"],
|
|
"app_type": "raw-cidr_json",
|
|
"aggregate": true,
|
|
"use_cache": true,
|
|
"as_js": false,
|
|
"js_var": "geoipBlocklist"
|
|
}</textarea>
|
|
<small class="api-muted">
|
|
Tip: set <code>use_cache</code> to <code>false</code> to force fresh scan.
|
|
</small>
|
|
</div>
|
|
|
|
<div class="col-12 col-md-4">
|
|
<label class="form-label mb-1 api-muted">Actions</label>
|
|
<div class="d-grid gap-2">
|
|
<button class="btn btn-sm btn-success" onclick="tryApiJsonTextarea('generate/raw','rawBody')">
|
|
<i class="fas fa-play me-1"></i>Execute (show response)
|
|
</button>
|
|
<button class="btn btn-sm btn-outline-primary" onclick="downloadFromApiJsonTextarea('generate/raw','rawBody','raw_blocklist')">
|
|
<i class="fas fa-download me-1"></i>Download result
|
|
</button>
|
|
<small class="api-muted">
|
|
“Download result” saves response as file (TXT/CSV/JSON/JS).
|
|
</small>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="response-generate-raw" class="mt-3" style="display:none;">
|
|
<h6 class="fw-bold">Response</h6>
|
|
<pre><code id="response-generate-raw-body"></code></pre>
|
|
</div>
|
|
</div>
|
|
|
|
<h6 class="fw-bold mt-4">cURL Examples</h6>
|
|
|
|
<p class="mb-2"><strong>JSON:</strong></p>
|
|
<pre><code class="language-bash">curl -X POST <span id="curlUrl-raw-json"></span>/api/generate/raw \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"countries":["PL"],"app_type":"raw-cidr_json","aggregate":true,"use_cache":true}' \
|
|
-o blocklist.json</code></pre>
|
|
|
|
<p class="mb-2 mt-3"><strong>JS wrapped:</strong></p>
|
|
<pre><code class="language-bash">curl -X POST <span id="curlUrl-raw-js"></span>/api/generate/raw \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"countries":["PL"],"app_type":"raw-cidr_json","as_js":true,"js_var":"geoipBlocklist"}' \
|
|
-o blocklist.js</code></pre>
|
|
|
|
<p class="mb-2 mt-3"><strong>TXT (default):</strong></p>
|
|
<pre><code class="language-bash">curl -X POST <span id="curlUrl-raw-txt"></span>/api/generate/raw \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"countries":["PL"]}' \
|
|
-o blocklist.txt</code></pre>
|
|
|
|
<p class="mb-2 mt-3"><strong>CSV:</strong></p>
|
|
<pre><code class="language-bash">curl -X POST <span id="curlUrl-raw-csv"></span>/api/generate/raw \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"countries":["PL"],"app_type":"raw-cidr_csv"}' \
|
|
-o blocklist.csv</code></pre>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Generate (download config) -->
|
|
<div class="card mb-3">
|
|
<div class="card-header api-header-post" onclick="toggleEndpoint('ep-generate')">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<div>
|
|
<span class="badge bg-success me-2 api-badge">POST</span>
|
|
<code class="api-path">/api/generate</code>
|
|
<span class="ms-3 api-muted">Download configuration file</span>
|
|
</div>
|
|
<i class="fas fa-chevron-down"></i>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card-body collapse" id="ep-generate">
|
|
<p class="mb-2">Returns a file download (text/plain). Use the download action below.</p>
|
|
|
|
<div class="alert alert-warning">
|
|
<strong>Not recommended:</strong> <code>nginx</code> + <code>map</code>. Prefer <code>nginx</code> <code>geo</code> / <code>deny</code>.
|
|
</div>
|
|
|
|
<h6 class="fw-bold mt-2">Supported Variants</h6>
|
|
<table class="table table-sm">
|
|
<thead>
|
|
<tr><th>app_type</th><th>app_variant</th><th>Recommendation</th></tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr><td><code class="text-info">nginx</code></td><td><code class="text-success">geo</code></td><td><span class="badge bg-success">recommended</span></td></tr>
|
|
<tr><td><code class="text-info">nginx</code></td><td><code class="text-success">deny</code></td><td><span class="badge bg-success">recommended</span></td></tr>
|
|
<tr><td><code class="text-info">nginx</code></td><td><code class="text-muted">map</code></td><td><span class="badge bg-warning text-dark">not recommended</span></td></tr>
|
|
|
|
<tr><td><code class="text-info">apache</code></td><td><code class="text-success">24</code></td><td><span class="badge bg-success">recommended</span></td></tr>
|
|
<tr><td><code class="text-info">apache</code></td><td><code class="text-secondary">22</code></td><td>legacy</td></tr>
|
|
|
|
<tr><td><code class="text-info">haproxy</code></td><td><code class="text-success">map</code></td><td><span class="badge bg-success">recommended</span></td></tr>
|
|
<tr><td><code class="text-info">haproxy</code></td><td><code class="text-success">acl</code></td><td>OK</td></tr>
|
|
<tr><td><code class="text-info">haproxy</code></td><td><code class="text-success">lua</code></td><td>OK</td></tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<div class="api-trybox">
|
|
<div class="row g-2">
|
|
<div class="col-12 col-md-8">
|
|
<label class="form-label mb-1 api-muted">Try body (JSON)</label>
|
|
<textarea id="generateBody" class="form-control form-control-sm" rows="10">{
|
|
"countries": ["SG"],
|
|
"app_type": "haproxy",
|
|
"app_variant": "map",
|
|
"aggregate": true,
|
|
"use_cache": true
|
|
}</textarea>
|
|
<small class="api-muted">
|
|
Use <code>use_cache:false</code> to force fresh scan. Prefer <code>haproxy</code> <code>map</code> or <code>apache</code> <code>24</code> / <code>nginx</code> <code>geo</code>.
|
|
</small>
|
|
</div>
|
|
|
|
<div class="col-12 col-md-4">
|
|
<label class="form-label mb-1 api-muted">Actions</label>
|
|
<div class="d-grid gap-2">
|
|
<button class="btn btn-sm btn-outline-primary" onclick="previewTextFromGenerate('generateBody')">
|
|
<i class="fas fa-eye me-1"></i>Preview (first lines)
|
|
</button>
|
|
<button class="btn btn-sm btn-success" onclick="downloadFromGenerate('generateBody','geoblock_config')">
|
|
<i class="fas fa-download me-1"></i>Download file
|
|
</button>
|
|
<small class="api-muted">Preview shows headers + first ~80 lines.</small>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="response-generate-download" class="mt-3" style="display:none;">
|
|
<h6 class="fw-bold">Result</h6>
|
|
<pre><code id="response-generate-download-body"></code></pre>
|
|
</div>
|
|
</div>
|
|
|
|
<h6 class="fw-bold mt-4">cURL (recommended variants)</h6>
|
|
|
|
<p class="mb-2"><strong>HAProxy (map):</strong></p>
|
|
<pre><code class="language-bash">curl -X POST <span id="curlUrl-gen-hmap"></span>/api/generate \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"countries":["SG"],"app_type":"haproxy","app_variant":"map","aggregate":true,"use_cache":true}' \
|
|
-o geoblock_haproxy_map.cfg</code></pre>
|
|
|
|
<p class="mb-2 mt-3"><strong>Apache 2.4:</strong></p>
|
|
<pre><code class="language-bash">curl -X POST <span id="curlUrl-gen-a24"></span>/api/generate \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"countries":["SG"],"app_type":"apache","app_variant":"24","aggregate":true,"use_cache":true}' \
|
|
-o geoblock_apache24.conf</code></pre>
|
|
|
|
<p class="mb-2 mt-3"><strong>Nginx (geo):</strong></p>
|
|
<pre><code class="language-bash">curl -X POST <span id="curlUrl-gen-geo"></span>/api/generate \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"countries":["SG"],"app_type":"nginx","app_variant":"geo","aggregate":true,"use_cache":true}' \
|
|
-o geoblock_nginx_geo.conf</code></pre>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block scripts %}
|
|
<script src="{{ url_for('static', filename='js/api.js') }}?v={{ js_hash }}"></script>
|
|
{% endblock %} |