@@ -2,6 +2,7 @@ package gateway
2
2
3
3
import (
4
4
"context"
5
+ "encoding/binary"
5
6
"fmt"
6
7
"io"
7
8
"net/http"
@@ -224,31 +225,43 @@ func getCarRootCidAndLastSegment(imPath path.ImmutablePath) (cid.Cid, string, er
224
225
}
225
226
226
227
func getCarEtag (imPath path.ImmutablePath , params CarParams , rootCid cid.Cid ) string {
227
- data := imPath .String ()
228
+ h := xxhash .New ()
229
+ h .WriteString (imPath .String ())
230
+ // be careful with hashes here, we need boundries and per entry salt, we don't want a request that has:
231
+ // - scope = dfs
232
+ // and:
233
+ // - order = dfs
234
+ // to result in the same hash because if we just do hash(scope + order) they would both yield hash("dfs").
228
235
if params .Scope != DagScopeAll {
229
- data += string (params .Scope )
236
+ h .WriteString ("\x00 scope=" )
237
+ h .WriteString (string (params .Scope ))
230
238
}
231
239
232
240
// 'order' from IPIP-412 impact Etag only if set to something else
233
241
// than DFS (which is the implicit default)
234
242
if params .Order != DagOrderDFS {
235
- data += string (params .Order )
243
+ h .WriteString ("\x00 order=" )
244
+ h .WriteString (string (params .Order ))
236
245
}
237
246
238
247
// 'dups' from IPIP-412 impact Etag only if 'y'
239
- if dups := params .Duplicates . String () ; dups == "y" {
240
- data += dups
248
+ if dups := params .Duplicates ; dups == DuplicateBlocksIncluded {
249
+ h . WriteString ( " \x00 dups=y" )
241
250
}
242
251
243
252
if params .Range != nil {
244
253
if params .Range .From != 0 || params .Range .To != nil {
245
- data += strconv .FormatInt (params .Range .From , 10 )
254
+ h .WriteString ("\x00 range=" )
255
+ var b [8 ]byte
256
+ binary .LittleEndian .PutUint64 (b [:], uint64 (params .Range .From ))
257
+ h .Write (b [:])
246
258
if params .Range .To != nil {
247
- data += strconv .FormatInt (* params .Range .To , 10 )
259
+ binary .LittleEndian .PutUint64 (b [:], uint64 (* params .Range .To ))
260
+ h .Write (b [:])
248
261
}
249
262
}
250
263
}
251
264
252
- suffix := strconv .FormatUint (xxhash .Sum64 ([] byte ( data ) ), 32 )
265
+ suffix := strconv .FormatUint (h .Sum64 (), 32 )
253
266
return `W/"` + rootCid .String () + ".car." + suffix + `"`
254
267
}
0 commit comments