diff --git a/lib/src/content_type.dart b/lib/src/content_type.dart new file mode 100644 index 0000000000..8a1222ac03 --- /dev/null +++ b/lib/src/content_type.dart @@ -0,0 +1,25 @@ +// Copyright (c) 2017, 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 'dart:convert'; + +import 'package:http_parser/http_parser.dart'; + +/// Returns the [Encoding] that corresponds to [charset]. +/// +/// Returns `null` if [charset] is `null` or if no [Encoding] was found that +/// corresponds to [charset]. +Encoding encodingForCharset(String charset) { + if (charset == null) return null; + return Encoding.getByName(charset); +} + +/// Determines the encoding from the media [type]. +/// +/// Returns `null` if the charset is not specified in the [type] or if no +/// [Encoding] was found that corresponds to the `charset`. +Encoding encodingForMediaType(MediaType type) { + if (type == null) return null; + return encodingForCharset(type.parameters['charset']); +} diff --git a/lib/src/message.dart b/lib/src/message.dart index 96608dda66..ae16e24963 100644 --- a/lib/src/message.dart +++ b/lib/src/message.dart @@ -9,6 +9,7 @@ import 'package:collection/collection.dart'; import 'package:http_parser/http_parser.dart'; import 'body.dart'; +import 'content_type.dart'; import 'http_unmodifiable_map.dart'; import 'utils.dart'; @@ -80,10 +81,12 @@ abstract class Message { /// If not set, `null`. int get contentLength { if (_contentLengthCache != null) return _contentLengthCache; - if (!headers.containsKey('content-length')) return null; - _contentLengthCache = int.parse(headers['content-length']); + var contentLengthHeader = getHeader(headers, 'content-length'); + if (contentLengthHeader == null) return null; + _contentLengthCache = int.parse(contentLengthHeader); return _contentLengthCache; } + int _contentLengthCache; /// The MIME type declared in [headers]. @@ -92,11 +95,7 @@ abstract class Message { /// the MIME type, without any Content-Type parameters. /// /// If [headers] doesn't have a Content-Type header, this will be `null`. - String get mimeType { - var contentType = _contentType; - if (contentType == null) return null; - return contentType.mimeType; - } + String get mimeType => _contentType?.mimeType; /// The encoding of the body returned by [read]. /// @@ -105,22 +104,19 @@ abstract class Message { /// /// If [headers] doesn't have a Content-Type header or it specifies an /// encoding that [dart:convert] doesn't support, this will be `null`. - Encoding get encoding { - var contentType = _contentType; - if (contentType == null) return null; - if (!contentType.parameters.containsKey('charset')) return null; - return Encoding.getByName(contentType.parameters['charset']); - } + Encoding get encoding => encodingForMediaType(_contentType); /// The parsed version of the Content-Type header in [headers]. /// /// This is cached for efficient access. MediaType get _contentType { if (_contentTypeCache != null) return _contentTypeCache; - if (!headers.containsKey('content-type')) return null; - _contentTypeCache = new MediaType.parse(headers['content-type']); + var contentLengthHeader = getHeader(headers, 'content-type'); + if (contentLengthHeader == null) return null; + _contentTypeCache = new MediaType.parse(contentLengthHeader); return _contentTypeCache; } + MediaType _contentTypeCache; /// Returns the message body as byte chunks. diff --git a/lib/src/utils.dart b/lib/src/utils.dart index 3e9fdf39bb..683e4abd18 100644 --- a/lib/src/utils.dart +++ b/lib/src/utils.dart @@ -53,24 +53,6 @@ List split1(String toSplit, String pattern) { ]; } -/// Returns the [Encoding] that corresponds to [charset]. Returns [fallback] if -/// [charset] is null or if no [Encoding] was found that corresponds to -/// [charset]. -Encoding encodingForCharset(String charset, [Encoding fallback = LATIN1]) { - if (charset == null) return fallback; - var encoding = Encoding.getByName(charset); - return encoding == null ? fallback : encoding; -} - - -/// Returns the [Encoding] that corresponds to [charset]. Throws a -/// [FormatException] if no [Encoding] was found that corresponds to [charset]. -/// [charset] may not be null. -Encoding requiredEncodingForCharset(String charset) { - var encoding = Encoding.getByName(charset); - if (encoding != null) return encoding; - throw new FormatException('Unsupported encoding "$charset".'); -} /// A regular expression that matches strings that are composed entirely of /// ASCII-compatible characters.