62 | 62 |
if val
|
63 | 63 |
200, val
|
64 | 64 |
else
|
65 | |
406, 'cant convert facet'
|
|
65 |
406, "cant convert facet '#{facet.name}' to '#{facet.type}'"
|
66 | 66 |
elseif fileder
|
67 | 67 |
-- no facet given
|
68 | 68 |
facets = [{k.name, k.type} for k,v in pairs fileder.facets]
|
|
73 | 73 |
-- fileder not found
|
74 | 74 |
404, "fileder '#{path}' not found"
|
75 | 75 |
else
|
76 | |
501, 'not implemented'
|
|
76 |
501, "not implemented"
|
|
77 |
|
|
78 |
handle_static: (method, path, stream) =>
|
|
79 |
path = path\match '^/%?static/(.*)'
|
|
80 |
return unless path
|
|
81 |
|
|
82 |
respond = (code, type, body) ->
|
|
83 |
res = headers.new!
|
|
84 |
res\upsert ':status', code
|
|
85 |
res\append 'content-type', type
|
|
86 |
|
|
87 |
assert stream\write_headers res, method == 'HEAD'
|
|
88 |
if body and method ~= 'HEAD'
|
|
89 |
assert stream\write_body_from_string body
|
|
90 |
|
|
91 |
if method ~= 'GET' and method ~= 'HEAD'
|
|
92 |
respond '405', 'text/plain', "can only GET/HEAD static resources"
|
|
93 |
return true
|
|
94 |
|
|
95 |
if path\match '^%.' or path\match '^%~'
|
|
96 |
respond '404', 'text/plain', "not found"
|
|
97 |
return
|
|
98 |
|
|
99 |
file_path = "static/#{path}"
|
|
100 |
if 'file' == lfs.attributes file_path, 'mode'
|
|
101 |
fd, err, errno = io.open file_path, 'rb'
|
|
102 |
|
|
103 |
if not fd
|
|
104 |
code = switch errno
|
|
105 |
when ce.ENOENT then '404'
|
|
106 |
when ce.EACCES then '403'
|
|
107 |
else '503'
|
|
108 |
|
|
109 |
respond code, 'text/plain', err or ''
|
|
110 |
|
|
111 |
else
|
|
112 |
suffix = file_path\match '%.([a-z]+)$'
|
|
113 |
type = switch suffix
|
|
114 |
when 'css' then 'text/css'
|
|
115 |
when 'lua' then 'application/lua'
|
|
116 |
when 'js' then 'application/javascript'
|
|
117 |
else 'application/octet-stream'
|
|
118 |
|
|
119 |
respond '200', type, nil
|
|
120 |
if method ~= 'HEAD'
|
|
121 |
assert stream\write_body_from_file fd
|
|
122 |
else
|
|
123 |
respond '404', 'text/plain', "not found"
|
|
124 |
|
|
125 |
true
|
77 | 126 |
|
78 | 127 |
stream: (sv, stream) =>
|
79 | 128 |
req = stream\get_headers!
|
80 | 129 |
method = req\get ':method'
|
81 | 130 |
path = req\get ':path'
|
82 | 131 |
|
83 | |
if path\match '^/%?'
|
84 | |
-- serve static assets, cheap hack for now
|
|
132 |
-- serve static assets, cheap hack for now
|
|
133 |
return if @handle_static method, path, stream
|
85 | 134 |
|
86 | |
res = headers.new!
|
87 | |
if method ~= 'GET' and method ~= 'HEAD'
|
88 | |
res\append ':status', '405'
|
89 | |
stream\write_headers res, true
|
90 | |
return
|
|
135 |
path_facet, type = path\match '(.*):(.*)'
|
|
136 |
path_facet or= path
|
|
137 |
path, facet = path_facet\match '(.*)/([^/]*)'
|
91 | 138 |
|
92 | |
static_path = "static/#{path\sub 3}"
|
93 | |
|
94 | |
if 'file' == lfs.attributes static_path, 'mode'
|
95 | |
fd, err, errno = io.open static_path, 'rb'
|
96 | |
|
97 | |
if not fd
|
98 | |
code = switch errno
|
99 | |
when ce.ENOENT then '404'
|
100 | |
when ce.EACCES then '403'
|
101 | |
else '503'
|
102 | |
|
103 | |
res\upsert ':status', code
|
104 | |
res\append 'content-type', 'text/plain'
|
105 | |
|
106 | |
assert stream\write_headers res, method == 'HEAD'
|
107 | |
if method ~= 'HEAD'
|
108 | |
assert stream\write_body_from_string err
|
109 | |
|
110 | |
else
|
111 | |
suffix = static_path\match '%.([a-z]+)$'
|
112 | |
type = switch suffix
|
113 | |
when 'css' then 'text/css'
|
114 | |
when 'lua' then 'application/lua'
|
115 | |
when 'js' then 'application/javascript'
|
116 | |
else 'application/octet-stream'
|
117 | |
|
118 | |
res\upsert ':status', '200'
|
119 | |
res\append 'content-type', type
|
120 | |
|
121 | |
assert stream\write_headers res, method == 'HEAD'
|
122 | |
if method ~= 'HEAD'
|
123 | |
assert stream\write_body_from_file fd
|
124 | |
else
|
125 | |
res\upsert ':status', '404'
|
126 | |
res\append 'content-type', 'text/plain'
|
127 | |
|
128 | |
assert stream\write_headers res, method == 'HEAD'
|
129 | |
if method ~= 'HEAD'
|
130 | |
assert stream\write_body_from_string "not found"
|
131 | |
|
132 | |
return
|
133 | |
|
134 | |
path, facet = dir_base path
|
135 | |
facet = if #facet > 0
|
136 | |
facet = '' if facet == ':'
|
137 | |
accept = req\get 'mmm-accept'
|
138 | |
Key facet, accept or 'text/html'
|
|
139 |
if facet ~= '?index'
|
|
140 |
type or= 'text/html'
|
|
141 |
type = type\match '%s*(.*)'
|
|
142 |
facet = Key facet, type
|
139 | 143 |
else
|
140 | |
nil
|
|
144 |
facet = nil
|
141 | 145 |
|
142 | 146 |
status, body = @handle method, path, facet
|
143 | 147 |
|
|
148 | 152 |
res\append ':status', tostring status
|
149 | 153 |
res\append 'content-type', response_type
|
150 | 154 |
|
151 | |
if method == 'HEAD'
|
152 | |
stream\write_headers res, true
|
153 | |
else
|
154 | |
stream\write_headers res, false
|
|
155 |
stream\write_headers res, method == 'HEAD'
|
|
156 |
if method ~= 'HEAD'
|
155 | 157 |
stream\write_chunk body, true
|
156 | 158 |
|
157 | 159 |
error: (sv, ctx, op, err, errno) =>
|