import std/algorithm import std/os import std/times import dirlist import loader/connecterror import utils/twtstr proc loadDir(path, opath: string) = var path = path if path[^1] != '/': #TODO dos/windows path &= '/' var base = "file://" & opath if base[^1] != '/': #TODO dos/windows base &= '/' stdout.write("Content-Type: text/html\n\n") stdout.write("""
""") var fs: seq[(PathComponent, string)] for pc, file in walkDir(path, relative = true): fs.add((pc, file)) fs.sort(cmp = proc(a, b: (PathComponent, string)): int = cmp(a[1], b[1])) var items: seq[DirlistItem] for (pc, file) in fs: let fullpath = path / file var info: FileInfo try: info = getFileInfo(fullpath, followSymlink = false) except OSError: continue let modified = $info.lastWriteTime.local().format("MMM/dd/yyyy HH:MM") case pc of pcDir: items.add(DirlistItem( t: ITEM_DIR, name: file, modified: modified )) of pcFile: items.add(DirlistItem( t: ITEM_FILE, name: file, modified: modified, nsize: int(info.size) )) of pcLinkToDir, pcLinkToFile: var target = expandSymlink(fullpath) if pc == pcLinkToDir: target &= '/' items.add(DirlistItem( t: ITEM_LINK, name: file, modified: modified, linkto: target )) stdout.write(makeDirlist(items)) stdout.write("\n\n\n\n") proc loadFile(f: File) = # No headers, we'll let the browser figure out the file type. stdout.write("\n") const BufferSize = 16384 var buffer {.noinit.}: array[BufferSize, char] while true: let n = readBuffer(f, addr buffer[0], BufferSize) if n == 0: break let n2 = stdout.writeBuffer(addr buffer[0], n) if n2 < n or n < BufferSize: break proc main() = if getEnv("MAPPED_URI_HOST") != "": let code = int(ERROR_INVALID_URL) stdout.write("Cha-Control: ConnectionError " & $code & " cannot use host in file") return let opath = getEnv("MAPPED_URI_PATH") let path = percentDecode(opath) var f: File if f.open(path, fmRead): loadFile(f) elif dirExists(path): loadDir(path, opath) else: let code = int(ERROR_FILE_NOT_FOUND) stdout.write("Cha-Control: ConnectionError " & $code) main()