blob: 90abb86680b74b9f3b5478f9f2e1ae24bcf9ee50 [file] [log] [blame]
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:collection/collection.dart';
import 'package:http_parser/http_parser.dart';
import '../middleware.dart';
/// Middleware that adds [chunked transfer coding][] to responses if none of the
/// following conditions are true:
///
/// [chunked transfer coding]: https://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.6.1
///
/// * A Content-Length header is provided.
/// * The Content-Type header indicates the MIME type `multipart/byteranges`.
/// * The Transfer-Encoding header already includes the `chunked` coding.
///
/// This is intended for use by [Shelf adapters][] rather than end-users.
///
/// [Shelf adapters]: https://github.com/dart-lang/shelf#adapters
final addChunkedEncoding = createMiddleware(responseHandler: (response) {
if (response.contentLength != null) return response;
if (response.statusCode < 200) return response;
if (response.statusCode == 204) return response;
if (response.statusCode == 304) return response;
if (response.mimeType == 'multipart/byteranges') return response;
// We only check the last coding here because HTTP requires that the chunked
// encoding be listed last.
var coding = response.headers['transfer-encoding'];
if (coding != null && !equalsIgnoreAsciiCase(coding, 'identity')) {
return response;
}
return response.change(
headers: {'transfer-encoding': 'chunked'},
body: chunkedCoding.encoder.bind(response.read()));
});