Skip to content

Commit

Permalink
refactor: do not use serveRawBlock inside serveCodec bc headers and o…
Browse files Browse the repository at this point in the history
…ther options
  • Loading branch information
hacdias committed Oct 17, 2022
1 parent 312ef5f commit a9b08c9
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 13 deletions.
2 changes: 1 addition & 1 deletion core/corehttp/gateway_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ func (i *gatewayHandler) getOrHeadHandler(w http.ResponseWriter, r *http.Request
return
case "application/vnd.ipld.raw":
logger.Debugw("serving raw block", "path", contentPath)
i.serveRawBlock(r.Context(), w, r, resolvedPath, contentPath, begin, responseFormat)
i.serveRawBlock(r.Context(), w, r, resolvedPath, contentPath, begin)
return
case "application/vnd.ipld.car":
logger.Debugw("serving car stream", "path", contentPath)
Expand Down
4 changes: 2 additions & 2 deletions core/corehttp/gateway_handler_block.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
)

// serveRawBlock returns bytes behind a raw block
func (i *gatewayHandler) serveRawBlock(ctx context.Context, w http.ResponseWriter, r *http.Request, resolvedPath ipath.Resolved, contentPath ipath.Path, begin time.Time, contentType string) {
func (i *gatewayHandler) serveRawBlock(ctx context.Context, w http.ResponseWriter, r *http.Request, resolvedPath ipath.Resolved, contentPath ipath.Path, begin time.Time) {
ctx, span := tracing.Span(ctx, "Gateway", "ServeRawBlock", trace.WithAttributes(attribute.String("path", resolvedPath.String())))
defer span.End()
blockCid := resolvedPath.Cid()
Expand All @@ -41,7 +41,7 @@ func (i *gatewayHandler) serveRawBlock(ctx context.Context, w http.ResponseWrite

// Set remaining headers
modtime := addCacheControlHeaders(w, r, contentPath, blockCid)
w.Header().Set("Content-Type", contentType)
w.Header().Set("Content-Type", "application/vnd.ipld.raw")
w.Header().Set("X-Content-Type-Options", "nosniff") // no funny business in the browsers :^)

// ServeContent will take care of
Expand Down
37 changes: 27 additions & 10 deletions core/corehttp/gateway_handler_codec.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package corehttp

import (
"bytes"
"context"
"fmt"
"html"
"io"
"net/http"
"time"

Expand Down Expand Up @@ -42,28 +44,43 @@ func (i *gatewayHandler) serveCodec(ctx context.Context, w http.ResponseWriter,
return
}

// If the data is already encoded with the possible codecs, we can defer execution to
// serveRawBlock, which will simply stream the raw data of this block.
// Set Cache-Control and read optional Last-Modified time
modtime := addCacheControlHeaders(w, r, contentPath, resolvedPath.Cid())
name := addContentDispositionHeader(w, r, contentPath)
w.Header().Set("Content-Type", contentType)
w.Header().Set("X-Content-Type-Options", "nosniff")

// If the data is already encoded with the possible codecs, we can just stream the raw
// data. serveRawBlock cannot be directly used here as it sets different headers.
for _, codec := range codecs {
if resolvedPath.Cid().Prefix().Codec == codec {
i.serveRawBlock(ctx, w, r, resolvedPath, contentPath, begin, contentType)

blockCid := resolvedPath.Cid()
blockReader, err := i.api.Block().Get(ctx, resolvedPath)
if err != nil {
webError(w, "ipfs block get "+blockCid.String(), err, http.StatusInternalServerError)
return
}
block, err := io.ReadAll(blockReader)
if err != nil {
webError(w, "ipfs block get "+blockCid.String(), err, http.StatusInternalServerError)
return
}
content := bytes.NewReader(block)

// ServeContent will take care of
// If-None-Match+Etag, Content-Length and range requests
_, _, _ = ServeContent(w, r, name, modtime, content)
return
}
}

// Set Cache-Control and read optional Last-Modified time
modtime := addCacheControlHeaders(w, r, contentPath, resolvedPath.Cid())

// Sets correct Last-Modified header. This code is borrowed from the standard
// library (net/http/server.go) as we cannot use serveFile.
if !(modtime.IsZero() || modtime.Equal(unixEpochTime)) {
w.Header().Set("Last-Modified", modtime.UTC().Format(http.TimeFormat))
}

addContentDispositionHeader(w, r, contentPath)
w.Header().Set("Content-Type", contentType)
w.Header().Set("X-Content-Type-Options", "nosniff")

obj, err := i.api.Dag().Get(ctx, resolvedPath.Cid())
if err != nil {
webError(w, "ipfs dag get "+html.EscapeString(resolvedPath.String()), err, http.StatusInternalServerError)
Expand Down

0 comments on commit a9b08c9

Please sign in to comment.