add method

void add (ContentType contentType, Codec codec, { bool allowCompression: true })

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:

    HTTPCodecRepository.defaultInstance.add(
      new 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 {
    var innerCodecs = _fullySpecificedCodecs[contentType.primaryType] ?? {};
    innerCodecs[contentType.subType] = codec;
    _fullySpecificedCodecs[contentType.primaryType] = innerCodecs;

    var innerCompress =
        _fullySpecifiedCompressionMap[contentType.primaryType] ?? {};
    innerCompress[contentType.subType] = allowCompression;
    _fullySpecifiedCompressionMap[contentType.primaryType] = innerCompress;
  }

  if (contentType.charset != null) {
    var innerCodecs = _defaultCharsetMap[contentType.primaryType] ?? {};
    innerCodecs[contentType.subType] = contentType.charset;
    _defaultCharsetMap[contentType.primaryType] = innerCodecs;
  }
}