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
|
// Local reference filesystem for HTTP/browser tests. No external target.
package main
import (
"fmt"
"github.com/knusbaum/go9p"
"github.com/knusbaum/go9p/fs"
"net"
"os"
)
type fragmented struct{ net.Conn }
func (f fragmented) Read(p []byte) (int, error) {
if len(p) > 17 {
p = p[:17]
}
return f.Conn.Read(p)
}
func (f fragmented) Write(p []byte) (int, error) {
total := 0
for len(p) > 0 {
n := len(p)
if n > 31 {
n = 31
}
written, err := f.Conn.Write(p[:n])
total += written
p = p[written:]
if err != nil {
return total, err
}
}
return total, nil
}
func check(err error) {
if err != nil {
panic(err)
}
}
func main() {
tree, root := fs.NewFS("user", "user", 0755)
check(root.AddChild(fs.NewStaticFile(tree.NewStat("hello.txt", "user", "user", 0644), []byte("Hello from 9P.\n"))))
check(root.AddChild(fs.NewStaticFile(tree.NewStat("edit.txt", "user", "user", 0644), []byte("Edit me.\n"))))
large := make([]byte, 180000)
for i := range large {
large[i] = byte(i % 251)
}
check(root.AddChild(fs.NewStaticFile(tree.NewStat("large.bin", "user", "user", 0644), large)))
check(root.AddChild(fs.NewStaticFile(tree.NewStat("<literal>.txt", "user", "user", 0644), []byte("Names are text.\n"))))
for _, name := range []string{"app.mjs", "style.css", "client.mjs", "config.json", "cloud9.wasm", "9p", "space #?% ü.txt", "literal%2F.txt", "back\\slash.txt"} {
check(root.AddChild(fs.NewStaticFile(tree.NewStat(name, "user", "user", 0644), []byte("Path: "+name+"\n"))))
}
internal := fs.NewStaticDir(tree.NewStat("_cloud9", "user", "user", 0755))
check(root.AddChild(internal))
check(internal.AddChild(fs.NewStaticFile(tree.NewStat("app.mjs", "user", "user", 0644), []byte("Upstream private-looking path.\n"))))
dir := fs.NewStaticDir(tree.NewStat("notes", "user", "user", 0755))
check(root.AddChild(dir))
check(dir.AddChild(fs.NewStaticFile(tree.NewStat("café.txt", "user", "user", 0644), []byte("Olá, 世界.\n"))))
for i := 0; i < 150; i++ {
name := fmt.Sprintf("item-%03d.txt", i)
check(dir.AddChild(fs.NewStaticFile(tree.NewStat(name, "user", "user", 0644), nil)))
}
parent := root
for i := 0; i < 18; i++ {
d := fs.NewStaticDir(tree.NewStat("deep", "user", "user", 0755))
check(parent.AddChild(d))
parent = d
}
check(parent.AddChild(fs.NewStaticFile(tree.NewStat("end.txt", "user", "user", 0644), []byte("Deep walk.\n"))))
network, address := "tcp", "127.0.0.1:0"
if len(os.Args) == 2 {
network, address = "unix", os.Args[1]
}
listener, err := net.Listen(network, address)
check(err)
fmt.Println(listener.Addr().String())
for {
conn, err := listener.Accept()
check(err)
go func() { defer conn.Close(); f := fragmented{conn}; _ = go9p.ServeReadWriter(f, f, tree.Server()) }()
}
}
|