33 | 33 |
|
34 | 34 |
@flags = opts.flags
|
35 | 35 |
|
36 | |
if @flags.rw == nil
|
37 | |
@flags.rw = opts.host == 'localhost' or opts.host == '127.0.0.1'
|
38 | |
|
39 | 36 |
if @flags.unsafe == nil
|
40 | |
@flags.unsafe = not @flags.rw or opts.host == 'localhost' or opts.host == '127.0.0.1'
|
|
37 |
@flags.unsafe = opts.host == 'localhost' or opts.host == '127.0.0.1'
|
41 | 38 |
|
42 | 39 |
if @flags.cache
|
43 | |
assert not @flags.rw, "--rw and --cache are incompatible"
|
44 | 40 |
@root = Fileder @store
|
45 | 41 |
init_cache!
|
46 | 42 |
|
|
92 | 88 |
convert 'text/mermaid-graph', 'text/html', debugger\render!, fileder, facet.name
|
93 | 89 |
|
94 | 90 |
handle: (method, path, facet, value) =>
|
95 | |
if not @flags.rw and method != 'GET' and method != 'HEAD'
|
96 | |
return 403, 'editing not allowed'
|
97 | |
|
98 | |
switch method
|
99 | |
when 'GET', 'HEAD'
|
100 | |
root = @root or Fileder @store
|
101 | |
export BROWSER
|
102 | |
BROWSER = :path
|
103 | |
fileder = root\walk path
|
104 | |
|
105 | |
if not fileder
|
106 | |
-- fileder not found
|
107 | |
return 404, "fileder '#{path}' not found"
|
108 | |
|
109 | |
val = switch facet.name
|
110 | |
when '?index', '?tree'
|
111 | |
-- serve fileder index
|
112 | |
-- '?index': one level deep
|
113 | |
-- '?tree': recursively
|
114 | |
depth = if facet.name == '?tree' then -1 else 1
|
115 | |
index = @store\get_index path, depth
|
116 | |
convert 'table', facet.type, index, fileder, facet.name
|
117 | |
else
|
118 | |
if facet.type == '?'
|
119 | |
facet.type = 'text/html'
|
120 | |
current = fileder
|
121 | |
while current
|
122 | |
if type = current\get '_web_view: type'
|
123 | |
facet.type = type\match '^%s*(.-)%s*$'
|
124 | |
break
|
125 | |
|
126 | |
if current.path == ''
|
127 | |
break
|
128 | |
|
129 | |
path, _ = dir_base current.path
|
130 | |
current = root\walk path
|
131 | |
|
132 | |
if facet.type == 'text/html+interactive'
|
133 | |
@handle_interactive fileder, facet
|
134 | |
else if base = facet.type\match '^DEBUG %-> (.*)'
|
135 | |
facet.type = base
|
136 | |
@handle_debug fileder, facet
|
137 | |
else if not fileder\has_facet facet.name
|
138 | |
404, "facet '#{facet.name}' not found in fileder '#{path}'"
|
139 | |
else
|
140 | |
fileder\get facet
|
141 | |
|
142 | |
if val
|
143 | |
200, val
|
|
91 |
if method != 'GET' and method != 'HEAD'
|
|
92 |
return 501, "not implemented"
|
|
93 |
|
|
94 |
root = @root or Fileder @store
|
|
95 |
export BROWSER
|
|
96 |
BROWSER = :path
|
|
97 |
fileder = root\walk path
|
|
98 |
|
|
99 |
if not fileder
|
|
100 |
-- fileder not found
|
|
101 |
return 404, "fileder '#{path}' not found"
|
|
102 |
|
|
103 |
val = switch facet.name
|
|
104 |
when '?index', '?tree'
|
|
105 |
-- serve fileder index
|
|
106 |
-- '?index': one level deep
|
|
107 |
-- '?tree': recursively
|
|
108 |
depth = if facet.name == '?tree' then -1 else 1
|
|
109 |
index = @store\get_index path, depth
|
|
110 |
convert 'table', facet.type, index, fileder, facet.name
|
|
111 |
else
|
|
112 |
if facet.type == '?'
|
|
113 |
facet.type = 'text/html'
|
|
114 |
current = fileder
|
|
115 |
while current
|
|
116 |
if type = current\get '_web_view: type'
|
|
117 |
facet.type = type\match '^%s*(.-)%s*$'
|
|
118 |
break
|
|
119 |
|
|
120 |
if current.path == ''
|
|
121 |
break
|
|
122 |
|
|
123 |
path, _ = dir_base current.path
|
|
124 |
current = root\walk path
|
|
125 |
|
|
126 |
if facet.type == 'text/html+interactive'
|
|
127 |
@handle_interactive fileder, facet
|
|
128 |
else if base = facet.type\match '^DEBUG %-> (.*)'
|
|
129 |
facet.type = base
|
|
130 |
@handle_debug fileder, facet
|
|
131 |
else if not fileder\has_facet facet.name
|
|
132 |
404, "facet '#{facet.name}' not found in fileder '#{path}'"
|
144 | 133 |
else
|
145 | |
406, "cant convert facet '#{facet.name}' to '#{facet.type}'"
|
146 | |
when 'POST'
|
147 | |
if facet
|
148 | |
@store\create_facet path, facet.name, facet.type, value
|
149 | |
200, 'ok'
|
150 | |
else
|
151 | |
200, @store\create_fileder dir_base path
|
152 | |
when 'PUT'
|
153 | |
if facet
|
154 | |
@store\update_facet path, facet.name, facet.type, value
|
155 | |
200, 'ok'
|
156 | |
else
|
157 | |
cmd, args = value\match '^([^\n]+)\n(.*)'
|
158 | |
switch cmd
|
159 | |
when 'swap'
|
160 | |
child_a, child_b = args\match '^([^\n]+)\n([^\n]+)$'
|
161 | |
assert child_a and child_b, "invalid arguments"
|
162 | |
|
163 | |
@store\swap_fileders path, child_a, child_b
|
164 | |
200, 'ok'
|
165 | |
when nil
|
166 | |
400, "invalid request"
|
167 | |
else
|
168 | |
501, "unknown command #{cmd}"
|
169 | |
when 'DELETE'
|
170 | |
if facet
|
171 | |
@store\remove_facet path, facet.name, facet.type
|
172 | |
else
|
173 | |
@store\remove_fileder path
|
174 | |
200, 'ok'
|
175 | |
else
|
176 | |
501, "not implemented"
|
|
134 |
fileder\get facet
|
|
135 |
|
|
136 |
if val
|
|
137 |
200, val
|
|
138 |
else
|
|
139 |
406, "cant convert facet '#{facet.name}' to '#{facet.type}'"
|
177 | 140 |
|
178 | 141 |
err_and_trace = (msg) -> debug.traceback msg, 2
|
179 | 142 |
stream: (sv, stream) =>
|
|
219 | 182 |
-- usage:
|
220 | 183 |
-- moon server.moon [FLAGS] [STORE] [host] [port]
|
221 | 184 |
-- * FLAGS - any of the following:
|
222 | |
-- --[no-]rw - enable/disable POST?PUT/DELETE operations (default: on if local)
|
223 | |
-- --[no-]unsafe - enable/disable server-side code execution when writable is on (default: on if local or --no-rw)
|
|
185 |
-- --[no-]unsafe - enable/disable server-side code execution when writable is on (default: on if local)
|
224 | 186 |
-- --[no-]cache - cache all fileder contents (default: off)
|
225 | 187 |
-- * STORE - see mmm/mmmfs/stores/init.moon:get_store
|
226 | 188 |
-- * host - interface to bind to (default localhost, set to 0.0.0.0 for public hosting)
|