Description
Provides a bounded HTTP/1.1 connection engine over a task-aware transport. The engine supports persistent requests, fixed-length and chunked request bodies, fixed responses, server-sent events, and RFC 6455 WebSockets.
Accept_Body
procedure Accept_Body
(Item : in out Connection;
Token : access Flyology.Cancellation.Token := null)
Accept the current request body, sending 100 Continue when requested. The original Read_Request_Head deadline remains authoritative.
Parameters
- Item
HTTP connection with an unread request body
- Token
Optional cancellation source
Accept_WebSocket
procedure Accept_WebSocket
(Item : in out Connection;
Value : Request;
Protocol : String := "";
Origin_Policy : WebSocket_Origin_Policy := Reject_Browser_Origins;
Allowed_Origin : String := "";
Timeout : Duration := 30.0;
Token : access Flyology.Cancellation.Token := null;
Compression : WebSocket_Compression_Mode := No_WebSocket_Compression)
Perform an RFC 6455 server upgrade for Request. The client key and required Upgrade, Connection, and version fields are validated.
Parameters
- Item
HTTP connection
- Value
Request being upgraded
- Protocol
Optional selected subprotocol token
- Origin_Policy
Browser-origin policy; secure non-browser default
- Allowed_Origin
Exact origin required by Require_Exact_Origin
- Timeout
Transport send deadline
- Token
Optional cancellation source
- Compression
Explicit RFC 7692 negotiation policy
Raised exceptions
- Protocol_Error
Request is not a valid version 13 upgrade
Begin_Response_Stream
procedure Begin_Response_Stream
(Item : in out Connection;
Status : Positive;
Content_Type : String;
Extra_Headers : String := "";
Close : Boolean := False;
Timeout : Duration := 30.0;
Token : access Flyology.Cancellation.Token := null)
Start an arbitrary streaming response. HTTP/1.1 uses chunked framing; HTTP/1.0 uses connection-close delimiting. The handler remains the sole writer until End_Response_Stream completes.
Parameters
- Item
HTTP connection
- Status
HTTP status
- Content_Type
Media type, or empty to omit
- Extra_Headers
Additional validated response fields
- Close
Force connection closure after the stream
- Timeout
Transport send deadline
- Token
Optional cancellation source
Begin_SSE
procedure Begin_SSE
(Item : in out Connection;
Extra_Headers : String := "";
Timeout : Duration := 30.0;
Token : access Flyology.Cancellation.Token := null)
Start a chunked text/event-stream response.
Parameters
- Item
HTTP connection
- Extra_Headers
Additional validated response fields
- Timeout
Transport send deadline
- Token
Optional cancellation source
Body_Complete
function Body_Complete (Item : Connection) return Boolean
Report whether the current request body and trailers are consumed.
Parameters
- Item
HTTP connection
Return value
True when another request may be parsed after the response
Buffer_Request_Body
procedure Buffer_Request_Body
(Item : in out Connection;
Value : in out Request;
Token : access Flyology.Cancellation.Token := null)
Buffer the current decoded body into Value under the configured shared ingress budget. This is the routed equivalent of Read_Request's body phase and preserves the request-head deadline.
Parameters
- Item
HTTP connection with an unread body
- Value
Request head previously read from Item
- Token
Optional cancellation source
Raised exceptions
- Resource_Exhausted
Shared buffered ingress budget is full
Close_WebSocket
procedure Close_WebSocket
(Item : in out Connection;
Code : Positive := 1_000;
Reason : String := "";
Timeout : Duration := 30.0;
Token : access Flyology.Cancellation.Token := null)
Send a normal WebSocket close frame and make Item terminal.
Parameters
- Item
Upgraded WebSocket connection
- Code
RFC 6455 close status
- Reason
Optional UTF-8 close reason
- Timeout
Transport send deadline
- Token
Optional cancellation source
Configure_Ingress_Budget
procedure Configure_Ingress_Budget
(Item : in out Connection;
Budget : not null access Ingress_Budget)
Attach one shared ingress budget before the first request is read. The budget must outlive Item and cannot be replaced while bytes are reserved.
Parameters
- Item
HTTP connection to configure
- Budget
Shared server budget
Connection
type Connection (Channel : not null access Transport'Class) is limited
private;
HTTP/WebSocket state for one transport. The object and transport must remain owned by one handler at a time. Buffered pipelined input is kept between Read_Request calls.
Record fields
- Channel
Borrowed transport kept alive for this object
Content
function Content (Item : Request) return String
Return the decoded fixed-length or chunked request body.
Parameters
- Item
Request to inspect
Return value
Body bytes represented as an Ada String
Current
function Current (Item : Ingress_Budget) return Ingress_Budget_Snapshot
Read current budget counters.
Parameters
- Item
Shared server budget
Return value
Stable accounting snapshot
Current
function Current (Item : Outbound_Budget) return Outbound_Budget_Snapshot
Read current outbound budget counters.
Parameters
- Item
Shared application/server budget
Return value
Stable accounting snapshot
Default_Ingress_Budget_Bytes
Default_Ingress_Budget_Bytes : constant := 64 * 1_024 * 1_024;
Process-wide retained-payload budget used by connections that do not attach a server-specific Ingress_Budget.
Default_Max_WebSocket_Message
Default_Max_WebSocket_Message : constant := 1_024 * 1_024;
Default maximum retained or reassembled inbound WebSocket message.
Default_Outbound_Budget_Bytes
Default_Outbound_Budget_Bytes : constant := 64 * 1_024 * 1_024;
Process-wide retained outbound-message budget used by high-level SSE and WebSocket sessions without an application-supplied budget.
Discard_Body
procedure Discard_Body
(Item : in out Connection;
Token : access Flyology.Cancellation.Token := null)
Consume and discard the current body under the original absolute deadline. This is explicit because silently draining an unwanted body can itself be a slow-client attack.
Parameters
- Item
HTTP connection with a current request
- Token
Optional cancellation source
End_Response_Stream
procedure End_Response_Stream
(Item : in out Connection;
Timeout : Duration := 30.0;
Token : access Flyology.Cancellation.Token := null)
Complete a streaming response and release the connection for another request when persistence remains safe.
Parameters
- Item
Active streaming response
- Timeout
Transport send deadline
- Token
Optional cancellation source
End_SSE
procedure End_SSE
(Item : in out Connection;
Timeout : Duration := 30.0;
Token : access Flyology.Cancellation.Token := null)
Finish a chunked SSE response. The HTTP connection can process another request when persistence remains enabled.
Parameters
- Item
Active SSE response
- Timeout
Transport send deadline
- Token
Optional cancellation source
Expectation_Failed
Expectation_Failed : exception;
Raised for an unsupported or malformed Expect request field.
Header
function Header (Item : Request; Name : String) return String
Return a case-insensitive header value with surrounding whitespace removed. Repeated fields are comma-joined in wire order.
Parameters
- Item
Request to inspect
- Name
Header field name
Return value
Header value, or an empty string when absent
Header_Count
function Header_Count (Item : Request; Name : String) return Natural
Count physical occurrences of one case-insensitive request field.
Parameters
- Item
Request to inspect
- Name
Header field name
Return value
Physical field count before comma joining
Header_Has_Token
function Header_Has_Token
(Item : Request; Name : String; Value : String) return Boolean
Report whether a comma-separated header contains a token.
Parameters
- Item
Request to inspect
- Name
Header field name
- Value
Token sought case-insensitively
Return value
True when the token occurs as a complete list member
Ingress_Budget
type Ingress_Budget (Limit : Positive) is limited private;
Nonblocking shared budget for retained request bodies and WebSocket messages. Streaming operations write into caller-owned buffers and do not reserve their payload bytes here.
Record fields
- Limit
Maximum simultaneously reserved payload bytes
Ingress_Budget_Snapshot
type Ingress_Budget_Snapshot is record
Limit : Positive;
Current : Natural;
Peak : Natural;
Denials : Natural;
end record;
Snapshot of shared buffered-ingress accounting.
Record fields
- Limit
Configured maximum reserved bytes
- Current
Bytes currently reserved
- Peak
Highest observed reservation
- Denials
Failed nonblocking reservation attempts
Max_Header_Bytes
Max_Header_Bytes : constant := 16 * 1_024;
Maximum bytes before the terminating empty request-header line.
Max_Request_Body
Max_Request_Body : constant := 1_024 * 1_024;
Maximum decoded request representation.
Max_WebSocket_Frame
Max_WebSocket_Frame : constant := 16 * 1_024 * 1_024;
Maximum supported inbound or generated WebSocket frame payload. Callers may opt into this bound with Receive_WebSocket's Max_Message parameter.
Method
function Method (Item : Request) return String
Return the request method exactly as received.
Parameters
- Item
Request to inspect
Return value
Case-sensitive method token
Narrow_Body_Limit
procedure Narrow_Body_Limit
(Item : in out Connection;
Maximum : Natural)
Reduce the decoded body limit after request-head routing. This must be called before body consumption and can never increase the parser limit.
Parameters
- Item
HTTP connection with an unread request body
- Maximum
New decoded-body maximum
Narrow_Request_Deadline
procedure Narrow_Request_Deadline
(Item : in out Connection;
Deadline : Ada.Real_Time.Time)
Shorten the current request deadline. A later value is rejected so no application layer can restart or extend slow-client protection.
Parameters
- Item
HTTP connection with a current request
- Deadline
Earlier absolute monotonic deadline
Outbound_Budget
type Outbound_Budget (Limit : Positive) is limited private;
Nonblocking shared budget for application messages retained by the optional SSE and WebSocket lifecycle APIs.
Record fields
- Limit
Maximum simultaneously retained outbound bytes
Outbound_Budget_Snapshot
subtype Outbound_Budget_Snapshot is Ingress_Budget_Snapshot;
Snapshot of shared queued-outbound accounting.
Payload_Too_Large
Payload_Too_Large : exception;
Raised when the declared or decoded body exceeds the active limit.
Read_Body
procedure Read_Body
(Item : in out Connection;
Data : out Ada.Streams.Stream_Element_Array;
Last : out Ada.Streams.Stream_Element_Offset;
Finished : out Boolean;
Token : access Flyology.Cancellation.Token := null)
Stream decoded body bytes into caller-owned storage. Fixed-length and chunked framing are removed. Finished becomes true only after all body framing and trailers are consumed. The request-head deadline is never restarted by incremental reads.
Parameters
- Item
HTTP connection with a current request
- Data
Caller-owned destination
- Last
Last decoded byte, or Data'First - 1 when none
- Finished
True after the complete body and trailers
- Token
Optional cancellation source
Read_Request
procedure Read_Request
(Item : in out Connection;
Value : out Request;
Peer_Closed : out Boolean;
Timeout : Duration := 30.0;
Max_Body : Natural := Max_Request_Body;
Token : access Flyology.Cancellation.Token := null)
Read and parse the next request, buffering its complete decoded body. This compatibility operation is implemented over Read_Request_Head and Read_Body. When Item has an ingress budget, fixed bodies reserve their declared length and chunked bodies reserve Max_Body before allocation. Resource_Exhausted is raised without waiting when reservation fails. Header and body limits are enforced before allocation grows beyond their public bounds. One monotonic Timeout covers the complete header and decoded body, so incremental progress cannot extend a slow client's deadline. HTTP/1.1 requires Host.
Parameters
- Item
HTTP connection
- Value
Parsed request on success
- Peer_Closed
True only when the peer closes between requests
- Timeout
Deadline used by each transport receive
- Max_Body
Application body limit, capped by Max_Request_Body
- Token
Optional cancellation source
Raised exceptions
- Protocol_Error
Input is malformed, oversized, or unsupported
- Resource_Exhausted
Shared buffered ingress budget is full
Read_Request_Head
procedure Read_Request_Head
(Item : in out Connection;
Value : out Request;
Peer_Closed : out Boolean;
Header_Timeout : Duration;
Request_Timeout : Duration;
Max_Body : Natural := Max_Request_Body;
Token : access Flyology.Cancellation.Token := null)
Read and validate a request head with distinct absolute budgets for the header and complete request. Both clocks start before the first header byte, so neither incremental headers nor a streamed body can restart a deadline. Request_Timeout may exceed Header_Timeout for explicitly admitted long-lived responses such as SSE and WebSocket lifecycles.
Parameters
- Item
HTTP connection
- Value
Parsed request head on success; Content is empty
- Peer_Closed
True only when the peer closes between requests
- Header_Timeout
Absolute request-head deadline interval
- Request_Timeout
Absolute complete-request deadline interval
- Max_Body
Application body limit, capped by Max_Request_Body
- Token
Optional cancellation source
Read_Request_Head
procedure Read_Request_Head
(Item : in out Connection;
Value : out Request;
Peer_Closed : out Boolean;
Timeout : Duration := 30.0;
Max_Body : Natural := Max_Request_Body;
Token : access Flyology.Cancellation.Token := null)
Read and validate the next request head without buffering its body. Body framing remains attached to Item and must be consumed with Read_Body or Discard_Body before another request can be read. One monotonic Timeout begins here and covers the complete streamed body. Expect: 100-continue is not emitted until Accept_Body is called.
Parameters
- Item
HTTP connection
- Value
Parsed request head on success; Content is empty
- Peer_Closed
True only when the peer closes between requests
- Timeout
Absolute header-and-body deadline interval
- Max_Body
Application body limit, capped by Max_Request_Body
- Token
Optional cancellation source
Receive
procedure Receive
(Item : in out Transport;
Data : out Ada.Streams.Stream_Element_Array;
Last : out Ada.Streams.Stream_Element_Offset;
Timeout : Duration;
Token : access Flyology.Cancellation.Token)
Receive one available transport chunk.
Parameters
- Item
Transport to read
- Data
Destination buffer
- Last
Last byte received, or Data'First - 1 on orderly closure
- Timeout
Operation deadline interval in seconds
- Token
Optional cancellation source that must outlive the call
Receive_WebSocket
procedure Receive_WebSocket
(Item : in out Connection;
Kind : out WebSocket_Data_Kind;
Data : out Flyology.Bytes.Unbounded_Bytes;
Closed : out Boolean;
Max_Message : Natural := Default_Max_WebSocket_Message;
Timeout : Duration := 30.0;
Message_Timeout : Duration := 30.0;
Token : access Flyology.Cancellation.Token := null)
Receive one complete client message, reassembling fragments within Max_Message. Timeout bounds one wait quantum; Message_Timeout is one monotonic deadline retained across retry quanta, all fragments, and interleaved control frames. Ping is answered automatically and close sets Closed. Client frames must be masked. Protocol failure makes Item terminal. Negotiated compression is decoded before return; compressed and decompressed storage is charged to the shared ingress budget. A Timeout expiry may be retried while Item remains active. Expiry of the retained whole-message deadline or a control-frame write makes Item terminal before raising Timeout_Error.
Parameters
- Item
Upgraded WebSocket connection
- Kind
Text or binary message kind
- Data
Message payload
- Closed
True after a valid close frame
- Max_Message
Application message limit, capped by the 16 MiB supported frame maximum; the default remains 1 MiB
- Timeout
Transport receive/send wait quantum
- Message_Timeout
Whole-message monotonic deadline
- Token
Optional cancellation source
Raised exceptions
- Resource_Exhausted
Shared message reassembly budget is full
Release
procedure Release (Item : in out Ingress_Budget; Bytes : Natural)
Release a prior successful reservation.
Parameters
- Item
Shared server budget
- Bytes
Reserved bytes to return
Release
procedure Release (Item : in out Outbound_Budget; Bytes : Natural)
Release a prior outbound reservation.
Parameters
- Item
Shared application/server budget
- Bytes
Reserved bytes to return
Request
type Request is private;
One parsed request. Values are replaced by Read_Request.
Request_Deadline
function Request_Deadline (Item : Connection) return Ada.Real_Time.Time
Return the absolute monotonic deadline established for the current request. Time_Last represents an unlimited deadline.
Parameters
- Item
HTTP connection
Return value
Original or narrowed request deadline
Resource_Exhausted
Resource_Exhausted : exception;
Raised when a buffered compatibility operation cannot reserve its payload from the configured shared ingress budget.
Respond
procedure Respond
(Item : in out Connection;
Status : Positive;
Content_Type : String;
Payload : String;
Extra_Headers : String := "";
Close : Boolean := False;
Timeout : Duration := 30.0;
Token : access Flyology.Cancellation.Token := null)
Send one complete fixed-length response. Reason is derived from Status. Extra_Headers is a sequence of complete CRLF-terminated fields and must not contain an empty line. HEAD sends the declared body length without body bytes. Statuses 204, 205, and 304 reject nonempty Payload; 204 and 304 omit Content-Length. Connection persistence follows the request unless Close is true.
Parameters
- Item
HTTP connection
- Status
Three-digit HTTP status
- Content_Type
Media type, or empty to omit
- Payload
Response representation
- Extra_Headers
Additional validated header fields
- Close
Force connection closure after the response
- Timeout
Transport send deadline
- Token
Optional cancellation source
Response_Started
function Response_Started (Item : Connection) return Boolean
Report whether the current request already received a response or protocol upgrade.
Parameters
- Item
HTTP connection
Return value
True after Respond, Begin_SSE, or Accept_WebSocket
Send_All
procedure Send_All
(Item : in out Transport;
Data : Ada.Streams.Stream_Element_Array;
Timeout : Duration;
Token : access Flyology.Cancellation.Token)
Send a complete transport chunk.
Parameters
- Item
Transport to write
- Data
Source bytes
- Timeout
Operation deadline interval in seconds
- Token
Optional cancellation source that must outlive the call
Send_Event
procedure Send_Event
(Item : in out Connection;
Data : String;
Event : String := "";
Id : String := "";
Retry : Natural := 0;
Timeout : Duration := 30.0;
Token : access Flyology.Cancellation.Token := null;
Include_Id : Boolean := False;
Include_Retry : Boolean := False)
Send one SSE event as one HTTP chunk. Embedded newlines in Data become repeated data fields. Empty Event and ordinary default Id/Retry values are omitted; include flags allow the valid empty-id reset and retry 0.
Parameters
- Item
Active SSE response
- Data
Event data
- Event
Optional event type
- Id
Optional event id
- Retry
Optional client retry interval in milliseconds
- Timeout
Transport send deadline
- Token
Optional cancellation source
- Include_Id
Emit id even when Id is empty
- Include_Retry
Emit retry even when Retry is zero
Send_SSE_Comment
procedure Send_SSE_Comment
(Item : in out Connection;
Comment : String := "";
Timeout : Duration := 30.0;
Token : access Flyology.Cancellation.Token := null)
Send one SSE comment, commonly used as a heartbeat without dispatching an application message in EventSource clients.
Parameters
- Item
Active SSE response
- Comment
Comment text; embedded newlines become comment fields
- Timeout
Transport send deadline
- Token
Optional cancellation source
Send_WebSocket
procedure Send_WebSocket
(Item : in out Connection;
Kind : WebSocket_Data_Kind;
Data : Ada.Streams.Stream_Element_Array;
Timeout : Duration := 30.0;
Token : access Flyology.Cancellation.Token := null)
Send one unmasked, final server data frame.
Parameters
- Item
Upgraded WebSocket connection
- Kind
Text or binary message kind
- Data
Frame payload
- Timeout
Transport send deadline
- Token
Optional cancellation source
Send_WebSocket
procedure Send_WebSocket
(Item : in out Connection;
Kind : WebSocket_Data_Kind;
Data : Flyology.Bytes.Unbounded_Bytes;
Timeout : Duration := 30.0;
Token : access Flyology.Cancellation.Token := null)
Send one unmasked, final server data frame directly from owned bytes. This overload writes large messages in bounded chunks and does not form a contiguous copy on the caller's task stack.
Parameters
- Item
Upgraded WebSocket connection
- Kind
Text or binary message kind
- Data
Owned frame payload
- Timeout
Whole-frame transport send deadline
- Token
Optional cancellation source
Send_WebSocket
procedure Send_WebSocket
(Item : in out Connection;
Data : String;
Timeout : Duration := 30.0;
Token : access Flyology.Cancellation.Token := null)
Send one unmasked, final UTF-8 text frame. Data is interpreted as UTF-8 encoded octets and validated before any frame bytes are written.
Parameters
- Item
Upgraded WebSocket connection
- Data
UTF-8 byte string
- Timeout
Transport send deadline
- Token
Optional cancellation source
Should_Close
function Should_Close (Item : Connection) return Boolean
Report whether the last request or response requires transport close.
Parameters
- Item
HTTP connection
Return value
True when no further request may be processed
Target
function Target (Item : Request) return String
Return the request target exactly as received.
Parameters
- Item
Request to inspect
Return value
Origin-form or application-defined target
Transport
type Transport is limited interface;
Transport boundary shared by plain and TLS connections. Implementations retain closing ownership and must preserve Flyology cancellation and deadline semantics.
Try_Reserve
procedure Try_Reserve
(Item : in out Ingress_Budget;
Bytes : Natural;
Granted : out Boolean)
Attempt to reserve Bytes without suspending a handler.
Parameters
- Item
Shared server budget
- Bytes
Requested buffered payload bytes
- Granted
True only when the reservation was recorded
Try_Reserve
procedure Try_Reserve
(Item : in out Outbound_Budget;
Bytes : Natural;
Granted : out Boolean)
Attempt to reserve outbound bytes without suspending a producer.
Parameters
- Item
Shared application/server budget
- Bytes
Requested retained bytes
- Granted
True only when recorded
Version
function Version (Item : Request) return HTTP_Version
Return the parsed protocol version.
Parameters
- Item
Request to inspect
Return value
HTTP/1.0 or HTTP/1.1
WebSocket_Compression_Mode
type WebSocket_Compression_Mode is
(No_WebSocket_Compression, Permessage_Deflate);
WebSocket extension policy selected explicitly at upgrade time. Permessage_Deflate negotiates RFC 7692 with no context takeover in both directions so compression state and history do not cross message boundaries. Outbound compression uses a 32 KiB history, so an offer requiring server_max_window_bits below 15 is declined. Applications must assess compression side channels before enabling it for secret-bearing messages.
Enumeration literals
- No_WebSocket_Compression
Decline compression offers
- Permessage_Deflate
Negotiate bounded per-message raw DEFLATE
WebSocket_Data_Kind
type WebSocket_Data_Kind is (Text_Frame, Binary_Frame);
WebSocket application-data kind.
Enumeration literals
- Text_Frame
Validated UTF-8 text payload
- Binary_Frame
Binary payload
WebSocket_Origin_Policy
type WebSocket_Origin_Policy is
(Reject_Browser_Origins, Allow_Any_Origin, Require_Exact_Origin);
Browser-origin policy applied before a WebSocket upgrade.
Enumeration literals
- Reject_Browser_Origins
Reject requests containing Origin
- Allow_Any_Origin
Accept zero or one syntactically bounded Origin
- Require_Exact_Origin
Require exact case-sensitive Allowed_Origin
Write_Response_Chunk
procedure Write_Response_Chunk
(Item : in out Connection;
Data : Ada.Streams.Stream_Element_Array;
Timeout : Duration := 30.0;
Token : access Flyology.Cancellation.Token := null)
Send one binary streaming response chunk with transport backpressure. Empty data is a no-op and HEAD suppresses data bytes.
Parameters
- Item
Active streaming response
- Data
Response bytes
- Timeout
Transport send deadline
- Token
Optional cancellation source
Write_Response_Chunk
procedure Write_Response_Chunk
(Item : in out Connection;
Data : String;
Timeout : Duration := 30.0;
Token : access Flyology.Cancellation.Token := null)
Send one streaming response chunk with transport backpressure. Empty data is a no-op and HEAD suppresses data bytes.
Parameters
- Item
Active streaming response
- Data
Response bytes
- Timeout
Transport send deadline
- Token
Optional cancellation source