pkg/handlers/files/handler.go (60 lines of code) (raw):

// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. package files import ( "context" "net/http" "os" "time" pcontext "github.com/azure/peerd/pkg/context" "github.com/azure/peerd/pkg/files/store" "github.com/azure/peerd/pkg/metrics" ) // FilesHandler describes a handler for files. type FilesHandler struct { store store.FilesStore metricsRecorder metrics.Metrics } // Handle handles a request for a file. func (h *FilesHandler) Handle(c pcontext.Context) { log := pcontext.Logger(c).With().Str("blob", pcontext.BlobUrl(c)).Bool("p2p", pcontext.IsRequestFromAPeer(c)).Logger() log.Debug().Msg("files handler start") s := time.Now() defer func() { dur := time.Since(s) h.metricsRecorder.RecordRequest(c.Request.Method, "files", float64(dur.Milliseconds())) log.Debug().Dur("duration", dur).Msg("files handler stop") }() err := h.fill(c) if err != nil { log.Debug().Err(err).Msg("failed to fill context") // nolint c.AbortWithError(http.StatusBadRequest, err) return } f, err := h.store.Open(c) if err == os.ErrNotExist { c.AbortWithStatus(http.StatusNotFound) return } if err != nil { // nolint c.AbortWithError(http.StatusInternalServerError, err) return } w := c.Writer w.Header().Set("Content-Type", "application/octet-stream") w.Header().Del("Content-Length") w.Header().Set(pcontext.NodeHeaderKey, pcontext.NodeName) w.Header().Set(pcontext.CorrelationHeaderKey, c.GetString(pcontext.CorrelationIdCtxKey)) http.ServeContent(w, c.Request, "file", time.Now(), f) } // fill fills the context with handler specific information. func (h *FilesHandler) fill(c pcontext.Context) error { c.Set("handler", "files") key, d, err := h.store.Key(c) if err != nil { return err } c.Set(pcontext.DigestCtxKey, d.String()) c.Set(pcontext.FileChunkCtxKey, key) c.Set(pcontext.BlobUrlCtxKey, pcontext.BlobUrl(c)) c.Set(pcontext.BlobRangeCtxKey, c.Request.Header.Get("Range")) return nil } // New creates a new files handler. func New(ctx context.Context, fs store.FilesStore) *FilesHandler { return &FilesHandler{fs, metrics.FromContext(ctx)} }