Skip to content

Commit 4770a65

Browse files
committed
avoid chunked transfers in putBlob when possible
This is to avoid Downloads.jl from initiating chunked transfer when a file IOStream is supplied to `putBlob`. In 0.4.0, we have switched to using Downloads.jl as the HTTP client instead of HTTP.jl. This issue happens because Downloads.jl is not able to determine the content length when an IO instance is provided to upload data from, and switches to using a chunked transfer encoding. And the putBlob Azure API endpoint does not support chunked transfers. The solution is to not use chunked transfers for putBlob. This PR (JuliaLang/Downloads.jl#167) to Downloads.jl would let it also look into the content-length header that we supply to determine the data size to expect in the IO instance we pass. But until the Downloads.jl PR is merged (and backported), we need this change in Azure.jl to detect IO handles that point to locally mappable files and supply the correct content length and `IOBuffer` of memory mapped file contents as data to upload instead. fixes: #25
1 parent 4fd0112 commit 4770a65

File tree

3 files changed

+30
-1
lines changed

3 files changed

+30
-1
lines changed

Project.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
1010
Downloads = "f43a241f-c20a-4ad4-852c-f6b1247861c6"
1111
JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
1212
MbedTLS = "739be429-bea8-5141-9913-cc70e7f3736d"
13+
Mmap = "a63ad114-7e13-5084-954f-fe012c677804"
1314
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
1415
Swagger = "2d69052b-6a58-5cd9-a030-a48559c324ac"
1516
XMLDict = "228000da-037f-5747-90a9-8195ccbf91a5"

src/StorageServices/StorageServices.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ using URIs
88
using MbedTLS
99
using Dates
1010
using Base64
11+
using Mmap
1112

1213
include("common.jl")
1314
include("blob.jl")

src/StorageServices/blob.jl

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,19 @@ end
107107

108108
const valid_blob_types = ("BlockBlob", "PageBlob", "AppendBlob")
109109

110+
function check_mappable_file(io)
111+
if isa(io, IOStream)
112+
try
113+
fsz = filesize(io)
114+
data = Mmap.mmap(io, Vector{UInt8}, fsz)
115+
return IOBuffer(data), fsz
116+
catch
117+
return io, nothing
118+
end
119+
end
120+
return io, nothing
121+
end
122+
110123
"""
111124
Creates a new block, page, or append blob, or updates the content of an existing block blob.
112125
@@ -164,8 +177,22 @@ function putBlob(ctx, subscription_id::String, resource_group_name::String, uri:
164177
content_length = length(codeunits(block_blob_contents))
165178
elseif isa(block_blob_contents, Vector{UInt8})
166179
content_length = length(block_blob_contents)
180+
elseif isa(block_blob_contents, IOBuffer)
181+
content_length = block_blob_contents.size
182+
else
183+
wrapped_contents, content_length = check_mappable_file(block_blob_contents)
184+
if content_length === nothing
185+
error("content_length must be specified for blob contents of type $(typeof(block_blob_contents))")
186+
else
187+
block_blob_contents = wrapped_contents
188+
end
189+
end
190+
elseif isa(block_blob_contents, IOStream)
191+
wrapped_contents, wrapped_content_length = check_mappable_file(block_blob_contents)
192+
if content_length !== wrapped_content_length
193+
error("content_length must match the length of the stream")
167194
else
168-
error("content_length must be specified for blob contents of type $(typeof(block_blob_contents))")
195+
block_blob_contents = wrapped_contents
169196
end
170197
end
171198
end

0 commit comments

Comments
 (0)