mirror of
https://github.com/flutter/flutter
synced 2024-10-13 11:42:54 +00:00
Re-apply compressionState changes. (#34341)
This re-applies the changes that were made in #33697 and #33729, but which were reverted in #33792 and #33790, respectively due to the Dart SDK not having received the update within Google yet. The SDK has now rolled, so these changes can be re-applied. https://github.com/flutter/flutter/issues/32374 https://github.com/flutter/flutter/issues/33791
This commit is contained in:
parent
25c84001c4
commit
8163c0aebb
|
@ -43,10 +43,8 @@ typedef BytesReceivedCallback = void Function(int cumulative, int total);
|
|||
/// bytes from this method (assuming the response is sending compressed bytes),
|
||||
/// set both [HttpClient.autoUncompress] to false and the `autoUncompress`
|
||||
/// parameter to false.
|
||||
// TODO(tvolkert): Remove the [client] param once https://github.com/dart-lang/sdk/issues/36971 is fixed.
|
||||
Future<Uint8List> consolidateHttpClientResponseBytes(
|
||||
HttpClientResponse response, {
|
||||
HttpClient client,
|
||||
bool autoUncompress = true,
|
||||
BytesReceivedCallback onBytesReceived,
|
||||
}) {
|
||||
|
@ -58,15 +56,21 @@ Future<Uint8List> consolidateHttpClientResponseBytes(
|
|||
int expectedContentLength = response.contentLength;
|
||||
if (expectedContentLength == -1)
|
||||
expectedContentLength = null;
|
||||
if (response.headers?.value(HttpHeaders.contentEncodingHeader) == 'gzip') {
|
||||
if (client?.autoUncompress ?? true) {
|
||||
switch (response.compressionState) {
|
||||
case HttpClientResponseCompressionState.compressed:
|
||||
if (autoUncompress) {
|
||||
// We need to un-compress the bytes as they come in.
|
||||
sink = gzip.decoder.startChunkedConversion(output);
|
||||
}
|
||||
break;
|
||||
case HttpClientResponseCompressionState.decompressed:
|
||||
// response.contentLength will not match our bytes stream, so we declare
|
||||
// that we don't know the expected content length.
|
||||
expectedContentLength = null;
|
||||
} else if (autoUncompress) {
|
||||
// We need to un-compress the bytes as they come in.
|
||||
sink = gzip.decoder.startChunkedConversion(output);
|
||||
}
|
||||
break;
|
||||
case HttpClientResponseCompressionState.notCompressed:
|
||||
// Fall-through.
|
||||
break;
|
||||
}
|
||||
|
||||
int bytesReceived = 0;
|
||||
|
|
|
@ -552,7 +552,6 @@ class NetworkImage extends ImageProvider<NetworkImage> {
|
|||
|
||||
final Uint8List bytes = await consolidateHttpClientResponseBytes(
|
||||
response,
|
||||
client: _httpClient,
|
||||
onBytesReceived: (int cumulative, int total) {
|
||||
chunkEvents.add(ImageChunkEvent(
|
||||
cumulativeBytesLoaded: cumulative,
|
||||
|
|
|
@ -16,17 +16,11 @@ void main() {
|
|||
group(consolidateHttpClientResponseBytes, () {
|
||||
final List<int> chunkOne = <int>[0, 1, 2, 3, 4, 5];
|
||||
final List<int> chunkTwo = <int>[6, 7, 8, 9, 10];
|
||||
MockHttpClient client;
|
||||
MockHttpClientResponse response;
|
||||
MockHttpHeaders headers;
|
||||
|
||||
setUp(() {
|
||||
client = MockHttpClient();
|
||||
response = MockHttpClientResponse();
|
||||
headers = MockHttpHeaders();
|
||||
when(client.autoUncompress).thenReturn(true);
|
||||
when(response.headers).thenReturn(headers);
|
||||
when(headers.value(HttpHeaders.contentEncodingHeader)).thenReturn(null);
|
||||
when(response.compressionState).thenReturn(HttpClientResponseCompressionState.notCompressed);
|
||||
when(response.listen(
|
||||
any,
|
||||
onDone: anyNamed('onDone'),
|
||||
|
@ -52,7 +46,7 @@ void main() {
|
|||
when(response.contentLength)
|
||||
.thenReturn(chunkOne.length + chunkTwo.length);
|
||||
final List<int> bytes =
|
||||
await consolidateHttpClientResponseBytes(response, client: client);
|
||||
await consolidateHttpClientResponseBytes(response);
|
||||
|
||||
expect(bytes, <int>[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
||||
});
|
||||
|
@ -60,7 +54,7 @@ void main() {
|
|||
test('Converts a compressed HttpClientResponse with contentLength to bytes', () async {
|
||||
when(response.contentLength).thenReturn(chunkOne.length);
|
||||
final List<int> bytes =
|
||||
await consolidateHttpClientResponseBytes(response, client: client);
|
||||
await consolidateHttpClientResponseBytes(response);
|
||||
|
||||
expect(bytes, <int>[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
||||
});
|
||||
|
@ -68,7 +62,7 @@ void main() {
|
|||
test('Converts an HttpClientResponse without contentLength to bytes', () async {
|
||||
when(response.contentLength).thenReturn(-1);
|
||||
final List<int> bytes =
|
||||
await consolidateHttpClientResponseBytes(response, client: client);
|
||||
await consolidateHttpClientResponseBytes(response);
|
||||
|
||||
expect(bytes, <int>[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
||||
});
|
||||
|
@ -79,7 +73,6 @@ void main() {
|
|||
final List<int> records = <int>[];
|
||||
await consolidateHttpClientResponseBytes(
|
||||
response,
|
||||
client: client,
|
||||
onBytesReceived: (int cumulative, int total) {
|
||||
records.addAll(<int>[cumulative, total]);
|
||||
},
|
||||
|
@ -116,7 +109,7 @@ void main() {
|
|||
});
|
||||
when(response.contentLength).thenReturn(-1);
|
||||
|
||||
expect(consolidateHttpClientResponseBytes(response, client: client),
|
||||
expect(consolidateHttpClientResponseBytes(response),
|
||||
throwsA(isInstanceOf<Exception>()));
|
||||
});
|
||||
|
||||
|
@ -124,7 +117,6 @@ void main() {
|
|||
when(response.contentLength).thenReturn(-1);
|
||||
final Future<List<int>> result = consolidateHttpClientResponseBytes(
|
||||
response,
|
||||
client: client,
|
||||
onBytesReceived: (int cumulative, int total) {
|
||||
throw 'misbehaving callback';
|
||||
},
|
||||
|
@ -139,7 +131,7 @@ void main() {
|
|||
final List<int> gzippedChunkTwo = gzipped.sublist(gzipped.length ~/ 2);
|
||||
|
||||
setUp(() {
|
||||
when(headers.value(HttpHeaders.contentEncodingHeader)).thenReturn('gzip');
|
||||
when(response.compressionState).thenReturn(HttpClientResponseCompressionState.compressed);
|
||||
when(response.listen(
|
||||
any,
|
||||
onDone: anyNamed('onDone'),
|
||||
|
@ -161,27 +153,26 @@ void main() {
|
|||
});
|
||||
});
|
||||
|
||||
test('Uncompresses GZIP bytes if autoUncompress is true and response.autoUncompress is false', () async {
|
||||
when(client.autoUncompress).thenReturn(false);
|
||||
test('Uncompresses GZIP bytes if autoUncompress is true and response.compressionState is compressed', () async {
|
||||
when(response.compressionState).thenReturn(HttpClientResponseCompressionState.compressed);
|
||||
when(response.contentLength).thenReturn(gzipped.length);
|
||||
final List<int> bytes = await consolidateHttpClientResponseBytes(response, client: client);
|
||||
final List<int> bytes = await consolidateHttpClientResponseBytes(response);
|
||||
expect(bytes, <int>[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
||||
});
|
||||
|
||||
test('returns gzipped bytes if autoUncompress is false and response.autoUncompress is false', () async {
|
||||
when(client.autoUncompress).thenReturn(false);
|
||||
test('returns gzipped bytes if autoUncompress is false and response.compressionState is compressed', () async {
|
||||
when(response.compressionState).thenReturn(HttpClientResponseCompressionState.compressed);
|
||||
when(response.contentLength).thenReturn(gzipped.length);
|
||||
final List<int> bytes = await consolidateHttpClientResponseBytes(response, client: client, autoUncompress: false);
|
||||
final List<int> bytes = await consolidateHttpClientResponseBytes(response, autoUncompress: false);
|
||||
expect(bytes, gzipped);
|
||||
});
|
||||
|
||||
test('Notifies onBytesReceived with gzipped numbers', () async {
|
||||
when(client.autoUncompress).thenReturn(false);
|
||||
when(response.compressionState).thenReturn(HttpClientResponseCompressionState.compressed);
|
||||
when(response.contentLength).thenReturn(gzipped.length);
|
||||
final List<int> records = <int>[];
|
||||
await consolidateHttpClientResponseBytes(
|
||||
response,
|
||||
client: client,
|
||||
onBytesReceived: (int cumulative, int total) {
|
||||
records.addAll(<int>[cumulative, total]);
|
||||
},
|
||||
|
@ -195,13 +186,13 @@ void main() {
|
|||
]);
|
||||
});
|
||||
|
||||
test('Notifies onBytesReceived with expectedContentLength of -1 if response.autoUncompress is true', () async {
|
||||
test('Notifies onBytesReceived with expectedContentLength of -1 if response.compressionState is decompressed', () async {
|
||||
final int syntheticTotal = (chunkOne.length + chunkTwo.length) * 2;
|
||||
when(response.compressionState).thenReturn(HttpClientResponseCompressionState.decompressed);
|
||||
when(response.contentLength).thenReturn(syntheticTotal);
|
||||
final List<int> records = <int>[];
|
||||
await consolidateHttpClientResponseBytes(
|
||||
response,
|
||||
client: client,
|
||||
onBytesReceived: (int cumulative, int total) {
|
||||
records.addAll(<int>[cumulative, total]);
|
||||
},
|
||||
|
@ -218,6 +209,4 @@ void main() {
|
|||
});
|
||||
}
|
||||
|
||||
class MockHttpClient extends Mock implements HttpClient {}
|
||||
class MockHttpClientResponse extends Mock implements HttpClientResponse {}
|
||||
class MockHttpHeaders extends Mock implements HttpHeaders {}
|
||||
|
|
|
@ -1770,20 +1770,10 @@ class _MockHttpResponse extends Stream<List<int>> implements HttpClientResponse
|
|||
@override
|
||||
int get contentLength => -1;
|
||||
|
||||
// TODO(tvolkert): Update (flutter/flutter#33791)
|
||||
/*
|
||||
@override
|
||||
HttpClientResponseCompressionState get compressionState {
|
||||
return HttpClientResponseCompressionState.decompressed;
|
||||
}
|
||||
*/
|
||||
@override
|
||||
dynamic noSuchMethod(Invocation invocation) {
|
||||
if (invocation.memberName == #compressionState) {
|
||||
return null;
|
||||
}
|
||||
return super.noSuchMethod(invocation);
|
||||
}
|
||||
|
||||
@override
|
||||
List<Cookie> get cookies => null;
|
||||
|
|
|
@ -47,8 +47,7 @@ export 'dart:io'
|
|||
HttpClient,
|
||||
HttpClientRequest,
|
||||
HttpClientResponse,
|
||||
// TODO(tvolkert): Uncomment (flutter/flutter#33791)
|
||||
//HttpClientResponseCompressionState,
|
||||
HttpClientResponseCompressionState,
|
||||
HttpHeaders,
|
||||
HttpRequest,
|
||||
HttpServer,
|
||||
|
|
|
@ -1295,13 +1295,10 @@ class MockHttpClientResponse extends Stream<List<int>> implements HttpClientResp
|
|||
@override
|
||||
String get reasonPhrase => '<reason phrase>';
|
||||
|
||||
// TODO(tvolkert): Update (flutter/flutter#33791)
|
||||
/*
|
||||
@override
|
||||
HttpClientResponseCompressionState get compressionState {
|
||||
return HttpClientResponseCompressionState.decompressed;
|
||||
}
|
||||
*/
|
||||
|
||||
@override
|
||||
StreamSubscription<Uint8List> listen(
|
||||
|
@ -1316,10 +1313,6 @@ class MockHttpClientResponse extends Stream<List<int>> implements HttpClientResp
|
|||
|
||||
@override
|
||||
dynamic noSuchMethod(Invocation invocation) {
|
||||
// TODO(tvolkert): Update (flutter/flutter#33791)
|
||||
if (invocation.memberName == #compressionState) {
|
||||
return null;
|
||||
}
|
||||
throw 'io.HttpClientResponse - $invocation';
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue