151 lines
3.7 KiB
Go
151 lines
3.7 KiB
Go
package mockupdateserver
|
|
|
|
import (
|
|
"archive/zip"
|
|
"bytes"
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"encoding/json"
|
|
"net/http"
|
|
"runtime"
|
|
|
|
"github.com/Eriyc/rules_wails/pkg/wails3kit/updates"
|
|
)
|
|
|
|
const BearerToken = "test-token"
|
|
|
|
func NewHandler() http.Handler {
|
|
mux := http.NewServeMux()
|
|
mux.HandleFunc("/manifest.json", manifest)
|
|
mux.HandleFunc("/artifacts/updater-example_0.2.0.zip", artifact)
|
|
mux.HandleFunc("/artifacts/updater-example_0.2.0.zip.sha256", checksum)
|
|
|
|
return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
|
|
if request.Header.Get("Authorization") != "Bearer "+BearerToken {
|
|
http.Error(writer, "unauthorized", http.StatusUnauthorized)
|
|
return
|
|
}
|
|
mux.ServeHTTP(writer, request)
|
|
})
|
|
}
|
|
|
|
func manifest(writer http.ResponseWriter, request *http.Request) {
|
|
_, checksumValue, err := archiveWithChecksum()
|
|
if err != nil {
|
|
http.Error(writer, err.Error(), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
document := map[string]any{
|
|
"schemaVersion": 1,
|
|
"productID": "com.eriyc.updater-example",
|
|
"releases": []any{
|
|
map[string]any{
|
|
"id": "0.2.0",
|
|
"version": "0.2.0",
|
|
"channel": "stable",
|
|
"publishedAt": "2026-03-01T03:10:56Z",
|
|
"notesMarkdown": "Adds a staged resource update and relaunch flow.",
|
|
"artifacts": []any{
|
|
map[string]any{
|
|
"os": runtime.GOOS,
|
|
"arch": runtime.GOARCH,
|
|
"kind": updates.ArtifactKindBundleArchive,
|
|
"format": updates.ArtifactFormatZip,
|
|
"url": baseURL(request) + "/artifacts/updater-example_0.2.0.zip",
|
|
"sha256": checksumValue,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
writer.Header().Set("Content-Type", "application/json")
|
|
_ = json.NewEncoder(writer).Encode(document)
|
|
}
|
|
|
|
func artifact(writer http.ResponseWriter, _ *http.Request) {
|
|
archive, err := buildArchive()
|
|
if err != nil {
|
|
http.Error(writer, err.Error(), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
writer.Header().Set("Content-Type", "application/zip")
|
|
_, _ = writer.Write(archive)
|
|
}
|
|
|
|
func checksum(writer http.ResponseWriter, _ *http.Request) {
|
|
_, checksumValue, err := archiveWithChecksum()
|
|
if err != nil {
|
|
http.Error(writer, err.Error(), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
_, _ = writer.Write([]byte(checksumValue + " updater-example_0.2.0.zip"))
|
|
}
|
|
|
|
func buildArchive() ([]byte, error) {
|
|
buffer := bytes.NewBuffer(nil)
|
|
archive := zip.NewWriter(buffer)
|
|
|
|
bundleFile, err := archive.Create("bundle.json")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
bundle := updates.BundleManifest{
|
|
SchemaVersion: 1,
|
|
EntryPoint: entryPoint(),
|
|
Files: []updates.BundleFile{
|
|
{Path: resourcePath(), Mode: "0644"},
|
|
},
|
|
}
|
|
if err := json.NewEncoder(bundleFile).Encode(bundle); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
resourceFile, err := archive.Create(resourcePath())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if _, err := resourceFile.Write([]byte(`{"version":"0.2.0","status":"downloaded"}`)); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err := archive.Close(); err != nil {
|
|
return nil, err
|
|
}
|
|
return buffer.Bytes(), nil
|
|
}
|
|
|
|
func archiveWithChecksum() ([]byte, string, error) {
|
|
archive, err := buildArchive()
|
|
if err != nil {
|
|
return nil, "", err
|
|
}
|
|
sum := sha256.Sum256(archive)
|
|
return archive, hex.EncodeToString(sum[:]), nil
|
|
}
|
|
|
|
func entryPoint() string {
|
|
if runtime.GOOS == "darwin" {
|
|
return "Contents/MacOS/updater-example"
|
|
}
|
|
if runtime.GOOS == "windows" {
|
|
return "updater-example.exe"
|
|
}
|
|
return "updater-example"
|
|
}
|
|
|
|
func resourcePath() string {
|
|
if runtime.GOOS == "darwin" {
|
|
return "Contents/Resources/update.json"
|
|
}
|
|
return "resources/update.json"
|
|
}
|
|
|
|
func baseURL(request *http.Request) string {
|
|
scheme := "http"
|
|
if request.TLS != nil {
|
|
scheme = "https"
|
|
}
|
|
return scheme + "://" + request.Host
|
|
}
|