mirror of
https://github.com/ipfs/kubo.git
synced 2025-06-29 09:34:03 +08:00
Merge pull request #3869 from Recmo/fix/gateway/3868-etag
gateway: use CID as an ETag strong validator
This commit is contained in:
@ -164,7 +164,22 @@ func (i *gatewayHandler) getOrHeadHandler(ctx context.Context, w http.ResponseWr
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
dr, err := i.api.Unixfs().Cat(ctx, parsedPath)
|
// Resolve path to the final DAG node for the ETag
|
||||||
|
resolvedPath, err := i.api.ResolvePath(ctx, parsedPath)
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
case coreiface.ErrOffline:
|
||||||
|
if !i.node.OnlineMode() {
|
||||||
|
webError(w, "ipfs resolve -r "+urlPath, err, http.StatusServiceUnavailable)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fallthrough
|
||||||
|
default:
|
||||||
|
webError(w, "ipfs resolve -r "+urlPath, err, http.StatusNotFound)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
dr, err := i.api.Unixfs().Cat(ctx, resolvedPath)
|
||||||
dir := false
|
dir := false
|
||||||
switch err {
|
switch err {
|
||||||
case nil:
|
case nil:
|
||||||
@ -172,18 +187,13 @@ func (i *gatewayHandler) getOrHeadHandler(ctx context.Context, w http.ResponseWr
|
|||||||
defer dr.Close()
|
defer dr.Close()
|
||||||
case coreiface.ErrIsDir:
|
case coreiface.ErrIsDir:
|
||||||
dir = true
|
dir = true
|
||||||
case coreiface.ErrOffline:
|
|
||||||
if !i.node.OnlineMode() {
|
|
||||||
webError(w, "ipfs cat "+urlPath, err, http.StatusServiceUnavailable)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
fallthrough
|
|
||||||
default:
|
default:
|
||||||
webError(w, "ipfs cat "+urlPath, err, http.StatusNotFound)
|
webError(w, "ipfs cat "+urlPath, err, http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
etag := gopath.Base(urlPath)
|
// Check etag send back to us
|
||||||
|
etag := "\"" + resolvedPath.Cid().String() + "\""
|
||||||
if r.Header.Get("If-None-Match") == etag {
|
if r.Header.Get("If-None-Match") == etag {
|
||||||
w.WriteHeader(http.StatusNotModified)
|
w.WriteHeader(http.StatusNotModified)
|
||||||
return
|
return
|
||||||
@ -191,6 +201,7 @@ func (i *gatewayHandler) getOrHeadHandler(ctx context.Context, w http.ResponseWr
|
|||||||
|
|
||||||
i.addUserHeaders(w) // ok, _now_ write user's headers.
|
i.addUserHeaders(w) // ok, _now_ write user's headers.
|
||||||
w.Header().Set("X-IPFS-Path", urlPath)
|
w.Header().Set("X-IPFS-Path", urlPath)
|
||||||
|
w.Header().Set("Etag", etag)
|
||||||
|
|
||||||
// set 'allowed' headers
|
// set 'allowed' headers
|
||||||
w.Header().Set("Access-Control-Allow-Headers", "X-Stream-Output, X-Chunked-Output")
|
w.Header().Set("Access-Control-Allow-Headers", "X-Stream-Output, X-Chunked-Output")
|
||||||
@ -202,8 +213,8 @@ func (i *gatewayHandler) getOrHeadHandler(ctx context.Context, w http.ResponseWr
|
|||||||
// and only if it's /ipfs!
|
// and only if it's /ipfs!
|
||||||
// TODO: break this out when we split /ipfs /ipns routes.
|
// TODO: break this out when we split /ipfs /ipns routes.
|
||||||
modtime := time.Now()
|
modtime := time.Now()
|
||||||
|
|
||||||
if strings.HasPrefix(urlPath, ipfsPathPrefix) && !dir {
|
if strings.HasPrefix(urlPath, ipfsPathPrefix) && !dir {
|
||||||
w.Header().Set("Etag", etag)
|
|
||||||
w.Header().Set("Cache-Control", "public, max-age=29030400, immutable")
|
w.Header().Set("Cache-Control", "public, max-age=29030400, immutable")
|
||||||
|
|
||||||
// set modtime to a really long time ago, since files are immutable and should stay cached
|
// set modtime to a really long time ago, since files are immutable and should stay cached
|
||||||
@ -216,7 +227,7 @@ func (i *gatewayHandler) getOrHeadHandler(ctx context.Context, w http.ResponseWr
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
links, err := i.api.Unixfs().Ls(ctx, parsedPath)
|
links, err := i.api.Unixfs().Ls(ctx, resolvedPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
internalWebError(w, err)
|
internalWebError(w, err)
|
||||||
return
|
return
|
||||||
|
@ -139,7 +139,7 @@ func TestGatewayGet(t *testing.T) {
|
|||||||
{"localhost:5001", "/", http.StatusNotFound, "404 page not found\n"},
|
{"localhost:5001", "/", http.StatusNotFound, "404 page not found\n"},
|
||||||
{"localhost:5001", "/" + k, http.StatusNotFound, "404 page not found\n"},
|
{"localhost:5001", "/" + k, http.StatusNotFound, "404 page not found\n"},
|
||||||
{"localhost:5001", "/ipfs/" + k, http.StatusOK, "fnord"},
|
{"localhost:5001", "/ipfs/" + k, http.StatusOK, "fnord"},
|
||||||
{"localhost:5001", "/ipns/nxdomain.example.com", http.StatusNotFound, "ipfs cat /ipns/nxdomain.example.com: " + namesys.ErrResolveFailed.Error() + "\n"},
|
{"localhost:5001", "/ipns/nxdomain.example.com", http.StatusNotFound, "ipfs resolve -r /ipns/nxdomain.example.com: " + namesys.ErrResolveFailed.Error() + "\n"},
|
||||||
{"localhost:5001", "/ipns/example.com", http.StatusOK, "fnord"},
|
{"localhost:5001", "/ipns/example.com", http.StatusOK, "fnord"},
|
||||||
{"example.com", "/", http.StatusOK, "fnord"},
|
{"example.com", "/", http.StatusOK, "fnord"},
|
||||||
} {
|
} {
|
||||||
|
Reference in New Issue
Block a user