From 01940ecf7696b33bcecd82f00f5b5eaf81d2b156 Mon Sep 17 00:00:00 2001
From: Rutger Broekhoff
Date: Sun, 31 Dec 2023 00:13:17 +0100
Subject: Try formatting x-amz-checksum-sha256 as Base64

Although this already looks like a lost cause (Scaleway Object Storage
doesn't seem to care about these headers -- certainly not about
Content-Length -- I wanted to see if I could still get automatic
checksum verification working.
---
 cmd/git-lfs-server/main.go | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/cmd/git-lfs-server/main.go b/cmd/git-lfs-server/main.go
index 63b6edf..a1ad5a4 100644
--- a/cmd/git-lfs-server/main.go
+++ b/cmd/git-lfs-server/main.go
@@ -4,6 +4,7 @@ import (
 	"bytes"
 	"context"
 	"crypto/ed25519"
+	"encoding/base64"
 	"encoding/hex"
 	"encoding/json"
 	"errors"
@@ -134,6 +135,14 @@ func makeObjError(obj parsedBatchObject, message string, code int) batchResponse
 	}
 }
 
+func sha256AsBase64(hash string) string {
+	raw, err := hex.DecodeString(hash)
+	if err != nil {
+		return ""
+	}
+	return base64.StdEncoding.EncodeToString(raw)
+}
+
 func (h *handler) handleDownloadObject(ctx context.Context, repo string, obj parsedBatchObject) batchResponseObject {
 	fullPath := path.Join(repo+".git", "lfs/objects", obj.firstByte, obj.secondByte, obj.fullHash)
 	expiresIn := time.Hour * 24
@@ -184,7 +193,7 @@ func (h *handler) handleUploadObject(ctx context.Context, repo string, obj parse
 
 	presigned, err := h.mc.Presign(ctx, http.MethodPut, h.bucket, fullPath, expiresIn, url.Values{
 		"x-amz-sdk-checksum-algorithm": {"sha256"},
-		"x-amz-checksum-sha256":        {obj.fullHash},
+		"x-amz-checksum-sha256":        {sha256AsBase64(obj.fullHash)},
 		"Content-Length":               {strconv.FormatUint(obj.size, 10)},
 	})
 	if err != nil {
@@ -332,6 +341,11 @@ func (h *handler) authorize(ctx context.Context, w http.ResponseWriter, r *http.
 func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 	ctx := context.WithValue(r.Context(), requestIDKey, xid.New().String())
 
+	if r.Method != http.MethodPost {
+		makeRespError(ctx, w, "Method not allowed", http.StatusMethodNotAllowed)
+		return
+	}
+
 	reqPath := os.Getenv("PATH_INFO")
 	if reqPath == "" {
 		reqPath = r.URL.Path
-- 
cgit v1.2.3