all repos — nimhttpd @ 441a39dc226afbf7c305971eac77a9a13aa24bb5

A useful static file web server.

Implemented automatic port binding.
h3rald h3rald@h3rald.com
Sat, 12 Sep 2020 12:01:13 +0200
commit

441a39dc226afbf7c305971eac77a9a13aa24bb5

parent

f2dc3d098056e4027d1dbc5841a816072de7b3ea

3 files changed, 30 insertions(+), 10 deletions(-)

jump to
M README.mdREADME.md

@@ -14,4 +14,5 @@

Where: * _directory_ is the directory to serve (default: current directory). -* _port_ is the port to listen to (default: 1337). +* _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.
M src/nimhttpd.nimsrc/nimhttpd.nim

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

import asynchttpserver, asyncdispatch, + nativesockets, os, strutils, mimetypes, times,

@@ -34,7 +35,8 @@ directory The directory to serve (default: current directory).

Options: -p, --port The port to listen to (default: $5). - -a, --address The address to listen to (default: $6). + -a, --address The address to listen to (default: $6). If the specified port is + unavailable, the number will be incremented until an available port is found. """ % [name, version, description, author, $portDefault, addressDefault]

@@ -51,6 +53,19 @@ port*: Port

address*: string name: string version*: string + +proc bindAvailablePort*(handle: SocketHandle, p: int): Port = + var check = -1 + var port = p - 1 + while check < 0'i32: + port += 1 + var name: Sockaddr_in + name.sin_family = typeof(name.sin_family)(toInt(AF_INET)) + name.sin_port = htons(uint16(port)) + name.sin_addr.s_addr = htonl(INADDR_ANY) + check = bindAddr(handle, cast[ptr SockAddr](addr(name)), sizeof(name).Socklen) + result = getLocalAddr(handle, AF_INET)[1] + proc h_page(settings:NimHttpSettings, content: string, title=""): string = var footer = """<div id="footer">$1 v$2</div>""" % [settings.name, settings.version]

@@ -148,10 +163,10 @@ 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] +Address: $3 +Directory: $4 +Current Time: $5 +PID: $6""" % [settings.name, settings.version, url, settings.directory.quoteShell, $t, $pid] proc serve*(settings: NimHttpSettings) = var server = newAsyncHttpServer()

@@ -173,7 +188,7 @@ asyncCheck server.serve(settings.port, handleHttpRequest, settings.address)

when isMainModule: - var port = Port(portDefault) + var port = portDefault var address = addressDefault var logging = false var www = getCurrentDir()

@@ -194,7 +209,7 @@ of "address", "a":

address = val of "port", "p": try: - port = Port(val.parseInt) + port = val.parseInt except: if val == "": echo "Port not set."

@@ -218,6 +233,10 @@ quit(1)

else: discard + let socket = createAsyncNativeSocket() + let availablePort = bindAvailablePort(socket.SocketHandle, port) + socket.closeSocket() + var settings: NimHttpSettings settings.directory = www settings.logging = logging

@@ -226,7 +245,7 @@ settings.mimes.register("htm", "text/html")

settings.address = address settings.name = name settings.version = version - settings.port = port + settings.port = availablePort serve(settings) runForever()
M src/nimhttpdpkg/config.nimsrc/nimhttpdpkg/config.nim

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

const pkgTitle* = "NimHTTPd" - pkgVersion* = "1.0.9" + pkgVersion* = "1.1.0" pkgAuthor* = "Fabio Cevasco" pkgDescription* = "A tiny static file web server."