Livt packages

Livt.Web

Version 1.0.0

Bounded HTTP routing, request parsing, response encoding, and Ethernet application composition for Livt.

Published files (63)

tests/http/HttpRequestTestData.lvt

namespace Livt.Web.Tests.Http

using Livt.Net
using Livt.Web.Http

/**
 * Published immutable test vectors plus injected failure and extent controls.
 */
component HttpRequestTestData : IPacketData
{
	// 0 Minimal: "GET / HTTP/1.0\r\n\r\n"
	// 1 Views: "GET /a%2Fb?x=1?? HTTP/1.1\r\nhOsT:\tboard.local:80 \t\r\nX-Note:  a\tb  \r\nEmpty:\t \r\nContent-Length: 000\r\n\r\n"
	// 2 EmptyQuery: "GET /? HTTP/1.0\r\n\r\n"
	// 3 Version11Host: "GET / HTTP/1.1\r\nHost: 10.0.0.2\r\n\r\n"
	// 4 PartialToken: "GET / "
	// 5 PartialPercent: "GET /%2"
	// 6 PartialVersion: "GET / HTTP/1."
	// 7 PartialHeader: "GET / HTTP/1.0\r\nX: hello\r"
	// 8 MissingTerminator: "GET / HTTP/1.0\r\nX: hello\r\n"
	// 9 BareLf: "GET / HTTP/1.0\n\n"
	// 10 DoubleSpace: "GET  / HTTP/1.0\r\n\r\n"
	// 11 BadPercent: "GET /%G0 HTTP/1.0\r\n\r\n"
	// 12 ShortPercent: "GET /%2 HTTP/1.0\r\n\r\n"
	// 13 Fragment: "GET /#x HTTP/1.0\r\n\r\n"
	// 14 BadName: "GET / HTTP/1.0\r\nBad Name: a\r\n\r\n"
	// 15 WhitespaceBeforeColon: "GET / HTTP/1.0\r\nHost : a\r\n\r\n"
	// 16 FoldedHeader: "GET / HTTP/1.0\r\nX: a\r\n b\r\n\r\n"
	// 17 ValueControl: "GET / HTTP/1.0\r\nX: a\u0000b\r\n\r\n"
	// 18 MissingHost: "GET / HTTP/1.1\r\n\r\n"
	// 19 DuplicateHost: "GET / HTTP/1.1\r\nHost: a\r\nhost: a\r\n\r\n"
	// 20 EmptyHost: "GET / HTTP/1.1\r\nHost: \t\r\n\r\n"
	// 21 InvalidPort: "GET / HTTP/1.1\r\nHost: a:65536\r\n\r\n"
	// 22 DuplicateLength: "GET / HTTP/1.0\r\nContent-Length: 0\r\ncontent-length: 0\r\n\r\n"
	// 23 ConflictingLength: "GET / HTTP/1.0\r\nContent-Length: 0\r\nContent-Length: 1\r\n\r\n"
	// 24 LengthList: "GET / HTTP/1.0\r\nContent-Length: 0, 0\r\n\r\n"
	// 25 SignedLength: "GET / HTTP/1.0\r\nContent-Length: +0\r\n\r\n"
	// 26 EmptyLength: "GET / HTTP/1.0\r\nContent-Length:\r\n\r\n"
	// 27 ConflictingFraming: "GET / HTTP/1.0\r\nTransfer-Encoding: chunked\r\nContent-Length: 0\r\n\r\n"
	// 28 ReversedFraming: "GET / HTTP/1.0\r\nContent-Length: 0\r\nTransfer-Encoding: chunked\r\n\r\n"
	// 29 Body: "GET / HTTP/1.0\r\nContent-Length: 1\r\n\r\nx"
	// 30 HugeLength: "GET / HTTP/1.0\r\nContent-Length: 9999999999999999999999999\r\n\r\n"
	// 31 TransferCoding: "GET / HTTP/1.1\r\nHost: a\r\nTransfer-Encoding: chunked\r\n\r\n"
	// 32 Expectation: "GET / HTTP/1.1\r\nHost: a\r\nExpect: 100-continue\r\n\r\n"
	// 33 Post: "POST / HTTP/1.0\r\n\r\n"
	// 34 Version12: "GET / HTTP/1.2\r\n\r\n"
	// 35 AbsoluteTarget: "GET http://a/ HTTP/1.0\r\n\r\n"
	// 36 TrailingByte: "GET / HTTP/1.0\r\n\r\nx"
	// 37 Pipeline: "GET / HTTP/1.0\r\n\r\nGET / HTTP/1.0\r\n\r\n"
	// 38 TrailingSlash: "GET /a/ HTTP/1.0\r\n\r\n"
	// 39 EncodedPath: "GET /%61 HTTP/1.0\r\n\r\n"
	// 40 TargetAtLimit: "GET /abc HTTP/1.0\r\n\r\n"
	// 41 TargetOverLimit: "GET /abcd HTTP/1.0\r\n\r\n"
	// 42 HeaderAtLimit: "GET / HTTP/1.0\r\nX: a\r\n\r\n"
	// 43 HeaderOverLimit: "GET / HTTP/1.0\r\nX: a\r\nY: b\r\n\r\n"
	// 44 InvalidVersion: "GET / HTTP/x.0\r\n\r\n"
	// 45 InvalidMethod: "GE(T / HTTP/1.0\r\n\r\n"
	// 46 EmptyName: "GET / HTTP/1.0\r\n: a\r\n\r\n"
	// 47 HeaderBareLf: "GET / HTTP/1.0\r\nX: a\n\r\n"
	// 48 EmptyTransfer: "GET / HTTP/1.0\r\nTransfer-Encoding:\r\n\r\n"
	// 49 UnsupportedHost: "GET / HTTP/1.1\r\nHost: [::1]\r\n\r\n"
	// 50 HeadMethod: "HEAD / HTTP/1.0\r\n\r\n"
	const BYTES[1556] = [
		0x47, 0x45, 0x54, 0x20, 0x2F, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30, 0x0D, 0x0A,
		0x0D, 0x0A, 0x47, 0x45, 0x54, 0x20, 0x2F, 0x61, 0x25, 0x32, 0x46, 0x62, 0x3F, 0x78, 0x3D, 0x31,
		0x3F, 0x3F, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x31, 0x0D, 0x0A, 0x68, 0x4F, 0x73,
		0x54, 0x3A, 0x09, 0x62, 0x6F, 0x61, 0x72, 0x64, 0x2E, 0x6C, 0x6F, 0x63, 0x61, 0x6C, 0x3A, 0x38,
		0x30, 0x20, 0x09, 0x0D, 0x0A, 0x58, 0x2D, 0x4E, 0x6F, 0x74, 0x65, 0x3A, 0x20, 0x20, 0x61, 0x09,
		0x62, 0x20, 0x20, 0x0D, 0x0A, 0x45, 0x6D, 0x70, 0x74, 0x79, 0x3A, 0x09, 0x20, 0x0D, 0x0A, 0x43,
		0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x2D, 0x4C, 0x65, 0x6E, 0x67, 0x74, 0x68, 0x3A, 0x20, 0x30,
		0x30, 0x30, 0x0D, 0x0A, 0x0D, 0x0A, 0x47, 0x45, 0x54, 0x20, 0x2F, 0x3F, 0x20, 0x48, 0x54, 0x54,
		0x50, 0x2F, 0x31, 0x2E, 0x30, 0x0D, 0x0A, 0x0D, 0x0A, 0x47, 0x45, 0x54, 0x20, 0x2F, 0x20, 0x48,
		0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x31, 0x0D, 0x0A, 0x48, 0x6F, 0x73, 0x74, 0x3A, 0x20, 0x31,
		0x30, 0x2E, 0x30, 0x2E, 0x30, 0x2E, 0x32, 0x0D, 0x0A, 0x0D, 0x0A, 0x47, 0x45, 0x54, 0x20, 0x2F,
		0x20, 0x47, 0x45, 0x54, 0x20, 0x2F, 0x25, 0x32, 0x47, 0x45, 0x54, 0x20, 0x2F, 0x20, 0x48, 0x54,
		0x54, 0x50, 0x2F, 0x31, 0x2E, 0x47, 0x45, 0x54, 0x20, 0x2F, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2F,
		0x31, 0x2E, 0x30, 0x0D, 0x0A, 0x58, 0x3A, 0x20, 0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x0D, 0x47, 0x45,
		0x54, 0x20, 0x2F, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30, 0x0D, 0x0A, 0x58, 0x3A,
		0x20, 0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x0D, 0x0A, 0x47, 0x45, 0x54, 0x20, 0x2F, 0x20, 0x48, 0x54,
		0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30, 0x0A, 0x0A, 0x47, 0x45, 0x54, 0x20, 0x20, 0x2F, 0x20, 0x48,
		0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30, 0x0D, 0x0A, 0x0D, 0x0A, 0x47, 0x45, 0x54, 0x20, 0x2F,
		0x25, 0x47, 0x30, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30, 0x0D, 0x0A, 0x0D, 0x0A,
		0x47, 0x45, 0x54, 0x20, 0x2F, 0x25, 0x32, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30,
		0x0D, 0x0A, 0x0D, 0x0A, 0x47, 0x45, 0x54, 0x20, 0x2F, 0x23, 0x78, 0x20, 0x48, 0x54, 0x54, 0x50,
		0x2F, 0x31, 0x2E, 0x30, 0x0D, 0x0A, 0x0D, 0x0A, 0x47, 0x45, 0x54, 0x20, 0x2F, 0x20, 0x48, 0x54,
		0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30, 0x0D, 0x0A, 0x42, 0x61, 0x64, 0x20, 0x4E, 0x61, 0x6D, 0x65,
		0x3A, 0x20, 0x61, 0x0D, 0x0A, 0x0D, 0x0A, 0x47, 0x45, 0x54, 0x20, 0x2F, 0x20, 0x48, 0x54, 0x54,
		0x50, 0x2F, 0x31, 0x2E, 0x30, 0x0D, 0x0A, 0x48, 0x6F, 0x73, 0x74, 0x20, 0x3A, 0x20, 0x61, 0x0D,
		0x0A, 0x0D, 0x0A, 0x47, 0x45, 0x54, 0x20, 0x2F, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E,
		0x30, 0x0D, 0x0A, 0x58, 0x3A, 0x20, 0x61, 0x0D, 0x0A, 0x20, 0x62, 0x0D, 0x0A, 0x0D, 0x0A, 0x47,
		0x45, 0x54, 0x20, 0x2F, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30, 0x0D, 0x0A, 0x58,
		0x3A, 0x20, 0x61, 0x00, 0x62, 0x0D, 0x0A, 0x0D, 0x0A, 0x47, 0x45, 0x54, 0x20, 0x2F, 0x20, 0x48,
		0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x31, 0x0D, 0x0A, 0x0D, 0x0A, 0x47, 0x45, 0x54, 0x20, 0x2F,
		0x20, 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x31, 0x0D, 0x0A, 0x48, 0x6F, 0x73, 0x74, 0x3A,
		0x20, 0x61, 0x0D, 0x0A, 0x68, 0x6F, 0x73, 0x74, 0x3A, 0x20, 0x61, 0x0D, 0x0A, 0x0D, 0x0A, 0x47,
		0x45, 0x54, 0x20, 0x2F, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x31, 0x0D, 0x0A, 0x48,
		0x6F, 0x73, 0x74, 0x3A, 0x20, 0x09, 0x0D, 0x0A, 0x0D, 0x0A, 0x47, 0x45, 0x54, 0x20, 0x2F, 0x20,
		0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x31, 0x0D, 0x0A, 0x48, 0x6F, 0x73, 0x74, 0x3A, 0x20,
		0x61, 0x3A, 0x36, 0x35, 0x35, 0x33, 0x36, 0x0D, 0x0A, 0x0D, 0x0A, 0x47, 0x45, 0x54, 0x20, 0x2F,
		0x20, 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30, 0x0D, 0x0A, 0x43, 0x6F, 0x6E, 0x74, 0x65,
		0x6E, 0x74, 0x2D, 0x4C, 0x65, 0x6E, 0x67, 0x74, 0x68, 0x3A, 0x20, 0x30, 0x0D, 0x0A, 0x63, 0x6F,
		0x6E, 0x74, 0x65, 0x6E, 0x74, 0x2D, 0x6C, 0x65, 0x6E, 0x67, 0x74, 0x68, 0x3A, 0x20, 0x30, 0x0D,
		0x0A, 0x0D, 0x0A, 0x47, 0x45, 0x54, 0x20, 0x2F, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E,
		0x30, 0x0D, 0x0A, 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x2D, 0x4C, 0x65, 0x6E, 0x67, 0x74,
		0x68, 0x3A, 0x20, 0x30, 0x0D, 0x0A, 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x2D, 0x4C, 0x65,
		0x6E, 0x67, 0x74, 0x68, 0x3A, 0x20, 0x31, 0x0D, 0x0A, 0x0D, 0x0A, 0x47, 0x45, 0x54, 0x20, 0x2F,
		0x20, 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30, 0x0D, 0x0A, 0x43, 0x6F, 0x6E, 0x74, 0x65,
		0x6E, 0x74, 0x2D, 0x4C, 0x65, 0x6E, 0x67, 0x74, 0x68, 0x3A, 0x20, 0x30, 0x2C, 0x20, 0x30, 0x0D,
		0x0A, 0x0D, 0x0A, 0x47, 0x45, 0x54, 0x20, 0x2F, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E,
		0x30, 0x0D, 0x0A, 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x2D, 0x4C, 0x65, 0x6E, 0x67, 0x74,
		0x68, 0x3A, 0x20, 0x2B, 0x30, 0x0D, 0x0A, 0x0D, 0x0A, 0x47, 0x45, 0x54, 0x20, 0x2F, 0x20, 0x48,
		0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30, 0x0D, 0x0A, 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74,
		0x2D, 0x4C, 0x65, 0x6E, 0x67, 0x74, 0x68, 0x3A, 0x0D, 0x0A, 0x0D, 0x0A, 0x47, 0x45, 0x54, 0x20,
		0x2F, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30, 0x0D, 0x0A, 0x54, 0x72, 0x61, 0x6E,
		0x73, 0x66, 0x65, 0x72, 0x2D, 0x45, 0x6E, 0x63, 0x6F, 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x63,
		0x68, 0x75, 0x6E, 0x6B, 0x65, 0x64, 0x0D, 0x0A, 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x2D,
		0x4C, 0x65, 0x6E, 0x67, 0x74, 0x68, 0x3A, 0x20, 0x30, 0x0D, 0x0A, 0x0D, 0x0A, 0x47, 0x45, 0x54,
		0x20, 0x2F, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30, 0x0D, 0x0A, 0x43, 0x6F, 0x6E,
		0x74, 0x65, 0x6E, 0x74, 0x2D, 0x4C, 0x65, 0x6E, 0x67, 0x74, 0x68, 0x3A, 0x20, 0x30, 0x0D, 0x0A,
		0x54, 0x72, 0x61, 0x6E, 0x73, 0x66, 0x65, 0x72, 0x2D, 0x45, 0x6E, 0x63, 0x6F, 0x64, 0x69, 0x6E,
		0x67, 0x3A, 0x20, 0x63, 0x68, 0x75, 0x6E, 0x6B, 0x65, 0x64, 0x0D, 0x0A, 0x0D, 0x0A, 0x47, 0x45,
		0x54, 0x20, 0x2F, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30, 0x0D, 0x0A, 0x43, 0x6F,
		0x6E, 0x74, 0x65, 0x6E, 0x74, 0x2D, 0x4C, 0x65, 0x6E, 0x67, 0x74, 0x68, 0x3A, 0x20, 0x31, 0x0D,
		0x0A, 0x0D, 0x0A, 0x78, 0x47, 0x45, 0x54, 0x20, 0x2F, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31,
		0x2E, 0x30, 0x0D, 0x0A, 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x2D, 0x4C, 0x65, 0x6E, 0x67,
		0x74, 0x68, 0x3A, 0x20, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39,
		0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x0D, 0x0A, 0x0D,
		0x0A, 0x47, 0x45, 0x54, 0x20, 0x2F, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x31, 0x0D,
		0x0A, 0x48, 0x6F, 0x73, 0x74, 0x3A, 0x20, 0x61, 0x0D, 0x0A, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x66,
		0x65, 0x72, 0x2D, 0x45, 0x6E, 0x63, 0x6F, 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x63, 0x68, 0x75,
		0x6E, 0x6B, 0x65, 0x64, 0x0D, 0x0A, 0x0D, 0x0A, 0x47, 0x45, 0x54, 0x20, 0x2F, 0x20, 0x48, 0x54,
		0x54, 0x50, 0x2F, 0x31, 0x2E, 0x31, 0x0D, 0x0A, 0x48, 0x6F, 0x73, 0x74, 0x3A, 0x20, 0x61, 0x0D,
		0x0A, 0x45, 0x78, 0x70, 0x65, 0x63, 0x74, 0x3A, 0x20, 0x31, 0x30, 0x30, 0x2D, 0x63, 0x6F, 0x6E,
		0x74, 0x69, 0x6E, 0x75, 0x65, 0x0D, 0x0A, 0x0D, 0x0A, 0x50, 0x4F, 0x53, 0x54, 0x20, 0x2F, 0x20,
		0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30, 0x0D, 0x0A, 0x0D, 0x0A, 0x47, 0x45, 0x54, 0x20,
		0x2F, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x32, 0x0D, 0x0A, 0x0D, 0x0A, 0x47, 0x45,
		0x54, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x61, 0x2F, 0x20, 0x48, 0x54, 0x54, 0x50,
		0x2F, 0x31, 0x2E, 0x30, 0x0D, 0x0A, 0x0D, 0x0A, 0x47, 0x45, 0x54, 0x20, 0x2F, 0x20, 0x48, 0x54,
		0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30, 0x0D, 0x0A, 0x0D, 0x0A, 0x78, 0x47, 0x45, 0x54, 0x20, 0x2F,
		0x20, 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30, 0x0D, 0x0A, 0x0D, 0x0A, 0x47, 0x45, 0x54,
		0x20, 0x2F, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30, 0x0D, 0x0A, 0x0D, 0x0A, 0x47,
		0x45, 0x54, 0x20, 0x2F, 0x61, 0x2F, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30, 0x0D,
		0x0A, 0x0D, 0x0A, 0x47, 0x45, 0x54, 0x20, 0x2F, 0x25, 0x36, 0x31, 0x20, 0x48, 0x54, 0x54, 0x50,
		0x2F, 0x31, 0x2E, 0x30, 0x0D, 0x0A, 0x0D, 0x0A, 0x47, 0x45, 0x54, 0x20, 0x2F, 0x61, 0x62, 0x63,
		0x20, 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30, 0x0D, 0x0A, 0x0D, 0x0A, 0x47, 0x45, 0x54,
		0x20, 0x2F, 0x61, 0x62, 0x63, 0x64, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30, 0x0D,
		0x0A, 0x0D, 0x0A, 0x47, 0x45, 0x54, 0x20, 0x2F, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E,
		0x30, 0x0D, 0x0A, 0x58, 0x3A, 0x20, 0x61, 0x0D, 0x0A, 0x0D, 0x0A, 0x47, 0x45, 0x54, 0x20, 0x2F,
		0x20, 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30, 0x0D, 0x0A, 0x58, 0x3A, 0x20, 0x61, 0x0D,
		0x0A, 0x59, 0x3A, 0x20, 0x62, 0x0D, 0x0A, 0x0D, 0x0A, 0x47, 0x45, 0x54, 0x20, 0x2F, 0x20, 0x48,
		0x54, 0x54, 0x50, 0x2F, 0x78, 0x2E, 0x30, 0x0D, 0x0A, 0x0D, 0x0A, 0x47, 0x45, 0x28, 0x54, 0x20,
		0x2F, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30, 0x0D, 0x0A, 0x0D, 0x0A, 0x47, 0x45,
		0x54, 0x20, 0x2F, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30, 0x0D, 0x0A, 0x3A, 0x20,
		0x61, 0x0D, 0x0A, 0x0D, 0x0A, 0x47, 0x45, 0x54, 0x20, 0x2F, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2F,
		0x31, 0x2E, 0x30, 0x0D, 0x0A, 0x58, 0x3A, 0x20, 0x61, 0x0A, 0x0D, 0x0A, 0x47, 0x45, 0x54, 0x20,
		0x2F, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30, 0x0D, 0x0A, 0x54, 0x72, 0x61, 0x6E,
		0x73, 0x66, 0x65, 0x72, 0x2D, 0x45, 0x6E, 0x63, 0x6F, 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x0D, 0x0A,
		0x0D, 0x0A, 0x47, 0x45, 0x54, 0x20, 0x2F, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x31,
		0x0D, 0x0A, 0x48, 0x6F, 0x73, 0x74, 0x3A, 0x20, 0x5B, 0x3A, 0x3A, 0x31, 0x5D, 0x0D, 0x0A, 0x0D,
		0x0A, 0x48, 0x45, 0x41, 0x44, 0x20, 0x2F, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30,
		0x0D, 0x0A, 0x0D, 0x0A]
	const OFFSETS[51] = [0, 18, 118, 137, 171, 177, 184, 197, 222, 248, 264, 283, 304, 324, 344, 375, 403, 431, 457, 475, 511, 538, 571, 627, 683, 723, 761, 796, 861, 926, 964, 1025, 1080, 1129, 1148, 1166, 1192, 1211, 1247, 1267, 1288, 1309, 1331, 1355, 1385, 1403, 1422, 1445, 1468, 1506, 1537]
	const LENGTHS[51] = [18, 100, 19, 34, 6, 7, 13, 25, 26, 16, 19, 21, 20, 20, 31, 28, 28, 26, 18, 36, 27, 33, 56, 56, 40, 38, 35, 65, 65, 38, 61, 55, 49, 19, 18, 26, 19, 36, 20, 21, 21, 22, 24, 30, 18, 19, 23, 23, 38, 31, 19]

	// Selected constant fixture extent and failure observations.
	offset: int
	length: int
	actualLength: int
	ready: bool
	failAt: int
	reads: int

	public fn Select(which: int)
	{
		ready = true
		failAt = -1
		reads = 0

		if (which < 0 || which >= 51) {
			ready = false
			return
		}

		offset = OFFSETS[which]
		length = LENGTHS[which]

		actualLength = length
	}

	public fn Limit(length: int)
	{
		this.length = length
	}

	public fn FailAt(index: int)
	{
		failAt = index
	}

	public fn Release()
	{
		ready = false
	}

	public fn GetReads() int
	{
		return reads
	}

	override fn IsReady() bool
	{
		return ready
	}

	override fn GetAvailableLength() int
	{
		return length
	}

	override fn TryRead(index: int, value: out byte) PacketDataResult
	{
		value = 0xFF
		reads = reads + 1

		if (!ready) {
			return PacketDataResult.NotReady
		}

		if (index < 0 || index >= length || index >= actualLength || index == failAt) {
			return PacketDataResult.Invalid
		}

		value = BYTES[offset + index]
		return PacketDataResult.Success
	}
}