native_http.bend checks
raw source on the hub · import 0x665ae73e3f32ce98f72c7cf6844cfd3f/native_http.bend as Native_http
bend-trace-context: native HTTP headers =======================================
The reference adapter for native HTTP on bend-kit's HTTP package (paymog/bend-kit, bend-kit-http on BendHub). bend-kit keeps the header fields of a request or a response in a Base Map from each field name to its values in arrival order; its parser lowercases the names and trims the values. This module turns such a map into the carrier of trace_context.bend and back, and gives a service its receive-to-send shortcuts around bend-kit's server and client on a caller's source. generation.bend gives the same shortcuts on the host's cryptographic source (NativeHttp.continue_or_start and NativeHttp.send there).
The module decides nothing about Trace Context. Which fields are context fields, how they are read and what is written all come from trace_context.bend: the shortcuts are the package's operations on the carrier of a map (laws http_continue and http_send), the carrier keeps every value of every name (law http_carrier), and the map of a carrier holds every value of every name (law http_headers). It imports only Base and trace_context.bend, not bend-kit or the host's entropy, so it builds wherever the package builds and every def in it is pure; a service imports bend-kit for the transport.
Names in the Headers namespace are internal: Bend lets any module import them, but they are not a compatibility contract.
2 imports
import Base import ./trace_context.bend as TC
Types
type Outbound source · line 37 · raw
Data
A request to send: the context fields the package gave it (sent), and
the header map to send it with, which holds those fields.
Outbound@sent:0x665ae73e3f32ce98f72c7cf6844cfd3f/trace_context.Sent -> @headers:Map<&2, List<&2, String>> -> Outbound
Definitions
def HeaderMap source · line 32 · raw
Data
The header fields of a bend-kit request or response: each name, as bend-kit stores it, with its values in arrival order.
def Headers.push source · line 43 · raw
@+name:String -> @values:List<&2, String> -> @fields:List<&2, 0x665ae73e3f32ce98f72c7cf6844cfd3f/trace_context.Header> -> List<&2, 0x665ae73e3f32ce98f72c7cf6844cfd3f/trace_context.Header>
One field for each value of name, pushed onto fields in order, so that
the last value ends up first. A loop: a received head of 64 KiB can hold
thousands of values.
def Headers.gather source · line 51 · raw
@entries:List<&2, Sigma<&2, &2, String, _ => List<&2, String>>> -> @fields:List<&2, 0x665ae73e3f32ce98f72c7cf6844cfd3f/trace_context.Header> -> List<&2, 0x665ae73e3f32ce98f72c7cf6844cfd3f/trace_context.Header>
The fields of every entry pushed onto fields, entry by entry.
def carrier source · line 63 · raw
@headers:HeaderMap -> List<&2, 0x665ae73e3f32ce98f72c7cf6844cfd3f/trace_context.Header>
The header fields of a map as a carrier for TC.Context.extract or TC.Context.send: every value of every name, in arrival order within each name (law http_carrier). The order between different names is the map's own, which no Trace Context rule depends on.
def Headers.values source · line 67 · raw
@+headers:HeaderMap -> @name:String -> List<&2, String>
The values a map holds under name, none when it has no entry for it.
def Headers.add source · line 71 · raw
@+headers:HeaderMap -> @header:0x665ae73e3f32ce98f72c7cf6844cfd3f/trace_context.Header -> HeaderMap
Put one field's value first among its name's values.
def Headers.write source · line 78 · raw
@fields:List<&2, 0x665ae73e3f32ce98f72c7cf6844cfd3f/trace_context.Header> -> @+headers:HeaderMap -> HeaderMap
Put every field of fields first among its name's values, in order. A
loop, as Headers.push is.
def headers source · line 91 · raw
@carrier:List<&2, 0x665ae73e3f32ce98f72c7cf6844cfd3f/trace_context.Header> -> HeaderMap
The header map of a carrier, such as the one TC.Sent.carrier gives for a message to send: under each name, the carrier's values of that name in order (law http_headers), as bend-kit's Http.add would add them one by one, with the names as the carrier spells them. The fields are put in from the last, each value first among its name's, which leaves every name's values in order. bend-kit writes one header line for each value.
def Headers.outbound source · line 106 · raw
@+sent:0x665ae73e3f32ce98f72c7cf6844cfd3f/trace_context.Sent -> Outbound
The request to send for a message: the message with the map of the fields that TC.Sent.carrier gives.
def Headers.strict source · line 110 · raw
@result:Result<&2, &2, 0x665ae73e3f32ce98f72c7cf6844cfd3f/trace_context.GenerationError, 0x665ae73e3f32ce98f72c7cf6844cfd3f/trace_context.Sent> -> Result<&2, &2, 0x665ae73e3f32ce98f72c7cf6844cfd3f/trace_context.GenerationError, Outbound>
The same for a strict result: a failure stays a failure.
def Headers.written source · line 119 · raw
@policy:0x665ae73e3f32ce98f72c7cf6844cfd3f/trace_context.FailurePolicy -> @result:0x665ae73e3f32ce98f72c7cf6844cfd3f/trace_context.FailurePolicy.result(policy, 0x665ae73e3f32ce98f72c7cf6844cfd3f/trace_context.Sent) -> 0x665ae73e3f32ce98f72c7cf6844cfd3f/trace_context.FailurePolicy.result(policy, Outbound)
A message sent under policy, with its header map.
def Headers.written.done source · line 128 · raw
@-S:Type -> @+policy:0x665ae73e3f32ce98f72c7cf6844cfd3f/trace_context.FailurePolicy -> @done:Pair(S, 0x665ae73e3f32ce98f72c7cf6844cfd3f/trace_context.FailurePolicy.result(policy, 0x665ae73e3f32ce98f72c7cf6844cfd3f/trace_context.Sent)) -> Pair(S, 0x665ae73e3f32ce98f72c7cf6844cfd3f/trace_context.FailurePolicy.result(policy, Outbound))
The source's final state with a message sent under policy and its map.
def Outbound.sent source · line 147 · raw
@outbound:Outbound -> 0x665ae73e3f32ce98f72c7cf6844cfd3f/trace_context.Sent
The context fields that the package gave the request.
def Outbound.headers source · line 153 · raw
@outbound:Outbound -> HeaderMap
The header map to send the request with.
Templates
template continue_or_start_with source · line 98 · raw
@-S:Type -> @-read:(@_:S -> IO(Pair(S, Result<&1, &1, Pair(U32, String), U32>))) -> @source:S -> @+limits:0x665ae73e3f32ce98f72c7cf6844cfd3f/trace_context.Limits -> @headers:HeaderMap -> @base:Maybe<&2, 0x665ae73e3f32ce98f72c7cf6844cfd3f/trace_context.BaseContext> -> @reception:0x665ae73e3f32ce98f72c7cf6844cfd3f/trace_context.Reception -> @sampling:0x665ae73e3f32ce98f72c7cf6844cfd3f/trace_context.Sampling -> @+policy:0x665ae73e3f32ce98f72c7cf6844cfd3f/trace_context.FailurePolicy -> IO(Pair(S, 0x665ae73e3f32ce98f72c7cf6844cfd3f/trace_context.FailurePolicy.result(policy, 0x665ae73e3f32ce98f72c7cf6844cfd3f/trace_context.Service)))
The service's own operation for a received message, from the header map of
its request, on a caller's source: TC.Context.continue_or_start_with over
the extraction of the map's carrier (law http_continue). base is the
context to keep when the request carries no usable traceparent.
template send_with source · line 139 · raw
@-S:Type -> @-read:(@_:S -> IO(Pair(S, Result<&1, &1, Pair(U32, String), U32>))) -> @source:S -> @+limits:0x665ae73e3f32ce98f72c7cf6844cfd3f/trace_context.Limits -> @service:0x665ae73e3f32ce98f72c7cf6844cfd3f/trace_context.Service -> @sampling:0x665ae73e3f32ce98f72c7cf6844cfd3f/trace_context.Sampling -> @+policy:0x665ae73e3f32ce98f72c7cf6844cfd3f/trace_context.FailurePolicy -> @headers:HeaderMap -> IO(Pair(S, 0x665ae73e3f32ce98f72c7cf6844cfd3f/trace_context.FailurePolicy.result(policy, Outbound)))
Give one request that the service sends the context of a new operation, on
a caller's source: TC.Context.send_with on the carrier of headers, the
request's own header map, and the map of the fields it gives back (law
http_send). The request's old context fields go, whatever the case of
their names, and the new ones replace them; without a new operation, the
map forwards the received pair or carries no context fields.