Skip to content

Commit 482e385

Browse files
committed
wip: add application/json and application/cbor
1 parent 3a25b14 commit 482e385

File tree

3 files changed

+69
-47
lines changed

3 files changed

+69
-47
lines changed

core/corehttp/gateway_handler.go

+11-3
Original file line numberDiff line numberDiff line change
@@ -432,12 +432,14 @@ func (i *gatewayHandler) getOrHeadHandler(w http.ResponseWriter, r *http.Request
432432
i.serveCAR(r.Context(), w, r, resolvedPath, contentPath, carVersion, begin)
433433
return
434434
case "application/vnd.ipld.dag-json":
435+
case "application/json":
435436
logger.Debugw("serving dag-json", "path", contentPath)
436-
i.serveJSON(r.Context(), w, r, resolvedPath, begin, "application/vnd.ipld.dag-json", uint64(mc.DagJson))
437+
i.serveCodec(r.Context(), w, r, resolvedPath, contentPath, begin, responseFormat, uint64(mc.DagJson))
437438
return
438439
case "application/vnd.ipld.dag-cbor":
440+
case "application/cbor":
439441
logger.Debugw("serving dag-cbor", "path", contentPath)
440-
i.serveJSON(r.Context(), w, r, resolvedPath, begin, "application/vnd.ipld.dag-cbor", uint64(mc.DagCbor))
442+
i.serveCodec(r.Context(), w, r, resolvedPath, contentPath, begin, responseFormat, uint64(mc.DagCbor))
441443
return
442444
default: // catch-all for unsuported application/vnd.*
443445
err := fmt.Errorf("unsupported format %q", responseFormat)
@@ -870,16 +872,22 @@ func customResponseFormat(r *http.Request) (mediaType string, params map[string]
870872
return "application/vnd.ipld.car", nil, nil
871873
case "dag-json":
872874
return "application/vnd.ipld.dag-json", nil, nil
875+
case "json":
876+
return "application/json", nil, nil
873877
case "dag-cbor":
874878
return "application/vnd.ipld.dag-cbor", nil, nil
879+
case "cbor":
880+
return "application/cbor", nil, nil
875881
}
876882
}
877883
// Browsers and other user agents will send Accept header with generic types like:
878884
// Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
879885
// We only care about explciit, vendor-specific content-types.
880886
for _, accept := range r.Header.Values("Accept") {
881887
// respond to the very first ipld content type
882-
if strings.HasPrefix(accept, "application/vnd.ipld") {
888+
if strings.HasPrefix(accept, "application/vnd.ipld") ||
889+
strings.HasPrefix(accept, "application/json") ||
890+
strings.HasPrefix(accept, "application/cbor") {
883891
mediatype, params, err := mime.ParseMediaType(accept)
884892
if err != nil {
885893
return "", nil, err
+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package corehttp
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"html"
7+
"net/http"
8+
"time"
9+
10+
ipldlegacy "github.com/ipfs/go-ipld-legacy"
11+
ipath "github.com/ipfs/interface-go-ipfs-core/path"
12+
"github.com/ipfs/kubo/tracing"
13+
"github.com/ipld/go-ipld-prime"
14+
"github.com/ipld/go-ipld-prime/multicodec"
15+
"go.opentelemetry.io/otel/attribute"
16+
"go.opentelemetry.io/otel/trace"
17+
)
18+
19+
var unixEpochTime = time.Unix(0, 0)
20+
21+
func (i *gatewayHandler) serveCodec(ctx context.Context, w http.ResponseWriter, r *http.Request, resolvedPath ipath.Resolved, contentPath ipath.Path, begin time.Time, ctype string, codec uint64) {
22+
ctx, span := tracing.Span(ctx, "Gateway", "ServeCodec", trace.WithAttributes(attribute.String("path", resolvedPath.String()), attribute.String("ctype", ctype)))
23+
defer span.End()
24+
25+
// Set Cache-Control and read optional Last-Modified time
26+
modtime := addCacheControlHeaders(w, r, contentPath, resolvedPath.Cid())
27+
28+
// Sets correct Last-Modified header. This code is borrowed from the standard
29+
// library (net/http/server.go) as we cannot use serveFile.
30+
if !(modtime.IsZero() || modtime.Equal(unixEpochTime)) {
31+
w.Header().Set("Last-Modified", modtime.UTC().Format(http.TimeFormat))
32+
}
33+
34+
addContentDispositionHeader(w, r, contentPath)
35+
w.Header().Set("Content-Type", ctype)
36+
w.Header().Set("X-Content-Type-Options", "nosniff")
37+
38+
obj, err := i.api.Dag().Get(ctx, resolvedPath.Cid())
39+
if err != nil {
40+
webError(w, "ipfs dag get "+html.EscapeString(resolvedPath.String()), err, http.StatusInternalServerError)
41+
return
42+
}
43+
44+
universal, ok := obj.(ipldlegacy.UniversalNode)
45+
if !ok {
46+
webError(w, "todo", fmt.Errorf("%T is not a valid IPLD node", obj), http.StatusInternalServerError)
47+
return
48+
}
49+
finalNode := universal.(ipld.Node)
50+
51+
encoder, err := multicodec.LookupEncoder(codec)
52+
if err != nil {
53+
webError(w, "todo", err, http.StatusInternalServerError)
54+
return
55+
}
56+
57+
_ = encoder(finalNode, w)
58+
}

core/corehttp/gateway_handler_json.go

-44
This file was deleted.

0 commit comments

Comments
 (0)