Livt packages
Livt.Web
Version 1.0.0
Bounded HTTP routing, request parsing, response encoding, and Ethernet application composition for Livt.
Published files (63)
- CounterContent.lvt
- HttpApplicationTest.lvt
- HttpHandlerTest.lvt
- HttpHeaderRangeData.lvt
- HttpHeaderRangeTest.lvt
- HttpNetworkEndpointTest.lvt
- HttpPathTest.lvt
- HttpRequestBoundsTest.lvt
- HttpRequestParserTest.lvt
- HttpRequestTestData.lvt
- HttpResponseEncoderTest.lvt
- HttpResponseTestData.lvt
- HttpRoutingTest.lvt
- HttpTcpSequenceTest.lvt
- RoutingBytes.lvt
- RoutingCounter.lvt
tests/http/HttpNetworkEndpointTest.lvt
namespace Livt.Web.Tests.Http
using Livt.Net
using Livt.Web.Http
@Test
component HttpNetworkEndpointTest
{
const RX[658] = [
0x02, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0x02, 0x10, 0x20, 0x30, 0x40, 0x50, 0x08, 0x00, 0x45, 0x00,
0x00, 0x28, 0x00, 0x01, 0x40, 0x00, 0x40, 0x06, 0x26, 0xCD, 0x0A, 0x00, 0x00, 0x02, 0x0A, 0x00,
0x00, 0x01, 0x30, 0x39, 0x00, 0x50, 0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x50, 0x02,
0x04, 0x00, 0x63, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xAA, 0xBB, 0xCC,
0xDD, 0xEE, 0x02, 0x10, 0x20, 0x30, 0x40, 0x50, 0x08, 0x00, 0x45, 0x00, 0x00, 0x28, 0x00, 0x01,
0x40, 0x00, 0x40, 0x06, 0x26, 0xCD, 0x0A, 0x00, 0x00, 0x02, 0x0A, 0x00, 0x00, 0x01, 0x30, 0x39,
0x00, 0x50, 0x01, 0x02, 0x03, 0x05, 0x00, 0x00, 0x00, 0x02, 0x50, 0x10, 0x04, 0x00, 0x63, 0x40,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0x02, 0x10,
0x20, 0x30, 0x40, 0x50, 0x08, 0x00, 0x45, 0x00, 0x00, 0x40, 0x00, 0x01, 0x40, 0x00, 0x40, 0x06,
0x26, 0xB5, 0x0A, 0x00, 0x00, 0x02, 0x0A, 0x00, 0x00, 0x01, 0x30, 0x39, 0x00, 0x50, 0x01, 0x02,
0x03, 0x05, 0x00, 0x00, 0x00, 0x02, 0x50, 0x18, 0x04, 0x00, 0x28, 0x36, 0x00, 0x00, 0x47, 0x45,
0x54, 0x20, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31,
0x2E, 0x30, 0x0D, 0x0A, 0x0D, 0x0A, 0x02, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0x02, 0x10, 0x20, 0x30,
0x40, 0x50, 0x08, 0x00, 0x45, 0x00, 0x00, 0x40, 0x00, 0x01, 0x40, 0x00, 0x40, 0x06, 0x26, 0xB4,
0x0A, 0x00, 0x00, 0x03, 0x0A, 0x00, 0x00, 0x01, 0x30, 0x39, 0x00, 0x50, 0x01, 0x02, 0x03, 0x05,
0x00, 0x00, 0x00, 0x02, 0x50, 0x18, 0x04, 0x00, 0x28, 0x35, 0x00, 0x00, 0x47, 0x45, 0x54, 0x20,
0x2F, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30,
0x0D, 0x0A, 0x0D, 0x0A, 0x02, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0x02, 0x10, 0x20, 0x30, 0x40, 0x50,
0x08, 0x00, 0x45, 0x00, 0x00, 0x40, 0x00, 0x01, 0x40, 0x00, 0x40, 0x06, 0x26, 0xB5, 0x0A, 0x00,
0x00, 0x02, 0x0A, 0x00, 0x00, 0x01, 0x30, 0x39, 0x00, 0x50, 0x01, 0x02, 0x03, 0x05, 0x00, 0x00,
0x00, 0x02, 0x50, 0x18, 0x04, 0x00, 0x28, 0x36, 0x00, 0x00, 0x47, 0x45, 0x54, 0x20, 0x2F, 0x73,
0x74, 0x61, 0x74, 0x75, 0x02, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0x02, 0x10, 0x20, 0x30, 0x40, 0x50,
0x08, 0x00, 0x45, 0x00, 0x00, 0x2D, 0x00, 0x01, 0x40, 0x00, 0x40, 0x06, 0x26, 0xC8, 0x0A, 0x00,
0x00, 0x02, 0x0A, 0x00, 0x00, 0x01, 0x30, 0x39, 0x00, 0x50, 0x01, 0x02, 0x03, 0x05, 0x00, 0x00,
0x00, 0x02, 0x50, 0x18, 0x04, 0x00, 0x98, 0xCD, 0x00, 0x00, 0x47, 0x45, 0x54, 0x20, 0x2F, 0x00,
0x02, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0x02, 0x10, 0x20, 0x30, 0x40, 0x50, 0x08, 0x00, 0x45, 0x00,
0x00, 0x28, 0x00, 0x01, 0x40, 0x00, 0x40, 0x06, 0x26, 0xCD, 0x0A, 0x00, 0x00, 0x02, 0x0A, 0x00,
0x00, 0x01, 0x30, 0x39, 0x00, 0x50, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x50, 0x02,
0x04, 0x00, 0x67, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xAA, 0xBB, 0xCC,
0xDD, 0xEE, 0x02, 0x10, 0x20, 0x30, 0x40, 0x50, 0x08, 0x06, 0x00, 0x01, 0x08, 0x00, 0x06, 0x04,
0x00, 0x01, 0x02, 0x10, 0x20, 0x30, 0x40, 0x50, 0x0A, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x0A, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0x02, 0x10,
0x20, 0x30, 0x40, 0x50, 0x08, 0x00, 0x45, 0x00, 0x00, 0x1F, 0x00, 0x01, 0x40, 0x00, 0x40, 0x01,
0x26, 0xDB, 0x0A, 0x00, 0x00, 0x02, 0x0A, 0x00, 0x00, 0x01, 0x08, 0x00, 0x21, 0x68, 0x12, 0x34,
0x00, 0x01, 0x61, 0x62, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x02, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0x02, 0x10, 0x20, 0x30, 0x40, 0x50,
0x08, 0x00, 0x45, 0x00, 0x00, 0x40, 0x00, 0x01, 0x40, 0x00, 0x40, 0x06, 0x26, 0xB5, 0x0A, 0x00,
0x00, 0x02, 0x0A, 0x00, 0x00, 0x01, 0x30, 0x39, 0x00, 0x50, 0x01, 0x02, 0x03, 0x05, 0x00, 0x00,
0x00, 0x02, 0x50, 0x18, 0x04, 0x00, 0xD7, 0x36, 0x00, 0x00, 0x47, 0x45, 0x54, 0x20, 0x2F, 0x73,
0x74, 0x61, 0x74, 0x75, 0x73, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30, 0x0D, 0x0A,
0x0D, 0x0A]
const RX_OFFSETS[10] = [0, 60, 120, 198, 276, 340, 400, 460, 520, 580]
const RX_LENGTHS[10] = [60, 60, 78, 78, 64, 60, 60, 60, 60, 78]
const TX[386] = [
0x02, 0x10, 0x20, 0x30, 0x40, 0x50, 0x02, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0x08, 0x00, 0x45, 0x00,
0x00, 0x28, 0x00, 0x02, 0x40, 0x00, 0x40, 0x06, 0x26, 0xCC, 0x0A, 0x00, 0x00, 0x01, 0x0A, 0x00,
0x00, 0x02, 0x00, 0x50, 0x30, 0x39, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x03, 0x05, 0x50, 0x12,
0x04, 0x00, 0x63, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x20, 0x30,
0x40, 0x50, 0x02, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0x08, 0x00, 0x45, 0x00, 0x00, 0x84, 0x00, 0x01,
0x40, 0x00, 0x40, 0x06, 0x26, 0x71, 0x0A, 0x00, 0x00, 0x01, 0x0A, 0x00, 0x00, 0x02, 0x00, 0x50,
0x30, 0x39, 0x00, 0x00, 0x00, 0x02, 0x01, 0x02, 0x03, 0x1D, 0x50, 0x19, 0x04, 0x00, 0x49, 0xFB,
0x00, 0x00, 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30, 0x20, 0x32, 0x30, 0x30, 0x20, 0x4F,
0x4B, 0x0D, 0x0A, 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x2D, 0x54, 0x79, 0x70, 0x65, 0x3A,
0x20, 0x61, 0x70, 0x70, 0x6C, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x2F, 0x6A, 0x73, 0x6F,
0x6E, 0x0D, 0x0A, 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x2D, 0x4C, 0x65, 0x6E, 0x67, 0x74,
0x68, 0x3A, 0x20, 0x33, 0x0D, 0x0A, 0x43, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E,
0x3A, 0x20, 0x63, 0x6C, 0x6F, 0x73, 0x65, 0x0D, 0x0A, 0x0D, 0x0A, 0x5B, 0x37, 0x5D, 0x02, 0x10,
0x20, 0x30, 0x40, 0x50, 0x02, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0x08, 0x06, 0x00, 0x01, 0x08, 0x00,
0x06, 0x04, 0x00, 0x02, 0x02, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0x0A, 0x00, 0x00, 0x01, 0x02, 0x10,
0x20, 0x30, 0x40, 0x50, 0x0A, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x20, 0x30, 0x40, 0x50,
0x02, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0x08, 0x00, 0x45, 0x00, 0x00, 0x1F, 0x00, 0x01, 0x40, 0x00,
0x40, 0x01, 0x26, 0xDB, 0x0A, 0x00, 0x00, 0x01, 0x0A, 0x00, 0x00, 0x02, 0x00, 0x00, 0x29, 0x68,
0x12, 0x34, 0x00, 0x01, 0x61, 0x62, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x20, 0x30, 0x40, 0x50, 0x02, 0xAA, 0xBB, 0xCC,
0xDD, 0xEE, 0x08, 0x00, 0x45, 0x00, 0x00, 0x28, 0x00, 0x02, 0x40, 0x00, 0x40, 0x06, 0x26, 0xCC,
0x0A, 0x00, 0x00, 0x01, 0x0A, 0x00, 0x00, 0x02, 0x00, 0x50, 0x30, 0x39, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x50, 0x12, 0x04, 0x00, 0x67, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00]
const TX_OFFSETS[5] = [0, 60, 206, 266, 326]
const TX_LENGTHS[5] = [60, 146, 60, 60, 60]
source: RamPacketData<256>
ethernet: EthernetFrameParser<RamPacketData<256>>
ipv4: Ipv4PacketParser<EthernetFrameParser<RamPacketData<256>>>
connection: TcpConnectionRecognizer<RamPacketData<256>>
request: HttpRequestParser<TcpConnectionRecognizer<RamPacketData<256>>>
path: RoutingBytes
counter: RoutingCounter
handler: CounterContent
matcher: HttpPath<HttpRequestParser<TcpConnectionRecognizer<RamPacketData<256>>>, RoutingBytes>
route: Route<HttpRequestParser<TcpConnectionRecognizer<RamPacketData<256>>>, HttpPath<HttpRequestParser<TcpConnectionRecognizer<RamPacketData<256>>>, RoutingBytes>, CounterContent>
router: HttpRouter<Route<HttpRequestParser<TcpConnectionRecognizer<RamPacketData<256>>>, HttpPath<HttpRequestParser<TcpConnectionRecognizer<RamPacketData<256>>>, RoutingBytes>, CounterContent>>
application: HttpApplication<TcpConnectionRecognizer<RamPacketData<256>>, Route<HttpRequestParser<TcpConnectionRecognizer<RamPacketData<256>>>, HttpPath<HttpRequestParser<TcpConnectionRecognizer<RamPacketData<256>>>, RoutingBytes>, CounterContent>>
endpoint: HttpNetworkEndpoint<RamPacketData<256>, HttpApplication<TcpConnectionRecognizer<RamPacketData<256>>, Route<HttpRequestParser<TcpConnectionRecognizer<RamPacketData<256>>>, HttpPath<HttpRequestParser<TcpConnectionRecognizer<RamPacketData<256>>>, RoutingBytes>, CounterContent>>, 256>
new()
{
var localMac: byte[6] = [0x02, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE]
var localIp: byte[4] = [0x0A, 0x00, 0x00, 0x01]
var localPort: byte[2] = [0x00, 0x50]
source = new RamPacketData<256>()
ethernet = new EthernetFrameParser<RamPacketData<256>>(source)
ipv4 = new Ipv4PacketParser<EthernetFrameParser<RamPacketData<256>>>(ethernet)
connection = new TcpConnectionRecognizer<RamPacketData<256>>(ethernet, ipv4)
request = new HttpRequestParser<TcpConnectionRecognizer<RamPacketData<256>>>(connection)
path = new RoutingBytes()
counter = new RoutingCounter()
handler = new CounterContent(counter)
matcher = new HttpPath<HttpRequestParser<TcpConnectionRecognizer<RamPacketData<256>>>, RoutingBytes>(request, path)
route = new Route<HttpRequestParser<TcpConnectionRecognizer<RamPacketData<256>>>, HttpPath<HttpRequestParser<TcpConnectionRecognizer<RamPacketData<256>>>, RoutingBytes>, CounterContent>(HttpMethod.Get, request, matcher, handler)
router = new HttpRouter<Route<HttpRequestParser<TcpConnectionRecognizer<RamPacketData<256>>>, HttpPath<HttpRequestParser<TcpConnectionRecognizer<RamPacketData<256>>>, RoutingBytes>, CounterContent>>(route)
application = new HttpApplication<TcpConnectionRecognizer<RamPacketData<256>>, Route<HttpRequestParser<TcpConnectionRecognizer<RamPacketData<256>>>, HttpPath<HttpRequestParser<TcpConnectionRecognizer<RamPacketData<256>>>, RoutingBytes>, CounterContent>>(request, router)
endpoint = new HttpNetworkEndpoint<RamPacketData<256>, HttpApplication<TcpConnectionRecognizer<RamPacketData<256>>, Route<HttpRequestParser<TcpConnectionRecognizer<RamPacketData<256>>>, HttpPath<HttpRequestParser<TcpConnectionRecognizer<RamPacketData<256>>>, RoutingBytes>, CounterContent>>, 256>(source, ethernet, ipv4, connection, application, localMac, localIp, localPort)
}
fn Reset()
{
endpoint.Abort()
assert endpoint.TryRelease() == PacketDataResult.Success
if (source.IsReady()) {
assert source.TryRelease() == PacketDataResult.Success
}
else {
assert source.TryClear() == PacketDataResult.Success
}
path.Select(1)
counter.Set(7)
handler.ResetCounts()
}
fn Load(which: int)
{
assert endpoint.TryRelease() == PacketDataResult.Success
if (source.IsReady()) {
assert source.TryRelease() == PacketDataResult.Success
}
else {
assert source.TryClear() == PacketDataResult.Success
}
for (var i: int = 0; i < RX_LENGTHS[which]; i++) {
assert source.TryWrite(i, RX[RX_OFFSETS[which] + i]) == PacketDataResult.Success
}
assert source.TryPublish() == PacketDataResult.Success
}
fn CheckFrame(which: int)
{
assert endpoint.GetAvailableLength() == TX_LENGTHS[which]
for (var i: int = 0; i < TX_LENGTHS[which]; i++) {
var value: byte = 0xFF
assert endpoint.TryRead(i, value) == PacketDataResult.Success
assert value == TX[TX_OFFSETS[which] + i]
}
}
fn Finish()
{
assert endpoint.MarkEmitted()
assert endpoint.Complete()
assert endpoint.TryRelease() == PacketDataResult.Success
}
fn Handshake()
{
this.Load(0)
assert endpoint.HandleFrame() == HttpTransportState.Prepared
assert endpoint.GetResponseKind() == HttpNetworkResponse.TcpSynAck
this.Finish()
}
fn PrepareHttp()
{
this.Load(2)
assert endpoint.HandleFrame() == HttpTransportState.Pending
assert endpoint.HandleFrame() == HttpTransportState.Pending
assert endpoint.Poll() == HttpTransportState.Pending
assert endpoint.Poll() == HttpTransportState.Prepared
assert handler.GetStarts() == 1
}
@Test
fn SynResponseAndRetention()
{
this.Reset()
this.Load(0)
assert endpoint.HandleFrame() == HttpTransportState.Prepared
this.CheckFrame(0)
assert !endpoint.Complete()
assert endpoint.TryRelease() == PacketDataResult.Busy
assert endpoint.MarkEmitted()
assert endpoint.TryRelease() == PacketDataResult.Busy
assert endpoint.IsReady()
assert source.TryWrite(0, 0x00) == PacketDataResult.Busy
assert endpoint.Complete()
assert endpoint.TryRelease() == PacketDataResult.Success
assert !connection.IsReady()
assert handler.GetStarts() == 0
}
@Test
fn CombinedAckRequestResponseAndRetainedSnapshot()
{
this.Reset()
this.Handshake()
this.PrepareHttp()
assert endpoint.GetResponseKind() == HttpNetworkResponse.Http
assert endpoint.HandleFrame() == HttpTransportState.Prepared
this.CheckFrame(1)
assert endpoint.MarkEmitted()
assert application.GetState() == HttpApplicationState.Retained
assert request.IsReady()
assert endpoint.TryRelease() == PacketDataResult.Busy
counter.Set(9)
var value: byte = 0x00
assert endpoint.TryRead(TX_LENGTHS[1] - 2, value) == PacketDataResult.Success
assert value == 0x37
assert endpoint.Complete()
assert !application.IsReady()
assert handler.GetEnds() == 1
assert endpoint.TryRelease() == PacketDataResult.Success
assert !request.IsReady()
assert !connection.IsReady()
assert source.IsReady()
}
@Test
fn StandaloneAckThenHttp()
{
this.Reset()
this.Handshake()
this.Load(1)
assert endpoint.HandleFrame() == HttpTransportState.Ignored
this.PrepareHttp()
this.CheckFrame(1)
this.Finish()
}
@Test
fn ArpUsesSharedCaptureWithoutHttp()
{
this.Reset()
this.Load(7)
assert endpoint.HandleFrame() == HttpTransportState.Prepared
assert endpoint.GetResponseKind() == HttpNetworkResponse.Arp
this.CheckFrame(2)
this.Finish()
assert handler.GetStarts() == 0
}
@Test
fn IcmpUsesSharedCaptureWithoutHttp()
{
this.Reset()
this.Load(8)
assert endpoint.HandleFrame() == HttpTransportState.Prepared
assert endpoint.GetResponseKind() == HttpNetworkResponse.IcmpEcho
this.CheckFrame(3)
this.Finish()
assert handler.GetStarts() == 0
}
@Test
fn TruncatedCaptureDoesNotReachApplication()
{
this.Reset()
this.Handshake()
this.Load(4)
assert endpoint.HandleFrame() == HttpTransportState.Failed
assert handler.GetStarts() == 0
assert !endpoint.IsReady()
assert endpoint.TryRelease() == PacketDataResult.Success
}
@Test
fn IncompleteHttpPayloadDoesNotRunHandler()
{
this.Reset()
this.Handshake()
this.Load(5)
assert endpoint.HandleFrame() == HttpTransportState.Failed
assert application.GetRequestResult() == HttpRequestResult.Incomplete
assert handler.GetStarts() == 0
assert endpoint.TryRelease() == PacketDataResult.Success
}
@Test
fn OtherPeerCannotUseHandshake()
{
this.Reset()
this.Handshake()
this.Load(3)
assert endpoint.HandleFrame() == HttpTransportState.Ignored
assert handler.GetStarts() == 0
this.PrepareHttp()
this.Finish()
}
@Test
fn CancelPendingBeforeSourceReuse()
{
this.Reset()
this.Handshake()
this.Load(2)
assert endpoint.HandleFrame() == HttpTransportState.Pending
assert endpoint.TryRelease() == PacketDataResult.Busy
endpoint.Abort()
assert handler.GetEnds() == 1
assert endpoint.TryRelease() == PacketDataResult.Success
assert application.GetState() == HttpApplicationState.Idle
assert !connection.IsReady()
this.Load(2)
assert endpoint.HandleFrame() == HttpTransportState.Ignored
}
@Test
fn ChecksumPreparationFailurePublishesNoFrame()
{
this.Reset()
this.Handshake()
this.Load(2)
assert endpoint.HandleFrame() == HttpTransportState.Pending
assert endpoint.Poll() == HttpTransportState.Pending
handler.FailRead()
assert endpoint.Poll() == HttpTransportState.Failed
assert !endpoint.IsReady()
assert endpoint.GetAvailableLength() == 0
assert handler.GetEnds() == 1
assert endpoint.TryRelease() == PacketDataResult.Success
}
@Test
fn EmissionFailureStopsResponse()
{
this.Reset()
this.Handshake()
this.PrepareHttp()
handler.FailRead()
var value: byte = 0xFF
assert endpoint.TryRead(TX_LENGTHS[1] - 1, value) == PacketDataResult.Busy
assert value == 0x00
assert !endpoint.IsReady()
assert endpoint.GetState() == HttpTransportState.Failed
assert handler.GetEnds() == 1
assert endpoint.TryRelease() == PacketDataResult.Success
}
@Test
fn AbortRetainedResponseResetsSession()
{
this.Reset()
this.Handshake()
this.PrepareHttp()
assert endpoint.MarkEmitted()
endpoint.Abort()
endpoint.Abort()
assert endpoint.TryRelease() == PacketDataResult.Success
assert handler.GetEnds() == 1
assert source.IsReady()
this.Load(2)
assert endpoint.HandleFrame() == HttpTransportState.Ignored
}
@Test
fn UnpublishedCaptureDoesNotStartWork()
{
this.Reset()
assert endpoint.HandleFrame() == HttpTransportState.NotReady
assert handler.GetStarts() == 0
this.Load(0)
assert endpoint.HandleFrame() == HttpTransportState.Prepared
this.Finish()
}
@Test
fn SequenceAcknowledgmentWraps()
{
this.Reset()
this.Load(6)
assert endpoint.HandleFrame() == HttpTransportState.Prepared
this.CheckFrame(4)
this.Finish()
}
@Test
fn DocumentsCurrentUncheckedTcpChecksumPolicy()
{
this.Reset()
this.Handshake()
this.Load(9)
// Known Net policy gap: structural parsing does not enforce receive checksum.
assert endpoint.HandleFrame() == HttpTransportState.Pending
assert handler.GetStarts() == 1
endpoint.Abort()
assert endpoint.TryRelease() == PacketDataResult.Success
}
}