Files
kopia/internal/server/api_object_get.go
Jarek Kowalski 9cba4a97be refactor(repository): major server code refactoring (#1837)
This removes big shared lock held for for the duration of each request
and replaces it with trivially short lock to capture the current
state of the server/repository before passing it to handlers.

Handlers are now limited to only accessing a small subset of Server
functionality to be able to better reason about them.
2022-03-19 22:01:38 -07:00

54 lines
1.1 KiB
Go

package server
import (
"context"
"errors"
"net/http"
"time"
"github.com/kopia/kopia/internal/clock"
"github.com/kopia/kopia/repo/object"
"github.com/kopia/kopia/snapshot/snapshotfs"
)
func handleObjectGet(ctx context.Context, rc requestContext) {
oidstr := rc.muxVar("objectID")
if !requireUIUser(ctx, rc) {
http.Error(rc.w, "access denied", http.StatusForbidden)
return
}
oid, err := object.ParseID(oidstr)
if err != nil {
http.Error(rc.w, "invalid object id", http.StatusBadRequest)
return
}
obj, err := rc.rep.OpenObject(ctx, oid)
if errors.Is(err, object.ErrObjectNotFound) {
http.Error(rc.w, "object not found", http.StatusNotFound)
return
}
if snapshotfs.IsDirectoryID(oid) {
rc.w.Header().Set("Content-Type", "application/json")
}
fname := oid.String()
if p := rc.queryParam("fname"); p != "" {
fname = p
rc.w.Header().Set("Content-Disposition", "attachment; filename=\""+p+"\"")
}
mtime := clock.Now()
if p := rc.queryParam("mtime"); p != "" {
if m, err := time.Parse(time.RFC3339Nano, p); err == nil {
mtime = m
}
}
http.ServeContent(rc.w, rc.req, fname, mtime, obj)
}