httpclient
Этот модуль реализует простой HTTP-клиент, который можно использовать для получения веб-страниц и других данных.
Получение веб-сайта
В этом примере используется HTTP GET для получения http://google.com.
import httpclient
var client = newHttpClient()
echo client.getContent("http://google.com")
То же действие можно выполнить асинхронно, просто используйте AsyncHttpClient:
import asyncdispatch, httpclient
proc asyncProc(): Future[string] {.async.} =
var client = newAsyncHttpClient()
return await client.getContent("http://example.com")
echo waitFor asyncProc()
Функциональность, реализованная в HttpClient и AsyncHttpClient, одинакова, поэтому вы можете использовать тот, который вам больше подходит, в примерах, показанных здесь.
Примечание: Вам необходимо запускать асинхронные примеры в асинхронной процедуре, иначе вы получите ошибку Undeclared identifier: 'await'.
Использование HTTP POST
Этот пример демонстрирует использование W3 HTML-валидатора. Он использует multipart/form-data в качестве Content-Type для отправки HTML-кода на сервер для проверки.
var client = newHttpClient()
var data = newMultipartData()
data["output"] = "soap12"
data["uploaded_file"] = ("test.html", "text/html",
"<html><head></head><body><p>test</p></body></html>")
echo client.postContent("http://validator.w3.org/check", multipart=data)
Для потоковой передачи файлов из диска при выполнении запроса используйте addFiles.
Примечание: Это будет выделять новую базу данных Mimetypes каждый раз при вызове. Вы можете передать свою собственную через параметр mimeDb для предотвращения этого.
let mimes = newMimetypes()
var client = newHttpClient()
var data = newMultipartData()
data.addFiles({"uploaded_file": "test.html"}, mimeDb = mimes)
echo client.postContent("http://validator.w3.org/check", multipart=data)
Вы также можете делать POST-запросы с настраиваемыми заголовками. В этом примере Content-Type устанавливается в значение application/json, а в качестве тела используется JSON-объект.
import httpclient, json
let client = newHttpClient()
client.headers = newHttpHeaders({ "Content-Type": "application/json" })
let body = %*{
"data": "some text"
}
let response = client.request("http://some.api", httpMethod = HttpPost, body = $body)
echo response.status Отчет о прогрессе
Вы можете указать процедуру обратного вызова, которая будет вызываться во время HTTP-запроса. Этот обратный вызов будет выполняться каждую секунду с информацией о прогрессе HTTP-запроса.
import asyncdispatch, httpclient
proc onProgressChanged(total, progress, speed: BiggestInt) {.async.} =
echo("Downloaded ", progress, " of ", total)
echo("Current rate: ", speed div 1000, "kb/s")
proc asyncProc() {.async.} =
var client = newAsyncHttpClient()
client.onProgressChanged = onProgressChanged
discard await client.getContent("http://speedtest-ams2.digitalocean.com/100mb.test")
waitFor asyncProc()
Если вы хотите удалить обратный вызов, просто установите его в значение nil.
client.onProgressChanged = nil
Предупреждение: Значение total от httpclient в некоторых случаях может быть равно 0.
Поддержка SSL/TLS
Это требует библиотеки OpenSSL, которая, к счастью, широко используется и установлена на многих операционных системах. httpclient автоматически будет использовать SSL, если вы передадите функции URL со схемой https, например: https://github.com/.
Также необходимо скомпилировать с определённым значением ssl, как показано ниже: nim c -d:ssl ....
Проверка сертификатов по умолчанию НЕ выполняется. Это изменится в будущем.
Сканируются набор директорий и файлов из модуля ssl_certs для поиска сертификатов CA.
См. newContext для настройки или отключения проверки сертификатов.
Таймауты
В настоящее время таймауты поддерживаются только для синхронных функций. Таймаут измеряется в миллисекундах. После его установки любой вызов сокета, который может блокироваться, будет подвержен этому таймауту.
Возможно, вас удивит, но выполнение функции в целом может занять больше времени, чем указанный таймаут. Только отдельные внутренние вызовы сокета затрагиваются этим таймаутом. На практике это означает, что пока сервер отправляет данные, исключение не будет поднято. Однако, если данные не достигнут клиента в течение указанного таймаута, будет поднято исключение TimeoutError.
Вот как установить таймаут при создании экземпляра HttpClient:
import httpclient let client = newHttpClient(timeout = 42)
Прокси
Прокси может быть указан как параметр любой из процедур, определенных в этом модуле. Для этого используйте конструктор newProxy. К сожалению, в настоящее время поддерживается только базовая аутентификация.
Некоторые примеры настройки прокси для HttpClient:
import httpclient
let myProxy = newProxy("http://myproxy.network")
let client = newHttpClient(proxy = myProxy)
Получение URL прокси из переменных окружения:
import httpclient
var url = ""
try:
if existsEnv("http_proxy"):
url = getEnv("http_proxy")
elif existsEnv("https_proxy"):
url = getEnv("https_proxy")
except ValueError:
echo "Unable to parse proxy from environment variables."
let myProxy = newProxy(url = url)
let client = newHttpClient(proxy = myProxy) Перенаправления
Максимальное количество перенаправлений можно установить с помощью параметра maxRedirects типа int. Он определяет максимальное количество перенаправлений для следования. По умолчанию он равен 5. Вы можете установить его в значение 0 для отключения перенаправлений.
Вот пример установки параметра maxRedirects для HttpClient:
import httpclient let client = newHttpClient(maxRedirects = 0)
Импорты
- since, net, strutils, uri, parseutils, base64, os, mimetypes, streams, math, random, httpcore, times, tables, streams, monotimes, asyncnet, asyncdispatch, asyncfile, nativesockets
Типы
Response = ref object version*: string status*: string headers*: HttpHeaders body: string bodyStream*: Stream
- Исходный код Редактировать
AsyncResponse = ref object version*: string status*: string headers*: HttpHeaders body: string bodyStream*: FutureStream[string]
- Исходный код Редактировать
Proxy = ref object url*: Uri auth*: string
- Исходный код Редактировать
MultipartEntries = openArray[tuple[name, content: string]]
- Исходный код Редактировать
MultipartData = ref object content: seq[MultipartEntry]
- Исходный код Редактировать
ProtocolError = object of IOError
- исключение, которое генерируется, когда сервер не соответствует реализованному протоколу Исходный код Редактировать
HttpRequestError = object of IOError
- Выбрасывается в процедуре
getContentиpostContent, когда сервер возвращает ошибку Исходный код Редактировать ProgressChangedProc[ReturnType] = proc (total, progress, speed: BiggestInt): ReturnType {...}{. closure, gcsafe.}- Исходный код Редактировать
HttpClientBase[SocketType] = ref object socket: SocketType connected: bool currentURL: Uri ## Where we are currently connected. headers*: HttpHeaders ## Headers to send in requests. maxRedirects: Natural ## Maximum redirects, set to ``0`` to disable. userAgent: string timeout*: int ## Only used for blocking HttpClient for now. proxy: Proxy ## ``nil`` or the callback to call when request progress changes. when SocketType is Socket: onProgressChanged else: onProgressChanged when false: sslContext contentTotal: BiggestInt contentProgress: BiggestInt oneSecondProgress: BiggestInt lastProgressReport: MonoTime when SocketType is AsyncSocket: bodyStream parseBodyFut else: bodyStream getBody: bool ## When `false`, the body is never read in requestAux.- Исходный код Редактировать
HttpClient = HttpClientBase[Socket]
- Исходный код Редактировать
AsyncHttpClient = HttpClientBase[AsyncSocket]
- Исходный код Редактировать
Константы
defUserAgent = "Nim httpclient/1.4.8"
- Исходный код Редактировать
Процедуры
proc code(response: Response | AsyncResponse): HttpCode {...}{. raises: [ValueError, OverflowDefect].}-
Возвращает указанный ответ
HttpCode.Вызывает
Исходный код РедактироватьValueErrorесли у ответаstatusнет соответствующегоHttpCode. proc contentType(response: Response | AsyncResponse): string {...}{.inline.}-
Возвращает тип содержимого указанного ответа.
Это фактически значение заголовка "Content-Type".
Исходный код Редактировать proc contentLength(response: Response | AsyncResponse): int
-
Возвращает длину содержимого указанного ответа.
Это фактически значение заголовка "Content-Length".
Исключение
Исходный код РедактироватьValueErrorбудет вызвано, если значение не является целым числом. proc lastModified(response: Response | AsyncResponse): DateTime
-
Возвращает время последнего изменения указанного ответа.
Это фактически значение заголовка "Last-Modified".
Вызывает
Исходный код РедактироватьValueErrorесли попытка парсинга завершилась неудачно или значение не является корректным временем. proc body(response: Response): string {...}{.raises: [IOError, OSError], tags: [ReadIOEffect].}-
Возвращает тело указанного ответа.
Поток тела ответа читается синхронно.
Исходный код Редактировать proc body(response: AsyncResponse): Future[string] {...}{. raises: [Exception, ValueError], tags: [RootEffect].}- Читает тело ответа и кеширует его. Чтение выполняется только один раз. Исходный код Редактировать
proc newProxy(url: string; auth = ""): Proxy {...}{.raises: [], tags: [].}- Создаёт новый объект
TProxy. Исходный код Редактировать proc newMultipartData(): MultipartData {...}{.inline, raises: [], tags: [].}- Создаёт новый объект
MultipartData. Исходный код Редактировать proc `$`(data: MultipartData): string {...}{.raises: [], tags: [].}- Преобразует MultipartData в строку для удобочитаемости в выводе. https://github.com/nim-lang/Nim/issues/11863 Исходный код Редактировать
proc add(p: MultipartData; name, content: string; filename: string = ""; contentType: string = ""; useStream = true) {...}{.raises: [ValueError], tags: [].}-
Добавляет значение в данные multipart.
Если
useStreamравноfalse, файл будет прочитан в память.Вызывает исключение
Исходный код РедактироватьValueErrorеслиname,filenameилиcontentTypeсодержат символы новой строки. proc add(p: MultipartData; xs: MultipartEntries): MultipartData {...}{.discardable, raises: [ValueError], tags: [].}- Добавляет список элементов multipart в данные multipart
p. Все значения добавляются без имени файла и без типа содержимого.data.add({"action": "login", "format": "json"})Исходный код Редактировать proc newMultipartData(xs: MultipartEntries): MultipartData {...}{. raises: [ValueError], tags: [].}- Создаёт новый объект multipart data и заполняет его элементами
xsнапрямую.var data = newMultipartData({"action": "login", "format": "json"})Исходный код Редактировать proc addFiles(p: MultipartData; xs: openArray[tuple[name, file: string]]; mimeDb = newMimetypes(); useStream = true): MultipartData {...}{. discardable, raises: [IOError, ValueError], tags: [ReadIOEffect].}- Добавляет файлы в объект multipart data. Файлы будут передаваться из диска во время запроса. Если
streamравноfalse, файлы вместо этого считываются в память, но имейте в виду, что это очень неэффективно с точки зрения памяти, даже для небольших файлов. Типы MIME будут автоматически определяться. ВызываетIOErrorесли файл не может быть открыт или чтение завершилось ошибкой. Для ручного указания содержимого файла, имени файла и типа MIME используйте[]=вместо этого.data.addFiles({"uploaded_file": "public/test.html"})Исходный код Редактировать proc `[]=`(p: MultipartData; name, content: string) {...}{.inline, raises: [ValueError], tags: [].}- Добавляет элемент multipart в данные multipart
p. Значение добавляется без имени файла и без типа содержимого.data["username"] = "NimUser"
Исходный код Редактировать proc `[]=`(p: MultipartData; name: string; file: tuple[name, contentType, content: string]) {...}{.inline, raises: [ValueError], tags: [].}- Добавляет файл в данные multipart
p, задавая имя файла, contentType и содержимое вручную.data["uploaded_file"] = ("test.html", "text/html", "<html><head></head><body><p>test</p></body></html>")Исходный код Редактировать proc newHttpClient(userAgent = defUserAgent; maxRedirects = 5; sslContext = getDefaultSSL(); proxy: Proxy = nil; timeout = -1; headers = newHttpHeaders()): HttpClient {...}{. raises: [], tags: [].}-
Создаёт новый экземпляр HttpClient.
userAgentзадаёт пользовательского агента, который будет использоваться при выполнении запросов.maxRedirectsзадаёт максимальное количество редиректов, которые следует отслеживать, значение по умолчанию равно 5.sslContextзадаёт SSL контекст для использования в запросах HTTPS. См. Поддержка SSL/TLSproxyзадаёт HTTP-прокси для использования в подключениях этого HTTP-клиента.timeoutзадаёт количество миллисекунд, которые должны пройти, прежде чем будет вызвано исключениеTimeoutError.headersзадаёт HTTP-заголовки.Пример:
import asyncdispatch, httpclient, strutils proc asyncProc(): Future[string] {.async.} = var client = newAsyncHttpClient() return await client.getContent("http://example.com") let exampleHtml = waitFor asyncProc() assert "Example Domain" in exampleHtml assert not ("Pizza" in exampleHtml)Исходный код Редактировать proc newAsyncHttpClient(userAgent = defUserAgent; maxRedirects = 5; sslContext = getDefaultSSL(); proxy: Proxy = nil; headers = newHttpHeaders()): AsyncHttpClient {...}{. raises: [], tags: [].}-
Создаёт новый экземпляр AsyncHttpClient.
userAgentзадаёт пользовательского агента, который будет использоваться при выполнении запросов.maxRedirectsзадаёт максимальное количество редиректов, которые следует отслеживать, значение по умолчанию равно 5.sslContextзадаёт SSL контекст для использования в запросах HTTPS.proxyзадаёт HTTP-прокси для использования в подключениях этого HTTP-клиента.
Исходный код Редактироватьheadersзадаёт HTTP-заголовки. proc close(client: HttpClient | AsyncHttpClient)
- Закрывает все подключения, удерживаемые HTTP-клиентом. Исходный код Редактировать
proc getSocket(client: HttpClient): Socket {...}{.inline, raises: [], tags: [].}-
Получает сетевой сокет, полезно, если вы хотите получить больше информации о подключении
Этот пример показывает информацию о локальном и удалённом конечных точках
if client.connected: echo client.getSocket.getLocalAddr echo client.getSocket.getPeerAddr
Исходный код Редактировать proc getSocket(client: AsyncHttpClient): AsyncSocket {...}{.inline, raises: [], tags: [].}- Исходный код Редактировать
proc request(client: AsyncHttpClient; url: string; httpMethod: string; body = ""; headers: HttpHeaders = nil; multipart: MultipartData = nil): Future[AsyncResponse] {...}{. raises: [Exception, ValueError], tags: [ReadIOEffect, RootEffect, TimeEffect].}-
Подключается к хосту, указанному в URL, и выполняет запрос с использованием указанной строки метода, заданной
httpMethod.Подключение будет сохраняться. Дальнейшие запросы на тот же
clientк тому же хосту не потребуют нового подключения. Подключение можно закрыть с помощью процедурыclose.Необходимо убедиться, что
Исходный код Редактироватьurlне содержит символов новой строки. В противном случае будет вызваноAssertionDefect. proc request(client: HttpClient; url: string; httpMethod: string; body = ""; headers: HttpHeaders = nil; multipart: MultipartData = nil): Response {...}{.raises: [ ValueError, IOError, OSError, HttpRequestError, Exception, LibraryError, SslError, TimeoutError, ProtocolError, KeyError], tags: [ReadIOEffect, RootEffect, WriteIOEffect, TimeEffect].}- Исходный код Редактировать
proc request(client: AsyncHttpClient; url: string; httpMethod = HttpGet; body = ""; headers: HttpHeaders = nil; multipart: MultipartData = nil): Future[AsyncResponse] {...}{. raises: [Exception, ValueError], tags: [ReadIOEffect, RootEffect, TimeEffect].}-
Подключается к хосту, указанному в URL, и выполняет запрос с использованием указанного метода.
Подключение будет сохраняться. Дальнейшие запросы на тот же
clientк тому же хосту не потребуют нового подключения. Подключение можно закрыть с помощью процедурыclose.При запросе к другому хосту текущее подключение будет закрыто.
Исходный код Редактировать proc request(client: HttpClient; url: string; httpMethod = HttpGet; body = ""; headers: HttpHeaders = nil; multipart: MultipartData = nil): Response {...}{.raises: [ ValueError, IOError, OSError, HttpRequestError, Exception, LibraryError, SslError, TimeoutError, ProtocolError, KeyError], tags: [ReadIOEffect, RootEffect, WriteIOEffect, TimeEffect].}- Исходный код Редактировать
proc head(client: AsyncHttpClient; url: string): Future[AsyncResponse] {...}{. raises: [Exception, ValueError], tags: [ReadIOEffect, RootEffect, TimeEffect].}
-
Подключается к хосту, указанному в URL, и выполняет запрос HEAD.
Эта процедура использует значения httpClient, такие как
Источник Изменитьclient.maxRedirects. proc head(client: HttpClient; url: string): Response {...}{.raises: [ValueError, IOError, OSError, HttpRequestError, Exception, LibraryError, SslError, TimeoutError, ProtocolError, KeyError], tags: [ReadIOEffect, RootEffect, WriteIOEffect, TimeEffect].}- Источник Изменить
proc get(client: AsyncHttpClient; url: string): Future[AsyncResponse] {...}{. raises: [Exception, ValueError], tags: [ReadIOEffect, RootEffect, TimeEffect].}-
Подключается к хосту, указанному в URL, и выполняет запрос GET.
Эта процедура использует значения httpClient, такие как
Источник Изменитьclient.maxRedirects. proc get(client: HttpClient; url: string): Response {...}{.raises: [ValueError, IOError, OSError, HttpRequestError, Exception, LibraryError, SslError, TimeoutError, ProtocolError, KeyError], tags: [ReadIOEffect, RootEffect, WriteIOEffect, TimeEffect].}- Источник Изменить
proc getContent(client: AsyncHttpClient; url: string): Future[string] {...}{. raises: [Exception, ValueError], tags: [ReadIOEffect, RootEffect, TimeEffect].}- Подключается к хосту, указанному в URL, и возвращает содержимое запроса GET. Источник Изменить
proc getContent(client: HttpClient; url: string): string {...}{.raises: [ValueError, IOError, OSError, HttpRequestError, Exception, LibraryError, SslError, TimeoutError, ProtocolError, KeyError], tags: [ReadIOEffect, RootEffect, WriteIOEffect, TimeEffect].}- Источник Изменить
proc delete(client: AsyncHttpClient; url: string): Future[AsyncResponse] {...}{. raises: [Exception, ValueError], tags: [ReadIOEffect, RootEffect, TimeEffect].}- Подключается к хосту, указанному в URL, и выполняет запрос DELETE. Эта процедура использует значения httpClient, такие как
client.maxRedirects. Источник Изменить proc delete(client: HttpClient; url: string): Response {...}{.raises: [ValueError, IOError, OSError, HttpRequestError, Exception, LibraryError, SslError, TimeoutError, ProtocolError, KeyError], tags: [ReadIOEffect, RootEffect, WriteIOEffect, TimeEffect].}- Источник Изменить
proc deleteContent(client: AsyncHttpClient; url: string): Future[string] {...}{. raises: [Exception, ValueError], tags: [ReadIOEffect, RootEffect, TimeEffect].}- Подключается к хосту, указанному в URL, и возвращает содержимое запроса DELETE. Источник Изменить
proc deleteContent(client: HttpClient; url: string): string {...}{.raises: [ ValueError, IOError, OSError, HttpRequestError, Exception, LibraryError, SslError, TimeoutError, ProtocolError, KeyError], tags: [ReadIOEffect, RootEffect, WriteIOEffect, TimeEffect].}- Источник Изменить
proc post(client: AsyncHttpClient; url: string; body = ""; multipart: MultipartData = nil): Future[AsyncResponse] {...}{. raises: [Exception, ValueError], tags: [ReadIOEffect, RootEffect, TimeEffect].}- Подключается к хосту, указанному в URL, и выполняет запрос POST. Эта процедура использует значения httpClient, такие как
client.maxRedirects. Источник Изменить proc post(client: HttpClient; url: string; body = ""; multipart: MultipartData = nil): Response {...}{.raises: [ValueError, IOError, OSError, HttpRequestError, Exception, LibraryError, SslError, TimeoutError, ProtocolError, KeyError], tags: [ReadIOEffect, RootEffect, WriteIOEffect, TimeEffect].}- Источник Изменить
proc postContent(client: AsyncHttpClient; url: string; body = ""; multipart: MultipartData = nil): Future[string] {...}{. raises: [Exception, ValueError], tags: [ReadIOEffect, RootEffect, TimeEffect].}- Подключается к хосту, указанному в URL, и возвращает содержимое запроса POST. Источник Изменить
proc postContent(client: HttpClient; url: string; body = ""; multipart: MultipartData = nil): string {...}{.raises: [ValueError, IOError, OSError, HttpRequestError, Exception, LibraryError, SslError, TimeoutError, ProtocolError, KeyError], tags: [ReadIOEffect, RootEffect, WriteIOEffect, TimeEffect].}- Источник Изменить
proc put(client: AsyncHttpClient; url: string; body = ""; multipart: MultipartData = nil): Future[AsyncResponse] {...}{. raises: [Exception, ValueError], tags: [ReadIOEffect, RootEffect, TimeEffect].}- Подключается к хосту, указанному в URL, и выполняет запрос PUT. Эта процедура использует значения httpClient, такие как
client.maxRedirects. Источник Изменить proc put(client: HttpClient; url: string; body = ""; multipart: MultipartData = nil): Response {...}{.raises: [ValueError, IOError, OSError, HttpRequestError, Exception, LibraryError, SslError, TimeoutError, ProtocolError, KeyError], tags: [ReadIOEffect, RootEffect, WriteIOEffect, TimeEffect].}- Источник Изменить
proc putContent(client: AsyncHttpClient; url: string; body = ""; multipart: MultipartData = nil): Future[string] {...}{. raises: [Exception, ValueError], tags: [ReadIOEffect, RootEffect, TimeEffect].}- Подключается к хосту, указанному в URL, и возвращает содержимое запроса PUT. Источник Изменить
proc putContent(client: HttpClient; url: string; body = ""; multipart: MultipartData = nil): string {...}{.raises: [ValueError, IOError, OSError, HttpRequestError, Exception, LibraryError, SslError, TimeoutError, ProtocolError, KeyError], tags: [ReadIOEffect, RootEffect, WriteIOEffect, TimeEffect].}- Источник Изменить
proc patch(client: AsyncHttpClient; url: string; body = ""; multipart: MultipartData = nil): Future[AsyncResponse] {...}{. raises: [Exception, ValueError], tags: [ReadIOEffect, RootEffect, TimeEffect].}- Подключается к хосту, указанному в URL, и выполняет запрос PATCH. Эта процедура использует значения httpClient, такие как
client.maxRedirects. Источник Изменить proc patch(client: HttpClient; url: string; body = ""; multipart: MultipartData = nil): Response {...}{.raises: [ValueError, IOError, OSError, HttpRequestError, Exception, LibraryError, SslError, TimeoutError, ProtocolError, KeyError], tags: [ReadIOEffect, RootEffect, WriteIOEffect, TimeEffect].}- Источник Изменить
proc patchContent(client: AsyncHttpClient; url: string; body = ""; multipart: MultipartData = nil): Future[string] {...}{. raises: [Exception, ValueError], tags: [ReadIOEffect, RootEffect, TimeEffect].}- Подключается к хосту, указанному в URL, и возвращает содержимое запроса PATCH. Источник Изменить
proc patchContent(client: HttpClient; url: string; body = ""; multipart: MultipartData = nil): string {...}{.raises: [ValueError, IOError, OSError, HttpRequestError, Exception, LibraryError, SslError, TimeoutError, ProtocolError, KeyError], tags: [ReadIOEffect, RootEffect, WriteIOEffect, TimeEffect].}- Источник Изменить
proc downloadFile(client: HttpClient; url: string; filename: string) {...}{.raises: [ ValueError, IOError, OSError, HttpRequestError, Exception, LibraryError, SslError, TimeoutError, ProtocolError, KeyError], tags: [ReadIOEffect, RootEffect, WriteIOEffect, TimeEffect].}- Загружает
urlи сохраняет его вfilename. Источник Изменить proc downloadFile(client: AsyncHttpClient; url: string; filename: string): Future[ void] {...}{.raises: [Exception], tags: [ReadIOEffect, RootEffect, TimeEffect].}- Источник Изменить
Экспорт
- Http417, Http503, Http431, ==, contains, Http304, Http406, ==, $, clear, Http408, $, Http411, is3xx, Http418, Http206, HttpMethod, Http101, httpNewLine, Http505, Http413, newHttpHeaders, Http200, []=, Http414, add, Http401, Http205, ==, Http407, Http500, Http404, Http416, Http308, Http302, HttpHeaders, Http300, Http428, Http410, is2xx, Http202, Http502, headerLimit, HttpHeaderValues, contains, newHttpHeaders, $, [], Http305, Http451, Http409, Http504, Http426, hasKey, del, pairs, Http429, HttpVersion, []=, Http421, Http307, Http301, is4xx, Http203, getOrDefault, Http100, Http501, len, Http400, Http403, is5xx, Http415, toString, Http412, Http405, Http303, Http204, Http201, HttpCode, Http422, []
© 2006–2021 Andreas Rumpf
Licensed under the MIT License.
https://nim-lang.org/docs/httpclient.html