1818
1919using System . Collections . Generic ;
2020using System . IO ;
21+ using System . IO . Pipelines ;
2122using System . Linq ;
2223using System . Net ;
2324using System . Threading . Tasks ;
@@ -35,6 +36,159 @@ namespace Grpc.AspNetCore.FunctionalTests.Server
3536 [ TestFixture ]
3637 public class CompressionTests : FunctionalTestBase
3738 {
39+ [ Test ]
40+ public async Task SendCompressedMessage_UnaryEnabledInCallWithInvalidSetting_UncompressedMessageReturned ( )
41+ {
42+ async Task < HelloReply > UnaryEnableCompression ( HelloRequest request , ServerCallContext context )
43+ {
44+ var headers = new Metadata { new Metadata . Entry ( "grpc-internal-encoding-request" , "PURPLE_MONKEY_DISHWASHER" ) } ;
45+ await context . WriteResponseHeadersAsync ( headers ) ;
46+
47+ return new HelloReply { Message = "Hello " + request . Name } ;
48+ }
49+
50+ // Arrange
51+ var method = Fixture . DynamicGrpc . AddUnaryMethod < HelloRequest , HelloReply > ( UnaryEnableCompression ) ;
52+
53+ var ms = new MemoryStream ( ) ;
54+ MessageHelpers . WriteMessage ( ms , new HelloRequest
55+ {
56+ Name = "World"
57+ } ) ;
58+
59+ var httpRequest = GrpcHttpHelper . Create ( method . FullName ) ;
60+ httpRequest . Content = new PushStreamContent (
61+ async s =>
62+ {
63+ await s . WriteAsync ( ms . ToArray ( ) ) . AsTask ( ) . DefaultTimeout ( ) ;
64+ await s . FlushAsync ( ) . DefaultTimeout ( ) ;
65+ } ) ;
66+
67+ // Act
68+ var responseTask = Fixture . Client . SendAsync ( httpRequest ) ;
69+
70+ // Assert
71+ var response = await responseTask . DefaultTimeout ( ) ;
72+
73+ response . AssertIsSuccessfulGrpcRequest ( ) ;
74+
75+ // Because the client didn't send this encoding in accept, the server has sent the message uncompressed.
76+ Assert . AreEqual ( "PURPLE_MONKEY_DISHWASHER" , response . Headers . GetValues ( "grpc-encoding" ) . Single ( ) ) ;
77+
78+ var returnedMessageData = await response . Content . ReadAsByteArrayAsync ( ) . DefaultTimeout ( ) ;
79+ Assert . AreEqual ( 0 , returnedMessageData [ 0 ] ) ;
80+
81+ var responseMessage = MessageHelpers . AssertReadMessage < HelloReply > ( returnedMessageData ) ;
82+ Assert . AreEqual ( "Hello World" , responseMessage . Message ) ;
83+ response . AssertTrailerStatus ( ) ;
84+ }
85+
86+ [ Test ]
87+ public async Task SendCompressedMessage_UnaryEnabledInCall_CompressedMessageReturned ( )
88+ {
89+ async Task < HelloReply > UnaryEnableCompression ( HelloRequest request , ServerCallContext context )
90+ {
91+ var headers = new Metadata { new Metadata . Entry ( "grpc-internal-encoding-request" , "gzip" ) } ;
92+ await context . WriteResponseHeadersAsync ( headers ) ;
93+
94+ return new HelloReply { Message = "Hello " + request . Name } ;
95+ }
96+
97+ // Arrange
98+ var method = Fixture . DynamicGrpc . AddUnaryMethod < HelloRequest , HelloReply > ( UnaryEnableCompression ) ;
99+
100+ var ms = new MemoryStream ( ) ;
101+ MessageHelpers . WriteMessage ( ms , new HelloRequest
102+ {
103+ Name = "World"
104+ } ) ;
105+
106+ var httpRequest = GrpcHttpHelper . Create ( method . FullName ) ;
107+ httpRequest . Content = new PushStreamContent (
108+ async s =>
109+ {
110+ await s . WriteAsync ( ms . ToArray ( ) ) . AsTask ( ) . DefaultTimeout ( ) ;
111+ await s . FlushAsync ( ) . DefaultTimeout ( ) ;
112+ } ) ;
113+
114+ // Act
115+ var responseTask = Fixture . Client . SendAsync ( httpRequest ) ;
116+
117+ // Assert
118+ var response = await responseTask . DefaultTimeout ( ) ;
119+
120+ response . AssertIsSuccessfulGrpcRequest ( ) ;
121+
122+ Assert . AreEqual ( "gzip" , response . Headers . GetValues ( "grpc-encoding" ) . Single ( ) ) ;
123+
124+ var returnedMessageData = await response . Content . ReadAsByteArrayAsync ( ) . DefaultTimeout ( ) ;
125+ Assert . AreEqual ( 1 , returnedMessageData [ 0 ] ) ;
126+
127+ var responseMessage = MessageHelpers . AssertReadMessage < HelloReply > ( returnedMessageData , "gzip" ) ;
128+ Assert . AreEqual ( "Hello World" , responseMessage . Message ) ;
129+ response . AssertTrailerStatus ( ) ;
130+ }
131+
132+ [ Test ]
133+ public async Task SendCompressedMessage_ServerStreamingEnabledInCall_CompressedMessageReturned ( )
134+ {
135+ async Task ServerStreamingEnableCompression ( HelloRequest request , IServerStreamWriter < HelloReply > responseStream , ServerCallContext context )
136+ {
137+ var headers = new Metadata { new Metadata . Entry ( "grpc-internal-encoding-request" , "gzip" ) } ;
138+ await context . WriteResponseHeadersAsync ( headers ) ;
139+
140+ await responseStream . WriteAsync ( new HelloReply { Message = "Hello 1" } ) ;
141+
142+ responseStream . WriteOptions = new WriteOptions ( WriteFlags . NoCompress ) ;
143+ await responseStream . WriteAsync ( new HelloReply { Message = "Hello 2" } ) ;
144+ }
145+
146+ // Arrange
147+ var method = Fixture . DynamicGrpc . AddServerStreamingMethod < HelloRequest , HelloReply > ( ServerStreamingEnableCompression ) ;
148+
149+ var ms = new MemoryStream ( ) ;
150+ MessageHelpers . WriteMessage ( ms , new HelloRequest
151+ {
152+ Name = "World"
153+ } ) ;
154+
155+ var httpRequest = GrpcHttpHelper . Create ( method . FullName ) ;
156+ httpRequest . Content = new PushStreamContent (
157+ async s =>
158+ {
159+ await s . WriteAsync ( ms . ToArray ( ) ) . AsTask ( ) . DefaultTimeout ( ) ;
160+ await s . FlushAsync ( ) . DefaultTimeout ( ) ;
161+ } ) ;
162+
163+ // Act
164+ var responseTask = Fixture . Client . SendAsync ( httpRequest ) ;
165+
166+ // Assert
167+ var response = await responseTask . DefaultTimeout ( ) ;
168+
169+ response . AssertIsSuccessfulGrpcRequest ( ) ;
170+
171+ Assert . AreEqual ( "gzip" , response . Headers . GetValues ( "grpc-encoding" ) . Single ( ) ) ;
172+
173+ var responseStream = await response . Content . ReadAsStreamAsync ( ) . DefaultTimeout ( ) ;
174+ var pipeReader = PipeReader . Create ( responseStream ) ;
175+
176+ ReadResult readResult ;
177+
178+ readResult = await pipeReader . ReadAsync ( ) ;
179+ Assert . AreEqual ( 1 , readResult . Buffer . FirstSpan [ 0 ] ) ; // Message is compressed
180+ var greeting1 = await MessageHelpers . AssertReadStreamMessageAsync < HelloReply > ( pipeReader , "gzip" ) . DefaultTimeout ( ) ;
181+ Assert . AreEqual ( $ "Hello 1", greeting1 . Message ) ;
182+
183+ readResult = await pipeReader . ReadAsync ( ) ;
184+ Assert . AreEqual ( 0 , readResult . Buffer . FirstSpan [ 0 ] ) ; // Message is uncompressed
185+ var greeting2 = await MessageHelpers . AssertReadStreamMessageAsync < HelloReply > ( pipeReader , "gzip" ) . DefaultTimeout ( ) ;
186+ Assert . AreEqual ( $ "Hello 2", greeting2 . Message ) ;
187+
188+ var finishedTask = MessageHelpers . AssertReadStreamMessageAsync < HelloReply > ( pipeReader ) ;
189+ Assert . IsNull ( await finishedTask . DefaultTimeout ( ) ) ;
190+ }
191+
38192 [ Test ]
39193 public async Task SendCompressedMessage_ServiceHasNoCompressionConfigured_ResponseIdentityEncoding ( )
40194 {
0 commit comments