Pudu programming language
Menu
Package

@chrismichaelps / pudu-lang-httpclient

Named HTTP clients for Pudu: a client factory, delegating handlers, pooled keep-alive connections, handler lifetimes, logging, and resilience

0.1.1Apache-2.01

InstallClose

Handler.pudu

Pudu49 lines2.1 KB

GitHub ↗
1/** @HttpClient.Handler.Module — delegating handlers composed around a primary handler */2module PuduLangHttpClient.Handler34import Std.Concurrent.Cancel as Cancel5import PuduLangHttpClient as HttpClient6import PuduLangHttpClient.Request as Request7import PuduLangHttpClient.Response as Response89/** @HttpClient.Handler.Send — sends a request and answers its response; the primary handler's shape */10export type Send = fn(Request.Request, Cancel.Token) -> HttpClient.Outcome[Response.Response]1112/** @HttpClient.Handler.Handler — one layer: sees the request, may call the rest, sees the outcome */13export type Handler = fn(Request.Request, Cancel.Token, Send) -> HttpClient.Outcome[Response.Response]1415/// The handlers composed around the primary handler, the first outermost: a request passes16/// through them in order and its response comes back through them in reverse.17export fn compose(handlers: &Array[Handler], primary: Send) -> Send {18  var inner = primary19  var index = handlers.length() - 120  while index >= 0 {21    inner = around(handlers[index], inner)22    index = index - 123  }24  inner25}2627/// One handler made into a sender around the rest of the pipeline.28export fn around(handler: Handler, inner: Send) -> Send {29  fn(request: Request.Request, token: Cancel.Token) -> HttpClient.Outcome[Response.Response] { handler(request, token, inner) }30}3132/// A handler changing every request before it is passed on.33export fn before(step: fn(Request.Request) -> Request.Request) -> Handler {34  fn(request: Request.Request, token: Cancel.Token, next: Send) -> HttpClient.Outcome[Response.Response] { next(step(request), token) }35}3637/// A handler changing every response on its way back.38export fn after(step: fn(Response.Response) -> Response.Response) -> Handler {39  fn(request: Request.Request, token: Cancel.Token, next: Send) -> HttpClient.Outcome[Response.Response] {40    let response = next(request, token) ?41    Ok(step(response))42  }43}4445/// A handler that passes every request on unchanged.46export fn passThrough() -> Handler {47  fn(request: Request.Request, token: Cancel.Token, next: Send) -> HttpClient.Outcome[Response.Response] { next(request, token) }48}49