add method
Adds a custom codec
for contentType
.
The body of a Response sent with contentType
will be transformed by codec
. A Request with contentType
Content-Type
will be decode its Request.body with codec
.
codec
must produce a List<int> (or used chunked conversion to create a Stream<List<int>>
).
contentType
's subtype may be *
; all Content-Type's with a matching ContentType.primaryType will be
encoded or decoded by codec
, regardless of ContentType.subType. For example, if contentType
is text/*
, then all
text/
(text/html
, text/plain
, etc.) content types are converted by codec
.
The most specific codec for a content type is chosen when converting an HTTP body. For example, if both text/*
and text/html
have been added through this method, a Response with content type text/html
will select the codec
associated with text/html
and not text/*
.
allowCompression
chooses whether or not response bodies are compressed with gzip when using contentType
.
Media types like images and audio files should avoid setting allowCompression
because they are already compressed.
A response with a content type not in this instance will be sent unchanged to the HTTP client (and therefore must be List<int>
The ContentType.charset is not evaluated when selecting the codec for a content type. However, a charset indicates the default
used when a request's Content-Type header omits a charset. For example, in order to decode JSON data, the request body must first be decoded
from a list of bytes into a String. If a request omits the charset, this first step is would not be applied and the JSON codec would attempt
to decode a list of bytes instead of a String and would fail. Thus, application/json
is added through the following:
CodecRegistry.defaultInstance.add(
ContentType("application", "json", charset: "utf-8"), const JsonCodec(), allowsCompression: true);
In the event that a request is sent without a charset, the codec will automatically apply a UTF8 decode step because of this default.
Only use default charsets when the codec must first be decoded into a String.
Implementation
void add(
ContentType contentType,
Codec codec, {
bool allowCompression = true,
}) {
if (contentType.subType == "*") {
_primaryTypeCodecs[contentType.primaryType] = codec;
_primaryTypeCompressionMap[contentType.primaryType] = allowCompression;
} else {
final innerCodecs = _fullySpecificedCodecs[contentType.primaryType] ?? {};
innerCodecs[contentType.subType] = codec;
_fullySpecificedCodecs[contentType.primaryType] = innerCodecs;
final innerCompress =
_fullySpecifiedCompressionMap[contentType.primaryType] ?? {};
innerCompress[contentType.subType] = allowCompression;
_fullySpecifiedCompressionMap[contentType.primaryType] = innerCompress;
}
if (contentType.charset != null) {
final innerCodecs = _defaultCharsetMap[contentType.primaryType] ?? {};
innerCodecs[contentType.subType] = contentType.charset;
_defaultCharsetMap[contentType.primaryType] = innerCodecs;
}
}