@cryptotaxi247 / kubo / commits / f6825ab66

fix(gateway): JSON when Accept is a list

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

Marcin Rataj committed Jan 11, 2023 at 03:40 UTC f6825ab662c8ec097fd7bfd8ad0c5193960f5c7b
2 files changed +20 -11
core/corehttp/gateway_handler.go
+15 -11
@@ -890,18 +890,22 @@ func customResponseFormat(r *http.Request) (mediaType string, params map[string]
890 }
891 // Browsers and other user agents will send Accept header with generic types like:
892 // Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
893 - // We only care about explicit, vendor-specific content-types.
894 - for _, accept := range r.Header.Values("Accept") {
895 - // respond to the very first ipld content type
896 - if strings.HasPrefix(accept, "application/vnd.ipld") ||
897 - strings.HasPrefix(accept, "application/x-tar") ||
898 - strings.HasPrefix(accept, "application/json") ||
899 - strings.HasPrefix(accept, "application/cbor") {
900 - mediatype, params, err := mime.ParseMediaType(accept)
901 - if err != nil {
902 - return "", nil, err
893 + // We only care about explicit, vendor-specific content-types and respond to the first match (in order).
894 + // 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)
895 + for _, header := range r.Header.Values("Accept") {
896 + for _, value := range strings.Split(header, ",") {
897 + accept := strings.TrimSpace(value)
898 + // respond to the very first matching content type
899 + if strings.HasPrefix(accept, "application/vnd.ipld") ||
900 + strings.HasPrefix(accept, "application/x-tar") ||
901 + strings.HasPrefix(accept, "application/json") ||
902 + strings.HasPrefix(accept, "application/cbor") {
903 + mediatype, params, err := mime.ParseMediaType(accept)
904 + if err != nil {
905 + return "", nil, err
906 + }
907 + return mediatype, params, nil
908 }
904 - return mediatype, params, nil
909 }
910 }
911 return "", nil, nil
test/sharness/t0123-gateway-json-cbor.sh
+5
@@ -56,6 +56,11 @@ test_dag_pb_headers () {
56 test_should_contain "Content-Type: application/$format" curl_output &&
57 test_should_not_contain "Content-Type: application/vnd.ipld.dag-$format" curl_output
58 '
59 +
60 + test_expect_success "GET UnixFS as $name with 'Accept: foo, application/$format,bar' has expected Content-Type" '
61 + curl -sD - -H "Accept: foo, application/$format,text/plain" "http://127.0.0.1:$GWAY_PORT/ipfs/$FILE_CID" > curl_output 2>&1 &&
62 + test_should_contain "Content-Type: application/$format" curl_output
63 + '
64 }
65
66 test_dag_pb_headers "DAG-JSON" "json" "inline"