Commit Graph
147 Commits
Author SHA1 Message Date
Catherine 9af5565659 Make the existence cache more type-safe.
This makes the uncertain nature of a Bloom filter hit explicit at every
call site.
2026-05-19 12:22:39 +00:00
Catherine 0d24e1aa70 Rename "site existence cache" to "existence cache", tidy it up.
This commit includes no behavioral changes, only cosmetic ones:
 * Renames the concept to "existence cache".
 * Makes log messages more concise.
 * Adds written rationale for the module.
 * Renames feature to `existence-cache`.
2026-05-19 12:22:22 +00:00
miyuko c1400d5934 Add site-level granularity to the domain existence cache. 2026-05-19 05:07:06 +01:00
miyuko a9fc5780b1 Record git repo URL in the principal when forge auth is used.
Resolves: https://codeberg.org/git-pages/git-pages/issues/167
2026-05-11 03:40:46 +01:00
miyuko ad92847fa0 Record git repo URL in manifest for archive uploads with forge auth.
Resolves: https://codeberg.org/git-pages/git-pages/issues/165
2026-05-11 03:38:54 +01:00
miyukoandCatherine 5808e90e5a Allow detaching all audit records related to a site. 2026-05-03 11:53:01 +00:00
Catherine 59cf185143 Only log media type for PUT, PATCH, and POST requests.
There isn't much point in logging `Accept:` for GET requests and it
is very noisy.
2026-04-23 16:42:46 +00:00
Catherine 6097a9abb8 Add a Server: header unconditionally.
Previously we wouldn't do it if hostname could not be determined, which
would break git-pages-cli based uploads on those machines.
2026-04-14 03:39:52 +00:00
Catherine fe329d748d [breaking-change] Drop Fly.io-specific behavior.
Fly.io is led by AI boosterism, and we don't want to encourage that
kind of behavior.
2026-04-14 03:39:52 +00:00
miyuko bbdaae7280 Add a domain cache to quickly reject non-existent domains. 2026-04-13 13:45:16 +00:00
Catherine 5258bf756b Add support for Netlify Basic-Auth: mechanism. 2026-03-29 12:11:56 +00:00
miyuko 9e9664013b Record the authorized forge user's name in the audit log. 2026-03-03 03:21:40 +00:00
miyuko 3e377986bc Accept forge authorization for deleting a site. 2026-03-03 01:29:27 +00:00
miyuko c85c7327bf Reword the code comment regarding the webhook delivery timer. 2026-03-03 01:29:03 +00:00
Catherine 1f1927d95d Log Accept: value for HEAD/GET requests.
Instead of `Content-Type:` which is essentially never relevant.
2025-12-24 14:28:16 +00:00
David Leadbeater 7334b8f637 Add a Vary header when content negotiation happens
Without this, if a cache first sees a compressed version of the request,
it will return that for potentially any future requests, even if they
don't request compression.
2025-12-24 14:36:23 +11:00
Catherine 79407ba406 Fix timeout bug introduced in commit 9c6f735d.
This bug would cause POST hooks triggered for large repositories to
silently fail.

We need the update context to have the principal (which is tied to
the HTTP request), but not the cancellation (which is also tied to
the HTTP request and is triggered once the request is done either way).
2025-12-16 14:43:36 +00:00
David Leadbeater 937aadc5d3 Allow setting custom Cache-Control headers via _headers
Before this change Cache-Control header would always be overridden, this
change allows custom Cache-Control, provided Cache-Control is added to
the header allow list.
2025-12-15 21:02:25 +11:00
Catherine 30b6db2758 Limit amount of data fetched from git repository.
Like limiting the size of an archive, it is a supplementary check meant
to limit resource consumption prior to the final check done in
`StoreManifest()`.
2025-12-14 19:42:25 +00:00
Catherine 7655400560 Limit original size of the contents of a site manifest.
The limit is applied to the original size and not compressed size for
predictability and fairness.
2025-12-14 19:30:45 +00:00
Catherine 62ef4a5366 Make project name validation more consistent and stricter.
Previously, you could issue e.g. a `GET /%2e%2e/%2e%2e` and it would
get interpreted as a parent directory path segment in the handler.
This didn't result in a path traversal vulnerability when passed to
the S3 backend because of a `path.Clean()` call indirectly done by
`makeWebRoot()`, but it's prudent to not take chances.
2025-12-07 20:24:50 +00:00
Catherine b58fe54c50 Report "dead" redirects as site issues.
Using a non-forced redirect with a URL matching a manifest entry turns
out to be a common and confusing mistake.
2025-12-07 04:21:00 +00:00
Catherine d1f55d6776 Style. NFC 2025-12-07 03:41:16 +00:00
Catherine 9c6f735df0 Fix loss of context in POST handler.
This caused the principal to not be available when creating the new
audit record.
2025-12-06 00:36:46 +00:00
Catherine 92dc8f7231 Consolidate return values into BlobMetadata. NFC 2025-12-06 00:10:04 +00:00
miyuko e9edfb8f5c [breaking-change] Read principal's IP address from X-Forwarded-For. 2025-12-06 00:04:42 +00:00
Catherine 1283b4e0eb Set Content-Type: to negotiated content type. 2025-12-05 19:33:06 +00:00
Catherine 7313ab7d13 Fix several content type negotiation issues.
* No `Accept:` header should be the same as `Accept: */*`.
  * For unresolved reference error, `text/plain` should take priority.
2025-12-05 18:56:20 +00:00
Catherine bd44f65b51 Add handling of Accept: application/vnd.git-pages.unresolved.
This will be used for incremental archive updates.
2025-12-05 18:21:42 +00:00
Catherine 8d58793576 Provide Accept-Encoding: in 406 Not Acceptable responses. 2025-12-05 16:38:31 +00:00
Catherine 6076c17c51 Rename HTTP negotiation items. NFC 2025-12-05 16:37:49 +00:00
Catherine 959715269f Collect unresolved blob references in a dedicated error structure.
This will be used for incremental archive uploads.
2025-12-05 11:31:34 +00:00
Catherine 32c449e380 Use path.Join where applicable. NFC 2025-12-05 05:52:07 +00:00
Catherine da0758b972 Stabilize features patch and archive-site.
The PATCH method has been tested by myself and on Codeberg and found
to work satisfactorily.

Because using PATCH causes the git-pages server to store state that
is not necessarily easily reproducible from any single specific source
(i.e. it stores a composition of many disparate requests), it may be
necessary to back it up. For this, the feature `archive-site` is also
stabilized. It has not seen much use but not providing a backup method
would be a disservice.
2025-12-05 03:55:54 +00:00
Catherine 464c40db9c Add Create-Parents: mode to PATCH method.
This acts like `mkdir -p`, making it much less annoying to deploy
e.g. documentation preview generators that use deep paths.

Like before, the site must already exist: we cannot do a CAS on
a non-existent manifest at the moment.
2025-12-04 18:23:44 +00:00
Catherine 93565e4e04 Factor out getWebRoot(). NFCI 2025-12-04 17:51:07 +00:00
Catherine f59830ae20 Rename PATCH Race-Free: header to Atomic:.
Neither of these names is self-explanatory, and it is better to have
fewer distinct identifiers for the same concept.
2025-12-04 16:51:32 +00:00
Catherine 4161013fc0 Implement -audit-read option. 2025-12-04 15:25:28 +00:00
Catherine 1ad5d5590c Optionally include principal's IP address in audit record metadata.
Currently this doesn't handle `X-Forwarded-For` and as such isn't very
useful. It is surprisingly difficult to find a high-quality library for
parsing `X-Forwarded-For` and a solution will have to be found.
2025-12-04 06:17:11 +00:00
Catherine 92d6796ad9 Return both LastModified and ETag in manifest metadata. NFCI 2025-12-04 03:00:47 +00:00
Catherine 460ff41cc9 Allow PATCH method to apply partial updates.
Gated behind the `patch` feature.
2025-12-04 03:00:47 +00:00
Catherine e226f51dd4 Implement auditing of important site lifecycle actions.
The list of audit events is:
  - `CommitManifest`
  - `DeleteManifest`
  - `FreezeDomain`
  - `UnfreezeDomain`

Currently these are the main abuse/moderation-relevant actions.
If collection is enabled, these events will be logged to `audit/...`
storage hierarchy; a way to examine audit logs will be added in
the future.

The auditing interposer backend is enabled with feature `audit`.
2025-12-03 04:19:41 +00:00
Catherine f089208ca7 [breaking-change] Make fallback handler per-instance, not per-wildcard.
There was never a particularly good reason to tie the fallback handler
to a wildcard domain; most importantly, this prevented it from being
used for custom domains, which is required for migrating custom domains
from Codeberg Pages v2 server.
2025-12-03 00:39:07 +00:00
Catherine c250922f8d Allow domains to be administratively frozen.
The following script may be used to handle abusive sites:

    cd $(mktemp -d)
    echo "<h1>Gone</h1>" >index.html
    echo "/* /index.html 410" >_redirects
    tar cf site.tar index.html _redirects
    git-pages -update-site $1 site.tar
    git-pages -freeze-domain $1
2025-12-02 23:56:01 +00:00
Catherine 32111307eb Add "dry run" capability for all destructive endpoints. 2025-12-02 22:32:17 +00:00
CatherineandDavid Leadbeater 89c57cfadb Use git filters for incremental updates from a git repository.
This commit changes the git fetch algorithm to only retrieve blobs
that aren't included in the previously deployed site manifest, if
git filters are supported by the remote.

It also changes how manifest entry sizes are represented, such that
both decompressed and compressed sizes are stored. This enables
computing accurate (and repeatable) sizes even after incremental
updates.

Co-authored-by: David Leadbeater <dgl@dgl.cx>
2025-12-02 22:23:43 +00:00
Catherine 689030c28a Add a Prometheus metric for blob/request encoding pairs.
Forcing the server to repeatedly decompress a large blob is a potential
DoS vector, so having a metric for this is essential.
2025-12-01 11:04:50 +00:00
Catherine 30bde8c1c4 Rename blob transforms to match HTTP encoding names. 2025-12-01 11:04:50 +00:00
Catherine fa02595f8b Handle OPTIONS method. 2025-11-23 00:14:39 +00:00
miyuko cb7802df10 Pass the context to logging functions. 2025-11-22 07:05:07 +00:00