Skip to content

dropbear-software/structured_field_values

Repository files navigation

Structured Field Values for HTTP

pub package Dart CI License: MIT

A fully compliant implementation of RFC 9651 (Structured Field Values for HTTP) in native Dart. This package handles the parsing and serialization of structured headers and trailers, replacing the older RFC 8941 specification.

It provides a strongly typed representation of structured fields and adheres strictly to the step-by-step parsing and serialization algorithms outlined in the RFC.


Features

  • Top-level Structured Types:
    • StructuredList (comma-separated lists)
    • StructuredDictionary (comma-separated key-value maps)
    • StructuredItem (parameterized single values)
  • Inner Lists: StructuredInnerList (parenthesized space-separated lists).
  • Parameters: StructuredParameters (semicolon-delimited key-value pairs).

RFC 9651 Bare Item Types

This library provides full support for all bare item types defined in the RFC:

RFC Type Dart Class Description / Constraints Example Syntax
Integer StructuredInteger Range -999,999,999,999,999 to 999,999,999,999,999 42
Decimal StructuredDecimal Up to 12 integer digits and 3 fractional component digits 3.14
String StructuredString Zero or more printable ASCII characters (%x20-7E) "hello"
Token StructuredToken Identifiers starting with ALPHA or * text/html
Byte Sequence StructuredByteSequence Base64 encoded binary data enclosed in colons :aGVsbG8=:
Boolean StructuredBoolean ?1 (true) or ?0 (false) ?1
Date StructuredDate Unix timestamps preceded by @ @1659578233
Display String StructuredDisplayString Unicode strings formatted with percent-encoding %"hello"

Compliance Highlights

  • Official Test Suite Compliance: 100% compliant with the official IETF HTTP Working Group structured-field-tests suite (tested against all 2,135 parse and serialization test cases).
  • Order Preservation: Dictionary and Parameter maps preserve key insertion order.
  • Round-to-Even: Decimals with $>3$ fractional digits are rounded using the round-to-nearest-even strategy (IEEE 754 round half to even) during serialization.
  • Strict Parsing: Invalid syntaxes fail immediately throwing a StructuredFieldParseException.
  • Base64 Tolerances: Adheres to the RFC advice to tolerate missing base64 padding or non-zero pad bits.
  • Token / String Distinction: Explicit classes (StructuredToken vs StructuredString) ensure they are not conflated.

Getting started

Add the package to your pubspec.yaml:

dependencies:
  structured_field_values: ^1.0.0

Then run dart pub get.


Usage

Parsing Field Values

To parse an HTTP header value, use standard codecs: structuredList, structuredDictionary, or structuredItem. Decoding is fully type-safe and does not require manual casting:

import 'package:structured_field_values/structured_field_values.dart';

void main() {
  // Parsing a List of Inner Lists
  const listHeader = '("sugar" "tea"), ("rum")';
  final parsedList = structuredList.decode(listHeader); // StructuredList
  print(parsedList);

  // Parsing a Dictionary with Boolean Parameters
  const dictHeader = 'a=?0, b, c;foo=bar';
  final parsedDict = structuredDictionary.decode(dictHeader); // StructuredDictionary
  print(parsedDict);

  // Parsing an Item
  const itemHeader = '@1659578233;expires=3600';
  final parsedItem = structuredItem.decode(itemHeader); // StructuredItem
  print(parsedItem);
}

Serializing Structured Fields

To serialize a structured field back to its HTTP header string representation, use the codec's encode method:

import 'package:structured_field_values/structured_field_values.dart';

void main() {
  final dictionary = StructuredDictionary({
    'allow-cache': StructuredItem(StructuredBoolean(true)),
    'status': StructuredItem(
      StructuredToken('active'),
      StructuredParameters({
        'retry': StructuredInteger(3),
      }),
    ),
  });

  // Returns: "allow-cache, status;retry=3"
  // Note that boolean true is serialized by omitting the "=value" suffix
  final headerString = structuredDictionary.encode(dictionary);
  print(headerString);
}

Exception Handling

  • StructuredFieldParseException is thrown if the input string contains invalid syntax.
  • StructuredFieldSerializationException is thrown if you try to serialize an out-of-range integer, an invalid key, or prohibited surrogate code points.
import 'package:structured_field_values/structured_field_values.dart';

void main() {
  try {
    // Fails because hex values in display strings must be lowercase
    structuredItem.decode('%"Hello %C3%BC"');
  } on StructuredFieldParseException catch (e) {
    print('Failed to parse: $e');
  }
}

Conformance Testing

This package integrates the official IETF HTTP Working Group structured-field-tests suite as a Git submodule.

To run the conformance tests:

  1. Initialize the submodule (if not already done):
    git submodule update --init
  2. Generate the unit tests from the JSON specs:
    dart run tool/generate_conformance_tests.dart
  3. Run the tests:
    dart test

For support, feedback, or to report issues, please visit our Issue Tracker.

About

A Dart native implementation of Structured Field Values for HTTP (RFC 9651)

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages