src/bookofnim/deepdives/servers

Source   Edit  

servers

bookmark

TLDR

  • httpclient
    • generally always instantiate a newMimTypes before streaming files from disk
    • by default all procs set useStream == true
      • can be set to false; but then even small files are highly inefficient
    • TLS support requires openssl to be in path and nim compiled with -d:ssl
      • used automagically if any URL is prefixed with https
      • certs are retrieved via std/ssl_certs
    • only sync functions support timeouts (milliseconds)
      • sets max time to wait to receive data before throwing - NOT the total request time
      • must be specified when instantiating a client
      • affects all internal blocking socket invocations
    • Proxy
      • only basic auth is supported
    • creating clients
      • both a/sync http clients accept
        • userAgent default "Nim httpclient/x.y.z"
        • maxRedirects default 5
        • sslContext for HTTPS requests
        • proxy to use for connections
        • headers for requests
      • newHttpClient accepts an additional arg
        • timeout max ms to wait without receipt of data before throwing
      • newAsyncHttpClient: has additional restrictions
        • all client instance fns must be called with await in scope
    • request procs return one of Async/Response/FutureString/String depending on httpclient type
      • append Content to procname to return string, e.g. get -> getContent
        • delete
        • get
        • patch
        • post
        • put
      • downloadFile and optionally save to filename
      • head and return response
      • request using an arbitrary http method and keep the connection alive until close()
  • net and asyncnet
    • you generally still need some of the procs in net when working with asyncnet

links

TODOs

  • niminaction: copy notes from 80 to 100

httpclient

  • nim fetch

httpclient errors

  • TimeoutError when X milliseconds elapsed without receipt of data
  • HttpRequestError when server returns error during get/postContent
  • ProtocolError when server doesnt conform to protocol rfc
  • IOError when a file cant be opened/reading fails
  • ValueError when
    • reading response.code that doesnt have an HttpCode
    • reading response.contentLength thats not an int
    • reading response.lastModified thats not a valid time
  • AssertionDefect when making request to url containing \n

httpclient types

  • AsyncHttpClient HttpClientBaseAsyncsocket
  • AsyncResponse object
    • version
    • status
    • headers HttpHeaders
    • body
    • bodyStream FutureStreamstring
  • HttpClient HttpClientBaseSocket
  • HttpClientBaseSocketType ref object
    • socket SocketType
    • connected
    • currentUrl Uri we are connected to
    • headers set for the next request
    • maxRedirects allowed; 0 to never follow redirects
    • userAgent
    • timeout ms to wait without receiving data on blocking calls before throwing
    • onProgressChanged nil/proc to invoke when request progress changes
    • getBody
  • MultipartData ref object
  • MultipartEntries openArraytuple[name, content]
  • ProgressChangedProcT (total, progress, speed): T
  • Proxy ref object
    • url Uri
    • auth
  • Response ref object
    • version
    • status
    • headers HttpHeaders
    • body
    • bodyStream

httpclient consts

  • defUserAgent "Nim httpclient/x.y.z"

httpclient operators

  • = add file (fname, contentType, content)/entry "some content" to multipart data p

httpclient procs

  • add multipart entries to multipart data
  • addFiles
  • addFiles to a multipart data objects; should always be used with streams
  • body of a response
  • close connects held by an http client
  • code corronspding to a response status
  • contentLength from response header, throws if not an int
  • contentType from response header
  • getSocket for details about current connection
  • lastModified from response header
  • newHttpHeaders
  • newMultipartData
  • newProxy
  • onProgressChanged

asynchttpserver

  • minimalistic high performance async http server that should be fronted by a revproxy

asynchttpserver types

  • AsyncHttpServer ref object
    • socket AsyncSocket
    • reuseAddr
    • reusePort
    • maxBody read from incomging request bodies
    • maxFDs
  • Request object
    • client AsyncSocket
    • reqMethod HttpMethod
    • headers HttpHeaders
    • protocol tupleorig, major, minor
    • url Uri
    • hostname of client that made the request
    • body

asynchttpserver consts

  • nimMaxDescriptorsFallback default 16000; set via -d:nimMaxDescriptorsFallback=n

asynchttpserver procs

  • acceptRequest

Lets

afetch = newAsyncHttpClient(defUserAgent, 5, getDefaultSSL(), nil,
                            newHttpHeaders(false))
Source   Edit  
data = `%`([("data", `%`([("user", `%`("resu")), ("pass", `%`("ssap"))]))])
Source   Edit  
fetch = newHttpClient(defUserAgent, 5, getDefaultSSL(), nil, 250,
                      newHttpHeaders(false))
Source   Edit  

Consts

endpoint = "https://postman-echo.com/"
Source   Edit  
getmebad = "https://postman-echo.com/status/404"
Source   Edit  
getmegood = "https://postman-echo.com/status/200"
Source   Edit  
getmetimeout = "https://postman-echo.com/delay/260"
Source   Edit  
postme = "https://postman-echo.com/post"
Source   Edit  
timeout = 250
Source   Edit  

Procs

proc agetContent(self: AsyncHttpClient; url: string): Future[Option[string]] {.
    ...stackTrace: false, raises: [KeyError, Exception],
    tags: [RootEffect, TimeEffect, ReadIOEffect], forbids: [].}
wraps async calls to provide await for AsyncHttpClient Source   Edit  
proc fetchWithTimeout(): Future[void] {....stackTrace: false,
                                        raises: [KeyError, Exception], tags: [
    TimeEffect, RootEffect, ReadIOEffect], forbids: [].}
Source   Edit