|
1 | 1 | package corehttp |
2 | 2 |
|
3 | 3 | import ( |
| 4 | + "bytes" |
4 | 5 | "context" |
5 | 6 | "fmt" |
6 | 7 | "html" |
| 8 | + "io" |
7 | 9 | "net/http" |
8 | 10 | "time" |
9 | 11 |
|
@@ -42,28 +44,43 @@ func (i *gatewayHandler) serveCodec(ctx context.Context, w http.ResponseWriter, |
42 | 44 | return |
43 | 45 | } |
44 | 46 |
|
45 | | - // If the data is already encoded with the possible codecs, we can defer execution to |
46 | | - // serveRawBlock, which will simply stream the raw data of this block. |
| 47 | + // Set Cache-Control and read optional Last-Modified time |
| 48 | + modtime := addCacheControlHeaders(w, r, contentPath, resolvedPath.Cid()) |
| 49 | + name := addContentDispositionHeader(w, r, contentPath) |
| 50 | + w.Header().Set("Content-Type", contentType) |
| 51 | + w.Header().Set("X-Content-Type-Options", "nosniff") |
| 52 | + |
| 53 | + // If the data is already encoded with the possible codecs, we can just stream the raw |
| 54 | + // data. serveRawBlock cannot be directly used here as it sets different headers. |
47 | 55 | for _, codec := range codecs { |
48 | 56 | if resolvedPath.Cid().Prefix().Codec == codec { |
49 | | - i.serveRawBlock(ctx, w, r, resolvedPath, contentPath, begin, contentType) |
| 57 | + |
| 58 | + blockCid := resolvedPath.Cid() |
| 59 | + blockReader, err := i.api.Block().Get(ctx, resolvedPath) |
| 60 | + if err != nil { |
| 61 | + webError(w, "ipfs block get "+blockCid.String(), err, http.StatusInternalServerError) |
| 62 | + return |
| 63 | + } |
| 64 | + block, err := io.ReadAll(blockReader) |
| 65 | + if err != nil { |
| 66 | + webError(w, "ipfs block get "+blockCid.String(), err, http.StatusInternalServerError) |
| 67 | + return |
| 68 | + } |
| 69 | + content := bytes.NewReader(block) |
| 70 | + |
| 71 | + // ServeContent will take care of |
| 72 | + // If-None-Match+Etag, Content-Length and range requests |
| 73 | + _, _, _ = ServeContent(w, r, name, modtime, content) |
50 | 74 | return |
51 | 75 | } |
52 | 76 | } |
53 | 77 |
|
54 | | - // Set Cache-Control and read optional Last-Modified time |
55 | | - modtime := addCacheControlHeaders(w, r, contentPath, resolvedPath.Cid()) |
56 | | - |
57 | 78 | // Sets correct Last-Modified header. This code is borrowed from the standard |
58 | 79 | // library (net/http/server.go) as we cannot use serveFile. |
59 | 80 | if !(modtime.IsZero() || modtime.Equal(unixEpochTime)) { |
60 | 81 | w.Header().Set("Last-Modified", modtime.UTC().Format(http.TimeFormat)) |
61 | 82 | } |
62 | 83 |
|
63 | | - addContentDispositionHeader(w, r, contentPath) |
64 | | - w.Header().Set("Content-Type", contentType) |
65 | | - w.Header().Set("X-Content-Type-Options", "nosniff") |
66 | | - |
67 | 84 | obj, err := i.api.Dag().Get(ctx, resolvedPath.Cid()) |
68 | 85 | if err != nil { |
69 | 86 | webError(w, "ipfs dag get "+html.EscapeString(resolvedPath.String()), err, http.StatusInternalServerError) |
|
0 commit comments