Skip to content

Commit

Permalink
fix(gateway): JSON when Accept is a list
Browse files Browse the repository at this point in the history
Block/CAR responses always had single explicit type, and we did not bother
with implementing/testing lists.

With the introduction of JSON people may start passing a list.
This is the most basic fix which will return on the first matching
type (in order). This does not implements weights (can be added in
future, if needed).

Closes #9520
  • Loading branch information
lidel authored and galargh committed Jan 23, 2023
1 parent b22aae7 commit b333740
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 11 deletions.
26 changes: 15 additions & 11 deletions core/corehttp/gateway_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -890,18 +890,22 @@ func customResponseFormat(r *http.Request) (mediaType string, params map[string]
}
// Browsers and other user agents will send Accept header with generic types like:
// Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
// We only care about explicit, vendor-specific content-types.
for _, accept := range r.Header.Values("Accept") {
// respond to the very first ipld content type
if strings.HasPrefix(accept, "application/vnd.ipld") ||
strings.HasPrefix(accept, "application/x-tar") ||
strings.HasPrefix(accept, "application/json") ||
strings.HasPrefix(accept, "application/cbor") {
mediatype, params, err := mime.ParseMediaType(accept)
if err != nil {
return "", nil, err
// We only care about explicit, vendor-specific content-types and respond to the first match (in order).
// TODO: make this RFC compliant and respect weights (eg. return CAR for Accept:application/vnd.ipld.dag-json;q=0.1,application/vnd.ipld.car;q=0.2)
for _, header := range r.Header.Values("Accept") {
for _, value := range strings.Split(header, ",") {
accept := strings.TrimSpace(value)
// respond to the very first matching content type
if strings.HasPrefix(accept, "application/vnd.ipld") ||
strings.HasPrefix(accept, "application/x-tar") ||
strings.HasPrefix(accept, "application/json") ||
strings.HasPrefix(accept, "application/cbor") {
mediatype, params, err := mime.ParseMediaType(accept)
if err != nil {
return "", nil, err
}
return mediatype, params, nil
}
return mediatype, params, nil
}
}
return "", nil, nil
Expand Down
5 changes: 5 additions & 0 deletions test/sharness/t0123-gateway-json-cbor.sh
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ test_dag_pb_headers () {
test_should_contain "Content-Type: application/$format" curl_output &&
test_should_not_contain "Content-Type: application/vnd.ipld.dag-$format" curl_output
'

test_expect_success "GET UnixFS as $name with 'Accept: foo, application/$format,bar' has expected Content-Type" '
curl -sD - -H "Accept: foo, application/$format,text/plain" "http://127.0.0.1:$GWAY_PORT/ipfs/$FILE_CID" > curl_output 2>&1 &&
test_should_contain "Content-Type: application/$format" curl_output
'
}

test_dag_pb_headers "DAG-JSON" "json" "inline"
Expand Down

0 comments on commit b333740

Please sign in to comment.