Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ namespace Microsoft.Graph
using System.Threading.Tasks;
using System.Net.Http.Headers;
using System.IO.Compression;
using System.Collections.Generic;

/// <summary>
/// A <see cref="DelegatingHandler"/> implementation that handles compression.
Expand Down Expand Up @@ -53,7 +54,13 @@ protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage
// Decompress response content when Content-Encoding: gzip header is present.
if (ShouldDecompressContent(response))
{
response.Content = new StreamContent(new GZipStream(await response.Content.ReadAsStreamAsync(), CompressionMode.Decompress));
StreamContent streamContent = new StreamContent(new GZipStream(await response.Content.ReadAsStreamAsync(), CompressionMode.Decompress));
// Copy Content Headers to the destination stream content
foreach (var httpContentHeader in response.Content.Headers)
{
streamContent.Headers.TryAddWithoutValidation(httpContentHeader.Key, httpContentHeader.Value);
}
response.Content = streamContent;
}

return response;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ namespace Microsoft.Graph.DotnetCore.Core.Test.Requests.Middleware
using System.Threading.Tasks;
using System.Threading;
using System.Net.Http.Headers;
using System.Linq;
using System.Collections.Generic;
using Xunit.Abstractions;

public class CompressionHandlerTests : IDisposable
{
Expand Down Expand Up @@ -94,5 +97,55 @@ public async Task CompressionHandler_should_not_decompress_response_without_cont
Assert.Same(httpRequestMessage, compressedResponse.RequestMessage);
Assert.NotEqual(stringToCompress, responseContentString);
}

/// <summary>
/// Compression Handler should keep content headers after decompression
/// </summary>
/// <returns></returns>
[Fact]
public async Task CompressionHandler_should_keep_headers_after_decompression()
{
HttpRequestMessage httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, "http://example.org/foo");

string stringToCompress = "Microsoft Graph";
StringContent stringContent = new StringContent(stringToCompress);
stringContent.Headers.ContentType = new MediaTypeHeaderValue(CoreConstants.MimeTypeNames.Application.Json);

HttpResponseMessage httpResponse = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new MockCompressedContent(stringContent)
};
httpResponse.Content.Headers.ContentEncoding.Add(CoreConstants.Encoding.GZip);
httpResponse.Headers.CacheControl = new CacheControlHeaderValue { Private = true };
// Examples of Custom Headers returned by Microsoft Graph
httpResponse.Headers.Add(CoreConstants.Headers.ClientRequestId, Guid.NewGuid().ToString());
httpResponse.Headers.Add("request-id", Guid.NewGuid().ToString());
httpResponse.Headers.Add("OData-Version", "4.0");

this.testHttpMessageHandler.SetHttpResponse(httpResponse);

HttpResponseMessage compressedResponse = await this.invoker.SendAsync(httpRequestMessage, new CancellationToken());
string responseContentString = await compressedResponse.Content.ReadAsStringAsync();

// Ensure that headers in the compressedResponse are the same as in the original, expected response.
Assert.NotEmpty(compressedResponse.Headers);
Assert.NotEmpty(compressedResponse.Content.Headers);
Assert.Equal(httpResponse.Headers, compressedResponse.Headers, new HttpHeaderComparer());
Assert.Equal(httpResponse.Content.Headers, compressedResponse.Content.Headers, new HttpHeaderComparer());
}

internal class HttpHeaderComparer : IEqualityComparer<KeyValuePair<string, IEnumerable<string>>>
{
public bool Equals(KeyValuePair<string, IEnumerable<string>> x, KeyValuePair<string, IEnumerable<string>> y)
{
// For each key, the collection of header values should be equal.
return x.Key == y.Key && x.Value.SequenceEqual(y.Value);
}

public int GetHashCode(KeyValuePair<string, IEnumerable<string>> obj)
{
return obj.Key.GetHashCode();
}
}
}
}