Skip to content

Commit

Permalink
test: t0117-gateway-block.sh
Browse files Browse the repository at this point in the history
  • Loading branch information
lidel committed Mar 9, 2022
1 parent ee7b0ae commit aed0bf5
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 25 deletions.
46 changes: 21 additions & 25 deletions core/corehttp/gateway_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -326,29 +326,19 @@ func (i *gatewayHandler) getOrHeadHandler(w http.ResponseWriter, r *http.Request
}

// Support custom response formats passed via ?format or Accept HTTP header
if contentType := getExplicitContentType(r); contentType != "" {
switch contentType {
case "application/vnd.ipld.raw":
logger.Debugw("serving raw block", "path", parsedPath)
i.serveRawBlock(w, r, resolvedPath.Cid(), parsedPath)
return
case "application/vnd.ipld.car":
logger.Debugw("serving car stream", "path", parsedPath)
i.serveCar(w, r, resolvedPath.Cid(), parsedPath)
return
case "application/vnd.ipld.car; version=1":
logger.Debugw("serving car stream", "path", parsedPath)
i.serveCar(w, r, resolvedPath.Cid(), parsedPath)
return
case "application/vnd.ipld.car; version=2": // no CARv2 in go-ipfs atm
err := fmt.Errorf("unsupported CARv2 format, try again with CARv1")
webError(w, "failed respond with requested content type", err, http.StatusBadRequest)
return
default:
err := fmt.Errorf("unsupported format %q", contentType)
webError(w, "failed respond with requested content type", err, http.StatusBadRequest)
return
}
switch contentType := getExplicitContentType(r); contentType {
case "application/vnd.ipld.raw":
logger.Debugw("serving raw block", "path", parsedPath)
i.serveRawBlock(w, r, resolvedPath.Cid(), parsedPath)
return
case "application/vnd.ipld.car", "application/vnd.ipld.car; version=1":
logger.Debugw("serving car stream", "path", parsedPath)
i.serveCar(w, r, resolvedPath.Cid(), parsedPath)
return
default:
err := fmt.Errorf("unsupported format %q", contentType)
webError(w, "failed respond with requested content type", err, http.StatusBadRequest)
return
}

// Handling Unixfs
Expand Down Expand Up @@ -904,8 +894,14 @@ func getExplicitContentType(r *http.Request) string {
return "application/vnd.ipld.car"
}
}
if accept := r.Header.Get("Accept"); strings.HasPrefix(accept, "application/vnd.") {
return accept
// 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 explciit, 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") {
return accept
}
}
return ""
}
Expand Down
71 changes: 71 additions & 0 deletions test/sharness/t0117-gateway-block.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#!/usr/bin/env bash

test_description="Test HTTP Gateway Raw Block (application/vnd.ipld.raw) Support"

. lib/test-lib.sh

test_init_ipfs
test_launch_ipfs_daemon

test_expect_success "Create text fixtures" '
mkdir -p dir &&
echo "hello" > dir/ascii.txt &&
ROOT_DIR_CID=$(ipfs add -Qrw --cid-version 1 dir)
FILE_CID=$(ipfs resolve -r /ipfs/$ROOT_DIR_CID/dir/ascii.txt | cut -d "/" -f3)
'

# GET unixfs dir root block and compare it with `ipfs block get` output

test_expect_success "GET with format=raw param returns a raw block" '
ipfs block get "/ipfs/$ROOT_DIR_CID/dir" > expected &&
curl -sX GET "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT_DIR_CID/dir?format=raw" -o curl_ipfs_dir_block_param_output &&
test_cmp expected curl_ipfs_dir_block_param_output
'

test_expect_success "GET for application/vnd.ipld.raw returns a raw block" '
ipfs block get "/ipfs/$ROOT_DIR_CID/dir" > expected_block &&
curl -sX GET -H "Accept: application/vnd.ipld.raw" "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT_DIR_CID/dir" -o curl_ipfs_dir_block_accept_output &&
test_cmp expected_block curl_ipfs_dir_block_accept_output
'

# Make sure expected HTTP headers are returned with the block bytes

test_expect_success "GET response for application/vnd.ipld.raw has expected Content-Type" '
curl -svX GET -H "Accept: application/vnd.ipld.raw" "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT_DIR_CID/dir/ascii.txt" >/dev/null 2>curl_output &&
cat curl_output &&
grep "< Content-Type: application/vnd.ipld.raw" curl_output
'

test_expect_success "GET response for application/vnd.ipld.raw includes Content-Length" '
BYTES=$(ipfs block get $FILE_CID | wc --bytes)
grep "< Content-Length: $BYTES" curl_output
'

test_expect_success "GET response for application/vnd.ipld.raw includes Content-Disposition" '
grep "< Content-Disposition: attachment\; filename=\"${FILE_CID}.raw\"" curl_output
'

test_expect_success "GET response for application/vnd.ipld.raw includes nosniff hint" '
grep "< X-Content-Type-Options: nosniff" curl_output
'

# Cache control HTTP headers
# (basic checks, detailed behavior is tested in t0116-gateway-cache.sh)

test_expect_success "GET response for application/vnd.ipld.raw includes Etag" '
grep "< Etag: \"${FILE_CID}\"" curl_output
'

test_expect_success "GET response for application/vnd.ipld.raw includes X-Ipfs-Path and X-Ipfs-Roots" '
grep "< X-Ipfs-Path" curl_output &&
grep "< X-Ipfs-Roots" curl_output
'

test_expect_success "GET response for application/vnd.ipld.raw includes Cache-Control" '
grep "< X-Ipfs-Path" curl_output &&
grep "< X-Ipfs-Roots" curl_output
'

test_kill_ipfs_daemon

test_done

0 comments on commit aed0bf5

Please sign in to comment.