Session-authenticated examples¶
These examples use safe dummy identifiers and never embed a real checked-in credential. Set:
BASE_URL=https://geosync.example.invalid/geosync-service
SESSION_TOKEN=<raw Central acugis_session cookie from an authorized session>
PROJECT_ID=12
The Central cookie is opaque and must be protected like a password. Prefer a
cookie jar with restrictive filesystem permissions. The examples first list
projects (HTML), then read status HTML, start synchronization, and query the
allowlisted analysis table endpoint. A 2xx action response is not enough:
inspect success.
curl¶
curl --fail-with-body --cookie "acugis_session=$SESSION_TOKEN" \
"$BASE_URL/admin/projects.php" -o projects.html
curl --fail-with-body --cookie "acugis_session=$SESSION_TOKEN" \
"$BASE_URL/admin/project_settings.php?id=$PROJECT_ID&tab=synchronize" \
-o status.html
curl --fail-with-body --cookie "acugis_session=$SESSION_TOKEN" \
--data-urlencode "id=$PROJECT_ID" --data-urlencode "op=start" \
"$BASE_URL/admin/action/backend.php"
curl --fail-with-body --get --cookie "acugis_session=$SESSION_TOKEN" \
--data-urlencode "service=analysis" \
--data-urlencode "path=api/tables" \
--data-urlencode "connection_id=1" \
--data-urlencode "schema=public" \
"$BASE_URL/api/proxy.php"
JavaScript¶
In a browser on the GeoSync origin, use credentials: "include" and do not
read or copy the HttpOnly cookie. Node callers can set the cookie explicitly:
const base = process.env.BASE_URL;
const token = process.env.SESSION_TOKEN;
const projectId = process.env.PROJECT_ID ?? "12";
const headers = { Cookie: `acugis_session=${token}` };
async function request(path, options = {}) {
const response = await fetch(`${base}${path}`, {
redirect: "manual",
...options,
headers: { ...headers, ...options.headers },
});
if (!response.ok) throw new Error(`HTTP ${response.status}: ${await response.text()}`);
return response;
}
const projectsHtml = await (await request("/admin/projects.php")).text();
console.log(`projects page bytes: ${projectsHtml.length}`);
const body = new URLSearchParams({ id: projectId, op: "start" });
const action = await (await request("/admin/action/backend.php", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body,
})).json();
if (!action.success) throw new Error(action.message);
const query = new URLSearchParams({
service: "analysis", path: "api/tables", connection_id: "1", schema: "public",
});
const tables = await (await request(`/api/proxy.php?${query}`)).json();
console.log(tables);
Python¶
import os
import requests
base = os.environ["BASE_URL"].rstrip("/")
project_id = os.getenv("PROJECT_ID", "12")
s = requests.Session()
s.cookies.set("acugis_session", os.environ["SESSION_TOKEN"])
r = s.get(f"{base}/admin/projects.php", timeout=30)
r.raise_for_status()
print("projects page bytes:", len(r.content))
r = s.post(
f"{base}/admin/action/backend.php",
data={"id": project_id, "op": "start"},
timeout=30,
)
r.raise_for_status()
action = r.json()
if not action.get("success"):
raise RuntimeError(action.get("message", "start failed"))
r = s.get(
f"{base}/api/proxy.php",
params={
"service": "analysis",
"path": "api/tables",
"connection_id": 1,
"schema": "public",
},
timeout=30,
)
r.raise_for_status()
print(r.json())
Go¶
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"strings"
)
type actionResult struct {
Success bool `json:"success"`
Message string `json:"message"`
}
func main() {
base := strings.TrimRight(os.Getenv("BASE_URL"), "/")
token := os.Getenv("SESSION_TOKEN")
projectID := os.Getenv("PROJECT_ID")
if projectID == "" { projectID = "12" }
do := func(req *http.Request) *http.Response {
req.AddCookie(&http.Cookie{Name: "acugis_session", Value: token})
resp, err := http.DefaultClient.Do(req)
if err != nil { panic(err) }
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
b, _ := io.ReadAll(resp.Body); resp.Body.Close()
panic(fmt.Sprintf("HTTP %d: %s", resp.StatusCode, b))
}
return resp
}
req, _ := http.NewRequest(http.MethodGet, base+"/admin/projects.php", nil)
resp := do(req); b, _ := io.ReadAll(resp.Body); resp.Body.Close()
fmt.Println("projects page bytes:", len(b))
form := url.Values{"id": {projectID}, "op": {"start"}}
req, _ = http.NewRequest(http.MethodPost, base+"/admin/action/backend.php",
strings.NewReader(form.Encode()))
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
resp = do(req)
var result actionResult
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil { panic(err) }
resp.Body.Close()
if !result.Success { panic(result.Message) }
q := url.Values{
"service": {"analysis"}, "path": {"api/tables"},
"connection_id": {"1"}, "schema": {"public"},
}
req, _ = http.NewRequest(http.MethodGet, base+"/api/proxy.php?"+q.Encode(), nil)
resp = do(req); defer resp.Body.Close()
io.Copy(os.Stdout, resp.Body)
}
PHP¶
<?php
$base = rtrim(getenv('BASE_URL'), '/');
$token = getenv('SESSION_TOKEN');
$projectId = getenv('PROJECT_ID') ?: '12';
function call_geosync(string $url, string $token, ?array $form = null): array {
$ch = curl_init($url);
$options = [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_HTTPHEADER => ['Cookie: acugis_session=' . $token],
CURLOPT_TIMEOUT => 30,
];
if ($form !== null) {
$options[CURLOPT_POST] = true;
$options[CURLOPT_POSTFIELDS] = http_build_query($form);
$options[CURLOPT_HTTPHEADER][] =
'Content-Type: application/x-www-form-urlencoded';
}
curl_setopt_array($ch, $options);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
$error = curl_error($ch);
curl_close($ch);
if ($body === false || $status < 200 || $status >= 300) {
throw new RuntimeException("HTTP {$status}: {$error} {$body}");
}
return [$body, $status];
}
[$html] = call_geosync($base . '/admin/projects.php', $token);
echo 'projects page bytes: ' . strlen($html) . PHP_EOL;
[$body] = call_geosync(
$base . '/admin/action/backend.php',
$token,
['id' => $projectId, 'op' => 'start']
);
$action = json_decode($body, true, flags: JSON_THROW_ON_ERROR);
if (empty($action['success'])) {
throw new RuntimeException($action['message'] ?? 'start failed');
}
$query = http_build_query([
'service' => 'analysis',
'path' => 'api/tables',
'connection_id' => 1,
'schema' => 'public',
]);
[$tables] = call_geosync($base . '/api/proxy.php?' . $query, $token);
echo $tables . PHP_EOL;
Downloading a retained version¶
First obtain the exact gpkg value from the authenticated Files settings HTML,
then URL-encode it. Never concatenate an untrusted path: