Conversation
Running HEAD on a pre-signed S3 URI gives a 403 response because the URI is signed for GET, so accept the response on pre-signed URIs and fall back into downloading the entire file instead. If the 403 was because the file doesn't exist rather than a signature error, the full download will signal the error to the user. Fixes Open-EO#939
| # If the 403 is because the file doesn't exist rather than a signature | ||
| # issue, the full download will get the 403 and signal an error | ||
| # to the user. | ||
| if "Signature" in parameters or "X-Amz-Signature" in parameters: |
There was a problem hiding this comment.
As noted in #940, I'm not a big fan of sprinkling all these S3/Ceph implementation details here, this function should ideally be agnostic of these things.
Thinking a bit more about this: wouldn't the whole problem be solved by just dropping stream=True from the original self.head(url, call? I'm not sure why that toggle was enabled actually (originally from 8082083 I think)
There was a problem hiding this comment.
I don't know why stream=True is enabled for a HEAD call, but just dropping the stream parameter without any other code changes still gives a 403 response for me against some recent version of RadosGW in Ceph.
Do you prefer to accept 403 on the HEAD call for all URIs, rather than singling out the URIs we are interested in? The blast radius of that feels significantly bigger than doing it just the pre-signed URIs.
There was a problem hiding this comment.
I think there is still confusion about the exact problem we're talking here.
in #939 (comment) you say
downloading files from open-EO jobs fails with our backend
and I interpreted that "fails" as getting exceptions, triggered from the .head() call at
openeo-python-client/openeo/rest/_connection.py
Lines 308 to 309 in f4ab16c
But that code is actually already pretty defensive regarding non-2xx reponses and doesn't cause exceptions:
import requests
resp = requests.head(
"https://httpbin.org/status/403",
stream=True,
)
print(resp.ok, resp)just produces "False <Response [403]>", no exceptions.
Can you clarify (here, but maybe preferably at #939) what you actually mean with "downloading fails"?
There was a problem hiding this comment.
The user-side code isn't mine so I can't share that, but I've added some simplified code snippets along with a backtrace in #939.
Edit:
and I interpreted that "fails" as getting exceptions, triggered from the .head() call
Yes, this is what happens for me.
But that code is actually already pretty defensive regarding non-2xx reponses and doesn't cause exceptions:
Cut and paste error? I realize it's not requests.head() that is raising the exception, it's somewhere in the callstack for self.head() that is used in the code you linked.
Running HEAD on a pre-signed S3 URI
gives a 403 response because the URI
is signed for GET, so accept the response
on pre-signed URIs and fall back
into downloading the entire file
instead. If the 403 was because
the file doesn't exist rather than
a signature error, the full download
will signal the error to the user.
Fixes #939