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/HttpRouteFallback.lvt
namespace Livt.Web.Http
using Livt.Net
/**
* Shared constant fallback bodies. No per-route content store.
*/
component HttpRouteFallback : IHttpResponse
{
// Shared immutable plain-text fallback bodies; no per-route copies.
const NOT_FOUND[10] = [0x4E, 0x6F, 0x74, 0x20, 0x46, 0x6F, 0x75, 0x6E, 0x64, 0x0A]
const METHOD_NOT_ALLOWED[19] = [0x4D, 0x65, 0x74, 0x68, 0x6F, 0x64, 0x20, 0x4E, 0x6F, 0x74, 0x20, 0x41, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x0A]
// Prepared error descriptor; constants are never copied into a body buffer.
status: HttpStatus
allowedMethods: HttpAllowedMethods
/**
* Clears the fallback descriptor; shared constant bodies require no release.
*/
public fn Invalidate()
{
status = HttpStatus.Unknown
allowedMethods = HttpAllowedMethods.None
}
/**
* Publishes a shared plain-text 404 or a supported 405/Allow response.
* Other dispatch outcomes return false with no publication.
*/
public fn TryPrepare(dispatch: RouteDispatch, allowedMethods: HttpAllowedMethods) bool
{
this.Invalidate()
if (dispatch == RouteDispatch.NotFound) {
status = HttpStatus.NotFound
return true
}
if (dispatch == RouteDispatch.MethodNotAllowed && HttpResponseSyntax.IsSupported(HttpStatus.MethodNotAllowed, HttpContentType.PlainText, allowedMethods)) {
status = HttpStatus.MethodNotAllowed
this.allowedMethods = allowedMethods
return true
}
return false
}
/**
* Reports current publication availability, not a reservation.
* Keep the borrowed providers stable until all consumers finish.
*/
override fn IsReady() bool
{
return status != HttpStatus.Unknown
}
/**
* Returns the selected response status; use only while IsReady is true.
*/
override fn GetStatus() HttpStatus
{
return status
}
/**
* Returns the selected body media type; use only while IsReady is true.
*/
override fn GetContentType() HttpContentType
{
if (!this.IsReady()) {
return HttpContentType.Unknown
}
return HttpContentType.PlainText
}
/**
* Returns the selected response Allow set, not the routing tree's match set.
* Use only while IsReady is true; None omits the Allow header.
*/
override fn GetAllowedMethods() HttpAllowedMethods
{
return allowedMethods
}
/**
* Returns the currently advertised byte extent, or zero without publication.
* The extent is a snapshot; it does not reserve the backing storage.
*/
override fn GetAvailableLength() int
{
if (status == HttpStatus.NotFound) {
return 10
}
if (status == HttpStatus.MethodNotAllowed) {
return 19
}
return 0
}
/**
* Reads a zero-based byte within the published extent. Check PacketDataResult
* before using value; keep all borrowed providers stable throughout the read.
*/
override fn TryRead(index: int, value: out byte) PacketDataResult
{
value = 0x00
if (!this.IsReady()) {
return PacketDataResult.NotReady
}
if (index < 0 || index >= this.GetAvailableLength()) {
return PacketDataResult.Invalid
}
if (status == HttpStatus.NotFound) {
value = NOT_FOUND[index]
}
else {
value = METHOD_NOT_ALLOWED[index]
}
return PacketDataResult.Success
}
}