From 3fbb77153b676c773dd12821cf46be1ed351f65f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 18 Oct 2017 22:25:36 +0200 Subject: [PATCH] gateway: custom seeker for files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Ɓukasz Magiera --- core/corehttp/gateway_handler.go | 24 ++++++++++++++++++++++++ unixfs/io/pbdagreader.go | 7 +++++++ 2 files changed, 31 insertions(+) diff --git a/core/corehttp/gateway_handler.go b/core/corehttp/gateway_handler.go index 336169404..0a7e657de 100644 --- a/core/corehttp/gateway_handler.go +++ b/core/corehttp/gateway_handler.go @@ -372,7 +372,31 @@ func (i *gatewayHandler) getOrHeadHandler(ctx context.Context, w http.ResponseWr } } +type sizeReadSeeker interface { + Size() uint64 + + io.ReadSeeker +} + +type sizeSeeker struct { + sizeReadSeeker +} + +func (s *sizeSeeker) Seek(offset int64, whence int) (int64, error) { + if whence == io.SeekEnd && offset == 0 { + return int64(s.Size()), nil + } + + return s.sizeReadSeeker.Seek(offset, whence) +} + func (i *gatewayHandler) serverFile(w http.ResponseWriter, req *http.Request, name string, modtime time.Time, content io.ReadSeeker) { + if sp, ok := content.(sizeReadSeeker); ok { + content = &sizeSeeker{ + sizeReadSeeker: sp, + } + } + http.ServeContent(w, req, name, modtime, content) //TODO: check for errors in ServeContent.. somehow diff --git a/unixfs/io/pbdagreader.go b/unixfs/io/pbdagreader.go index 7ba63649f..dcd383460 100644 --- a/unixfs/io/pbdagreader.go +++ b/unixfs/io/pbdagreader.go @@ -188,6 +188,9 @@ func (dr *pbDagReader) Seek(offset int64, whence int) (int64, error) { if offset < 0 { return -1, errors.New("Invalid offset") } + if offset == dr.offset { + return offset, nil + } // Grab cached protobuf object (solely to make code look cleaner) pb := dr.pbdata @@ -239,6 +242,10 @@ func (dr *pbDagReader) Seek(offset int64, whence int) (int64, error) { return offset, nil case io.SeekCurrent: // TODO: be smarter here + if offset == 0 { + return dr.offset, nil + } + noffset := dr.offset + offset return dr.Seek(noffset, io.SeekStart) case io.SeekEnd: