all repos — nimhttpd @ ca15b65e55c7d599fdaf2a4b332aea0b01bea5ae

A useful static file web server.

Merge pull request #14 from unquietwiki/master

Dual-stack nimhttpd
Fabio Cevasco h3rald@h3rald.com
Mon, 16 Jan 2023 11:50:34 +0100
commit

ca15b65e55c7d599fdaf2a4b332aea0b01bea5ae

parent

6606091dbc99480297cc34dcfccdfc682f129463

4 files changed, 39 insertions(+), 36 deletions(-)

jump to
M LICENSELICENSE

@@ -1,6 +1,6 @@

The MIT License (MIT) -Copyright (c) 2015-2021 Fabio Cevasco +Copyright (c) 2015-2023 Fabio Cevasco Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal
M README.mdREADME.md

@@ -9,14 +9,14 @@ _NimHTTPd_ is a minimal web server that can be used to serve static files.

## Usage -**nimhttpd** **[** **-6** **-p:**_port_ **-t:**_title_ **-a:**_address_ **-H**:_"key: val"_ **]** **[** _directory_ **]** +**nimhttpd** **[** **-p:**_port_ **-t:**_title_ **-a:**_address_ **-6:**_ipv6_ **-H**:_"key: val"_ **]** **[** _directory_ **]** Where: - _directory_ is the directory to serve (default: current directory). - _port_ is the port to listen to (default: 1337). If the specified port is unavailable, the number will be incremented until an available port is found. -- _address_ is the address to bind to (default: 0.0.0.0). +- _address_ is the address to bind to (default: localhost; use "0.0.0.0" to accept any IPv4 address). +- _ipv6_ is the IPv6 address to bind to (default: localhost; use "::" to accept any IPv6 address). - _title_ is the title to use when listing the contents of a directory. -- _-6_ enables IPv6 support - _-H_ is a custom header (Specified like in curl)
M src/nimhttpd.nimsrc/nimhttpd.nim

@@ -1,11 +1,11 @@

import asyncdispatch, - asynchttpserver, + asynchttpserver, mimetypes, nativesockets, os, parseopt, - strutils, + strutils, times, uri

@@ -23,10 +23,8 @@ author = pkgAuthor

addressDefault = "localhost" portDefault = 1337 -var domain = AF_INET - let usage = """ $1 v$2 - $3 - (c) 2014-2022 $4 + (c) 2014-2023 $4 Usage: nimhttpd [-p:port] [directory]

@@ -37,9 +35,9 @@

Options: -t, --title The title to use in index pages (default: Index) -p, --port The port to listen to (default: $5). - -a, --address The address to listen to (default: $6). If the specified port is + -a, --address The IPv4 address to listen to (default: $6). If the specified port is unavailable, the number will be incremented until an available port is found. - -6, --ipv6 Listen to IPv6 addresses. + -6, --ipv6 The IPv6 address to listen to (default: $6). -H --header Add a custom header. Multiple headers can be added """ % [name, version, description, author, $portDefault, $addressDefault]

@@ -55,7 +53,8 @@ directory*: string

mimes*: MimeDb port*: Port title*: string - address*: string + address4*: string + address6*: string name*: string version*: string headers*: HttpHeaders

@@ -109,20 +108,20 @@ var content = "<p>This server does not support the functionality required to fulfill the request.</p>"

return (code: Http501, content: hPage(settings, content, $int(Http501), "Not Implemented"), headers: {"Content-Type": "text/html"}.newHttpHeaders()) proc sendStaticFile(settings: NimHttpSettings, path: string): NimHttpResponse = - let mimes = settings.mimes - var ext = path.splitFile.ext - if ext == "": - ext = ".txt" - ext = ext[1 .. ^1] + var + mimes = settings.mimes + ext = path.splitFile.ext + if ext == "": ext = ".txt" else: ext = ext[1 .. ^1] let mimetype = mimes.getMimetype(ext.toLowerAscii) var file = path.readFile return (code: Http200, content: file, headers: {"Content-Type": mimetype}.newHttpHeaders) proc sendDirContents(settings: NimHttpSettings, dir: string): NimHttpResponse = - let cwd = settings.directory.absolutePath - var res: NimHttpResponse - var files = newSeq[string](0) - var path = dir.absolutePath + var + res: NimHttpResponse + cwd = settings.directory.absolutePath + files = newSeq[string](0) + path = dir.absolutePath if not path.startsWith(cwd): path = cwd if path != cwd and path != cwd&"/" and path != cwd&"\\":

@@ -158,14 +157,14 @@

setControlCHook(handleCtrlC) proc genMsg(settings: NimHttpSettings): string = - let url = "http://$1:$2/" % [settings.address, $settings.port.int] let t = now() let pid = getCurrentProcessId() result = """$1 v$2 -Address: $3 -Directory: $4 -Current Time: $5 -PID: $6""" % [settings.name, settings.version, url, settings.directory.quoteShell, $t, $pid] +Address4: $3 +Address6: $4 +Directory: $5 +Current Time: $6 +PID: $7""" % [settings.name, settings.version, settings.address4, settings.address6, settings.directory.quoteShell, $t, $pid] proc serve*(settings: NimHttpSettings) = var server = newAsyncHttpServer()

@@ -186,12 +185,14 @@ for key, value in settings.headers:

res.headers[key] = value await req.respond(res.code, res.content, res.headers) echo genMsg(settings) - asyncCheck server.serve(settings.port, handleHttpRequest, settings.address, -1, domain) + asyncCheck server.serve(settings.port, handleHttpRequest, settings.address4, -1, AF_INET) + asyncCheck server.serve(settings.port, handleHttpRequest, settings.address6, -1, AF_INET6) when isMainModule: var port = portDefault - var address = addressDefault + var address4 = addressDefault + var address6 = addressDefault var logging = false var www = getCurrentDir() var title = "Index"

@@ -209,10 +210,10 @@ quit(0)

of "version", "v": echo version quit(0) - of "-ipv6", "6": - domain = AF_INET6 of "address", "a": - address = val + address4 = val + of "ipv6", "6": + address6 = val of "title", "t": title = val of "port", "p":

@@ -244,9 +245,10 @@ quit(1)

else: discard - var addrInfo = getAddrInfo(address, Port(port), domain) - if addrInfo == nil: - echo "Error: Could not resolve address '"&address&"'." + var addrInfo4 = getAddrInfo(address4, Port(port), AF_INET) + var addrInfo6 = getAddrInfo(address6, Port(port), AF_INET6) + if (addrInfo4 == nil) and (addrInfo6 == nil): + echo "Error: Could not resolve given IPv4 or IPv6 addresses." quit(1) var settings: NimHttpSettings

@@ -254,7 +256,8 @@ settings.directory = www

settings.logging = logging settings.mimes = newMimeTypes() settings.mimes.register("htm", "text/html") - settings.address = address + settings.address4 = address4 + settings.address6 = address6 settings.name = name settings.title = title settings.version = version
M src/nimhttpdpkg/config.nimsrc/nimhttpdpkg/config.nim

@@ -1,5 +1,5 @@

const pkgTitle* = "NimHTTPd" - pkgVersion* = "1.4.0" + pkgVersion* = "1.5.0" pkgAuthor* = "Fabio Cevasco & Michael Adams" pkgDescription* = "A tiny static file web server. IPv4 & IPv6 supported!"