-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Description
- Package Name: azure-storage-blob
- Package Version: 12.8.1
- Operating System: debian 10
- Python Version: 3.7.3
Describe the bug
When passing a socket (e.g. requests raw response) to BlobClient.upload_blob(), upload_blob incorrectly infers a 0 length and does not read any data out of the socket to upload.
The problem appears to be in request_handlers.py def get_length(data). The function calls fstat(fileno).st_size in a try block, but st_size does not seem to have a valid meaning for socket fds, see https://linux.die.net/man/2/fstat. In my environment this returns zero but does not throw an OSError, so get_length erroneously returns 0.
To Reproduce
This minimal code will upload 0 bytes:
import requests
import os
from azure.storage.blob import BlobClient
blob_client = BlobClient.from_connection_string(
conn_str=os.environ["BLOB_CONN_STR"],
container_name="blobtest",
blob_name="test.iso")
with requests.get('https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/debian-10.10.0-amd64-netinst.iso', stream=True) as resp:
blob_client.upload_blob(resp.raw, overwrite=True)
Expected behavior
The above code should upload the full iso in chunks.
Additional context
I believe the correct way to handle this is to check if the fd is a regular file or symlink before returning st_size, and if it is not a regular file fall through the rest of the get_length call which ends up returning None which results in the correct behaviour.
I have a pull request I will attach here shortly.