Skip to content

Commit b28776f

Browse files
committed
wip: ipip-412
1 parent a9794ec commit b28776f

File tree

3 files changed

+75
-6
lines changed

3 files changed

+75
-6
lines changed

gateway/gateway.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,10 @@ func (i ImmutablePath) IsValid() error {
121121
var _ path.Path = (*ImmutablePath)(nil)
122122

123123
type CarParams struct {
124-
Range *DagByteRange
125-
Scope DagScope
124+
Range *DagByteRange
125+
Scope DagScope
126+
Order DagOrder
127+
Duplicates *bool
126128
}
127129

128130
// DagByteRange describes a range request within a UnixFS file. "From" and
@@ -189,6 +191,13 @@ const (
189191
DagScopeBlock DagScope = "block"
190192
)
191193

194+
type DagOrder string
195+
196+
const (
197+
DagOrderDFS DagOrder = "dfs"
198+
DagOrderUnknown DagOrder = "unk"
199+
)
200+
192201
type ContentPathMetadata struct {
193202
PathSegmentRoots []cid.Cid
194203
LastSegment path.Resolved

gateway/handler_car.go

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ func (i *handler) serveCAR(ctx context.Context, w http.ResponseWriter, r *http.R
3939
return false
4040
}
4141

42-
params, err := getCarParams(r)
42+
params, err := getCarParams(r, rq.responseParams)
4343
if err != nil {
4444
i.webError(w, r, err, http.StatusBadRequest)
4545
return false
@@ -113,7 +113,7 @@ func (i *handler) serveCAR(ctx context.Context, w http.ResponseWriter, r *http.R
113113
return true
114114
}
115115

116-
func getCarParams(r *http.Request) (CarParams, error) {
116+
func getCarParams(r *http.Request, formatParams map[string]string) (CarParams, error) {
117117
queryParams := r.URL.Query()
118118
rangeStr, hasRange := queryParams.Get(carRangeBytesKey), queryParams.Has(carRangeBytesKey)
119119
scopeStr, hasScope := queryParams.Get(carTerminalElementTypeKey), queryParams.Has(carTerminalElementTypeKey)
@@ -140,6 +140,28 @@ func getCarParams(r *http.Request) (CarParams, error) {
140140
params.Scope = DagScopeAll
141141
}
142142

143+
switch order := DagOrder(formatParams["order"]); order {
144+
case DagOrderUnknown, DagOrderDFS:
145+
params.Order = order
146+
case "":
147+
params.Order = DagOrderUnknown
148+
default:
149+
return CarParams{}, fmt.Errorf("unsupported order %s", order)
150+
}
151+
152+
switch dups := formatParams["dups"]; dups {
153+
case "y":
154+
v := true
155+
params.Duplicates = &v
156+
case "n":
157+
v := false
158+
params.Duplicates = &v
159+
case "":
160+
// Acceptable, we do not set anything.
161+
default:
162+
return CarParams{}, fmt.Errorf("unsupported dups %s", dups)
163+
}
164+
143165
return params, nil
144166
}
145167

gateway/handler_car_test.go

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ func TestCarParams(t *testing.T) {
2828
}
2929
for _, test := range tests {
3030
r := mustNewRequest(t, http.MethodGet, "http://example.com/?"+test.query, nil)
31-
params, err := getCarParams(r)
31+
params, err := getCarParams(r, map[string]string{})
3232
if test.expectedError {
3333
assert.Error(t, err)
3434
} else {
@@ -60,7 +60,7 @@ func TestCarParams(t *testing.T) {
6060
}
6161
for _, test := range tests {
6262
r := mustNewRequest(t, http.MethodGet, "http://example.com/?"+test.query, nil)
63-
params, err := getCarParams(r)
63+
params, err := getCarParams(r, map[string]string{})
6464
if test.hasError {
6565
assert.Error(t, err)
6666
} else {
@@ -73,6 +73,44 @@ func TestCarParams(t *testing.T) {
7373
}
7474
}
7575
})
76+
77+
t.Run("order and duplicates parsing", func(t *testing.T) {
78+
t.Parallel()
79+
80+
T := true
81+
F := false
82+
83+
tests := []struct {
84+
contentTypeHeader string
85+
order DagOrder
86+
duplicates *bool
87+
}{
88+
{"application/vnd.ipld.car; order=dfs; dups=y", DagOrderDFS, &T},
89+
{"application/vnd.ipld.car; order=unk; dups=n", DagOrderUnknown, &F},
90+
{"application/vnd.ipld.car; order=unk", DagOrderUnknown, nil},
91+
{"application/vnd.ipld.car; dups=y", DagOrderUnknown, &T},
92+
{"application/vnd.ipld.car; dups=n", DagOrderUnknown, &F},
93+
{"application/vnd.ipld.car", DagOrderUnknown, nil},
94+
}
95+
for _, test := range tests {
96+
r := mustNewRequest(t, http.MethodGet, "http://example.com/", nil)
97+
r.Header.Set("Accept", test.contentTypeHeader)
98+
99+
mediaType, formatParams, err := customResponseFormat(r)
100+
assert.NoError(t, err)
101+
assert.Equal(t, carResponseFormat, mediaType)
102+
103+
params, err := getCarParams(r, formatParams)
104+
assert.NoError(t, err)
105+
require.Equal(t, test.order, params.Order)
106+
107+
if test.duplicates == nil {
108+
require.Nil(t, params.Duplicates)
109+
} else {
110+
require.Equal(t, *test.duplicates, *params.Duplicates)
111+
}
112+
}
113+
})
76114
}
77115

78116
func TestGetCarEtag(t *testing.T) {

0 commit comments

Comments
 (0)