Posts are Markdown files stored via gakofs.php, a
key-value store over HTTP backed by the server filesystem. The key is
the file’s relative path. A post named my-post lives at
my-post.md and is served at
https://www.monperrus.net/martin/my-post.
Authentication uses HTTP Digest. You may be user martin.
Retrieve the password from the local keyring — never hardcode it:
PASS=$(keyring get monperrus.net martin)Create a New Post
PASS=$(keyring get monperrus.net martin)
EMPTY_SHA="e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
cat > /tmp/my-post.md << 'EOF'
---
title: My Post Title
author: Martin Monperrus
---
Content goes here (Markdown).
EOF
curl -s --digest -u martin:$PASS -X PUT --data-binary @/tmp/my-post.md \
"https://www.monperrus.net/martin/gakofs.php/my-post.md?previous_checksum=$EMPTY_SHA"The post is immediately live at
https://www.monperrus.net/martin/my-post.
Rules: - Always use a .md extension.
Without it, gakofs returns rendered HTML instead of the raw file. - Use
previous_checksum equal to the SHA-256 of the empty string
when creating a new file.
Update an Existing Post
GET to retrieve the current content and checksum, edit, then PUT:
PASS=$(keyring get monperrus.net martin)
# 1. Fetch current content and checksum
curl -s --digest -u martin:$PASS \
"https://www.monperrus.net/martin/gakofs.php/my-post.md" \
-D /tmp/headers.txt -o /tmp/current.md
CHECKSUM=$(grep -i x-checksum-sha256 /tmp/headers.txt | awk '{print $2}' | tr -d '\r')
# 2. Edit /tmp/current.md, then PUT back
curl -s --digest -u martin:$PASS -X PUT --data-binary @/tmp/current.md \
"https://www.monperrus.net/martin/gakofs.php/my-post.md?previous_checksum=$CHECKSUM"If the content is unchanged, the server responds with
{"status":"identical"} and writes nothing. If the checksum
is stale (file was edited elsewhere), it returns
503 file has been modified — get the latest changes and
merge.
Post Format
Posts are Markdown with a YAML front matter block for metadata. The
title comes from front matter — do not use a # H1 heading.
Example:
---
title: My Post Title
author: Martin Monperrus
---
Introduction paragraph.
## Section
Content with **bold**, `code`, and [links](https://example.com).List Recent Posts (RSS)
PASS=$(keyring get monperrus.net martin)
curl -s --digest -u martin:$PASS "https://www.monperrus.net/martin/gakofs.php?rss"