-
-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(subdomain-gw): curl on localhost (Option A: HTTP301+payload) #6982
Conversation
This changes the way we return CID payload in body of HTTP 301 response. We no longer get superfluous response.WriteHeader call, as it is executed only once, in http.ServeContent() Gist: If Location header is present in ResponseWriter's Header map, we ensure http.ServeContent() returns HTTP 301 Context: #6982 License: MIT Signed-off-by: Marcin Rataj <lidel@lidel.org>
core/corehttp/gateway_handler.go
Outdated
func (sw *statusResponseWriter) WriteHeader(code int) { | ||
// Check if we need to adjust Status Code to account for scheduled redirect | ||
// This enables us to return HTTP 301 | ||
// for subdomain redirect in web browsers while also returning body for cli | ||
// tools which does not follow redirects by default (curl, wget). | ||
redirect := sw.w.Header().Get("Location") | ||
if redirect != "" { | ||
code = http.StatusMovedPermanently | ||
} | ||
sw.w.WriteHeader(code) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I came up with this surgical wrapper because status code is hardcoded to 200
inside http.ServeContent()
.
Is this idiomatic/acceptable in go? Not sure if we can make this change more elegant while keeping is small without duplicating http.ServeContent
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wrapping is normal. Swapping the code like this is weird but fine.
core/corehttp/gateway_handler.go
Outdated
func (sw *statusResponseWriter) WriteHeader(code int) { | ||
// Check if we need to adjust Status Code to account for scheduled redirect | ||
// This enables us to return HTTP 301 | ||
// for subdomain redirect in web browsers while also returning body for cli | ||
// tools which does not follow redirects by default (curl, wget). | ||
redirect := sw.w.Header().Get("Location") | ||
if redirect != "" { | ||
code = http.StatusMovedPermanently | ||
} | ||
sw.w.WriteHeader(code) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wrapping is normal. Swapping the code like this is weird but fine.
When request is sent to http://localhost:8080/ipfs/$cid response has HTTP 301 status code and "Location" header with redirect destination at $cid.ipfs.localhost:8080 Redirect is followed by browsersi, but not by commandline tools. Status 301 is ignored by curl in default mode: it will print response and won't follow redirect, user needs to add -L for that. To fix curl, we return correct payload in body of HTTP 301 response, but set Clear-Site-Data header to ensure Origin sandbox can't be abused. This requires a surgical workaround: If Location header is present in ResponseWriter's Header map, we ensure http.ServeContent() returns HTTP 301 Context: #6982 License: MIT Signed-off-by: Marcin Rataj <lidel@lidel.org>
e705f02
to
9fe44b7
Compare
When request is sent to http://localhost:8080/ipfs/$cid response has HTTP 301 status code and "Location" header with redirect destination at $cid.ipfs.localhost:8080 Redirect is followed by browsersi, but not by commandline tools. Status 301 is ignored by curl in default mode: it will print response and won't follow redirect, user needs to add -L for that. To fix curl, we return correct payload in body of HTTP 301 response, but set Clear-Site-Data header to ensure Origin sandbox can't be abused. This requires a surgical workaround: If Location header is present in ResponseWriter's Header map, we ensure http.ServeContent() returns HTTP 301 Context: #6982 License: MIT Signed-off-by: Marcin Rataj <lidel@lidel.org>
When request is sent to http://localhost:8080/ipfs/$cid response has HTTP 301 status code and "Location" header with redirect destination at $cid.ipfs.localhost:8080 Redirect is followed by browsersi, but not by commandline tools. Status 301 is ignored by curl in default mode: it will print response and won't follow redirect, user needs to add -L for that. To fix curl, we return correct payload in body of HTTP 301 response, but set Clear-Site-Data header to ensure Origin sandbox can't be abused. This requires a surgical workaround: If Location header is present in ResponseWriter's Header map, we ensure http.ServeContent() returns HTTP 301 Context: #6982 License: MIT Signed-off-by: Marcin Rataj <lidel@lidel.org>
When request is sent to http://localhost:8080/ipfs/$cid response has HTTP 301 status code and "Location" header with redirect destination at $cid.ipfs.localhost:8080 Redirect is followed by browsersi, but not by commandline tools. Status 301 is ignored by curl in default mode: it will print response and won't follow redirect, user needs to add -L for that. To fix curl, we return correct payload in body of HTTP 301 response, but set Clear-Site-Data header to ensure Origin sandbox can't be abused. This requires a surgical workaround: If Location header is present in ResponseWriter's Header map, we ensure http.ServeContent() returns HTTP 301 Context: ipfs#6982 License: MIT Signed-off-by: Marcin Rataj <lidel@lidel.org>
When request is sent to http://localhost:8080/ipfs/$cid response has HTTP 301 status code and "Location" header with redirect destination at $cid.ipfs.localhost:8080 Redirect is followed by browsersi, but not by commandline tools. Status 301 is ignored by curl in default mode: it will print response and won't follow redirect, user needs to add -L for that. To fix curl, we return correct payload in body of HTTP 301 response, but set Clear-Site-Data header to ensure Origin sandbox can't be abused. This requires a surgical workaround: If Location header is present in ResponseWriter's Header map, we ensure http.ServeContent() returns HTTP 301 Context: ipfs#6982 License: MIT Signed-off-by: Marcin Rataj <lidel@lidel.org>
When request is sent to http://localhost:8080/ipfs/$cid response has HTTP 301 status code and "Location" header with redirect destination at $cid.ipfs.localhost:8080 Redirect is followed by browsersi, but not by commandline tools. Status 301 is ignored by curl in default mode: it will print response and won't follow redirect, user needs to add -L for that. To fix curl, we return correct payload in body of HTTP 301 response, but set Clear-Site-Data header to ensure Origin sandbox can't be abused. This requires a surgical workaround: If Location header is present in ResponseWriter's Header map, we ensure http.ServeContent() returns HTTP 301 Context: ipfs#6982 License: MIT Signed-off-by: Marcin Rataj <lidel@lidel.org>
When request is sent to http://localhost:8080/ipfs/$cid response has HTTP 301 status code and "Location" header with redirect destination at $cid.ipfs.localhost:8080 Redirect is followed by browsersi, but not by commandline tools. Status 301 is ignored by curl in default mode: it will print response and won't follow redirect, user needs to add -L for that. To fix curl, we return correct payload in body of HTTP 301 response, but set Clear-Site-Data header to ensure Origin sandbox can't be abused. This requires a surgical workaround: If Location header is present in ResponseWriter's Header map, we ensure http.ServeContent() returns HTTP 301 Context: ipfs#6982 License: MIT Signed-off-by: Marcin Rataj <lidel@lidel.org>
When request is sent to http://localhost:8080/ipfs/$cid response has HTTP 301 status code and "Location" header with redirect destination at $cid.ipfs.localhost:8080 Redirect is followed by browsersi, but not by commandline tools. Status 301 is ignored by curl in default mode: it will print response and won't follow redirect, user needs to add -L for that. To fix curl, we return correct payload in body of HTTP 301 response, but set Clear-Site-Data header to ensure Origin sandbox can't be abused. This requires a surgical workaround: If Location header is present in ResponseWriter's Header map, we ensure http.ServeContent() returns HTTP 301 Context: ipfs/kubo#6982 License: MIT Signed-off-by: Marcin Rataj <lidel@lidel.org> This commit was moved from ipfs/kubo@f9567a0
TL;DR
Return payload with HTTP 301 response:
Location
header, so there should not be any bandwidth wastedClear-Site-Data
header with such responseDescription
When request is sent to
http://localhost:8080/ipfs/$cid
HTTP 301 status code with "Location" header redirect client to subdomain destination at$cid.ipfs.localhost:8080
Redirects are not followed by
curl
in default mode, but will be respected by user agents that follow redirects by default, namely web browsers.To fix curl, we return correct payload in body of HTTP 301 response, but set
Clear-Site-Data
header to ensure Origin sandbox can't be abused.Caveat
This comes with side effect of prometeus client making redundantWriteHeader
call, which produces warning in logs:I attempted to fix prometeus and avoid redundant call in https://github.com/prometheus/client_golang/pull/724 but am not sure if that approach will be approved upstream.Update:
superfluous response.WriteHeader call
fixed in e705f02