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.
- 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).
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" |
- 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 (
StructuredTokenvsStructuredString) ensure they are not conflated.
Add the package to your pubspec.yaml:
dependencies:
structured_field_values: ^1.0.0Then run dart pub get.
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);
}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);
}StructuredFieldParseExceptionis thrown if the input string contains invalid syntax.StructuredFieldSerializationExceptionis 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');
}
}This package integrates the official IETF HTTP Working Group structured-field-tests suite as a Git submodule.
To run the conformance tests:
- Initialize the submodule (if not already done):
git submodule update --init
- Generate the unit tests from the JSON specs:
dart run tool/generate_conformance_tests.dart
- Run the tests:
dart test
For support, feedback, or to report issues, please visit our Issue Tracker.