Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(gateway): JSON and CBOR response formats (IPIP-328) #9335

Merged
merged 39 commits into from
Dec 5, 2022
Merged
Changes from 1 commit
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
ac8f9b1
wip: play with dag-cbor and dag-json
hacdias Oct 6, 2022
3dce012
wip: add application/json and application/cbor
hacdias Oct 7, 2022
b557181
fix: go cases don't flow automatically :)
hacdias Oct 10, 2022
4104bb7
test: add some dag-json and dag-cbor tests
hacdias Oct 10, 2022
25893c5
test: improve names
hacdias Oct 10, 2022
e621e64
feat: allow json and cbor data types too
hacdias Oct 11, 2022
44946ed
refactor: avoid encoding things that are already on their right encoding
hacdias Oct 13, 2022
199ab42
fix: remove responseFormat from logging
hacdias Oct 13, 2022
89eb033
refactor: simplify serveCodec to use serveRawBlock iff data encoded i…
hacdias Oct 13, 2022
fb50869
tests: rename current tests to indicate they're unixfs only
hacdias Oct 13, 2022
fc31241
refactor: do not use serveRawBlock inside serveCodec bc headers and o…
hacdias Oct 13, 2022
55383cd
test: add test with pure json and cbor
hacdias Oct 17, 2022
a6d45c7
test: convert cbor <-> json
hacdias Oct 17, 2022
1986be1
test: path traversal and dag-pb output
hacdias Oct 19, 2022
9ef022e
fix: add more info about errors
hacdias Oct 20, 2022
cadc681
fix: add missing traversal
hacdias Oct 20, 2022
6331695
Merge branch 'master' into feat/8823
hacdias Nov 10, 2022
2c93672
fix: remove duplicate variable
hacdias Nov 10, 2022
462c71b
Merge branch 'master' into feat/8823
hacdias Nov 11, 2022
1e844c5
refactor: do not support traversal
hacdias Nov 11, 2022
bb98041
Update core/corehttp/gateway_handler_codec.go
hacdias Nov 15, 2022
53d5878
improve PR to match spec
hacdias Nov 16, 2022
4064f97
Merge branch 'master' into feat/8823
hacdias Nov 16, 2022
8c6a8da
feat: little web page
hacdias Nov 16, 2022
b5e5ff2
feat: update doc
hacdias Nov 16, 2022
8ca2a52
fix: Content-Disposition .json and .cbor
lidel Nov 23, 2022
b4dfa66
fix: inline disposition for JSON responses
lidel Nov 23, 2022
83913c7
refactor: return 501 for unsupported pathing
lidel Nov 23, 2022
ff55745
docs(cbor): improved info about codec
lidel Nov 23, 2022
52711d3
refactor: create template at assets/dag-index-html
lidel Nov 24, 2022
7e84856
fix(dag@gw): content type and cache headers
lidel Nov 25, 2022
3b89f20
Merge branch 'master' into feat/8823
hacdias Nov 28, 2022
162f435
add changelog info
hacdias Nov 28, 2022
12d0d7f
fix title
hacdias Nov 28, 2022
2d8ba78
rm wild block
hacdias Nov 30, 2022
b5874e7
Merge branch 'master' into feat/8823
hacdias Dec 5, 2022
0c08a76
Merge branch 'master' into feat/8823
hacdias Dec 5, 2022
f084f09
fix(dag-index-html): remove technical jargon
lidel Dec 5, 2022
32bcd41
Merge branch 'master' into feat/8823
lidel Dec 5, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 46 additions & 2 deletions core/corehttp/gateway_handler_codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,15 @@ var contentTypeToCodecs = map[string][]uint64{
"application/vnd.ipld.dag-cbor": {uint64(mc.DagCbor)},
}

// contentTypeToExtension maps the HTTP Content Type to the respective file
// extension, to apply them when downloading the file.
var contentTypeToExtension = map[string]string{
"application/json": ".json",
"application/vnd.ipld.dag-json": ".dag-json",
"application/cbor": ".cbor",
"application/vnd.ipld.dag-cbor": ".dag-cbor",
}

lidel marked this conversation as resolved.
Show resolved Hide resolved
func (i *gatewayHandler) serveCodec(ctx context.Context, w http.ResponseWriter, r *http.Request, resolvedPath ipath.Resolved, contentPath ipath.Path, begin time.Time, requestedContentType string) {
ctx, span := tracing.Span(ctx, "Gateway", "ServeCodec", trace.WithAttributes(attribute.String("path", resolvedPath.String()), attribute.String("requestedContentType", requestedContentType)))
defer span.End()
Expand Down Expand Up @@ -108,12 +117,30 @@ func (i *gatewayHandler) serveCodec(ctx context.Context, w http.ResponseWriter,
}

func (i *gatewayHandler) serverCodecHTML(ctx context.Context, w http.ResponseWriter, r *http.Request, resolvedPath ipath.Resolved, contentPath ipath.Path) {
w.Write([]byte("TODO"))
body := fmt.Sprintf(`<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
</head>
<body>
<p>The document you are trying to access cannot be previewed in the browser:</p>
<pre>%s</pre>
<p>Please follow the following links to download the document in other formats:</p>
<ul>
<li><a href="?format=dag-json">DAG-JSON</a></li>
<li><a href="?format=dag-cbor">DAG-CBOR</a></li>
<li><a href="?format=raw">Raw</a></li>
</ul>
</body>
</html>
`, contentPath.String())

w.Write([]byte(body))
}

func (i *gatewayHandler) serveCodecRaw(ctx context.Context, w http.ResponseWriter, r *http.Request, resolvedPath ipath.Resolved, contentPath ipath.Path, contentType string) {
modtime := addCacheControlHeaders(w, r, contentPath, resolvedPath.Cid())
name := addContentDispositionHeader(w, r, contentPath)
name := setCodecContentDisposition(w, r, resolvedPath, contentType)
w.Header().Set("Content-Type", contentType)
w.Header().Set("X-Content-Type-Options", "nosniff")

Expand Down Expand Up @@ -167,6 +194,7 @@ func (i *gatewayHandler) serveCodecConverted(ctx context.Context, w http.Respons

// Set Cache-Control and read optional Last-Modified time
modtime := addCacheControlHeaders(w, r, contentPath, resolvedPath.Cid())
setCodecContentDisposition(w, r, resolvedPath, contentType)
w.Header().Set("Content-Type", contentType)
w.Header().Set("X-Content-Type-Options", "nosniff")

Expand All @@ -178,3 +206,19 @@ func (i *gatewayHandler) serveCodecConverted(ctx context.Context, w http.Respons

w.Write(buf.Bytes())
}

func setCodecContentDisposition(w http.ResponseWriter, r *http.Request, resolvedPath ipath.Resolved, contentType string) string {
var name string
if urlFilename := r.URL.Query().Get("filename"); urlFilename != "" {
name = urlFilename
} else {
ext, ok := contentTypeToExtension[contentType]
if !ok {
// Should never happen.
ext = ".bin"
}
name = resolvedPath.Cid().String() + ext
}
setContentDispositionHeader(w, name, "attachment")
return name
}