Livt packages
Livt.Web
Version 1.0.0
Bounded HTTP routing, request parsing, response encoding, and Ethernet application composition for Livt.
Published files (63)
- HttpAllowedMethods.lvt
- HttpApplication.lvt
- HttpApplicationState.lvt
- HttpContentType.lvt
- HttpHeaderName.lvt
- HttpMatchResult.lvt
- HttpMethod.lvt
- HttpNetworkEndpoint.lvt
- HttpNetworkResponse.lvt
- HttpPath.lvt
- HttpPreparation.lvt
- HttpRequestCursor.lvt
- HttpRequestHeaders.lvt
- HttpRequestLine.lvt
- HttpRequestParser.lvt
- HttpRequestResult.lvt
- HttpRequestSyntax.lvt
- HttpResponse.lvt
- HttpResponseEncoder.lvt
- HttpResponseSyntax.lvt
- HttpRouteFallback.lvt
- HttpRouteMethods.lvt
- HttpRouter.lvt
- HttpServer.lvt
- HttpStatus.lvt
- HttpTcpFrame.lvt
- HttpTcpSequence.lvt
- HttpTcpState.lvt
- HttpTcpTransport.lvt
- HttpTransportPayload.lvt
- HttpTransportState.lvt
- HttpVersion.lvt
- IHttpApplication.lvt
- IHttpHandler.lvt
- IHttpRequest.lvt
- IHttpResponse.lvt
- IHttpRoute.lvt
- IHttpRouteMatcher.lvt
- Route.lvt
- RouteChain.lvt
- RouteDispatch.lvt
- RouteSelection.lvt
- StaticContent.lvt
src/http/HttpPath.lvt
namespace Livt.Web.Http
using Livt.Net
/**
* Exact encoded path matcher over one shared parsed request and an immutable
* application path provider. Owns no path copy. Configuration is checked within
* MAX_PATH on each match; queries, normalization and decoding are not matchers.
*/
component HttpPath<R: IHttpRequest, P: IPacketData, MAX_PATH: int = 128> : IHttpRouteMatcher
{
static assert MAX_PATH > 0, "Path bound must be positive"
// Borrowed request and application-owned constant path bytes.
request: R
path: P
/**
* Borrows the request and encoded path. Keep path bytes immutable during matching;
* the matcher and its route must refer to this same request instance.
*/
new(request: R, path: P)
{
this.request = request
this.path = path
}
/**
* Validates the configured encoded path within MAX_PATH, then compares exact
* request path bytes. Queries are excluded; no decoding or normalization occurs.
* NotReady is retryable; bad configuration or checked-read failure returns Failed.
*/
override fn TryMatch() HttpMatchResult
{
if (!request.IsReady() || !path.IsReady()) {
return HttpMatchResult.NotReady
}
var length = path.GetAvailableLength()
var actualLength = request.GetPathLength()
if (length <= 0 || length > MAX_PATH || actualLength <= 0) {
return HttpMatchResult.Failed
}
var matches = length == actualLength
var hexRemaining: int = 0
for (var i: int = 0; i < length; i++) {
var expected: byte = 0x00
if (path.TryRead(i, expected) != PacketDataResult.Success) {
return HttpMatchResult.Failed
}
if (!HttpRequestSyntax.IsTargetByte(expected) || expected == 0x3F || (i == 0 && expected != 0x2F)) {
return HttpMatchResult.Failed
}
if (hexRemaining > 0) {
if (!HttpRequestSyntax.IsHex(expected)) {
return HttpMatchResult.Failed
}
hexRemaining = hexRemaining - 1
}
elif (expected == 0x25) {
hexRemaining = 2
}
if (length == actualLength) {
var actual: byte = 0x00
if (request.TryReadPath(i, actual) != PacketDataResult.Success) {
return HttpMatchResult.Failed
}
if (actual != expected) {
matches = false
}
}
}
if (hexRemaining != 0) {
return HttpMatchResult.Failed
}
if (matches) {
return HttpMatchResult.Match
}
return HttpMatchResult.NoMatch
}
}