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/HttpResponse.lvt
namespace Livt.Web.Http
using Livt.Net
/**
* Borrowed body with frozen response metadata. Invalidate encoders before this
* view, then release the body. Preparation does not copy or scan body bytes.
*/
component HttpResponse<P: IPacketData> : IHttpResponse
{
// Borrowed stable body; its owner controls storage release.
body: P
// Owned publication extent and frozen response metadata.
ready: bool
length: int
status: HttpStatus
contentType: HttpContentType
allowedMethods: HttpAllowedMethods
/**
* Borrows the body and starts with no published response.
* The body owner must retain its bytes until this view and its consumers close.
*/
new(body: P)
{
this.body = body
this.Invalidate()
}
/**
* Clears publication and metadata without releasing body storage.
* Invalidate dependent encoders before calling this operation.
*/
public fn Invalidate()
{
ready = false
length = 0
status = HttpStatus.Unknown
contentType = HttpContentType.Unknown
allowedMethods = HttpAllowedMethods.None
}
/**
* Replaces the previous descriptor with supported status/media/Allow metadata
* and a published nonnegative body extent. Returns false with no publication;
* preparation neither copies nor reads body bytes.
*/
public fn TryPrepare(status: HttpStatus, contentType: HttpContentType, allowedMethods: HttpAllowedMethods) bool
{
this.Invalidate()
if (!HttpResponseSyntax.IsSupported(status, contentType, allowedMethods) || !body.IsReady()) {
return false
}
var available = body.GetAvailableLength()
if (available < 0) {
return false
}
length = available
this.status = status
this.contentType = contentType
this.allowedMethods = allowedMethods
ready = true
return true
}
/**
* Reports current publication availability, not a reservation.
* Keep the borrowed providers stable until all consumers finish.
*/
override fn IsReady() bool
{
if (ready && !body.IsReady()) {
this.Invalidate()
}
return ready
}
/**
* 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 (!this.IsReady()) {
return 0
}
return length
}
/**
* Returns the selected response status; use only while IsReady is true.
*/
override fn GetStatus() HttpStatus
{
if (!this.IsReady()) {
return HttpStatus.Unknown
}
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 contentType
}
/**
* 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
{
if (!this.IsReady()) {
return HttpAllowedMethods.None
}
return allowedMethods
}
/**
* 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 >= length) {
return PacketDataResult.Invalid
}
var bodyByte: byte = 0x00
var result = body.TryRead(index, bodyByte)
if (result != PacketDataResult.Success) {
this.Invalidate()
return result
}
value = bodyByte
return PacketDataResult.Success
}
}