Skip to content
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

API._streaming_download() does not handle HTTP 416 Range Not Satisfiable errors #2232

Open
cfm opened this issue Sep 17, 2024 · 3 comments
Open
Assignees
Labels
bug Something isn't working sdk
Milestone

Comments

@cfm
Copy link
Member

cfm commented Sep 17, 2024

Description

API._streaming_download() chokes on HTTP 416 Range Not Satisfiable errors, because the JSON error object may be received in the first chunk of any request, including any retry, not only at the beginning of the accumulated response.

Steps to Reproduce

--- a/client/securedrop_client/sdk/__init__.py
+++ b/client/securedrop_client/sdk/__init__.py
@@ -153,7 +153,7 @@ class API:
             try:
                 # Update the range request if we're retrying
                 if retry > 0:
-                    data["headers"]["Range"] = f"bytes={bytes_written}-"
+                    data["headers"]["Range"] = f"bytes={bytes_written}-{bytes_written-1}"
                     logger.debug(f"Retry {retry}, range: {bytes_written}-")
 
                 # Serialize the data to send

Expected Behavior

The SDK handles the error gracefully.

Actual Behavior

        filepath = os.path.join(path, submission.filename)
>       Path(filepath).write_bytes(response.contents)
E       AttributeError: 'NoneType' object has no attribute 'contents'

securedrop_client/sdk/__init__.py:699: AttributeError
@cfm cfm added bug Something isn't working sdk labels Sep 17, 2024
@cfm cfm self-assigned this Sep 17, 2024
@cfm cfm changed the title SDK does not handle HTTP 416 Range Not Satisfiable errors API._streaming_download() does not handle HTTP 416 Range Not Satisfiable errors Sep 17, 2024
@legoktm
Copy link
Member

legoktm commented Sep 17, 2024

Nice catch. Is this just applicable to 416 or could this be literally any error if e.g. the server returns a 504?

Ideally this would've been a type error caught by mypy...

@cfm
Copy link
Member Author

cfm commented Sep 17, 2024

Yes, you're right: any retry-level error fails this way, and we don't handle HTTP 416 anywhere.

I was going to ask you about mocking Popen.stdin for the purpose of mangling a Range header to get a real HTTP 416 cassette, but I think I'll give pytest-subprocess a try first.

@cfm cfm added this to the 0.14.0 milestone Oct 17, 2024
@cfm
Copy link
Member Author

cfm commented Oct 17, 2024

Clarifying from backlog-pruning: I'd like to finish this next week for v0.14. Otherwise we should defer it to v0.15 or a v0.14.x.

@zenmonkeykstop zenmonkeykstop modified the milestones: 0.14.0, 0.15.0 Nov 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working sdk
Projects
Status: In Progress
Development

No branches or pull requests

3 participants