1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
import algorithm
import os
import streams
import tables
import io/headers
import ips/serialize
import types/url
proc loadDir(url: URL, path: string, ostream: Stream) =
ostream.swrite(0)
ostream.swrite(200) # ok
ostream.swrite(newHeaders({"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] <A HREF="../">../</A></br>
""")
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]))
for (pc, file) in fs:
case pc
of pcDir:
ostream.write("[DIR] ")
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) =
ostream.swrite(0)
ostream.swrite(200) # ok
ostream.swrite(newHeaders({"Content-Type": "text/html"}.toTable()))
let sl = expandSymlink(path)
ostream.write("""
<HTML>
<HEAD>
<TITLE>Symlink view<TITLE>
</HEAD>
<BODY>
Symbolic link to <A HREF="""" & sl & """">""" & sl & """</A></br>
</BODY>
</HTML>""")
ostream.flush()
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(newHeaders())
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
|