about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--src/io/file.nim74
-rw-r--r--src/io/loader.nim26
2 files changed, 75 insertions, 25 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
diff --git a/src/io/loader.nim b/src/io/loader.nim
index 775cb78f..2c4245c8 100644
--- a/src/io/loader.nim
+++ b/src/io/loader.nim
@@ -21,6 +21,7 @@ when defined(posix):
 
 import bindings/curl
 import io/about
+import io/file
 import io/http
 import io/request
 import io/urlfilter
@@ -46,31 +47,6 @@ type
     cookiejar*: CookieJar
     referrerpolicy*: ReferrerPolicy
 
-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:
-    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
-
 proc loadResource(request: Request, ostream: Stream) =
   case request.url.scheme
   of "file":