feat: add independent platform modules and multi-provider storage
This commit is contained in:
63
internal/storagefixture/server.go
Normal file
63
internal/storagefixture/server.go
Normal file
@@ -0,0 +1,63 @@
|
||||
// Package storagefixture supplies a bounded protocol fixture, not a cloud service.
|
||||
package storagefixture
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type value struct {
|
||||
data []byte
|
||||
contentType string
|
||||
etag string
|
||||
}
|
||||
|
||||
func Handler() http.Handler {
|
||||
var mu sync.Mutex
|
||||
values := map[string]value{}
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
if r.Header.Get("Authorization") == "" && r.URL.Query().Get("X-Amz-Signature") == "" && r.URL.Query().Get("x-oss-signature") == "" {
|
||||
http.Error(w, "signature required", 403)
|
||||
return
|
||||
}
|
||||
key := r.URL.Path
|
||||
switch r.Method {
|
||||
case "PUT":
|
||||
data, err := io.ReadAll(io.LimitReader(r.Body, 1025))
|
||||
if err != nil || len(data) > 1024 {
|
||||
http.Error(w, "too large", 413)
|
||||
return
|
||||
}
|
||||
v := value{data: data, contentType: r.Header.Get("Content-Type"), etag: fmt.Sprintf("%x", md5.Sum(data))}
|
||||
values[key] = v
|
||||
w.Header().Set("ETag", `"`+v.etag+`"`)
|
||||
w.WriteHeader(200)
|
||||
case "DELETE":
|
||||
delete(values, key)
|
||||
w.WriteHeader(204)
|
||||
case "GET", "HEAD":
|
||||
v, ok := values[key]
|
||||
if !ok {
|
||||
w.Header().Set("Content-Type", "application/xml")
|
||||
w.WriteHeader(404)
|
||||
fmt.Fprint(w, `<Error><Code>NoSuchKey</Code><Message>not found</Message></Error>`)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Length", fmt.Sprint(len(v.data)))
|
||||
w.Header().Set("Content-Type", v.contentType)
|
||||
w.Header().Set("ETag", `"`+v.etag+`"`)
|
||||
w.Header().Set("Last-Modified", time.Now().UTC().Format(http.TimeFormat))
|
||||
if r.Method == "GET" {
|
||||
w.Write(v.data)
|
||||
}
|
||||
default:
|
||||
http.Error(w, "unsupported", 405)
|
||||
}
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user