diff --git a/handler.go b/handler.go index 38d2fe4..1ddc906 100644 --- a/handler.go +++ b/handler.go @@ -122,12 +122,12 @@ func (handler *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { if r.Method == "OPTIONS" { // Preflight request header.Set("Access-Control-Allow-Methods", "POST, HEAD, PATCH, OPTIONS") - header.Set("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Entity-Length, Offset, TUS-Resumable") + header.Set("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Entity-Length, Offset, TUS-Resumable, Metadata") header.Set("Access-Control-Max-Age", "86400") } else { // Actual request - header.Set("Access-Control-Expose-Headers", "Offset, Location, Entity-Length, TUS-Version, TUS-Resumable, TUS-Max-Size, TUS-Extension") + header.Set("Access-Control-Expose-Headers", "Offset, Location, Entity-Length, TUS-Version, TUS-Resumable, TUS-Max-Size, TUS-Extension, Metadata") } } @@ -245,6 +245,10 @@ func (handler *Handler) headFile(w http.ResponseWriter, r *http.Request) { w.Header().Set("Concat", v) } + if len(info.MetaData) != 0 { + w.Header().Set("Metadata", serializeMeta(info.MetaData)) + } + w.Header().Set("Entity-Length", strconv.FormatInt(info.Size, 10)) w.Header().Set("Offset", strconv.FormatInt(info.Offset, 10)) w.WriteHeader(http.StatusNoContent) @@ -462,8 +466,8 @@ func (handler *Handler) fillFinalUpload(id string, uploads []string) error { return handler.dataStore.WriteChunk(id, 0, reader) } -// Parse the meatadata as defined in the Metadata extension. -// e.g. Metadata: key base64value, key2 base64value +// Parse the Metadata header as defined in the File Creation extension. +// e.g. Metadata: name bHVucmpzLnBuZw==,type aW1hZ2UvcG5n func parseMeta(header string) map[string]string { meta := make(map[string]string) @@ -490,6 +494,24 @@ func parseMeta(header string) map[string]string { return meta } +// Serialize a map of strings into the Metadata header format used in the +// response for HEAD requests. +// e.g. Metadata: name bHVucmpzLnBuZw==,type aW1hZ2UvcG5n +func serializeMeta(meta map[string]string) string { + header := "" + for key, value := range meta { + valueBase64 := base64.StdEncoding.EncodeToString([]byte(value)) + header += key + " " + valueBase64 + "," + } + + // Remove trailing comma + if len(header) > 0 { + header = header[:len(header)-1] + } + + return header +} + // Parse the Concat header, e.g. // Concat: partial // Concat: final; http://tus.io/files/a /files/b/ diff --git a/head_test.go b/head_test.go index e0ad2a3..725e0aa 100644 --- a/head_test.go +++ b/head_test.go @@ -18,6 +18,10 @@ func (s headStore) GetInfo(id string) (FileInfo, error) { return FileInfo{ Offset: 11, Size: 44, + MetaData: map[string]string{ + "name": "lunrjs.png", + "type": "image/png", + }, }, nil } @@ -38,6 +42,7 @@ func TestHead(t *testing.T) { ResHeader: map[string]string{ "Offset": "11", "Entity-Length": "44", + "Metadata": "name bHVucmpzLnBuZw==,type aW1hZ2UvcG5n", }, }).Run(handler, t)