Suave Library Reference

Synopsis

module Suave.WebPart
type WebPart<'a> = 'a -> Async<'a option>
val succeed : WebPart<'a>
val fail<'a>  : Async<'a option>
val never : WebPart<'a>
val bind : f:('a -> Async<'b option>) -> a: Async<'a option> -> Async<'b option>
val compose : first:('a -> Async<'b option>) -> second:('b -> Async<'c option>) ->  'a -> Async<'c option>
type AsyncOptionBuilder =
  new : unit -> AsyncOptionBuilder
  member Return : 'a -> Async<'a option>
  member Zero : unit -> Async<unit option>
  member ReturnFrom : Async<'a option> -> Async<'a option>
  member Delay : (unit ->  Async<'a option>) -> Async<'a option>
  member Bind : Async<'a option> * ('a -> Async<'b option>) ->  Async<'b option>
val asyncOption : AsyncOptionBuilder
val choose : options:WebPart<'a> list -> WebPart<'a>
val inject : postOp:WebPart<'a> -> pairs:(WebPart<'a> * WebPart<'a>) list -> WebPart<'a>
val warbler : f:('t -> 't -> 'u) -> 't -> 'u
val cnst : x:'t -> 'u -> 't
val cond : item:Choice<'T, _> -> f:('T -> 'U -> 'V) -> g:('U -> 'V) -> 'U -> 'V
val tryThen : first:WebPart<'a> -> second:WebPart<'a> -> WebPart<'a>
val concatenate : first:('a -> 'b option) -> second:('a -> 'b option)
                       -> 'a -> 'b option
module Response =
  val response : statusCode:HttpCode -> content:byte [] -> WebPart
module Writers =
  val setStatus : status:HttpCode -> WebPart
  val setHeader : key:string -> value:string -> WebPart
  val setHeaderValue : key:string -> value:string -> WebPart
  val addHeader : key:string -> value:string -> WebPart
  val setUserData : key:string -> value:'T -> WebPart
  val unsetUserData : key : string -> WebPart
  val createMimeType : name:string -> compression:bool -> MimeType option
  val defaultMimeTypesMap : ext:string -> MimeType option
  val setMimeType : mimeType:string -> WebPart
module Intermediate =
  val CONTINUE : WebPart
  val SWITCHING_PROTO : WebPart
module Successful =
  val ok : bytes:byte [] -> WebPart
  val OK : body:string -> WebPart
  val created : bytes:byte [] -> WebPart
  val CREATED : body:string -> WebPart
  val accepted : bytes:byte [] -> WebPart
  val ACCEPTED : body:string -> WebPart
  val no_content : WebPart
  val NO_CONTENT : WebPart
module Redirection =
  val moved_permanently : location:string -> WebPart
  val MOVED_PERMANENTLY : location:string -> WebPart
  val found : location:string -> WebPart
  val FOUND : location:string -> WebPart
  val redirect : location:string -> WebPart
  val see_other : location:string -> WebPart
  val not_modified : WebPart
  val NOT_MODIFIED : WebPart
module RequestErrors =
  val bad_request : bytes:byte [] -> WebPart
  val BAD_REQUEST : body:string -> WebPart
  val unauthorized : bytes:byte [] -> WebPart
  val UNAUTHORIZED : body:string -> WebPart
  val challenge : WebPart
  val forbidden : bytes:byte [] -> WebPart
  val FORBIDDEN : body:string -> WebPart
  val not_found : bytes:byte [] -> WebPart
  val NOT_FOUND : body:string -> WebPart
  val method_not_allowed : bytes:byte [] -> WebPart
  val METHOD_NOT_ALLOWED : body:string -> WebPart
  val not_acceptable : bytes:byte[] -> WebPart
  val NOT_ACCEPTABLE : body:string -> WebPart
  val request_timeout : WebPart
  val conflict : bytes:byte[] -> WebPart
  val CONFLICT : body:string -> WebPart
  val gone : bytes:byte [] -> WebPart
  val GONE : body:string -> WebPart
  val unsupported_media_type : bytes:byte [] -> WebPart
  val UNSUPPORTED_MEDIA_TYPE : body:string -> WebPart
  val unprocessable_entity : bytes:byte [] -> WebPart
  val UNPROCESSABLE_ENTITY : body:string -> WebPart
  val precondition_required : bytes:byte[] -> WebPart
  val PRECONDITION_REQUIRED : body:string -> WebPart
  val too_many_requests : bytes:byte [] -> WebPart
  val TOO_MANY_REQUESTS : body:string -> WebPart
module ServerErrors =
  val internal_error : bytes:byte [] -> WebPart
  val INTERNAL_ERROR : body:string -> WebPart
  val not_implemented : bytes:byte [] -> WebPart
  val NOT_IMPLEMENTED : body:string -> WebPart
  val bad_gateway : bytes:byte [] -> WebPart
  val BAD_GATEWAY : body:string -> WebPart
  val service_unavailable : bytes:byte [] -> WebPart
  val SERVICE_UNAVAILABLE : body:string -> WebPart
  val gateway_timeout : bytes:byte [] -> WebPart
  val GATEWAY_TIMEOUT : body:string -> WebPart
  val invalid_http_version : bytes:byte [] -> WebPart
  val INVALID_HTTP_VERSION : WebPart
module Filters =
  val path : pathAfterDomain:string -> WebPart
  val pathCi : pathAfterDomain:string -> WebPart
  val pathStarts : pathAfterDomainSubstr:string -> WebPart
  val pathStartsCi : pathAfterDomainSubstr:string -> WebPart
  val   method   :   method  :HttpMethod -> WebPart
  val isSecure : WebPart
  val hasFlag : flag:string -> WebPart
  val pathRegex : pathAfterDomainRegex:string -> WebPart
  val host : hostname:string -> WebPart
  val serverHost : hostname:string -> WebPart
  val clientHost : hostname:string -> WebPart
  val logFormatStructured : ctx:HttpContext -> string * Map<string,obj>
  val logWithLevelStructured :  level:LogLevel -> logger:Logger -> messageFun:(HttpContext -> string * Map<string,obj>) -> WebPart
  val logStructured : logger:Logger -> messageFun:(HttpContext -> string * Map<string,obj>) -> WebPart
  val logFormat : ctx:HttpContext -> string
  val logWithLevel :  level:LogLevel -> logger:Logger -> messageFun:(HttpContext -> string) -> WebPart
  val log : logger:Logger -> messageFun:(HttpContext -> string) -> WebPart
  val pathScan : pf:PrintfFormat<'a,'b,'c,'d,'t> -> h:('t -> WebPart) -> WebPart
  val pathScanCi : format:PrintfFormat<'a,'b,'c,'d,'t> -> handler:('t -> WebPart) -> WebPart
  val timeoutWebPart : timeout:System.TimeSpan -> child:WebPart -> WebPart
  val GET : WebPart
  val POST : WebPart
  val DELETE : WebPart
  val PUT : WebPart
  val HEAD : WebPart
  val CONNECT : WebPart
  val PATCH : WebPart
  val TRACE : WebPart
  val OPTIONS : WebPart
module Files =
  val sendFile : fileName:string -> compression:bool -> WebPart
  val file : fileName:string -> WebPart
  val resolvePath : rootPath:string -> fileName:string -> string
  val browseFile : rootPath:string -> fileName:string -> WebPart
  val browseFileHome : fileName:string -> WebPart
  val browse : rootPath:string -> WebPart
  val browseHome : WebPart
  val dir : rootPath:string -> WebPart
  val dirHome : WebPart
module Embedded =
  val sendResource : source:Assembly -> resourceName:string -> compression:bool -> WebPart
  val sendResourceFromDefaultAssembly : resourceName:string -> compression:bool -> WebPart
  val resource : source:Assembly -> name:string -> WebPart
  val resourceFromDefaultAssembly : name:string -> WebPart
  val browse : source:Assembly -> WebPart
  val browseDefaultAsssembly : WebPart
module EventSource =
  val asyncWrite : out:Connection -> data:string -> SocketOp<unit>
  val (<<.) : out:Connection -> data:string -> SocketOp<unit>
  val dispatch : out:Connection -> SocketOp<unit>
  val comment : out:Connection -> cmt:string -> SocketOp<unit>
  val eventType : out:Connection -> eventType:string -> SocketOp<unit>
  val data : out:Connection -> data:string -> SocketOp<unit>
  val esId : out:Connection -> lastEventId:string -> SocketOp<unit>
  val retry : out:Connection -> retry:uint32 -> SocketOp<unit>
  type Message =
    { id       : string
      data     : string
      type   : string option }
    static member create : id:string -> data:string -> Message
    static member createType : id:string -> data:string -> typ:string -> Message
  val send : out:Connection -> msg:Message -> SocketOp<unit>
  val handShake : fCont:(Connection -> SocketOp<Connection>) -> WebPart
module TransferEncoding =
  val chunked: (Connection -> SocketOp<'a * Connection>) -> WebPart
module Control =
  val CLOSE : WebPart
module CORS =
  [<RequireQualifiedAccess>]
  type InclusiveOption<'T> =
    | None
    | Some of 'T
    | All
  type CORSConfig =
    {
      allowedUris             : InclusiveOption<string list>
      allowedMethods          : InclusiveOption<HttpMethod list>
      allowCookies            : bool
      exposeHeaders           : InclusiveOption<string list>
      maxAge                  : int option }
  val cors : CORSConfig:(CORSConfig) -> WebPart
  val defaultCORSConfig : CORSConfig
[<AutoOpen>]
module Http =
  type HttpMethod =
    | GET
    | POST
    | DELETE
    | PUT
    | HEAD
    | CONNECT
    | PATCH
    | TRACE
    | OPTIONS
    | OTHER of string
  [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
  module HttpMethod =
    val parse : string -> HttpMethod
  type HttpStatus =
    { code   : int
      reason : string
    }
  type HttpCode =
    | HTTP_100 | HTTP_101
    | HTTP_200 | HTTP_201 | HTTP_202 | HTTP_203 | HTTP_204 | HTTP_205 | HTTP_206
    | HTTP_300 | HTTP_301 | HTTP_302 | HTTP_303 | HTTP_304 | HTTP_305 | HTTP_306
    | HTTP_307 | HTTP_400 | HTTP_401 | HTTP_402 | HTTP_403 | HTTP_404 | HTTP_405
    | HTTP_406 | HTTP_407 | HTTP_408 | HTTP_409 | HTTP_410 | HTTP_411 | HTTP_412
    | HTTP_413 | HTTP_422 | HTTP_426 | HTTP_428 | HTTP_429 | HTTP_414 | HTTP_415
    | HTTP_416 | HTTP_417 | HTTP_451 | HTTP_500 | HTTP_501 | HTTP_502 | HTTP_503
    | HTTP_504 | HTTP_505
    member code : int
    member reason : string
    member message : string
    member describe : unit -> string
    member status : HttpStatus
    static member tryParse : code:int -> Choice<HttpCode, string>
  type SameSite =
    | Strict
    | Lax
  type HttpCookie =
    { name     : string
      value    : string
      expires  : DateTimeOffset option
      path     : string option
      domain   : string option
      secure   : bool
      httpOnly : bool
      sameSite : SameSite option }
  [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
  module HttpCookie =
    val create : name:string -> value:string -> expires:DateTimeOffset option
               -> path:string option -> domain:string option -> secure:bool
               -> httpOnly:bool
               -> sameSite:SameSite option
               -> HttpCookie
    val createKV : name:string -> value:string -> HttpCookie
    val empty : HttpCookie
    val toHeader : cookie:HttpCookie -> string
  type MimeType =
    { name        : string
      compression : bool }
  type MimeTypesMap = string -> MimeType option
  type HttpUpload =
    { fieldName    : string
      fileName     : string
      mimeType     : string
      tempFilePath : string }
  [<AllowNullLiteral>]
  type TlsProvider =
    abstract wrap : Connection * obj -> SocketOp<Connection>
  type Protocol =
    | HTTP
    | HTTPS of obj
    member secure : bool
  type Host = string
  type HttpBinding =
    { scheme        : Protocol
      socketBinding : SocketBinding }
    member uri : path:string -> query:string -> Uri
    override ToString : unit -> string
  type HttpRequest =
    { httpVersion     : string
      binding         : HttpBinding
      rawPath         : string
      rawHost         : string
      rawMethod       : string
      headers         : (string * string) list
      rawForm         : byte []
      rawQuery        : string
      files           : HttpUpload list
      multiPartFields : (string * string) list
      trace           : TraceHeader }
    member query : (string * string option) list
    member queryParam : key:string -> Choice<string, string>
    member queryParamOpt : key:string -> (string * string option) option
    member queryFlag : flag:string -> bool
    member header : key:string -> Choice<string, string>
    member form : (string * string option) list
    member formData : key:string -> Choice<string, string>
    member fieldData : key:string -> Choice<string, string>
    member Item : key:string -> string option with get
    member clientHost : trustProxy:bool -> sources:string list -> Host
    member clientHostTrustProxy : Host
    member path : string
    member url : Uri
    member host : Host
    member method : HttpMethod
  [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
  module HttpRequest =
    val empty : HttpRequest
  [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
  module HttpBinding =
    val DefaultBindingPort : Port
    val defaults : HttpBinding
    val create : scheme:Protocol -> ip:IPAddress -> port:Port -> HttpBinding
    val createSimple : scheme:Protocol -> ip:string -> port:int -> HttpBinding
  type HttpContent =
    | NullContent
    | Bytes of byte []
    | SocketTask of (Connection * HttpResult -> SocketOp<Connection>)
  and HttpResult =
    { status        : HttpStatus
      headers       : (string * string) list
      content       : HttpContent
      writePreamble : bool }
  [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
  module HttpResult =
    val empty : HttpResult
  type ServerKey = byte []
  [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
  module ServerKey =
    val validate : ServerKey -> ServerKey
    val fromBase64 : (string -> ServerKey)
  type IPAddress with
    static member tryParseC : ip:string -> Choice<IPAddress, unit>
  type HttpRuntime =
    { serverKey         : ServerKey
      errorHandler      : ErrorHandler
      mimeTypesMap      : MimeTypesMap
      homeDirectory     : string
      compressionFolder : string
      logger            : Logger
      matchedBinding    : HttpBinding
      cookieSerialiser  : CookieSerialiser
      tlsProvider       : TlsProvider
      hideHeader        : bool
      maxContentLength  : int }
  and HttpContext =
    { /// The HTTP request being processed
      request    : HttpRequest
      runtime    : HttpRuntime
      connection : Connection
      userState  : Dictionary<string, obj>
      response   : HttpResult }
    member clientIp : trustProxy:bool -> sources:string list -> IPAddress
    member clientIpTrustProxy : IPAddress
    member isLocal : bool
    member isLocalTrustProxy : bool
    member clientPort : trustProxy:bool -> sources:string list -> Port
    member clientPortTrustProxy : Port
    member clientProto : trustProxy:bool -> sources:string list -> string
    member clientProtoTrustProxy : string
  and ErrorHandler = Exception -> String -> WebPart<HttpContext>
  type WebPart = WebPart<HttpContext>
  [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
  module HttpRuntime =
    val ServerKeyLength : uint16
    val empty : HttpRuntime
    val create : serverKey:ServerKey -> errorHandler:ErrorHandler
               -> mimeTypes:MimeTypesMap -> homeDirectory:string
               -> compressionFolder:string -> logger:Logger
               -> cookieSerialiser:CookieSerialiser
               -> tlsProvider:TlsProvider -> hideHeader:bool -> maxContentLength:int
               -> binding:HttpBinding
               -> HttpRuntime
  [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
  module HttpContext =
    val empty : HttpContext
    val create : request:HttpRequest -> runtime:HttpRuntime -> connection:Connection
               -> writePreamble:bool
               -> HttpContext
  val request : apply:(HttpRequest -> HttpContext -> 'a) -> context:HttpContext -> 'a
  val context : apply:(HttpContext -> HttpContext -> 'a) -> context:HttpContext -> 'a
module Cookie =
  type CookieLife =
    | Session
    | MaxAge of duration:TimeSpan
  type CookieError =
    | NoCookieFound of cookieName:string
    | DecryptionError of error:Crypto.SecretboxDecryptionError
  val parseCookies : cookieString:string -> HttpCookie list
  val parseResultCookie : cookieString:string -> HttpCookie
  type HttpRequest with
    member cookies : Map<string, HttpCookie>
  type HttpResult with
    member cookies : Map<string, HttpCookie>
  val setCookie : cookie:HttpCookie -> WebPart
  val unsetCookie : name:string -> WebPart
  val setPair   : httpCookie:HttpCookie -> clientCookie:HttpCookie -> WebPart
  val unsetPair : httpCookieName:string -> WebPart
  type CookiesState =
    { serverKey      : ServerKey
      cookieName     : string
      userStateKey   : string
      relativeExpiry : CookieLife
      secure         : bool }
  [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
  module CookiesState =
    val create : serverKey:ServerKey
               -> cookieName:string
               -> userStateKey:string
               -> relativeExpiry:CookieLife
               -> secure:bool -> CookiesState
  val generateCookies : serverKey:ServerKey
                      -> cookieName:string
                      -> relativeExpiry:CookieLife
                      -> secure:bool
                      -> plainData:byte[]
                      -> HttpCookie * HttpCookie
  val readCookies : key:ServerKey
                  -> cookieName:string
                  -> cookies:Map<string, HttpCookie>
                  -> Choice<HttpCookie * byte [], CookieError>
  val refreshCookies : expiry:CookieLife
                     -> cookie:HttpCookie
                     -> WebPart
  val updateCookies :  csctx:CookiesState ->
                       fPlainText : (byte [] option -> byte []) -> WebPart
  val cookieState : csctx:CookiesState
                  -> noCookie:(unit -> Choice<byte [], WebPart>)
                  -> decryptionFailure:(Crypto.SecretboxDecryptionError -> Choice<byte [], WebPart>)
                  -> fSuccess:WebPart
                  -> WebPart
val UserNameKey : string
val authenticateBasic : f:(string * string -> bool) -> protectedPart:WebPart -> WebPart
val authenticateBasicAsync : f:(string * string -> bool Async) -> protectedPart:WebPart -> WebPart
val SessionAuthCookie : string
val StateStoreType : string
val SessionIdLength : int
val authenticate : relativeExpiry:CookieLife
                 -> secure:bool
                 -> missingCookie:(unit -> Choice<byte[], WebPart>)
                 -> decryptionFailure:(SecretboxDecryptionError -> Choice<byte [], WebPart>)
                 -> fSuccess:WebPart
                 -> WebPart
val authenticateWithLogin : relativeExpiry:CookieLife
                          -> loginPage:string
                          -> fSuccess:WebPart
                          -> WebPart
val deauthenticate : WebPart
val deauthenticateWithLogin : loginPage :string
                            -> WebPart
val authenticated : relativeExpiry:CookieLife
                  -> secure:bool
                  -> WebPart
module HttpContext =
  val sessionId : ctx:HttpContext -> string option

Description

[<AutoOpen>]
module Suave.WebPart
type WebPart<'a> = 'a -> Async<'a option>

Takes 'a and returns SuaveTask of 'a SuaveTask is also known as AsyncOption

val bind : f:('a -> Async<'b option>) -> a: Async<'a option> -> Async<'b option>

Classic bind (for SuaveTask)

val compose : first:('a -> Async<'b option>) -> second:('b -> Async<'c option>) ->  'a -> Async<'c option>

Left-to-right Kleisli composition (for SuaveTask).

val asyncOption : AsyncOptionBuilder

With this workflow you can write WebParts like this let task ctx = asyncOption { let! _ = GET ctx let! ctx = Writers.setHeader "foo" "bar" return ctx }

we can still use the old symbol but now has a new meaning let foo ctx = GET ctx >>= OK "hello"

val choose : options:WebPart<'a> list -> WebPart<'a>

Entry-point for composing the applicative routes of the http application, by iterating the options, applying the context, arg, to the predicate from the list of options, until there's a match/a Some(x) which can be run.

val inject : postOp:WebPart<'a> -> pairs:(WebPart<'a> * WebPart<'a>) list -> WebPart<'a>

Inject a webPart

+------------+ +--------------+ | url "/a" +----------+ +---------+ cont1 | +------------+ | | +--------------+ | | +-------------+ | +----------+ | +--------------+ | url "/b" +---------+-------+ injected +----+---------+ cont2 | +-------------+ | +----------+ | +--------------+ | | +-------------+ | | +--------------+ | url "/b" +---------+ +---------+ cont3 | +-------------+ +--------------+

val warbler : f:('t -> 't -> 'u) -> 't -> 'u

Which bird? A Warbler!

Pipe the request through to a bird that can peck at it.

Put another way, using 'warbler' lets you look at the first parameter and then make a decision about what thing to return (it's most likely a WebPart you'll be returning). (Remember, WebPart is HttpContext -> Async) where HttpContext is 'a and Async<_> is 'b.

val cnst : x:'t -> 'u -> 't

The constant function, which returns its constant, no matter its input. - theorem: identity = (warbler cnst) (warbler cnst) x = cnst x x = fun _ -> x

val cond : item:Choice<'T, _> -> f:('T -> 'U -> 'V) -> g:('U -> 'V) -> 'U -> 'V

The conditional function that applies f x a if there's a value in d, or otherwise, applies g a, if there is no value in d.

module Response =

The HTTP module has these main sub-modules: Response - response and response_f functions. Writers - ways to modify the response. Intermediate - 100 and 101 response codes. Successful- 2xx response codes. Redirection - 3xx response codes. RequestErrors - 4xx response codes. ServerErrors - 5xx response codes. Applicatives - use to filter down the request to something you want Files - send files to the client Authentication - Methods for authenticating http requests and these main types: WebResult = Async<unit> option WebPart = HttpContext -> WebResult HttpMethod general response functions
val response : statusCode:HttpCode -> content:byte [] -> WebPart

Respond with a given status code, http message, content in the body to a http request. Respond with a given status code, http reason phrase, content in the body to a http request.

module Writers =

Module that allows changing the output response in different ways. Functions have signature f :: params... -> HttpContext -> HttpContext.

val setStatus : status:HttpCode -> WebPart

Sets the HTTP response status

val setHeader : key:string -> value:string -> WebPart

Ensures that the header named by the key parameter has the given value, by removing any other headers with the same key from the response header list.

val setHeaderValue : key:string -> value:string -> WebPart

Ensures that the is unique in the comma-separated list of the response header, denoted by key. This is useful for example for the "Vary" header which should at the very minimum include "Accept-Encoding", but may also include "Accept-Language" for multi-lingual sites (see Suave.Locale repo) and "Authorization" and "Cookie" for authorized resources.

val addHeader : key:string -> value:string -> WebPart

Adds the header key with the given value to the list of returned headers, even if that header already exists. This means that Suave will serve a a response with the header denoted by key with possibly different values.

Also consider setHeader and setHeaderValue depending on what semantics you'd like.

Furthermore, Cookies must be set on separate header lines (using this function) and not comma-concatenated. See https://github.com/SuaveIO/suave/issues/338#issuecomment-156820747 for defails.

val setUserData : key:string -> value:'T -> WebPart

Sets a user data key-value pair with the key and value specified. Downstream web parts can read this.

val unsetUserData : key : string -> WebPart

Unset the user data by the given key

val createMimeType : name:string -> compression:bool -> MimeType option

Creates a MIME type record
val defaultMimeTypesMap : ext:string -> MimeType option

Map a file ending to a mime-type
val setMimeType : mimeType:string -> WebPart

Set the Content-Type header to the mime type given. Remember that it should include the encoding of your content. So for example, specifying a mimeType value of 'application/json; charset=utf-8' is strongly recommended (but replace 'json' with your own MIME type, of course ;))
module Intermediate =

Control-flow functions, such as 100 Continue and 101 Switching Protocol.

val CONTINUE : WebPart

100 The purpose of the 100 (Continue) status is to allow a client that is sending a request message with a request body to determine if the origin server is willing to accept the request (based on the request headers) before the client sends the request body
val SWITCHING_PROTO : WebPart

101 The server will switch protocols to those defined by the response's Upgrade header field immediately after the empty line which terminates the 101 response.
module Successful =

2xx successful responses Functions have signature f :: params... -> HttpContext -> Async<unit> option. Functions from here are 'end routes' in that they don't require you to keep returning applicatives, but can end up in an async monad/workflow that writes the data to the client in the end.
val ok : bytes:byte [] -> WebPart

200 Write the bytes to the body as a byte array
val OK : body:string -> WebPart

200 Write the string to the body as UTF-8
val created : bytes:byte [] -> WebPart

201 Write the bytes to the body as a byte array The request has been fulfilled and resulted in a new resource being created. The newly created resource can be referenced by the URI(s) returned in the entity of the response, with the most specific URI for the resource given by a Location header field. The response SHOULD include an entity containing a list of resource characteristics and location(s) from which the user or user agent can choose the one most appropriate. The entity format is specified by the media type given in the Content-Type header field. The origin server MUST create the resource before returning the 201 status code. If the action cannot be carried out immediately, the server SHOULD respond with 202 (Accepted) response instead. A 201 response MAY contain an ETag response header field indicating the current value of the entity tag for the requested variant just created, see section 14.19.
val CREATED : body:string -> WebPart

201 The request has been fulfilled and resulted in a new resource being created. The newly created resource can be referenced by the URI(s) returned in the entity of the response, with the most specific URI for the resource given by a Location header field. The response SHOULD include an entity containing a list of resource characteristics and location(s) from which the user or user agent can choose the one most appropriate. The entity format is specified by the media type given in the Content-Type header field. The origin server MUST create the resource before returning the 201 status code. If the action cannot be carried out immediately, the server SHOULD respond with 202 (Accepted) response instead. A 201 response MAY contain an ETag response header field indicating the current value of the entity tag for the requested variant just created, see section 14.19.
val accepted : bytes:byte [] -> WebPart

202 The request has been accepted for processing, but the processing has not been completed. The request might or might not eventually be acted upon, as it might be disallowed when processing actually takes place. There is no facility for re-sending a status code from an asynchronous operation such as this. The 202 response is intentionally non-committal. Its purpose is to allow a server to accept a request for some other process (perhaps a batch-oriented process that is only run once per day) without requiring that the user agent's connection to the server persist until the process is completed. The entity returned with this response SHOULD include an indication of the request's current status and either a pointer to a status monitor or some estimate of when the user can expect the request to be fulfilled.
val ACCEPTED : body:string -> WebPart

202 The request has been accepted for processing, but the processing has not been completed. The request might or might not eventually be acted upon, as it might be disallowed when processing actually takes place. There is no facility for re-sending a status code from an asynchronous operation such as this. The 202 response is intentionally non-committal. Its purpose is to allow a server to accept a request for some other process (perhaps a batch-oriented process that is only run once per day) without requiring that the user agent's connection to the server persist until the process is completed. The entity returned with this response SHOULD include an indication of the request's current status and either a pointer to a status monitor or some estimate of when the user can expect the request to be fulfilled.
val no_content : WebPart

204 The server has fulfilled the request but does not need to return an entity-body, and might want to return updated metainformation. The response MAY include new or updated metainformation in the form of entity-headers, which if present SHOULD be associated with the requested variant. If the client is a user agent, it SHOULD NOT change its document view from that which caused the request to be sent. This response is primarily intended to allow input for actions to take place without causing a change to the user agent's active document view, although any new or updated metainformation SHOULD be applied to the document currently in the user agent's active view. The 204 response MUST NOT include a message-body, and thus is always terminated by the first empty line after the header fields.
val NO_CONTENT : WebPart

204 The server has fulfilled the request but does not need to return an entity-body, and might want to return updated metainformation. The response MAY include new or updated metainformation in the form of entity-headers, which if present SHOULD be associated with the requested variant. If the client is a user agent, it SHOULD NOT change its document view from that which caused the request to be sent. This response is primarily intended to allow input for actions to take place without causing a change to the user agent's active document view, although any new or updated metainformation SHOULD be applied to the document currently in the user agent's active view. The 204 response MUST NOT include a message-body, and thus is always terminated by the first empty line after the header fields.
module Redirection =

Functions have signature f :: params... -> HttpContext -> Async<unit> option.

Functions from here are 'end routes' in that they don't require you to keep returning applicatives, but can end up in an async monad/workflow that writes the data to the client in the end.

This class of status code indicates that further action needs to be taken by the user agent in order to fulfill the request. The action required MAY be carried out by the user agent without interaction with the user if and only if the method used in the second request is GET or HEAD. A client SHOULD detect infinite redirection loops, since such loops generate network traffic for each redirection.

Note: previous versions of this specification recommended a maximum of five redirections. Content developers should be aware that there might be clients that implement such a fixed limitation.
val moved_permanently : location:string -> WebPart

301 The requested resource has been assigned a new permanent URI and any future references to this resource SHOULD use one of the returned URIs. Clients with link editing capabilities ought to automatically re-link references to the Request-URI to one or more of the new references returned by the server, where possible. This response is cacheable unless indicated otherwise. The new permanent URI SHOULD be given by the Location field in the response. Unless the request method was HEAD, the entity of the response SHOULD contain a short hypertext note with a hyperlink to the new URI(s). If the 301 status code is received in response to a request other than GET or HEAD, the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user, since this might change the conditions under which the request was issued. Note: When automatically redirecting a POST request after receiving a 301 status code, some existing HTTP/1.0 user agents will erroneously change it into a GET request.
val MOVED_PERMANENTLY : location:string -> WebPart

301 The requested resource has been assigned a new permanent URI and any future references to this resource SHOULD use one of the returned URIs. Clients with link editing capabilities ought to automatically re-link references to the Request-URI to one or more of the new references returned by the server, where possible. This response is cacheable unless indicated otherwise. The new permanent URI SHOULD be given by the Location field in the response. Unless the request method was HEAD, the entity of the response SHOULD contain a short hypertext note with a hyperlink to the new URI(s). If the 301 status code is received in response to a request other than GET or HEAD, the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user, since this might change the conditions under which the request was issued. Note: When automatically redirecting a POST request after receiving a 301 status code, some existing HTTP/1.0 user agents will erroneously change it into a GET request.
val found : location:string -> WebPart

302 The requested resource resides temporarily under a different URI. Since the redirection might be altered on occasion, the client SHOULD continue to use the Request-URI for future requests. This response is only cacheable if indicated by a Cache-Control or Expires header field. The temporary URI SHOULD be given by the Location field in the response. Unless the request method was HEAD, the entity of the response SHOULD contain a short hypertext note with a hyperlink to the new URI(s). If the 302 status code is received in response to a request other than GET or HEAD, the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user, since this might change the conditions under which the request was issued. If the 302 status code is received in response to a request other than GET or HEAD, the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user, since this might change the conditions under which the request was issued. Note: RFC 1945 and RFC 2068 specify that the client is not allowed to change the method on the redirected request. However, most existing user agent implementations treat 302 as if it were a 303 response, performing a GET on the Location field-value regardless of the original request method. The status codes 303 and 307 have been added for servers that wish to make unambiguously clear which kind of reaction is expected of the client.
val FOUND : location:string -> WebPart

302 The requested resource resides temporarily under a different URI. Since the redirection might be altered on occasion, the client SHOULD continue to use the Request-URI for future requests. This response is only cacheable if indicated by a Cache-Control or Expires header field. The temporary URI SHOULD be given by the Location field in the response. Unless the request method was HEAD, the entity of the response SHOULD contain a short hypertext note with a hyperlink to the new URI(s). If the 302 status code is received in response to a request other than GET or HEAD, the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user, since this might change the conditions under which the request was issued. If the 302 status code is received in response to a request other than GET or HEAD, the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user, since this might change the conditions under which the request was issued. Note: RFC 1945 and RFC 2068 specify that the client is not allowed to change the method on the redirected request. However, most existing user agent implementations treat 302 as if it were a 303 response, performing a GET on the Location field-value regardless of the original request method. The status codes 303 and 307 have been added for servers that wish to make unambiguously clear which kind of reaction is expected of the client.
val redirect : location:string -> WebPart

Composite: HTTP/1.1 302 Found Location: 'location' Content-Type: text/html; charset=utf-8 <html> <body> <a href="'location'">Content Moved</a> </body> </html> Redirect the request to another location specified by the url parameter. Sets the Location header and returns 302 Content Moved status-code/reason phrase.
val see_other : location:string -> WebPart

Composite: HTTP/1.1 303 See Other Location: 'location' Content-Type: text/html; charset=utf-8 <html> <body> <a href="'location'">See Other</a> </body> </html> The 303 (See Other) status code indicates that the server is redirecting the user agent to a different resource, as indicated by a URI in the Location header field, which is intended to provide an indirect response to the original request.
val not_modified : WebPart

If the client has performed a conditional GET request and access is allowed, but the document has not been modified, the server SHOULD respond with this status code. The 304 response MUST NOT contain a message-body, and thus is always terminated by the first empty line after the header fields. The response MUST include the following header fields: Date, unless its omission is required by section 14.18.1. If a clockless origin server obeys these rules, and proxies and clients add their own Date to any response received without one (as already specified by [RFC 2068], section 14.19), caches will operate correctly. ETag and/or Content-Location, if the header would have been sent in a 200 response to the same request Expires, Cache-Control, and/or Vary, if the field-value might differ from that sent in any previous response for the same variant If the conditional GET used a strong cache validator (see section 13.3.3), the response SHOULD NOT include other entity-headers. Otherwise (i.e., the conditional GET used a weak validator), the response MUST NOT include other entity-headers; this prevents inconsistencies between cached entity-bodies and updated headers. If a 304 response indicates an entity not currently cached, then the cache MUST disregard the response and repeat the request without the conditional. If a cache uses a received 304 response to update a cache entry, the cache MUST update the entry to reflect any new field values given in the response.
val NOT_MODIFIED : WebPart

If the client has performed a conditional GET request and access is allowed, but the document has not been modified, the server SHOULD respond with this status code. The 304 response MUST NOT contain a message-body, and thus is always terminated by the first empty line after the header fields. The response MUST include the following header fields: Date, unless its omission is required by section 14.18.1. If a clockless origin server obeys these rules, and proxies and clients add their own Date to any response received without one (as already specified by [RFC 2068], section 14.19), caches will operate correctly. ETag and/or Content-Location, if the header would have been sent in a 200 response to the same request Expires, Cache-Control, and/or Vary, if the field-value might differ from that sent in any previous response for the same variant If the conditional GET used a strong cache validator (see section 13.3.3), the response SHOULD NOT include other entity-headers. Otherwise (i.e., the conditional GET used a weak validator), the response MUST NOT include other entity-headers; this prevents inconsistencies between cached entity-bodies and updated headers. If a 304 response indicates an entity not currently cached, then the cache MUST disregard the response and repeat the request without the conditional. If a cache uses a received 304 response to update a cache entry, the cache MUST update the entry to reflect any new field values given in the response.
module RequestErrors =

10.4 Client Error 4xx

The 4xx class of status code is intended for cases in which the client seems to have erred. Except when responding to a HEAD request, the server SHOULD include an entity containing an explanation of the error situation, and whether it is a temporary or permanent condition. These status codes are applicable to any request method. User agents SHOULD display any included entity to the user. If the client is sending data, a server implementation using TCP SHOULD be careful to ensure that the client acknowledges receipt of the packet(s) containing the response, before the server closes the input connection. If the client continues sending data to the server after the close, the server's TCP stack will send a reset packet to the client, which may erase the client's unacknowledged input buffers before they can be read and interpreted by the HTTP application.

val bad_request : bytes:byte [] -> WebPart

400 The request could not be understood by the server due to malformed syntax. The client SHOULD NOT repeat the request without modifications.
val BAD_REQUEST : body:string -> WebPart

400 The request could not be understood by the server due to malformed syntax. The client SHOULD NOT repeat the request without modifications.
val unauthorized : bytes:byte [] -> WebPart

401 The request requires user authentication. The response MUST include a WWW-Authenticate header field (section 14.47) containing a challenge applicable to the requested resource. The client MAY repeat the request with a suitable Authorization header field (section 14.8). If the request already included Authorization credentials, then the 401 response indicates that authorization has been refused for those credentials. If the 401 response contains the same challenge as the prior response, and the user agent has already attempted authentication at least once, then the user SHOULD be presented the entity that was given in the response, since that entity might include relevant diagnostic information. HTTP access authentication is explained in "HTTP Authentication: Basic and Digest Access Authentication" [43].
val UNAUTHORIZED : body:string -> WebPart

401 The request requires user authentication. The response MUST include a WWW-Authenticate header field (section 14.47) containing a challenge applicable to the requested resource. The client MAY repeat the request with a suitable Authorization header field (section 14.8). If the request already included Authorization credentials, then the 401 response indicates that authorization has been refused for those credentials. If the 401 response contains the same challenge as the prior response, and the user agent has already attempted authentication at least once, then the user SHOULD be presented the entity that was given in the response, since that entity might include relevant diagnostic information. HTTP access authentication is explained in "HTTP Authentication: Basic and Digest Access Authentication" [43].
val challenge : WebPart

Composite: HTTP/1.1 401 Unauthorized WWW-Authenticate: Basic realm="protected" A challenge response with a WWW-Authenticate header, and 401 Authorization Required response message. Also see authenticate_basic and unauthorized
val forbidden : bytes:byte [] -> WebPart

403 The server understood the request, but is refusing to fulfill it. Authorization will not help and the request SHOULD NOT be repeated. If the request method was not HEAD and the server wishes to make public why the request has not been fulfilled, it SHOULD describe the reason for the refusal in the entity. If the server does not wish to make this information available to the client, the status code 404 (Not Found) can be used instead.
val FORBIDDEN : body:string -> WebPart

403 The server understood the request, but is refusing to fulfill it. Authorization will not help and the request SHOULD NOT be repeated. If the request method was not HEAD and the server wishes to make public why the request has not been fulfilled, it SHOULD describe the reason for the refusal in the entity. If the server does not wish to make this information available to the client, the status code 404 (Not Found) can be used instead.
val not_found : bytes:byte [] -> WebPart

404 Send a 404 Not Found with a byte array body specified by the 's' parameter. The server has not found anything matching the Request-URI. No indication is given of whether the condition is temporary or permanent. The 410 (Gone) status code SHOULD be used if the server knows, through some internally configurable mechanism, that an old resource is permanently unavailable and has no forwarding address. This status code is commonly used when the server does not wish to reveal exactly why the request has been refused, or when no other response is applicable.
val NOT_FOUND : body:string -> WebPart

404 Write the 'message' string to the body as UTF-8 encoded text, while returning 404 Not Found to the response The server has not found anything matching the Request-URI. No indication is given of whether the condition is temporary or permanent. The 410 (Gone) status code SHOULD be used if the server knows, through some internally configurable mechanism, that an old resource is permanently unavailable and has no forwarding address. This status code is commonly used when the server does not wish to reveal exactly why the request has been refused, or when no other response is applicable.
val method_not_allowed : bytes:byte [] -> WebPart

405 The method specified in the Request-Line is not allowed for the resource identified by the Request-URI. The response MUST include an Allow header containing a list of valid methods for the requested resource.
val METHOD_NOT_ALLOWED : body:string -> WebPart

405 The method specified in the Request-Line is not allowed for the resource identified by the Request-URI. The response MUST include an Allow header containing a list of valid methods for the requested resource.
val not_acceptable : bytes:byte[] -> WebPart

406 The resource identified by the request is only capable of generating response entities which have content characteristics not acceptable according to the accept headers sent in the request. Unless it was a HEAD request, the response SHOULD include an entity containing a list of available entity characteristics and location(s) from which the user or user agent can choose the one most appropriate. The entity format is specified by the media type given in the Content-Type header field. Depending upon the format and the capabilities of the user agent, selection of the most appropriate choice MAY be performed automatically. However, this specification does not define any standard for such automatic selection. Note: HTTP/1.1 servers are allowed to return responses which are not acceptable according to the accept headers sent in the request. In some cases, this may even be preferable to sending a 406 response. User agents are encouraged to inspect the headers of an incoming response to determine if it is acceptable. If the response could be unacceptable, a user agent SHOULD temporarily stop receipt of more data and query the user for a decision on further actions.
val NOT_ACCEPTABLE : body:string -> WebPart

406 The resource identified by the request is only capable of generating response entities which have content characteristics not acceptable according to the accept headers sent in the request. Unless it was a HEAD request, the response SHOULD include an entity containing a list of available entity characteristics and location(s) from which the user or user agent can choose the one most appropriate. The entity format is specified by the media type given in the Content-Type header field. Depending upon the format and the capabilities of the user agent, selection of the most appropriate choice MAY be performed automatically. However, this specification does not define any standard for such automatic selection. Note: HTTP/1.1 servers are allowed to return responses which are not acceptable according to the accept headers sent in the request. In some cases, this may even be preferable to sending a 406 response. User agents are encouraged to inspect the headers of an incoming response to determine if it is acceptable. If the response could be unacceptable, a user agent SHOULD temporarily stop receipt of more data and query the user for a decision on further actions.
val request_timeout : WebPart

408 The client did not produce a request within the time that the server was prepared to wait. The client MAY repeat the request without modifications at any later time.
val conflict : bytes:byte[] -> WebPart

409 The request could not be completed due to a conflict with the current state of the resource. This code is only allowed in situations where it is expected that the user might be able to resolve the conflict and resubmit the request. The response body SHOULD include enough information for the user to recognize the source of the conflict. Ideally, the response entity would include enough information for the user or user agent to fix the problem; however, that might not be possible and is not required. Conflicts are most likely to occur in response to a PUT request. For example, if versioning were being used and the entity being PUT included changes to a resource which conflict with those made by an earlier (third-party) request, the server might use the 409 response to indicate that it can't complete the request. In this case, the response entity would likely contain a list of the differences between the two versions in a format defined by the response Content-Type.
val CONFLICT : body:string -> WebPart

409 The request could not be completed due to a conflict with the current state of the resource. This code is only allowed in situations where it is expected that the user might be able to resolve the conflict and resubmit the request. The response body SHOULD include enough information for the user to recognize the source of the conflict. Ideally, the response entity would include enough information for the user or user agent to fix the problem; however, that might not be possible and is not required. Conflicts are most likely to occur in response to a PUT request. For example, if versioning were being used and the entity being PUT included changes to a resource which conflict with those made by an earlier (third-party) request, the server might use the 409 response to indicate that it can't complete the request. In this case, the response entity would likely contain a list of the differences between the two versions in a format defined by the response Content-Type.
val gone : bytes:byte [] -> WebPart

410 The requested resource is no longer available at the server and no forwarding address is known. This condition is expected to be considered permanent. Clients with link editing capabilities SHOULD delete references to the Request-URI after user approval. If the server does not know, or has no facility to determine, whether or not the condition is permanent, the status code 404 (Not Found) SHOULD be used instead. This response is cacheable unless indicated otherwise. The 410 response is primarily intended to assist the task of web maintenance by notifying the recipient that the resource is intentionally unavailable and that the server owners desire that remote links to that resource be removed. Such an event is common for limited-time, promotional services and for resources belonging to individuals no longer working at the server's site. It is not necessary to mark all permanently unavailable resources as "gone" or to keep the mark for any length of time -- that is left to the discretion of the server owner.
val GONE : body:string -> WebPart

410 The requested resource is no longer available at the server and no forwarding address is known. This condition is expected to be considered permanent. Clients with link editing capabilities SHOULD delete references to the Request-URI after user approval. If the server does not know, or has no facility to determine, whether or not the condition is permanent, the status code 404 (Not Found) SHOULD be used instead. This response is cacheable unless indicated otherwise. The 410 response is primarily intended to assist the task of web maintenance by notifying the recipient that the resource is intentionally unavailable and that the server owners desire that remote links to that resource be removed. Such an event is common for limited-time, promotional services and for resources belonging to individuals no longer working at the server's site. It is not necessary to mark all permanently unavailable resources as "gone" or to keep the mark for any length of time -- that is left to the discretion of the server owner.
val unsupported_media_type : bytes:byte [] -> WebPart

415 The server is refusing to service the request because the entity of the request is in a format not supported by the requested resource for the requested method.
val UNSUPPORTED_MEDIA_TYPE : body:string -> WebPart

415 The server is refusing to service the request because the entity of the request is in a format not supported by the requested resource for the requested method.
val unprocessable_entity : bytes:byte [] -> WebPart

422 The request was well-formed but was unable to be followed due to semantic errors.[4] (WebDAV; RFC 4918)
val UNPROCESSABLE_ENTITY : body:string -> WebPart

422 The request was well-formed but was unable to be followed due to semantic errors.[4] (WebDAV; RFC 4918)
val precondition_required : bytes:byte[] -> WebPart

428 The 428 status code indicates that the origin server requires the request to be conditional. Its typical use is to avoid the "lost update" problem, where a client GETs a resource's state, modifies it, and PUTs it back to the server, when meanwhile a third party has modified the state on the server, leading to a conflict. By requiring requests to be conditional, the server can assure that clients are working with the correct copies. Responses using this status code SHOULD explain how to resubmit the request successfully. For example: HTTP/1.1 428 Precondition Required Content-Type: text/html

<html> <head> <title>Precondition Required</title> </head> <body> <h1>Precondition Required</h1> <p>This request is required to be conditional; try using "If-Match".</p> </body> </html> Responses with the 428 status code MUST NOT be stored by a cache.

https://tools.ietf.org/html/rfc6585
val PRECONDITION_REQUIRED : body:string -> WebPart

428 The 428 status code indicates that the origin server requires the request to be conditional. Its typical use is to avoid the "lost update" problem, where a client GETs a resource's state, modifies it, and PUTs it back to the server, when meanwhile a third party has modified the state on the server, leading to a conflict. By requiring requests to be conditional, the server can assure that clients are working with the correct copies. Responses using this status code SHOULD explain how to resubmit the request successfully. For example: HTTP/1.1 428 Precondition Required Content-Type: text/html

<html> <head> <title>Precondition Required</title> </head> <body> <h1>Precondition Required</h1> <p>This request is required to be conditional; try using "If-Match".</p> </body> </html> Responses with the 428 status code MUST NOT be stored by a cache.

https://tools.ietf.org/html/rfc6585
val too_many_requests : bytes:byte [] -> WebPart

429 The user has sent too many requests in a given amount of time. Intended for use with rate limiting schemes.[18] https://tools.ietf.org/html/rfc6585
val TOO_MANY_REQUESTS : body:string -> WebPart

429 The user has sent too many requests in a given amount of time. Intended for use with rate limiting schemes.[18] https://tools.ietf.org/html/rfc6585
module ServerErrors =

10.5 Server Error 5xx Response status codes beginning with the digit "5" indicate cases in which the server is aware that it has erred or is incapable of performing the request. Except when responding to a HEAD request, the server SHOULD include an entity containing an explanation of the error situation, and whether it is a temporary or permanent condition. User agents SHOULD display any included entity to the user. These response codes are applicable to any request method.

val internal_error : bytes:byte [] -> WebPart

500 The server encountered an unexpected condition which prevented it from fulfilling the request.
val INTERNAL_ERROR : body:string -> WebPart

500 The server encountered an unexpected condition which prevented it from fulfilling the request.
val not_implemented : bytes:byte [] -> WebPart

501 The server does not recognize the request method and can not support it for any resource.
val NOT_IMPLEMENTED : body:string -> WebPart

501 The server does not recognize the request method and can not support it for any resource.
val bad_gateway : bytes:byte [] -> WebPart

An upstream server that suave communicated with did not respond in a timely fashion

val BAD_GATEWAY : body:string -> WebPart

An upstream server that suave communicated with did not respond in a timely fashion

val service_unavailable : bytes:byte [] -> WebPart

The service is currently under too much load and cannot service the request

val SERVICE_UNAVAILABLE : body:string -> WebPart

The service is currently under too much load and cannot service the request

val gateway_timeout : bytes:byte [] -> WebPart

An upstream server that suave communicated with did not respond in a timely fashion

val GATEWAY_TIMEOUT : body:string -> WebPart

An upstream server that suave communicated with did not respond in a timely fashion

val invalid_http_version : bytes:byte [] -> WebPart

Only used internally in Suave.

val INVALID_HTTP_VERSION : WebPart

Only used internally in Suave.

module Filters =

Module that deals with the applicatives of suave - use functions from this module to filter what requests a given route responds to. Functions have signature f :: params... -> HttpContext -> HttpContext option.

val path : pathAfterDomain:string -> WebPart

Match on the path

val pathCi : pathAfterDomain:string -> WebPart

Match on the path regardless of casing

val pathStarts : pathAfterDomainSubstr:string -> WebPart

Match on the initial path

val pathStartsCi : pathAfterDomainSubstr:string -> WebPart

Match on the initial path regardless of casing

val   method   :   method  :HttpMethod -> WebPart

Match on the method

val isSecure : WebPart

Match on the protocol being HTTPS

val hasFlag : flag:string -> WebPart

Ensure the query-string parameter exists (it exists even if it does not have a value associated with it.)

val pathRegex : pathAfterDomainRegex:string -> WebPart

Applies the regex to the path and matches on the result

val host : hostname:string -> WebPart

Match on the hostname (which is a required header for a Http client to send) -> allows you to have multiple sites with a single application. TODO: support SNI #177

Perform a case-insensitive string comparison with context.request.clientHostTrustProxy which is the client-host; i.e. what the request says is the host, or what the proxy server says is the forwarded Host value. To match on what the web server *knows for sure* is the host, in the case when you've not overridden x-forwarded-host in your proxy, you should use x.request.host or Http.Applicatives.serverHost instead. The normal use- case, however, is to match on what's publically routable, which is the client host.

val serverHost : hostname:string -> WebPart

This is the server's knowledge of what's the host is. In the case you have a clustered web server deployment, you might be more interested in what the client expects the host to be, since most validation logic you have in your app is concerned with this.

val clientHost : hostname:string -> WebPart

Alias for host.

val logFormatStructured : ctx:HttpContext -> string * Map<string,obj>

The structured version of default log format for . NCSA Common log format

127.0.0.1 user-identifier frank [10/Oct/2000:13:55:36 -0700] "GET /apache_pb.gif HTTP/1.0" 200 2326

A "-" in a field indicates missing data.

127.0.0.1 is the IP address of the client (remote host) which made the request to the server. user-identifier is the RFC 1413 identity of the client. frank is the userid of the person requesting the document. [10/Oct/2000:13:55:36 -0700] is the date, time, and time zone when the server finished processing the request, by default in strftime format %d/%b/%Y:%H:%M:%S %z. "GET /apache_pb.gif HTTP/1.0" is the request line from the client. The method GET, /apache_pb.gif the resource requested, and HTTP/1.0 the HTTP protocol. 200 is the HTTP status code returned to the client. 2xx is a successful response, 3xx a redirection, 4xx a client error, and 5xx a server error. 2326 is the size of the object returned to the client, measured in bytes.

val logWithLevelStructured :  level:LogLevel -> logger:Logger -> messageFun:(HttpContext -> string * Map<string,obj>) -> WebPart

Log the HttpRequest to the given logger, given the Suave Logger, a LogLevel and a message formatter that can inspect the context and produce a message to send to the logger, along with the structured fields as a name*obj map.
val logStructured : logger:Logger -> messageFun:(HttpContext -> string * Map<string,obj>) -> WebPart

The function log is equivalent to logWithLevel LogLevel.Debug.
val logFormat : ctx:HttpContext -> string

The default log format for . NCSA Common log format

127.0.0.1 user-identifier frank [10/Oct/2000:13:55:36 -0700] "GET /apache_pb.gif HTTP/1.0" 200 2326

A "-" in a field indicates missing data.

127.0.0.1 is the IP address of the client (remote host) which made the request to the server. user-identifier is the RFC 1413 identity of the client. frank is the userid of the person requesting the document. [10/Oct/2000:13:55:36 -0700] is the date, time, and time zone when the server finished processing the request, by default in strftime format %d/%b/%Y:%H:%M:%S %z. "GET /apache_pb.gif HTTP/1.0" is the request line from the client. The method GET, /apache_pb.gif the resource requested, and HTTP/1.0 the HTTP protocol. 200 is the HTTP status code returned to the client. 2xx is a successful response, 3xx a redirection, 4xx a client error, and 5xx a server error. 2326 is the size of the object returned to the client, measured in bytes.

val logWithLevel :  level:LogLevel -> logger:Logger -> messageFun:(HttpContext -> string) -> WebPart

Log the HttpRequest to the given logger, given the Suave Logger, a LogLevel and a message formatter that can inspect the context and produce a message to send to the logger.
val log : logger:Logger -> messageFun:(HttpContext -> string) -> WebPart

The function log is equivalent to logWithLevel LogLevel.Debug.
val pathScan : pf:PrintfFormat<'a,'b,'c,'d,'t> -> h:('t -> WebPart) -> WebPart

Strongly typed route matching! Matching the uri can be used with the 'parsers' characters specified in Sscanf. The supported characters for the formatter: 'b', bool 'd', int64 'i', int64 's', string 'u', uint64 'x', check (String.forall Char.IsLower) >> ((+) "0x") >> int64 'X', check (String.forall Char.IsUpper) >> ((+) "0x") >> int64 'o', ((+) "0o") >> int64. Base8 numbers; e.g. "1" = 0o1 = 1, "7" = 0o7 = 7, "10" = 0o10 = 8. 'e', float 'E', float 'f', float 'F', float 'g', float 'G', float 'M', decimal 'c', char
val pathScanCi : format:PrintfFormat<'a,'b,'c,'d,'t> -> handler:('t -> WebPart) -> WebPart

Strongly typed route matching regardless of casing! Matching the uri can be used with the 'parsers' characters specified in Sscanf. The supported characters for the formatter: 'b', Boolean.Parse 'd', int 'i', int 's', box 'u', uint32 'x', check (String.forall Char.IsLower) >> ((+) "0x") >> int 'X', check (String.forall Char.IsUpper) >> ((+) "0x") >> int 'o', ((+) "0o") >> int 'e', float// no check for correct format for floats 'E', float 'f', float 'F', float 'g', float 'G', float 'M', parse_decimal 'c', char
val timeoutWebPart : timeout:System.TimeSpan -> child:WebPart -> WebPart

Fails the WebPart after x seconds
val GET : WebPart

Match on GET requests. The GET method means retrieve whatever information (in the form of an entity) is identified by the Request-URI. If the Request-URI refers to a data-producing process, it is the produced data which shall be returned as the entity in the response and not the source text of the process, unless that text happens to be the output of the process. The semantics of the GET method change to a "conditional GET" if the request message includes an If-Modified-Since, If-Unmodified-Since, If-Match, If-None-Match, or If-Range header field. A conditional GET method requests that the entity be transferred only under the circumstances described by the conditional header field(s). The conditional GET method is intended to reduce unnecessary network usage by allowing cached entities to be refreshed without requiring multiple requests or transferring data already held by the client.
val POST : WebPart

Match on POST requests. The POST method is used to request that the origin server accept the entity enclosed in the request as a new subordinate of the resource identified by the Request-URI in the Request-Line. POST is designed to allow a uniform method to cover the following functions: Annotation of existing resources; Posting a message to a bulletin board, newsgroup, mailing list, similar group of articles; Providing a block of data, such as the result of submitting a form, to a data-handling process; Extending a database through an append operation. The actual function performed by the POST method is determined by the server and is usually dependent on the Request-URI. The posted entity is subordinate to that URI in the same way that a file is subordinate to a directory containing it, a news article is subordinate to a newsgroup to which it is posted, or a record is subordinate to a database. The action performed by the POST method might not result in a resource that can be identified by a URI. In this case, either 200 (OK) or 204 (No Content) is the appropriate response status, depending on whether or not the response includes an entity that describes the result. If a resource has been created on the origin server, the response SHOULD be 201 (Created) and contain an entity which describes the status of the request and refers to the new resource, and a Location header (see section 14.30). Responses to this method are not cacheable, unless the response includes appropriate Cache-Control or Expires header fields. However, the 303 (See Other) response can be used to direct the user agent to retrieve a cacheable resource.
val DELETE : WebPart

Match on DELETE requests. The DELETE method requests that the origin server delete the resource identified by the Request-URI. This method MAY be overridden by human intervention (or other means) on the origin server. The client cannot be guaranteed that the operation has been carried out, even if the status code returned from the origin server indicates that the action has been completed successfully. However, the server SHOULD NOT indicate success unless, at the time the response is given, it intends to delete the resource or move it to an inaccessible location. A successful response SHOULD be 200 (OK) if the response includes an entity describing the status, 202 (Accepted) if the action has not yet been enacted, or 204 (No Content) if the action has been enacted but the response does not include an entity. If the request passes through a cache and the Request-URI identifies one or more currently cached entities, those entries SHOULD be treated as stale. Responses to this method are not cacheable.
val PUT : WebPart

Match on PUT requests The PUT method requests that the enclosed entity be stored under the supplied Request-URI. If the Request-URI refers to an already existing resource, the enclosed entity SHOULD be considered as a modified version of the one residing on the origin server. If the Request-URI does not point to an existing resource, and that URI is capable of being defined as a new resource by the requesting user agent, the origin server can create the resource with that URI. If a new resource is created, the origin server MUST inform the user agent via the 201 (Created) response. If an existing resource is modified, either the 200 (OK) or 204 (No Content) response codes SHOULD be sent to indicate successful completion of the request. If the resource could not be created or modified with the Request-URI, an appropriate error response SHOULD be given that reflects the nature of the problem. The recipient of the entity MUST NOT ignore any Content-* (e.g. Content-Range) headers that it does not understand or implement and MUST return a 501 (Not Implemented) response in such cases. If the request passes through a cache and the Request-URI identifies one or more currently cached entities, those entries SHOULD be treated as stale. Responses to this method are not cacheable. The fundamental difference between the POST and PUT requests is reflected in the different meaning of the Request-URI. The URI in a POST request identifies the resource that will handle the enclosed entity. That resource might be a data-accepting process, a gateway to some other protocol, or a separate entity that accepts annotations. In contrast, the URI in a PUT request identifies the entity enclosed with the request -- the user agent knows what URI is intended and the server MUST NOT attempt to apply the request to some other resource. If the server desires that the request be applied to a different URI, it MUST send a 301 (Moved Permanently) response; the user agent MAY then make its own decision regarding whether or not to redirect the request. A single resource MAY be identified by many different URIs. For example, an article might have a URI for identifying "the current version" which is separate from the URI identifying each particular version. In this case, a PUT request on a general URI might result in several other URIs being defined by the origin server. PUT requests MUST obey the message transmission requirements set out in section 8.2. HTTP/1.1 does not define how a PUT method affects the state of an origin server. Unless otherwise specified for a particular entity-header, the entity-headers in the PUT request SHOULD be applied to the resource created or modified by the PUT.
val HEAD : WebPart

Match on HEAD requests. The HEAD method is identical to GET except that the server MUST NOT return a message-body in the response. The metainformation contained in the HTTP headers in response to a HEAD request SHOULD be identical to the information sent in response to a GET request. This method can be used for obtaining metainformation about the entity implied by the request without transferring the entity-body itself. This method is often used for testing hypertext links for validity, accessibility, and recent modification. The response to a HEAD request MAY be cacheable in the sense that the information contained in the response MAY be used to update a previously cached entity from that resource. If the new field values indicate that the cached entity differs from the current entity (as would be indicated by a change in Content-Length, Content-MD5, ETag or Last-Modified), then the cache MUST treat the cache entry as stale.
val CONNECT : WebPart

Match on CONNECT requests. This specification (RFC 2616) reserves the method name CONNECT for use with a proxy that can dynamically switch to being a tunnel (e.g. SSL tunneling [44]).
val PATCH : WebPart

Match on PATCH requests. The PATCH method requests that a set of changes described in the request entity be applied to the resource identified by the Request- URI. The set of changes is represented in a format called a "patch document" identified by a media type. If the Request-URI does not point to an existing resource, the server MAY create a new resource, depending on the patch document type (whether it can logically modify a null resource) and permissions, etc. The difference between the PUT and PATCH requests is reflected in the way the server processes the enclosed entity to modify the resource identified by the Request-URI. In a PUT request, the enclosed entity is considered to be a modified version of the resource stored on the origin server, and the client is requesting that the stored version be replaced. With PATCH, however, the enclosed entity contains a set of instructions describing how a resource currently residing on the origin server should be modified to produce a new version. The PATCH method affects the resource identified by the Request-URI, and it also MAY have side effects on other resources; i.e., new resources may be created, or existing ones modified, by the application of a PATCH. From http://tools.ietf.org/html/rfc5789#page-2
val TRACE : WebPart

Match on TRACE requests. The TRACE method is used to invoke a remote, application-layer loop- back of the request message. The final recipient of the request SHOULD reflect the message received back to the client as the entity-body of a 200 (OK) response. The final recipient is either the origin server or the first proxy or gateway to receive a Max-Forwards value of zero (0) in the request (see section 14.31). A TRACE request MUST NOT include an entity. TRACE allows the client to see what is being received at the other end of the request chain and use that data for testing or diagnostic information. The value of the Via header field (section 14.45) is of particular interest, since it acts as a trace of the request chain. Use of the Max-Forwards header field allows the client to limit the length of the request chain, which is useful for testing a chain of proxies forwarding messages in an infinite loop. If the request is valid, the response SHOULD contain the entire request message in the entity-body, with a Content-Type of "message/http". Responses to this method MUST NOT be cached.
val OPTIONS : WebPart

Match on OPTIONS requests The OPTIONS method represents a request for information about the communication options available on the request/response chain identified by the Request-URI. This method allows the client to determine the options and/or requirements associated with a resource, or the capabilities of a server, without implying a resource action or initiating a resource retrieval. Responses to this method are not cacheable.

module Files =

The files module can be used to serve from the file system. It encapsulates common patterns like verifying that back-symlinks or keywords aren't used to gain access outside the intended folder.

val sendFile : fileName:string -> compression:bool -> WebPart

Send a file as a response to the request
val file : fileName:string -> WebPart

Send the embedded file by the filename given. Will search relative to the current assembly. Will also set the MIME type based on the file extension.
val resolvePath : rootPath:string -> fileName:string -> string

Format a string with a local file path given a file name 'fileName'. You should use this helper method to find the current directory and concatenate that current directory to the filename which should be absolute and start with a path separator. The current implementation doesn't take kindly to relative paths.
val browseFile : rootPath:string -> fileName:string -> WebPart

'browse' the file given as the filename, by sending it to the browser with a MIME-type/Content-Type header based on its extension. Will service from the rootPath.
val browseFileHome : fileName:string -> WebPart

'browse' the file given as the filename, by sending it to the browser with a MIME-type/Content-Type header based on its extension. Will service from the current directory.
val browse : rootPath:string -> WebPart

'browse' the file in the sense that the contents of the file are sent based on the request's Url property. Will serve from the passed root path/directory. The current implementation doesn't take kindly to relative paths.
val browseHome : WebPart

'browse' the file in the sense that the contents of the file are sent based on the request's Url property. Will serve from the current as configured in directory. Suave's runtime.
val dir : rootPath:string -> WebPart

Serve a 'file browser' for a rootPath The current implementation doesn't take kindly to relative paths.
val dirHome : WebPart

Serve a 'file browser' for the current directory
module Embedded =
val sendResource : source:Assembly -> resourceName:string -> compression:bool -> WebPart

Send an embedded resource as a response to the request. Allows you to control the source assembly to read from.
val sendResourceFromDefaultAssembly : resourceName:string -> compression:bool -> WebPart

Send an embedded resource as a response to the request
val resource : source:Assembly -> name:string -> WebPart

Send the resource by the name given. Will also set the MIME type based on the file extension.
val resourceFromDefaultAssembly : name:string -> WebPart

Send the resource by the name given. Will also set the MIME type based on the file extension.
val browse : source:Assembly -> WebPart

'browse' the file in the sense that the contents of the file are sent based on the request's Url property. Will serve from the executing assemblies resources.
val browseDefaultAsssembly : WebPart

'browse' the file in the sense that the contents of the file are sent based on the request's Url property. Will serve from the executing assemblies resources.
module EventSource =

A module that implements the Server-Sent Event specification, which can be read at www.w3.org/TR/eventsource.

val asyncWrite : out:Connection -> data:string -> SocketOp<unit>

Helper function that writes a string of data. Most often you are better off using the send function and give it a message, as this will ensure the proper framing is used. However, if you have a desire to write raw data, this function overrides the Socket.async_write function so that you will be writing UTF8 data only, as per the specification.

val (<<.) : out:Connection -> data:string -> SocketOp<unit>

Same as async_write; convenience function.

val dispatch : out:Connection -> SocketOp<unit>

"If the line is empty (a blank line) - dispatch the event." Dispatches the event properly to the browser.

val comment : out:Connection -> cmt:string -> SocketOp<unit>

"If the line starts with a U+003A COLON character (:) - Ignore the line." Writes a comment to the stream

val eventType : out:Connection -> eventType:string -> SocketOp<unit>

"If the field name is 'event' - Set the event type buffer to field value." Writes the event type to the stream

val data : out:Connection -> data:string -> SocketOp<unit>

"If the field name is 'data' - Append the field value to the data buffer, then append a single U+000A LINE FEED (LF) character to the data buffer." Write a piece of data as part of the event

val esId : out:Connection -> lastEventId:string -> SocketOp<unit>

"If the field name is 'id' - Set the last event ID buffer to the field value." Sets the last event id in the stream.

val retry : out:Connection -> retry:uint32 -> SocketOp<unit>

Sets the option for the EventSource instance, of how long to wait in ms until a new connection is spawned as a retry.

type Message =

A container data type for the output events

static member create : id:string -> data:string -> Message

Create a new message to send over SSE

static member createType : id:string -> data:string -> typ:string -> Message

Create a new message with a given type to send over SSE

val send : out:Connection -> msg:Message -> SocketOp<unit>

send a message containing data to the output stream

val handShake : fCont:(Connection -> SocketOp<Connection>) -> WebPart

This function composes the passed function f with the hand-shake required to start a new event-stream protocol session with the browser.

module Control =
val CLOSE : WebPart

This webpart closes the conection
module CORS =
type CORSConfig =

The configuration values for CORS

allowedUris             : InclusiveOption<string list>

The list of allowed Uri(s) for requests.

allowedMethods          : InclusiveOption<HttpMethod list>

The list of allowed HttpMethods for the request.

allowCookies            : bool

Allow cookies? This is sent in the AccessControlAllowCredentials header.

exposeHeaders           : InclusiveOption<string list>

The list of response headers exposed to client. This is sent in AccessControlExposeHeaders header.

maxAge                  : int option }

Max age in seconds the user agent is allowed to cache the result of the request.

val cors : CORSConfig:(CORSConfig) -> WebPart

This WebPart handles CORS requests.
[<AutoOpen>]
module Http =
type HttpMethod =
  | GET
  | POST
  | DELETE
  | PUT
  | HEAD
  | CONNECT
  | PATCH
  | TRACE
  | OPTIONS
  | OTHER of string

These are the known HTTP methods. See http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html

[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module HttpMethod =
val parse : string -> HttpMethod

Parse a string into a HttpMethod

type HttpStatus =

A HTTP status code and reason message

type HttpCode =

The standard HTTP response codes

type HttpCookie =

HTTP cookie

domain   : string option

This cookies is only valid for the given domain

secure   : bool

This cookie is not forwarded over plaintext transports

httpOnly : bool

This cookie is not readable from JavaScript

[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module HttpCookie =
val create : name:string -> value:string -> expires:DateTimeOffset option
           -> path:string option -> domain:string option -> secure:bool
           -> httpOnly:bool
           -> sameSite:SameSite option
           -> HttpCookie

Create a new HttpCookie with all the given values.

val createKV : name:string -> value:string -> HttpCookie

Create a new cookie with the given name, value, and defaults:

- no explicit expiry time - path at "/", so that it's global to the domain that it's created under. - no specific domain (defaults to the current domain plus its subdomains) - secure = false (you can set it over plain text HTTP - change to true in SSL terminator) - http_only = true - the cookie can be read from JS - change this to false if you want to only be able to read the cookie from JS, but Good default if you're implementing session handling. - version: an optional version field

More reading: - http://www.nczonline.net/blog/2009/05/05/http-cookies-explained/ - https://developer.mozilla.org/en-US/docs/Web/API/document.cookie

val empty : HttpCookie

An empty cookie value

val toHeader : cookie:HttpCookie -> string

Assumes only valid characters go in, see http://tools.ietf.org/html/rfc6265#section-4.1.1

type MimeType =

A file's mime type and if compression is enabled or not

type HttpUpload =

A holder for uploaded file meta-data

type Protocol =

Gets the supported protocols, HTTP and HTTPS with a certificate

type Host = string

Type alias for string. This is the host as seen from the server; not necessarily as seen from the client.

type HttpBinding =

A HTTP binding is a protocol is the product of HTTP or HTTP, a DNS or IP binding and a port number.

override ToString : unit -> string

Overrides the default ToString() method to provide an implementation that is assignable to a BaseUri for a RestClient/HttpClient.

type HttpRequest =

A holder for the data extracted from the request.

member query : (string * string option) list

Gets the query string from the HttpRequest. Use queryParam to try to fetch data for individual items.

member queryParam : key:string -> Choice<string, string>

Finds the key k from the query string in the HttpRequest. To access form data, use either formData to access normal form data, or fieldData to access the multipart-fields.

member queryParamOpt : key:string -> (string * string option) option

Try to find the query parameter named key. Returns None if none was found, otherwise Some.

member queryFlag : flag:string -> bool

Check the query string for a flag:

- ?flag => true - ?flag=false => false - ?flag=apa => false - ?flag=true => true - ? => false

member header : key:string -> Choice<string, string>

Gets the header for the given key in the HttpRequest

member form : (string * string option) list

Gets the form as a ((string * string option) list) from the HttpRequest. Use formData to get the data for a particular key or use the indexed property in the HttpRequest.

member formData : key:string -> Choice<string, string>

Finds the key k from the form of the HttpRequest. To access query string parameters, use queryParam or to access multipart form fields, use fieldData.

member fieldData : key:string -> Choice<string, string>

Finds the key k from the multipart-form of the HttpRequest. To access query string parameters, use queryParam or to access regular form data, use formData.

member Item : key:string -> string option with get

Syntactic Sugar to retrieve query string, form or multi-field values from HttpRequest

member clientHost : trustProxy:bool -> sources:string list -> Host

Get the client's view of what host is being called. If you trust your proxy the value will be fetched from X-Forwarded-Host, then the Host headers. If you don't explicitly overwrite these headers in the proxy you may be open to clients spoofing the headers. Hence the explicit interfaces which force you as a developer to think abou the problem.

member clientHostTrustProxy : Host

See docs on clientHost

member path : string

path is equal to UrlDecode(rawPath)

member url : Uri

Returns Uri object representing the url associated with this request

member host : Host

The Host that the web server responds to; not necessarily the host called by the client, as the request may have traversed proxies. As Suave binds to an IP rather than IP+Hostname, this can be anything the client has passed as the Host header. If you're behind a proxy, it may be the DNS name of the node that the reverse proxy forwards to, or if you're exposing Suave publically, it should match the public DNS name of the node.

To ensure the correct host-name is being called, you can use Http.host in your web app.

member method : HttpMethod

Returns a HttpMethod

[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module HttpBinding =
val defaults : HttpBinding

This is the value of the default HttpBinding.

val create : scheme:Protocol -> ip:IPAddress -> port:Port -> HttpBinding

Create a HttpBinding for the given protocol, an IP address to bind to and a port to listen on – this is the strongly typed overload.

val createSimple : scheme:Protocol -> ip:string -> port:int -> HttpBinding

Create a HttpBinding for the given protocol, an IP address to bind to and a port to listen on – this is the "stringly typed" overload.

and HttpResult =

The HttpResult is the structure that you work with to tell Suave how to send the response. Have a look at the docs for HttpContent for further details on what is possible.

[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module HttpResult =
val empty : HttpResult

The empty HttpResult, with a 404 and a HttpContent.NullContent content

type ServerKey = byte []

A server-key is a 256 bit key with high entropy

[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module ServerKey =

Utilities to ensure server keys are well-formed

val validate : ServerKey -> ServerKey

Ensure that a server key is the proper length

val fromBase64 : (string -> ServerKey)

Create a key from a base-64 encoded string

type IPAddress with
static member tryParseC : ip:string -> Choice<IPAddress, unit>

Try parse the IP address from a string, returning a choice.

type HttpRuntime =

The HttpRuntime is created from the SuaveConfig structure when the web server starts. You can also use the HttpRuntime module to create a new value yourself, or use the empty one.

and HttpContext =

The HttpContext is the container of the request, runtime, user-state and response.

runtime    : HttpRuntime

The HttpRuntime for the request being processed

connection : Connection

The connection for the request being processed

userState  : Dictionary<string, obj>

The user state for the request being processed

response   : HttpResult }

The response for the request being processed

member clientIp : trustProxy:bool -> sources:string list -> IPAddress

Get the IP of the client from the HttpContext.

member clientIpTrustProxy : IPAddress

Warning; if you don't write these headers in your rev.proxy, the client will be able to spoof them. Related headers: - client-ip - x-forwarded-for: the "X-Forwarded-For" client request header field with the $remote_addr variable appended to it, separated by a comma. If the "X-Forwarded-For" field is not present in the client request header, the $proxy_add_x_forwarded_for variable is equal to the $remote_addr variable. from http://nginx.org/en/docs/http/ngx_http_proxy_module.html

Related blog entry, with suggestion on nginx module to use to recursively tell all upstream proxies to overwrite X-Real-IP: http://distinctplace.com/infrastructure/2014/04/23/story-behind-x-forwarded-for-and-x-real-ip-headers/

and ErrorHandler = Exception -> String -> WebPart<HttpContext>

A WebPart is an asynchronous function that transforms the HttpContext. An asynchronous return value of None indicates 'did not handle'. An error handler takes the exception, a programmer-provided message, a request (that failed) and returns an asynchronous workflow for the handling of the error.

[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module HttpRuntime =

a module that gives you the empty (beware) and create functions for creating a HttpRuntime

val ServerKeyLength : uint16

The key length in bytes, references Crypto.KeyLength which is appropriate for the underlying AES-256 bit symmetric crypto in use.

val empty : HttpRuntime

warn: this is not to be played around with; prefer using the config defaults instead, from Web.fs, as they contain the logic for printing to the output stream correctly.

val create : serverKey:ServerKey -> errorHandler:ErrorHandler
           -> mimeTypes:MimeTypesMap -> homeDirectory:string
           -> compressionFolder:string -> logger:Logger
           -> cookieSerialiser:CookieSerialiser
           -> tlsProvider:TlsProvider -> hideHeader:bool -> maxContentLength:int
           -> binding:HttpBinding
           -> HttpRuntime

make a new HttpRuntime from the given parameters

[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module HttpContext =

A module that provides functions to create a new HttpContext.

val empty : HttpContext

The empty HttpContext is fairly useless for doing real work; you'd be well adviced to write some of the properties. However, it can be quite useful in unit tests.

module Cookie =

The cookie module is geared towards the server having the client store state but the client not being able to read that state.

type CookieLife =
  | Session
  | MaxAge of duration:TimeSpan

For how long should the cookie persist in the client's browser?

type CookieError =
  | NoCookieFound of cookieName:string
  | DecryptionError of error:Crypto.SecretboxDecryptionError

There was an error reading or decrypting the cookie.

val parseCookies : cookieString:string -> HttpCookie list

Parse the cookie's name and data in the string into a dictionary.

type HttpRequest with
member cookies : Map<string, HttpCookie>

Finds the cookies of the request, or an empty Map otherwise, if there are no cookies.

val setPair   : httpCookie:HttpCookie -> clientCookie:HttpCookie -> WebPart

Sets the cookies to the HttpResult

type CookiesState =

A DTO structure for passing the right parameters to the XXX_cookies functions in this module.

val generateCookies : serverKey:ServerKey
                    -> cookieName:string
                    -> relativeExpiry:CookieLife
                    -> secure:bool
                    -> plainData:byte[]
                    -> HttpCookie * HttpCookie

Generate one server-side cookie, and another client-side cookie with name "${server-side-name}-client"

val readCookies : key:ServerKey
                -> cookieName:string
                -> cookies:Map<string, HttpCookie>
                -> Choice<HttpCookie * byte [], CookieError>

Tries to read the cookie of the given name from the HttpContext, and returns the cookie and its plaintext value if successful.

val refreshCookies : expiry:CookieLife
                   -> cookie:HttpCookie
                   -> WebPart

Bumps the expiry dates for all the cookies.

val UserNameKey : string

The key of the username placed in the userState map if present in the request

val authenticateBasic : f:(string * string -> bool) -> protectedPart:WebPart -> WebPart

Perform basic authentication on the request, applying a predicate to check the request for authentication tokens such as 'username' and 'password'. Otherwise, if failing, challenge the client again.
val authenticateBasicAsync : f:(string * string -> bool Async) -> protectedPart:WebPart -> WebPart

Perform basic authentication on the request, applying an asynchronous predicate to check the request for authentication tokens such as 'username' and 'password'. Otherwise, if failing, challenge the client again.
val StateStoreType : string

The key used in context.user_state to save the session id for downstream web parts.

val deauthenticate : WebPart

Deauthenticates, or 'logs out' the user

val deauthenticateWithLogin : loginPage :string
                            -> WebPart

Deauthenticates the user and then sends them to path specified by loginPage string

val authenticated : relativeExpiry:CookieLife
                  -> secure:bool
                  -> WebPart

Set server-signed cookies to make the response contain a cookie with a valid session id. It's worth having in mind that when you use this web part, you're setting cookies on the response; so you'll need to have the client re-send a request if you require authentication for it, after this web part has run.

Parameters: - relativeExpiry: how long does the authentication cookie last? - secure: HttpsOnly?

Always succeeds.

module HttpContext =
val sessionId : ctx:HttpContext -> string option

Read the session id from the HttpContext