diff --git a/api/server/handler.go b/api/server/handler.go index 4b3cf28..7bf82bc 100644 --- a/api/server/handler.go +++ b/api/server/handler.go @@ -27,6 +27,7 @@ func (m *HttpServer) handlePostBlob(w http.ResponseWriter, r *http.Request) { respondWithJson(w, errResponseNotStreamContentType, http.StatusBadRequest) return } + body := r.Body var contentLength uint64 if value := r.Header.Get("Content-Length"); value != "" { var err error @@ -38,9 +39,14 @@ func (m *HttpServer) handlePostBlob(w http.ResponseWriter, r *http.Request) { respondWithJson(w, errResponseContentLengthTooLarge(m.maxBlobLength), http.StatusBadRequest) return } + // Wrap body reader to signal content length to upstream components. + body = sizerReadCloser{ + ReadCloser: r.Body, + size: int64(contentLength), + } } - defer r.Body.Close() - desc, err := m.store.Put(r.Context(), r.Body) + defer body.Close() + desc, err := m.store.Put(r.Context(), body) switch err { case nil: case blob.ErrBlobTooLarge: diff --git a/api/server/sizer_reader.go b/api/server/sizer_reader.go new file mode 100644 index 0000000..d6d27b0 --- /dev/null +++ b/api/server/sizer_reader.go @@ -0,0 +1,14 @@ +package server + +import "io" + +var _ interface{ Size() int64 } = (*sizerReadCloser)(nil) + +type sizerReadCloser struct { + io.ReadCloser + size int64 +} + +func (s sizerReadCloser) Size() int64 { + return s.size +}