comparison src/luan/host/WebHandler.java @ 1315:5763597ca5c0

add DomainHandler
author Franklin Schmidt <fschmidt@gmail.com>
date Wed, 30 Jan 2019 01:21:49 -0700
parents 51a1987b55a3
children 307e76ccd0d6
comparison
equal deleted inserted replaced
1314:51a1987b55a3 1315:5763597ca5c0
1 package luan.host; 1 package luan.host;
2 2
3 import java.io.File; 3 import java.io.File;
4 import java.io.IOException;
5 import java.lang.ref.Reference;
6 import java.lang.ref.SoftReference;
7 //import java.lang.ref.WeakReference;
8 import java.lang.ref.ReferenceQueue;
9 import java.util.Map;
10 import java.util.HashMap;
11 import org.slf4j.Logger; 4 import org.slf4j.Logger;
12 import org.slf4j.LoggerFactory; 5 import org.slf4j.LoggerFactory;
13 import luan.webserver.Handler; 6 import luan.webserver.Handler;
14 import luan.webserver.Server;
15 import luan.webserver.Request; 7 import luan.webserver.Request;
16 import luan.webserver.Response; 8 import luan.webserver.Response;
17 import luan.webserver.handlers.IndexHandler; 9 import luan.webserver.handlers.DomainHandler;
18 import luan.webserver.handlers.ListHandler;
19 import luan.Luan;
20 import luan.LuanState; 10 import luan.LuanState;
21 import luan.LuanException; 11 import luan.LuanException;
22 import luan.LuanTable; 12 import luan.LuanTable;
23 import luan.LuanFunction;
24 import luan.modules.IoLuan; 13 import luan.modules.IoLuan;
25 import luan.modules.JavaLuan; 14 import luan.modules.JavaLuan;
26 import luan.modules.PackageLuan;
27 import luan.modules.http.LuanHandler; 15 import luan.modules.http.LuanHandler;
28 16
29 17
30 public class WebHandler implements Handler { 18 public class WebHandler implements Handler {
31 private static final Logger logger = LoggerFactory.getLogger(WebHandler.class); 19 private static final Logger logger = LoggerFactory.getLogger(WebHandler.class);
32 20
33 private static class LuanRef { 21 private static final DomainHandler.Factory factory = new DomainHandler.Factory() {
34 private final Handler handler; 22 public Handler newHandler(String domain) {
35 private final LuanHandler luanHandler; 23 File dir = new File(sitesDir,domain);
24 if( !dir.exists() /* && !recover(dir) */ )
25 return null;
26 String dirStr = dir.toString();
36 27
37 private LuanRef(Handler handler,LuanHandler luanHandler) { 28 String logDir = dirStr + "/site/private/local/logs/web";
38 this.handler = handler; 29 new File(logDir).mkdirs();
39 this.luanHandler = luanHandler; 30
31 LuanState luan = new LuanState();
32 LuanTable init = initLuan(luan,dirStr,domain);
33 String loggerRoot = (String)init.rawGet("logger_root");
34 return new LuanHandler(luan,loggerRoot);
40 } 35 }
41 } 36 };
42
43 private static final ReferenceQueue<LuanRef> queue = new ReferenceQueue<LuanRef>();
44
45 private static class MyReference extends SoftReference<LuanRef> {
46 private LuanHandler luanHandler;
47
48 private MyReference(LuanRef lr) {
49 super(lr,queue);
50 this.luanHandler = lr.luanHandler;
51 }
52 }
53
54 private static void sweep() {
55 while(true) {
56 MyReference ref = (MyReference)queue.poll();
57 if( ref == null )
58 return;
59 //logger.info("sweep");
60 ref.luanHandler.close();
61 ref.luanHandler = null;
62 }
63 }
64
65 37
66 public static String allowJavaFileName = "allow_java"; // change for security 38 public static String allowJavaFileName = "allow_java"; // change for security
67 private static final Map<String,MyReference> siteMap = new HashMap<String,MyReference>(); 39 private static final DomainHandler domainHandler = new DomainHandler(factory);
68 private static String sitesDir = null; 40 private static String sitesDir = null;
69 41
70 public static boolean isServing() { 42 public static boolean isServing() {
71 return sitesDir != null; 43 return sitesDir != null;
72 } 44 }
77 if( !new File(dir).exists() ) 49 if( !new File(dir).exists() )
78 throw new RuntimeException(); 50 throw new RuntimeException();
79 sitesDir = dir; 51 sitesDir = dir;
80 } 52 }
81 53
82 public Response handle(Request request) { 54 @Override public Response handle(Request request) {
83 String host = (String)request.headers.get("host"); 55 return domainHandler.handle(request);
84 int i = host.indexOf(':');
85 String domain = i == -1 ? host : host.substring(0,i);
86 // System.out.println("handle "+domain);
87 LuanRef lr = getSite(domain);
88 if( lr == null )
89 return null;
90 return lr.handler.handle(request);
91 } 56 }
92 57
93 public static Object runLuan(String domain,String sourceText,String sourceName) throws LuanException { 58 public static Object runLuan(String domain,String sourceText,String sourceName) throws LuanException {
94 LuanRef lr = getSite(domain); 59 LuanHandler luanHandler = (LuanHandler)domainHandler.getHandler(domain);
95 return lr.luanHandler.runLuan(sourceText,sourceName); 60 return luanHandler.runLuan(sourceText,sourceName);
96 } 61 }
97 62
98 public static Object callSite(String domain,String fnName,Object... args) throws LuanException { 63 public static Object callSite(String domain,String fnName,Object... args) throws LuanException {
99 LuanRef lr = getSite(domain); 64 LuanHandler luanHandler = (LuanHandler)domainHandler.getHandler(domain);
100 return lr.luanHandler.call_rpc(fnName,args); 65 return luanHandler.call_rpc(fnName,args);
101 } 66 }
102 67
103 private static LuanRef getSite(String domain) {
104 synchronized(siteMap) {
105 Reference<LuanRef> ref = siteMap.get(domain);
106 LuanRef lr = ref==null ? null : ref.get();
107 if( lr == null ) {
108 //if(ref!=null) logger.info("gc "+domain);
109 if( sitesDir==null )
110 throw new NullPointerException("sitesDir");
111 File dir = new File(sitesDir,domain);
112 if( !dir.exists() /* && !recover(dir) */ )
113 return null;
114 sweep();
115 lr = newSite(dir.toString(),domain);
116 siteMap.put(domain,new MyReference(lr));
117 }
118 return lr;
119 }
120 }
121 /* 68 /*
122 private static boolean recover(File dir) { 69 private static boolean recover(File dir) {
123 File backups = new File(dir.getParentFile().getParentFile(),"backups"); 70 File backups = new File(dir.getParentFile().getParentFile(),"backups");
124 if( !backups.exists() ) 71 if( !backups.exists() )
125 return false; 72 return false;
155 IoLuan.setSecurity( luan, ioSecurity(dir) ); 102 IoLuan.setSecurity( luan, ioSecurity(dir) );
156 } 103 }
157 return init; 104 return init;
158 } 105 }
159 106
160 private static LuanRef newSite(String dir,String domain) { 107 public static void removeHandler(String domain) {
161 LuanState luan = new LuanState(); 108 domainHandler.removeHandler(domain);
162 LuanTable init = initLuan(luan,dir,domain);
163
164 String loggerRoot = (String)init.rawGet("logger_root");
165 LuanHandler luanHandler = new LuanHandler(luan,loggerRoot);
166
167 Handler handler = luanHandler;
168 handler = new IndexHandler(handler);
169
170 String logDir = dir + "/site/private/local/logs/web";
171 new File(logDir).mkdirs();
172
173 return new LuanRef(handler,luanHandler);
174 }
175
176 public static void removeHandler(String domain) throws Exception {
177 synchronized(siteMap) {
178 Reference<LuanRef> ref = siteMap.remove(domain);
179 LuanRef lr = ref==null ? null : ref.get();
180 if( lr != null ) {
181 lr.luanHandler.close();
182 }
183 }
184 } 109 }
185 110
186 public static void loadHandler(String domain) { 111 public static void loadHandler(String domain) {
187 getSite(domain); 112 domainHandler.getHandler(domain);
188 } 113 }
189 114
190 private static final IoLuan.Security ioSecurity(String dir) { 115 private static final IoLuan.Security ioSecurity(String dir) {
191 final String siteUri = "file:" + dir + "/site"; 116 final String siteUri = "file:" + dir + "/site";
192 return new IoLuan.Security() { 117 return new IoLuan.Security() {