about summary refs log tree commit diff stats
path: root/src/io/file.nim
diff options
context:
space:
mode:
Diffstat (limited to 'src/io/file.nim')
-rw-r--r--src/io/file.nim74
1 files changed, 74 insertions, 0 deletions
diff --git a/src/io/file.nim b/src/io/file.nim
new file mode 100644
index 00000000..b35aee09
--- /dev/null
+++ b/src/io/file.nim
@@ -0,0 +1,74 @@
+import os
+import streams
+import tables
+
+import io/request
+import ips/serialize
+import types/url
+
+proc loadDir(url: URL, path: string, ostream: Stream) =
+  ostream.swrite(0)
+  ostream.swrite(200) # ok
+  ostream.swrite(newHeaderList({"Content-Type": "text/html"}.toTable()))
+  ostream.write("""
+<HTML>
+<HEAD>
+<BASE HREF="""" & $url & """">
+<TITLE>Directory list of """ & path & """</TITLE>
+</HEAD>
+<BODY>
+<H1>Directory list of """ & path & """</H1>
+[DIR]&nbsp; <A HREF="../">../</A></br>
+""")
+  for pc, file in walkDir(path, relative = true):
+    case pc
+    of pcDir:
+      ostream.write("[DIR]&nbsp; ")
+    of pcFile:
+      ostream.write("[FILE] ")
+    of pcLinkToDir, pcLinkToFile:
+      ostream.write("[LINK] ")
+    var fn = file
+    if pc == pcDir:
+      fn &= '/'
+    ostream.write("<A HREF=\"" & fn & "\">" & fn & "</A>")
+    if pc in {pcLinkToDir, pcLinkToFile}:
+      ostream.write(" -> " & expandSymlink(path / file))
+    ostream.write("<br>")
+  ostream.write("""
+</BODY>
+</HTML>""")
+  ostream.flush()
+
+proc loadSymlink(path: string, ostream: Stream) =
+  discard
+
+proc loadFile*(url: URL, ostream: Stream) =
+  when defined(windows) or defined(OS2) or defined(DOS):
+    let path = url.path.serialize_unicode_dos()
+  else:
+    let path = url.path.serialize_unicode()
+  let istream = newFileStream(path, fmRead)
+  if istream == nil:
+    if dirExists(path):
+      loadDir(url, path, ostream)
+    elif symlinkExists(path):
+      loadSymlink(path, ostream)
+    else:
+      ostream.swrite(-1) # error
+      ostream.flush()
+  else:
+    ostream.swrite(0)
+    ostream.swrite(200) # ok
+    ostream.swrite(newHeaderList())
+    while not istream.atEnd:
+      const bufferSize = 4096
+      var buffer {.noinit.}: array[bufferSize, char]
+      while true:
+        let n = readData(istream, addr buffer[0], bufferSize)
+        if n == 0:
+          break
+        ostream.writeData(addr buffer[0], n)
+        ostream.flush()
+        if n < bufferSize:
+          break