-
Notifications
You must be signed in to change notification settings - Fork 344
Added the ability to upload files larger than 4MB #2180
Changes from 5 commits
c8d31c4
8ee6979
33da66f
ee23d6b
40bec88
474d53f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,7 +28,7 @@ static void PrintUsage() | |
static void Main(string[] args) | ||
{ | ||
Log.Listeners.Add(new ConsoleTraceListener()); | ||
Log.Switch.Level = SourceLevels.Information; | ||
Log.Switch.Level = SourceLevels.Error; | ||
|
||
var options = new CommandLine(args); | ||
ReadOnlySpan<char> source = options.GetSpan("/Source:"); | ||
|
@@ -197,14 +197,27 @@ static async ValueTask<bool> CopyLocalFileToStorageFile(StorageClient client, st | |
{ | ||
using (var bytes = new FileStream(localFilePath, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, true)) | ||
{ | ||
var putRequest = new PutRangeRequest(storagePath, bytes); | ||
response = await client.SendRequest(putRequest).ConfigureAwait(false); | ||
if (response.StatusCode == 201) return true; | ||
long bytesLeft = bytes.Length; | ||
long index = 0; | ||
int length = 1024 * 1024 * 4; | ||
while (true) | ||
{ | ||
if (bytesLeft < length) length = (int)bytesLeft; | ||
var putRequest = new PutRangeRequest(storagePath, bytes, index, length); | ||
response = await client.SendRequest(putRequest).ConfigureAwait(false); | ||
if (response.StatusCode != 201) | ||
{ | ||
Log.TraceEvent(TraceEventType.Error, 0, "Response Status Code {0}", response.StatusCode); | ||
return false; | ||
} | ||
index += length; | ||
bytesLeft -= length; | ||
if (bytesLeft == 0) break; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: why not use this as the while loop condition, especially since we do this check at the end of the loop anyway? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. will do |
||
} | ||
} | ||
} | ||
|
||
Log.TraceEvent(TraceEventType.Error, 0, "Response Status Code {0}", response.StatusCode); | ||
return false; | ||
return true; | ||
} | ||
|
||
static async ValueTask<bool> CopyStorageFileToLocalFile(StorageClient client, string storagePath, string localFilePath) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -102,23 +102,30 @@ public static ReadOnlyMemory<byte> AsString(Http.Method verb) | |
|
||
public struct PutRangeRequest : IStorageRequest | ||
{ | ||
public Stream FileContent { get; set; } // TODO (pri 3): should there be a way to write from file handle or PipeReader? | ||
public string FilePath { get; set; } | ||
Stream _fileContent; // TODO (pri 3): should there be a way to write from file handle or PipeReader? | ||
string _filePath; | ||
long _offset; | ||
int _length; | ||
|
||
// TODO (pri 3): I dont like how the client property is a public API | ||
public StorageClient Client { get; set; } | ||
|
||
public PutRangeRequest(string filePath, Stream fileContent) | ||
public PutRangeRequest(string filePath, Stream fileContent, long offset, int length) | ||
{ | ||
FilePath = filePath; | ||
FileContent = fileContent; | ||
if (offset < 0) throw new ArgumentOutOfRangeException(nameof(offset)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need to add checks for offset greater than _length? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. offset can be greater, equal, or less than length. It cannot be greater than fileContent.Length - _length. I will add the check. |
||
if (length < 1) throw new ArgumentOutOfRangeException(nameof(length)); | ||
|
||
_filePath = filePath; | ||
_fileContent = fileContent; | ||
Client = null; | ||
_offset = offset; | ||
_length = length; | ||
} | ||
|
||
public long ContentLength => FileContent.Length; | ||
public long ContentLength => _length; | ||
// TODO (pri 2): would be nice to elimnate these allocations | ||
public string RequestPath => FilePath + "?comp=range"; | ||
public string CanonicalizedResource => FilePath + "\ncomp:range"; | ||
public string RequestPath => _filePath + "?comp=range"; | ||
public string CanonicalizedResource => _filePath + "\ncomp:range"; | ||
public bool ConsumeBody => true; | ||
|
||
// TODO (pri 3): can this be an extension method? All implementations are the same. | ||
|
@@ -131,14 +138,21 @@ class Writer : StorageRequestWriter<PutRangeRequest> | |
public override Http.Method Verb => Http.Method.Put; | ||
|
||
protected override async Task WriteBody(PipeWriter writer, PutRangeRequest arguments) | ||
=> await writer.WriteAsync(arguments.FileContent); | ||
{ | ||
var stream = arguments._fileContent; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: use of var |
||
stream.Seek(arguments._offset, SeekOrigin.Begin); | ||
await writer.WriteAsync(stream, arguments._length); | ||
} | ||
|
||
protected override void WriteXmsHeaders(ref BufferWriter writer, ref PutRangeRequest arguments) | ||
{ | ||
long size = arguments.FileContent.Length; | ||
long size = arguments._fileContent.Length; | ||
writer.WriteHeader("x-ms-date", Time, 'R'); | ||
// TODO (pri 3): this allocation should be eliminated | ||
writer.WriteHeader("x-ms-range", $"bytes=0-{size - 1}"); | ||
|
||
var start = arguments._offset; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: use of var There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. will fix |
||
var end = start + arguments._length - 1; | ||
writer.WriteHeader("x-ms-range", $"bytes={start}-{end}"); | ||
writer.WriteHeader("x-ms-version", "2017-04-17"); | ||
writer.WriteHeader("x-ms-write", "update"); | ||
} | ||
|
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.
nit: formatting, add space