Add tar+gzip and tar+zstd compressed archive support.

This commit is contained in:
Catherine
2025-09-21 06:25:10 +00:00
parent 382bee9b4e
commit 2af2975713
5 changed files with 32 additions and 4 deletions

View File

@@ -67,7 +67,7 @@ Features
- The `.git-pages/manifest.json` path returns a [ProtoJSON](https://protobuf.dev/programming-guides/json/) representation of the deployed site manifest. It enumerates site structure, redirect rules, and errors that were not severe enough to abort publishing.
* In response to a `PUT` or `POST` request, the server retrieves updates a site with new content. The URL of the request must be the root URL of the site that is being published.
- If the `PUT` method receives an `application/x-www-form-urlencoded` body, it contains a repository URL to be shallowly cloned. The `X-Pages-Branch` header contains the branch to be checked out; the `pages` branch is used if the header is absent.
- If the `PUT` method receives an `application/x-tar` or `application/zip` body, it contains an archive to be extracted.
- If the `PUT` method receives an `application/x-tar`, `application/x-tar+gzip`, `application/x-tar+zstd`, or `application/zip` body, it contains an archive to be extracted.
- The `POST` method requires an `application/json` body containing a Forgejo/Gitea/Gogs/GitHub webhook event payload. Requests where the `ref` key contains anything other than `refs/heads/pages` are ignored, and only the `pages` branch is used. The `repository.clone_url` key contains a repository URL to be shallowly cloned.
- If the received contents is empty, performs the same action as `DELETE`.
* In response to a `DELETE` request, the server unpublishes a site. The URL of the request must be the root URL of the site that is being unpublished. Site data remains stored for an indeterminate period of time, but becomes completely inaccessible.

View File

@@ -42,7 +42,7 @@
"-s -w"
];
vendorHash = "sha256-8hT8TC7I1jdfve9WOdwN3C51sjbLSRvwIj7a/1qCmVA=";
vendorHash = "sha256-4S4ccnyBuYMFRrFHAxy5N1JeNj9n43xO7+wg5hlCdL0=";
fixupPhase = ''
# Apparently `go install` doesn't support renaming the binary, so country girls make do.

2
go.mod
View File

@@ -7,6 +7,7 @@ require (
github.com/go-git/go-billy/v6 v6.0.0-20250627091229-31e2a16eef30
github.com/go-git/go-git/v6 v6.0.0-20250910120214-3a68d0404116
github.com/honeybadger-io/honeybadger-go v0.8.0
github.com/klauspost/compress v1.18.0
github.com/maypok86/otter/v2 v2.2.1
github.com/minio/minio-go/v7 v7.0.95
github.com/pelletier/go-toml/v2 v2.2.4
@@ -30,7 +31,6 @@ require (
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/kevinburke/ssh_config v1.4.0 // indirect
github.com/klauspost/compress v1.18.0 // indirect
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
github.com/minio/crc64nvme v1.0.2 // indirect
github.com/minio/md5-simd v1.1.2 // indirect

View File

@@ -4,11 +4,13 @@ import (
"archive/tar"
"archive/zip"
"bytes"
"compress/gzip"
"errors"
"fmt"
"io"
"strings"
"github.com/klauspost/compress/zstd"
"google.golang.org/protobuf/proto"
)
@@ -69,6 +71,26 @@ func ExtractTar(reader io.Reader) (*Manifest, error) {
return &manifest, nil
}
func ExtractTarGzip(reader io.Reader) (*Manifest, error) {
stream, err := gzip.NewReader(reader)
if err != nil {
return nil, err
}
defer stream.Close()
return ExtractTar(stream)
}
func ExtractTarZstd(reader io.Reader) (*Manifest, error) {
stream, err := zstd.NewReader(reader)
if err != nil {
return nil, err
}
defer stream.Close()
return ExtractTar(stream)
}
var errZipBomb = errors.New("zip file size limit exceeded")
func ExtractZip(reader io.Reader) (*Manifest, error) {

View File

@@ -114,7 +114,13 @@ func UpdateFromArchive(
switch contentType {
case "application/x-tar":
log.Printf("update %s: (tar)", webRoot)
manifest, err = ExtractTar(reader) // yellow? definitely yellow.
manifest, err = ExtractTar(reader) // yellow?
case "application/x-tar+gzip":
log.Printf("update %s: (tar.gz)", webRoot)
manifest, err = ExtractTarGzip(reader) // definitely yellow.
case "application/x-tar+zstd":
log.Printf("update %s: (tar.zst)", webRoot)
manifest, err = ExtractTarZstd(reader)
case "application/zip":
log.Printf("update %s: (zip)", webRoot)
manifest, err = ExtractZip(reader)