From 956f72593be275a521a8c3f7a3ad772b8e077ac5 Mon Sep 17 00:00:00 2001 From: Jon Skeet Date: Wed, 11 May 2016 14:48:28 +0100 Subject: [PATCH] Allow a null content type for resumable uploads. This fixes issue #743. --- .../Apis/Upload/ResumableUploadTest.cs | 34 +++++++++++++++++-- .../Apis/[Media]/Upload/ResumableUpload.cs | 18 ++++++---- 2 files changed, 43 insertions(+), 9 deletions(-) diff --git a/Src/Support/GoogleApis.Tests/Apis/Upload/ResumableUploadTest.cs b/Src/Support/GoogleApis.Tests/Apis/Upload/ResumableUploadTest.cs index 1780587a54..233d739f74 100644 --- a/Src/Support/GoogleApis.Tests/Apis/Upload/ResumableUploadTest.cs +++ b/Src/Support/GoogleApis.Tests/Apis/Upload/ResumableUploadTest.cs @@ -173,6 +173,8 @@ private class SingleChunkMessageHandler : BaseMockMessageHandler /// Gets or sets the path parameters which should be part of the initialize request. public string PathParameters { get; set; } + public string ExpectedContentType { get; set; } = "text/plain"; + protected override Task SendAsyncCore(HttpRequestMessage request, CancellationToken cancellationToken) { @@ -191,8 +193,12 @@ protected override Task SendAsyncCore(HttpRequestMessage re } Assert.That(request.RequestUri.Query, Is.EqualTo("?uploadType=resumable" + QueryParameters)); - Assert.That(request.Headers.GetValues("X-Upload-Content-Type").First(), - Is.EqualTo("text/plain")); + // HttpRequestMessage doesn't make it terrible easy to get a header value speculatively... + string actualContentType = request.Headers + .Where(h => h.Key == "X-Upload-Content-Type") + .Select(h => h.Value.FirstOrDefault()) + .FirstOrDefault(); + Assert.That(actualContentType, Is.EqualTo(ExpectedContentType)); Assert.That(request.Headers.GetValues("X-Upload-Content-Length").First(), Is.EqualTo(StreamLength.ToString())); @@ -609,6 +615,30 @@ public void TestUploadSingleChunk() Assert.That(handler.Calls, Is.EqualTo(2)); } + [Test] + public void TestUploadNullContentType() + { + var stream = new MemoryStream(Encoding.UTF8.GetBytes(UploadTestData)); + var handler = new SingleChunkMessageHandler() + { + StreamLength = stream.Length, + ExpectedContentType = null + }; + using (var service = new MockClientService(new BaseClientService.Initializer() + { + HttpClientFactory = new MockHttpClientFactory(handler) + })) + { + + int chunkSize = UploadTestData.Length + 10; + var upload = new MockResumableUpload(service, "", "POST", stream, null, chunkSize); + // Chunk size is bigger than the data we are sending. + upload.Upload(); + } + + Assert.That(handler.Calls, Is.EqualTo(2)); + } + /// Tests uploading a single chunk. [Test] public void TestUploadSingleChunk_ExactChunkSize() diff --git a/Src/Support/GoogleApis/Apis/[Media]/Upload/ResumableUpload.cs b/Src/Support/GoogleApis/Apis/[Media]/Upload/ResumableUpload.cs index e5e8a2b5f4..3076845156 100644 --- a/Src/Support/GoogleApis/Apis/[Media]/Upload/ResumableUpload.cs +++ b/Src/Support/GoogleApis/Apis/[Media]/Upload/ResumableUpload.cs @@ -97,7 +97,9 @@ public class ResumableUpload /// The path for this media upload method. /// The HTTP method to start this upload. /// The stream containing the content to upload. - /// Content type of the content to be uploaded. + /// Content type of the content to be uploaded. Some services + /// may allow this to be null; others require a content type to be specified and will + /// fail when the upload is started if the value is null. /// /// Caller is responsible for maintaining the open until the upload is /// completed. @@ -106,11 +108,10 @@ public class ResumableUpload protected ResumableUpload(IClientService service, string path, string httpMethod, Stream contentStream, string contentType) { - service.ThrowIfNull("service"); - path.ThrowIfNull("path"); - httpMethod.ThrowIfNullOrEmpty("httpMethod"); - contentStream.ThrowIfNull("stream"); - contentType.ThrowIfNull("contentType"); + service.ThrowIfNull(nameof(service)); + path.ThrowIfNull(nameof(path)); + httpMethod.ThrowIfNullOrEmpty(nameof(httpMethod)); + contentStream.ThrowIfNull(nameof(contentStream)); this.Service = service; this.Path = path; @@ -731,7 +732,10 @@ private HttpRequestMessage CreateInitializeRequest() SetAllPropertyValues(builder); HttpRequestMessage request = builder.CreateRequest(); - request.Headers.Add(PayloadContentTypeHeader, ContentType); + if (ContentType != null) + { + request.Headers.Add(PayloadContentTypeHeader, ContentType); + } // if the length is unknown at the time of this request, omit "X-Upload-Content-Length" header if (StreamLength != UnknownSize)