Skip to content

Commit

Permalink
feat: single and multi range test for RAW /ipfs/{cid}
Browse files Browse the repository at this point in the history
  • Loading branch information
hacdias committed Jul 31, 2023
1 parent 517e9e3 commit cfc0e22
Showing 1 changed file with 129 additions and 0 deletions.
129 changes: 129 additions & 0 deletions tests/trustless_gateway_raw_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"testing"

"github.com/ipfs/gateway-conformance/tooling/car"
. "github.com/ipfs/gateway-conformance/tooling/check"
"github.com/ipfs/gateway-conformance/tooling/specs"
. "github.com/ipfs/gateway-conformance/tooling/test"
)
Expand Down Expand Up @@ -125,3 +126,131 @@ func TestTrustlessRaw(t *testing.T) {

RunWithSpecs(t, tests, specs.TrustlessGatewayRaw)
}

func TestTrustlessRawRanges(t *testing.T) {
// Multi-range requests MUST conform to the HTTP semantics. The server does not
// need to be able to support returning multiple ranges. However, it must respond
// correctly.
fixture := car.MustOpenUnixfsCar("gateway-raw-block.car")

var (
contentType string
contentRange string
)

RunWithSpecs(t, SugarTests{
{
Name: "GETaa with application/vnd.ipld.raw with single range request includes correct bytes",
Request: Request().
Path("/ipfs/{{cid}}", fixture.MustGetCid("dir", "ascii.txt")).
Headers(
Header("Accept", "application/vnd.ipld.raw"),
Header("Range", "bytes=6-16"),
),
Response: Expect().
Status(206).
Headers(
Header("Content-Type").Contains("application/vnd.ipld.raw"),
Header("Content-Range").Equals("bytes 6-16/31"),
).
Body(fixture.MustGetRawData("dir", "ascii.txt")[6:17]),
},
{
Name: "GET with application/vnd.ipld.raw with multiple range request includes correct bytes",
Request: Request().
Path("/ipfs/{{cid}}", fixture.MustGetCid("dir", "ascii.txt")).
Headers(
Header("Accept", "application/vnd.ipld.raw"),
Header("Range", "bytes=6-16,0-4"),
),
Response: Expect().
Status(206).
Headers(
Header("Content-Type").
Checks(func(v string) bool {
contentType = v
return v != ""
}),
Header("Content-Range").
ChecksAll(func(v []string) bool {
if len(v) == 1 {
contentRange = v[0]
}
return true
}),
),
},
}, specs.PathGatewayRaw)

tests := SugarTests{}

if strings.Contains(contentType, "application/vnd.ipld.raw") {
// The server is not able to respond to a multi-range request. Therefore,
// there might be only one range or... just the whole file, depending on the headers.

if contentRange == "" {
// Server does not support range requests and must send back the complete file.
tests = append(tests, SugarTest{
Name: "GET with application/vnd.ipld.raw with multiple range request includes correct bytes",
Request: Request().
Path("/ipfs/{{cid}}", fixture.MustGetCid("dir", "ascii.txt")).
Headers(
Header("Accept", "application/vnd.ipld.raw"),
Header("Range", "bytes=6-16,0-4"),
),
Response: Expect().
Status(206).
Headers(
Header("Content-Type").Contains("application/vnd.ipld.raw"),
Header("Content-Range").IsEmpty(),
).
Body(fixture.MustGetRawData("dir", "ascii.txt")),
})
} else {
// Server supports range requests but only the first range.
tests = append(tests, SugarTest{
Name: "GET with application/vnd.ipld.raw with multiple range request includes correct bytes",
Request: Request().
Path("/ipfs/{{cid}}", fixture.MustGetCid("dir", "ascii.txt")).
Headers(
Header("Accept", "application/vnd.ipld.raw"),
Header("Range", "bytes=6-16,0-4"),
),
Response: Expect().
Status(206).
Headers(
Header("Content-Type").Contains("application/vnd.ipld.raw"),
Header("Content-Range", "bytes 6-16/31"),
).
Body(fixture.MustGetRawData("dir", "ascii.txt")[6:17]),
})
}
} else if strings.Contains(contentType, "multipart/byteranges") {
// The server supports responding with multi-range requests.
tests = append(tests, SugarTest{
Name: "GET with application/vnd.ipld.raw with multiple range request includes correct bytes",
Request: Request().
Path("/ipfs/{{cid}}", fixture.MustGetCid("dir", "ascii.txt")).
Headers(
Header("Accept", "application/vnd.ipld.raw"),
Header("Range", "bytes=6-16,0-4"),
),
Response: Expect().
Status(206).
Headers(
Header("Content-Type").Contains("multipart/byteranges"),
).
Body(And(
Contains("Content-Range: bytes 6-16/31"),
Contains("Content-Type: application/vnd.ipld.raw"),
Contains(string(fixture.MustGetRawData("dir", "ascii.txt")[6:17])),
Contains("Content-Range: bytes 0-4/31"),
Contains(string(fixture.MustGetRawData("dir", "ascii.txt")[0:5])),
)),
})
} else {
t.Error("Content-Type header did not match any of the accepted options")
}

RunWithSpecs(t, tests, specs.TrustlessGatewayRaw)
}

0 comments on commit cfc0e22

Please sign in to comment.