### Nim HttpBeast Server Example Source: https://github.com/dom96/httpbeast/blob/master/readme.md A basic HTTP server implementation in Nim using the httpbeast library. It handles GET requests, responding with 'Hello World' for the root path and a 404 for other paths. The server utilizes asyncdispatch for asynchronous operations. ```nim import options, asyncdispatch import httpbeast proc onRequest(req: Request): Future[void] = if req.httpMethod == some(HttpGet): case req.path.get() of "/": req.send("Hello World") else: req.send(Http404) run(onRequest) ``` -------------------------------- ### Start the HTTP Server - run Source: https://context7.com/dom96/httpbeast/llms.txt The `run` procedure starts the HTTP server and invokes the provided callback for each incoming request. It accepts an `OnRequest` callback and optional `Settings` configuration. ```APIDOC ## POST /run ### Description Starts the HTTP server and invokes the provided callback for each incoming request. ### Method POST ### Endpoint /run ### Parameters #### Query Parameters - **onRequest** (callback) - Required - The callback function to handle incoming requests. - **settings** (Settings) - Optional - Configuration settings for the server. ### Request Example ```nim import httpbeast proc onRequest(req: Request): Future[void] = req.send("Hello World") run(onRequest) ``` ### Response #### Success Response (200) - **None** - The server runs indefinitely until stopped. #### Response Example N/A ``` -------------------------------- ### Start HTTP Server with Callback - Nim Source: https://context7.com/dom96/httpbeast/llms.txt Starts the httpbeast server and executes a provided callback for each incoming request. Supports automatic parallelization with threads enabled. Requires `options`, `asyncdispatch`, and `httpbeast` modules. ```nim import options, asyncdispatch import httpbeast proc onRequest(req: Request): Future[void] = if req.httpMethod == some(HttpGet): case req.path.get() of "/": req.send("Hello World") of "/health": req.send(Http200) else: req.send(Http404) # Start server with default settings (port 8080) run(onRequest) ``` -------------------------------- ### Get Request HTTP Method - httpMethod Source: https://context7.com/dom96/httpbeast/llms.txt The `httpMethod` procedure parses and returns the HTTP method of the request as an `Option[HttpMethod]`. Supported methods include GET, POST, PUT, DELETE, PATCH, HEAD, and OPTIONS. ```APIDOC ## GET /httpMethod ### Description Parses and returns the HTTP method of the request. ### Method GET ### Endpoint /httpMethod ### Parameters None ### Request Example N/A (This is accessed via the `req` object within a request handler) ### Response #### Success Response (200) - **httpMethod** (Option[HttpMethod]) - The HTTP method of the request (e.g., some(HttpGet), some(HttpPost), or none() if not parsed). #### Response Example ```json { "httpMethod": "GET" } ``` ``` -------------------------------- ### Get Request HTTP Method - Nim Source: https://context7.com/dom96/httpbeast/llms.txt Parses and returns the HTTP method of an incoming request as an `Option[HttpMethod]`. Handles common methods like GET, POST, PUT, DELETE, PATCH, HEAD, and OPTIONS. Returns `Http501` for unhandled methods and `Http405` for disallowed methods. Requires `options`, `asyncdispatch`, and `httpbeast` modules. ```nim import options, asyncdispatch import httpbeast proc onRequest(req: Request): Future[void] = let method = req.httpMethod if method == some(HttpGet): req.send("GET request received") elif method == some(HttpPost): req.send("POST request received") elif method == some(HttpPut): req.send("PUT request received") elif method == some(HttpDelete): req.send("DELETE request received") elif method.isNone(): req.send(Http501) # Not Implemented else: req.send(Http405) # Method Not Allowed run(onRequest) ``` -------------------------------- ### Nim Package Definition for HttpBeast Project Source: https://github.com/dom96/httpbeast/blob/master/readme.md Defines the metadata for a Nimble package, including version, author, description, license, source directory, binary name, and dependencies. This example specifically requires the httpbeast library. ```nim # Package version = "0.1.0" author = "Your Name" description = "Your Description" license = "MIT" srcDir = "src" bin = @["helloHttp"] # Dependencies requires "nim >= 1.0.0" requires "httpbeast >= 0.4.0" ``` -------------------------------- ### Thread Initialization Callback in Nim Source: https://context7.com/dom96/httpbeast/llms.txt Configures a `startup` callback in `Settings` to execute code at the beginning of each worker thread's event loop. This is useful for initializing thread-local variables, loading configuration, or setting up per-thread resources. The example initializes thread-local variables `serverName` and `debugMode`. ```nim import os, options, asyncdispatch, parsecfg, strutils, streams import httpbeast var serverName {.threadvar.}: string var debugMode {.threadvar.}: bool proc onRequest(req: Request): Future[void] = if req.path.get() == "/info": req.send("Server: " & serverName & ", Debug: " & $debugMode) else: req.send("OK") var startup = proc () = # Initialize thread-local variables serverName = "MyServer" debugMode = true echo "Thread initialized with serverName=", serverName let settings = initSettings( port = Port(8080), startup = startup ) run(onRequest, settings) ``` -------------------------------- ### Get Request Path - path Source: https://context7.com/dom96/httpbeast/llms.txt The `path` procedure extracts the request target (URL path) from the HTTP request. It returns an `Option[string]` containing the path portion of the request URL. ```APIDOC ## GET /path ### Description Extracts the request target (URL path) from the HTTP request. ### Method GET ### Endpoint /path ### Parameters None ### Request Example N/A (This is accessed via the `req` object within a request handler) ### Response #### Success Response (200) - **path** (Option[string]) - The path portion of the request URL (e.g., some("/"), some("/api/users"), or none() if not present). #### Response Example ```json { "path": "/api/users" } ``` ``` -------------------------------- ### Get Client IP Address Source: https://context7.com/dom96/httpbeast/llms.txt The `ip` procedure returns the IP address of the client that made the request. This is useful for logging, rate limiting, or access control purposes. ```APIDOC ## ip - Get Client IP Address ### Description Returns the IP address of the client that made the request. ### Method GET ### Endpoint /whoami ### Parameters None ### Request Example None ### Response #### Success Response (200) - **string** - The IP address of the client. #### Response Example ``` Your IP address is: 192.168.1.100 ``` ``` -------------------------------- ### Get Request Headers Source: https://context7.com/dom96/httpbeast/llms.txt The `headers` procedure parses and returns all HTTP headers from the request as an `Option[HttpHeaders]`. Headers can be accessed by name using the standard Nim `HttpHeaders` interface. ```APIDOC ## headers - Get Request Headers ### Description Parses and returns all HTTP headers from the request as an `Option[HttpHeaders]`. ### Method GET (Implicit) ### Endpoint Any ### Parameters None ### Request Example None ### Response #### Success Response (200) - **HttpHeaders** (Option[HttpHeaders]) - An optional object containing the request headers. #### Response Example ```nim // Example of accessing headers let hdrs = req.headers if hdrs.isSome(): let headers = hdrs.get() if headers.hasKey("Content-Type"): echo "Content-Type: " & headers["Content-Type"] ``` ``` -------------------------------- ### Get Request Body Source: https://context7.com/dom96/httpbeast/llms.txt The `body` procedure retrieves the body content of the request, typically used for POST, PUT, and PATCH requests. It returns an `Option[string]` containing the raw body data. ```APIDOC ## body - Get Request Body ### Description Retrieves the body content of the request, typically used for POST, PUT, and PATCH requests. Returns an `Option[string]`. ### Method POST, PUT, PATCH ### Endpoint /api/data ### Parameters None ### Request Example ```json { "key": "value" } ``` ### Response #### Success Response (200) - **string** - A string indicating the number of bytes received and the content of the body. #### Response Example ``` Received 15 bytes: {"key": "value"} ``` ``` -------------------------------- ### Get Request Path - Nim Source: https://context7.com/dom96/httpbeast/llms.txt Extracts the request target (URL path) from an HTTP request, returning it as an `Option[string]`. Handles different paths to serve content or return 404 errors. Requires `options`, `asyncdispatch`, and `httpbeast` modules. ```nim import options, asyncdispatch import httpbeast proc onRequest(req: Request): Future[void] = let requestPath = req.path if requestPath.isSome(): case requestPath.get() of "/": req.send("Home page") of "/api/users": req.send("{\"users\": []}") of "/api/products": req.send("{\"products\": []}") else: req.send(Http404, "Path not found: " & requestPath.get()) else: req.send(Http400) run(onRequest) ``` -------------------------------- ### Get Request Headers in Nim Source: https://context7.com/dom96/httpbeast/llms.txt Parses and returns all HTTP headers from a request using the `headers` procedure. Headers can be accessed by name using the standard Nim `HttpHeaders` interface. It returns an `Option[HttpHeaders]`. ```nim import options, asyncdispatch import httpbeast proc onRequest(req: Request): Future[void] = let hdrs = req.headers if hdrs.isSome(): let headers = hdrs.get() var response = "Headers received:\n" if headers.hasKey("Content-Type"): response.add("Content-Type: " & headers["Content-Type"] & "\n") if headers.hasKey("Authorization"): response.add("Authorization header present\n") if headers.hasKey("User-Agent"): response.add("User-Agent: " & headers["User-Agent"] & "\n") req.send(response) else: req.send(Http400, "Could not parse headers") run(onRequest) ``` -------------------------------- ### Get Client IP Address in Nim Source: https://context7.com/dom96/httpbeast/llms.txt Returns the IP address of the client that made the request using the `ip` procedure. This is useful for logging, rate limiting, or access control purposes. The IP address is returned as a string. ```nim import options, asyncdispatch import httpbeast proc onRequest(req: Request): Future[void] = let clientIP = req.ip if req.path.get() == "/whoami": req.send("Your IP address is: " & clientIP) else: # Log the request with IP echo "Request from: ", clientIP, " to ", req.path.get() req.send("OK") run(onRequest) ``` -------------------------------- ### Get Request Body in Nim Source: https://context7.com/dom96/httpbeast/llms.txt Retrieves the body content of a request, typically used for POST, PUT, and PATCH requests. It returns an `Option[string]` containing the raw body data. This is useful for processing incoming data payloads. ```nim import options, asyncdispatch import httpbeast proc onRequest(req: Request): Future[void] = if req.httpMethod == some(HttpPost): case req.path.get() of "/api/data": let requestBody = req.body if requestBody.isSome(): let data = requestBody.get() req.send(Http200, "Received " & $data.len & " bytes: " & data) else: req.send(Http400, "No body provided") else: req.send(Http404) else: req.send(Http405) run(onRequest) ``` -------------------------------- ### Configure Server Settings - initSettings Source: https://context7.com/dom96/httpbeast/llms.txt The `initSettings` procedure creates a `Settings` object to customize the server's behavior including port, bind address, number of threads, domain type, and listen backlog. ```APIDOC ## POST /initSettings ### Description Creates a `Settings` object to customize the server's behavior. ### Method POST ### Endpoint /initSettings ### Parameters #### Query Parameters - **port** (Port) - Optional - The port the server will listen on. Defaults to 8080. - **bindAddr** (string) - Optional - The address the server will bind to. Defaults to "0.0.0.0". - **numThreads** (int) - Optional - The number of worker threads. Defaults to the number of CPU cores when threads are enabled. - **domain** (Domain) - Optional - The network domain (e.g., AF_INET for IPv4). Defaults to AF_INET. - **reusePort** (bool) - Optional - Whether to enable SO_REUSEPORT. Must be true when using threads. - **listenBacklog** (int) - Optional - The maximum length of the queue for pending connections. Defaults to SOMAXCONN. ### Request Example ```nim import httpbeast let settings = initSettings( port = Port(3000), numThreads = 4, reusePort = true ) ``` ### Response #### Success Response (200) - **Settings** (object) - An object containing the server configuration settings. #### Response Example ```json { "port": 3000, "bindAddr": "0.0.0.0", "numThreads": 4, "domain": "AF_INET", "reusePort": true, "listenBacklog": 1024 } ``` ``` -------------------------------- ### Thread Initialization Callback Source: https://context7.com/dom96/httpbeast/llms.txt The `startup` callback in `Settings` allows executing code at the beginning of each worker thread's event loop. This is useful for initializing thread-local variables, loading configuration, or setting up per-thread resources. ```APIDOC ## startup - Thread Initialization Callback ### Description Executes a callback function at the beginning of each worker thread's event loop for initialization purposes. ### Method GET ### Endpoint /info ### Parameters None ### Request Example None ### Response #### Success Response (200) - **string** - Information about the server name and debug mode for the current thread. #### Response Example ``` Server: MyServer, Debug: true ``` ``` -------------------------------- ### Async Request Handler in Nim Source: https://context7.com/dom96/httpbeast/llms.txt Demonstrates how to create asynchronous request handlers using `asyncdispatch`. Handlers marked with `{.async.}` can use `await` for non-blocking operations like HTTP client requests or database queries. This allows for efficient handling of concurrent requests. ```nim import options, asyncdispatch, httpclient import httpbeast proc onRequest(req: Request) {.async.} = if req.httpMethod == some(HttpGet): case req.path.get() of "/": # Make an async HTTP request to another service var client = newAsyncHttpClient() let content = await client.getContent("http://localhost:8080/data") req.send(content) of "/data": req.send("Internal data response") of "/delayed": # Simulate async operation await sleepAsync(100) req.send("Delayed response") else: req.send(Http404) run(onRequest) ``` -------------------------------- ### Configure HTTP Server Settings - Nim Source: https://context7.com/dom96/httpbeast/llms.txt Initializes and configures httpbeast server settings, including port, bind address, thread count, and socket options. The `reusePort` option must be enabled when using threads. Requires `options`, `asyncdispatch`, and `httpbeast` modules. ```nim import options, asyncdispatch import httpbeast proc onRequest(req: Request): Future[void] = req.send("Configured server response") let settings = initSettings( port = Port(3000), bindAddr = "0.0.0.0", numThreads = 4, domain = Domain.AF_INET, reusePort = true, listenBacklog = SOMAXCONN ) run(onRequest, settings) ``` -------------------------------- ### Async Request Handler Source: https://context7.com/dom96/httpbeast/llms.txt httpbeast integrates with Nim's `asyncdispatch` module, allowing handlers to perform async operations like HTTP client requests, database queries, or file I/O. Mark the handler with `{.async.}` to enable await syntax. ```APIDOC ## Async Request Handler ### Description Handles asynchronous operations within request handlers using Nim's `asyncdispatch` module. ### Method GET ### Endpoint / (for external request), /data (internal response), /delayed (simulated delay) ### Parameters None ### Request Example None ### Response #### Success Response (200) - **string** - Content from an external service, an internal response, or a delayed response. #### Response Example ``` // Response from http://localhost:8080/data { "message": "Data from external service" } ``` ``` // Response for /delayed after 100ms Delayed response ``` ``` -------------------------------- ### Low-Level Data Sending with unsafeSend in Nim Source: https://context7.com/dom96/httpbeast/llms.txt Demonstrates the use of the `unsafeSend` procedure in httpbeast to send raw data directly on the request socket. This method allows for multiple calls and manual HTTP header construction, suitable for scenarios like chunked data transfer. It bypasses automatic header generation and socket state validation, requiring careful usage. ```nim import options, asyncdispatch import httpbeast proc onRequest(req: Request): Future[void] = if req.path.get() == "/stream": # Send HTTP headers manually req.unsafeSend("HTTP/1.1 200 OK\r\n") req.unsafeSend("Content-Type: text/plain\r\n") req.unsafeSend("Transfer-Encoding: chunked\r\n\r\n") # Send chunked data req.unsafeSend("5\r\nHello\r\n") req.unsafeSend("6\r\n World\r\n") req.unsafeSend("0\r\n\r\n") else: req.send("OK") run(onRequest) ``` -------------------------------- ### Send HTTP Response - send Source: https://context7.com/dom96/httpbeast/llms.txt The `send` procedure sends an HTTP response to the client. It has multiple overloads for sending different combinations of HTTP codes, bodies, and custom headers. ```APIDOC ## POST /send ### Description Sends an HTTP response to the client. ### Method POST ### Endpoint /send ### Parameters #### Request Body - **httpCode** (HttpCode) - Optional - The HTTP status code to send. Defaults to 200 OK. - **body** (string) - Optional - The response body content. - **headers** (string) - Optional - Custom headers to include in the response, formatted as a string (e.g., "Content-Type: application/json"). ### Request Example ```nim import httpbeast # Simple text response req.send("Plain text response") # JSON response with custom headers req.send(Http200, "{\"status\": \"ok\"}", "Content-Type: application/json") # Response with specific HTTP code and body req.send(Http201, "Resource created successfully") # Error response using just HTTP code req.send(Http500) ``` ### Response #### Success Response (200) - **None** - The response is sent to the client. #### Response Example N/A ``` -------------------------------- ### Send HTTP Response - Nim Source: https://context7.com/dom96/httpbeast/llms.txt Sends an HTTP response to the client with various overloads for status codes, bodies, and custom headers. Supports sending plain text, JSON with headers, or specific HTTP status codes. Requires `options`, `asyncdispatch`, and `httpbeast` modules. ```nim import options, asyncdispatch import httpbeast proc onRequest(req: Request): Future[void] = case req.path.get() of "/text": # Simple text response with default 200 OK req.send("Plain text response") of "/json": # JSON response with custom headers req.send(Http200, "{\"status\": \"ok\", \"message\": \"Success\"}", "Content-Type: application/json") of "/created": # Response with specific HTTP code req.send(Http201, "Resource created successfully") of "/error": # Error response using just HTTP code req.send(Http500) else: req.send(Http404) run(onRequest) ``` -------------------------------- ### unsafeSend - Low-Level Data Sending Source: https://context7.com/dom96/httpbeast/llms.txt The unsafeSend procedure provides direct access to send raw data on the request socket. It can be called multiple times and does not include HTTP headers. Use with caution as it doesn't validate socket state. ```APIDOC ## POST /stream (Example Usage) ### Description This endpoint demonstrates the usage of `unsafeSend` to manually send HTTP headers and chunked data for a streaming response. ### Method POST ### Endpoint /stream ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example (No request body for this example, as it's triggered by a GET request to /stream) ### Response #### Success Response (200) - **Content** (string) - The streamed content sent via `unsafeSend`. #### Response Example ``` HTTP/1.1 200 OK Content-Type: text/plain Transfer-Encoding: chunked 5 Hello 6 World 0 ``` ``` -------------------------------- ### Unregister Socket for External Use in Nim Source: https://context7.com/dom96/httpbeast/llms.txt Uses the `forget` procedure to unregister the request's client socket from httpbeast's event loop. This is essential when integrating with WebSocket libraries or other protocols that need to take over the socket connection. After calling `forget`, `req.client` can be used with external libraries. ```nim import options, asyncdispatch import httpbeast proc onRequest(req: Request): Future[void] = if req.path.get() == "/websocket": # Unregister socket from httpbeast for WebSocket upgrade req.forget() # Now req.client can be used with a WebSocket library # websocketLibrary.upgrade(req.client) else: req.send("Regular HTTP response") run(onRequest) ``` -------------------------------- ### Unregister Socket for External Use Source: https://context7.com/dom96/httpbeast/llms.txt The `forget` procedure unregisters the request's client socket from httpbeast's event loop. This is essential when integrating with WebSocket libraries or other protocols that need to take over the socket connection. ```APIDOC ## forget - Unregister Socket for External Use ### Description Unregisters the request's client socket from httpbeast's event loop, allowing external libraries to manage the connection. ### Method GET ### Endpoint /websocket ### Parameters None ### Request Example None ### Response #### Success Response (200) - **string** - A message indicating a regular HTTP response or that the socket has been unregistered for WebSocket upgrade. #### Response Example ``` Regular HTTP response ``` ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.