comparison src/luan/host/main.luan @ 1135:707a5d874f3e

add luan.host
author Franklin Schmidt <fschmidt@gmail.com>
date Sun, 28 Jan 2018 21:36:58 -0700
parents
children 1f9d34a6f308
comparison
equal deleted inserted replaced
1134:e54ae41e9501 1135:707a5d874f3e
1 java()
2 local Luan = require "luan:Luan.luan"
3 local error = Luan.error
4 local assert_string = Luan.assert_string or error()
5 local ipairs = Luan.ipairs or error()
6 local try = Luan.try or error()
7 local Io = require "luan:Io.luan"
8 local print = Io.print or error()
9 local Rpc = require "luan:Rpc.luan"
10 local Thread = require "luan:Thread.luan"
11 local String = require "luan:String.luan"
12 local literal = String.literal or error()
13 local lower = String.lower or error()
14 local matches = String.matches or error()
15 local Hosting = require "luan:host/Hosting.luan"
16 local Logging = require "luan:logging/Logging.luan"
17 local logger = Logging.logger "main"
18 local WebHandler = require "java:luan.host.WebHandler"
19
20
21 local sites_dir = Io.schemes.file(Hosting.sites_dir)
22
23 sites_dir.mkdir()
24
25 local function delete_unused(file)
26 if file.is_directory() then
27 if file.name() == "local" then
28 return false
29 end
30 local all_deleted = true
31 for _,child in ipairs(file.children()) do
32 all_deleted = delete_unused(child) and all_deleted
33 end
34 if not all_deleted then
35 return false
36 end
37 end
38 file.delete()
39 return true
40 end
41
42
43 local fns = Rpc.functions
44
45 local function get_dir(domain,password)
46 assert_string(domain)
47 assert_string(password)
48 domain = lower(domain)
49 local dir = sites_dir.child(domain)
50 if dir.exists() then
51 local pwd = dir.child("password").read_text()
52 if pwd ~= password then
53 error "wrong password"
54 end
55 return dir.child("site")
56 else
57 return nil
58 end
59 end
60
61 function fns.get(domain,password)
62 local site_dir = get_dir(domain,password)
63 if site_dir == nil then
64 return nil
65 end
66
67 local children, file_info
68
69 function children(dir)
70 if dir.name() == "local" then
71 return {}
72 end
73 local rtn = {}
74 for _,child in ipairs(dir.children()) do
75 local info = file_info(child)
76 if info ~= nil then
77 rtn[info.name] = info
78 end
79 end
80 return rtn
81 end
82
83 function file_info(file)
84 local info = { name = file.name(), path = file.to_string() }
85 if file.is_directory() then
86 info.children = children(file)
87 elseif file.is_file() then
88 info.checksum = file.checksum()
89 else
90 return nil
91 end
92 return info
93 end
94
95 return file_info(site_dir)
96 end
97
98 function fns.create(domain,password)
99 assert_string(domain)
100 assert_string(password)
101 domain = lower(domain)
102 local dir = sites_dir.child(domain)
103 dir.exists() and error "already exists"
104 dir.mkdir()
105 dir.child("password").write(password)
106 dir = dir.child("site")
107 dir.mkdir()
108 return { name = dir.name(), path = dir.to_string(), children = {} }
109 end
110
111 local function security(site_dir,file)
112 matches( file.to_string(), "^"..literal(site_dir.to_string()) ) or error "security violation"
113 end
114
115 function fns.copy_file(domain,password,dir,name,content)
116 local site_dir = get_dir(domain,password)
117 site_dir or error "domain not found"
118 local file = Io.schemes.file(dir).child(name)
119 security(site_dir,file)
120 file.delete()
121 file.write(content)
122 end
123
124 function fns.mkdir(domain,password,dir,name)
125 local site_dir = get_dir(domain,password)
126 site_dir or error "domain not found"
127 local file = Io.schemes.file(dir).child(name)
128 security(site_dir,file)
129 file.mkdir()
130 return { name = file.name(), path = file.to_string(), children = {} }
131 end
132
133 function fns.delete_unused(domain,password,path)
134 local site_dir = get_dir(domain,password)
135 site_dir or error "domain not found"
136 local file = Io.schemes.file(path)
137 security(site_dir,file)
138 return delete_unused(file)
139 end
140
141 function fns.update_handler(domain,password)
142 local site_dir = get_dir(domain,password)
143 site_dir or error "domain not found"
144 domain = lower(domain)
145 WebHandler.removeHandler(domain)
146 WebHandler.loadHandler(domain)
147 end
148
149 function fns.delete(domain,password)
150 local site_dir = get_dir(domain,password)
151 site_dir or error "domain not found"
152 site_dir.parent().delete()
153 domain = lower(domain)
154 WebHandler.removeHandler(domain)
155 end
156
157 function fns.exists(domain)
158 assert_string(domain)
159 domain = lower(domain)
160 return sites_dir.child(domain).exists()
161 end
162
163 function fns.change_domain(old_domain,new_domain,password)
164 local old_dir = get_dir(old_domain,password)
165 old_dir or error "domain not found"
166 old_dir = old_dir.parent()
167 assert_string(new_domain)
168 new_domain = lower(new_domain)
169 local new_dir = sites_dir.child(new_domain)
170 new_dir.exists() and error "new_domain already exists"
171 WebHandler.removeHandler(old_domain)
172 old_dir.rename_to(new_dir.to_string())
173 WebHandler.removeHandler(old_domain)
174 WebHandler.loadHandler(new_domain)
175 end
176
177 function fns.change_password(domain,old_password,new_password)
178 local site_dir = get_dir(domain,old_password)
179 site_dir or error "domain not found"
180 site_dir.parent().child("password").write(new_password)
181 WebHandler.removeHandler(domain)
182 WebHandler.loadHandler(domain)
183 end
184
185 fns.call = WebHandler.callSite
186
187 Thread.fork(Rpc.serve)