Spec-Zone.ru › Nim

std/asynchttpserver

Source Edit

Этот модуль реализует высокопроизводительный асинхронный HTTP-сервер.

Этот HTTP-сервер не предназначен для использования в производстве, а только для тестирования приложений локально. По этой причине при развертывании приложения в производстве следует использовать обратный прокси-сервер (например, nginx), а не разрешать пользователям подключаться непосредственно к этому серверу.

Пример: cmd: -r:off

import std/asynchttpserver
# This example will create an HTTP server on an automatically chosen port.
# It will respond to all requests with a `200 OK` response code and "Hello World"
# as the response body.
import std/asyncdispatch
proc main {.async.} =
  var server = newAsyncHttpServer()
  proc cb(req: Request) {.async.} =
    echo (req.reqMethod, req.url, req.headers)
    let headers = {"Content-type": "text/plain; charset=utf-8"}
    await req.respond(Http200, "Hello World", headers.newHttpHeaders())

  server.listen(Port(0)) # or Port(8080) to hardcode the standard HTTP port.
  let port = server.getPort
  echo "test this with: curl localhost:" & $port.uint16 & "/"
  while true:
    if server.shouldAcceptRequest():
      await server.acceptRequest(cb)
    else:
      # too many concurrent connections, `maxFDs` exceeded
      # wait 500ms for FDs to be closed
      await sleepAsync(500)

waitFor main()

Импорты

asyncnet, asyncdispatch, parseutils, uri, strutils, httpcore, nativesockets, since

Типы

AsyncHttpServer = ref object
  ## The maximum content-length that will be read for the body.
Source Edit
Request = object
  client*: AsyncSocket
  reqMethod*: HttpMethod
  headers*: HttpHeaders
  protocol*: tuple[orig: string, major, minor: int]
  url*: Uri
  hostname*: string          ## The hostname of the client that made the request.
  body*: string
Source Edit

Константы

nimMaxDescriptorsFallback {.intdefine.} = 16000
значение по умолчанию, используемое, когда maxDescriptors недоступно. Это можно задать в командной строке во время компиляции через -d:nimMaxDescriptorsFallback=N Source Edit

Процедуры

proc acceptRequest(server: AsyncHttpServer; callback: proc (request: Request): Future[
    void] {.closure, ...gcsafe.}): owned(Future[void]) {....stackTrace: false,
    raises: [Exception], tags: [RootEffect], forbids: [].}
Принимает один запрос. Необходимо написать явную петлю вокруг этой процедуры для правильной обработки ошибок. Source Edit
proc close(server: AsyncHttpServer) {....raises: [LibraryError, Exception, SslError],
                                      tags: [RootEffect], forbids: [].}
Завершает экземпляр асинхронного HTTP-сервера. Source Edit
proc getPort(self: AsyncHttpServer): Port {....raises: [OSError, Exception],
    tags: [], forbids: [].}

Возвращает порт, к которому self был привязан.

Полезно для определения порта, к которому self привязан, если он был выбран автоматически, например, через listen(Port(0)).

Пример:

from std/nativesockets import Port
let server = newAsyncHttpServer()
server.listen(Port(0))
assert server.getPort.uint16 > 0
server.close()
Source Edit
proc listen(server: AsyncHttpServer; port: Port; address = ""; domain = AF_INET) {.
    ...raises: [OSError, ValueError], tags: [WriteIOEffect, ReadIOEffect],
    forbids: [].}
Прослушивает указанный порт и адрес. Source Edit
proc newAsyncHttpServer(reuseAddr = true; reusePort = false; maxBody = 8388608): AsyncHttpServer {.
    ...raises: [], tags: [], forbids: [].}
Создаёт новый экземпляр AsyncHttpServer. Source Edit
proc respond(req: Request; code: HttpCode; content: string;
             headers: HttpHeaders = nil): Future[void] {....raises: [Exception],
    tags: [RootEffect], forbids: [].}

Отвечает на запрос указанным HttpCode, заголовками и содержимым.

Эта процедура не закроет сокет клиента.

Пример:

import std/json
proc handler(req: Request) {.async.} =
  if req.url.path == "/hello-world":
    let msg = %* {"message": "Hello World"}
    let headers = newHttpHeaders([("Content-Type","application/json")])
    await req.respond(Http200, $msg, headers)
  else:
    await req.respond(Http404, "Not Found")
Source Edit
proc sendHeaders(req: Request; headers: HttpHeaders): Future[void] {.
    ...raises: [Exception], tags: [RootEffect], forbids: [].}
Отправляет указанные заголовки запрошивающему клиенту. Source Edit
proc serve(server: AsyncHttpServer; port: Port;
           callback: proc (request: Request): Future[void] {.closure, ...gcsafe.};
           address = ""; assumedDescriptorsPerRequest = -1; domain = AF_INET): owned(
    Future[void]) {....stackTrace: false, raises: [Exception], tags: [
    WriteIOEffect, ReadIOEffect, RootEffect, TimeEffect], forbids: [].}

Запускает процесс прослушивания входящих HTTP-соединений на указанном адресе и порту.

При получении запроса клиентом вызывается указанная функция обратного вызова.

Если assumedDescriptorsPerRequest равно 0 или больше, сервер учитывает максимальный лимит дескрипторов файлов процесса. Затем он гарантирует, что у процесса все еще есть ресурсы для assumedDescriptorsPerRequest дескрипторов файлов перед принятием соединения.

Вы должны предпочесть вызывать acceptRequest вместо этого с пользовательской петлей сервера, чтобы контролировать обработку ошибок и ведение журнала.

Source Edit
proc shouldAcceptRequest(server: AsyncHttpServer;
                         assumedDescriptorsPerRequest = 5): bool {.inline,
    ...raises: [], tags: [], forbids: [].}
Возвращает true, если текущее число открытых дескрипторов файлов процесса все еще находится в пределах максимального лимита, и поэтому прием еще одного запроса оправдан. Source Edit

© 2006–2024 Andreas Rumpf
Licensed under the MIT License.
https://nim-lang.org/docs/asynchttpserver.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API