Mercurial Hosting > luan
comparison src/luan/modules/http/jetty/LuanHandler.java @ 1136:d30d400fd43d
add http/jetty
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Mon, 29 Jan 2018 17:50:49 -0700 |
parents | src/luan/modules/http/LuanHandler.java@e15be31cee92 |
children |
comparison
equal
deleted
inserted
replaced
1135:707a5d874f3e | 1136:d30d400fd43d |
---|---|
1 package luan.modules.http.jetty; | |
2 | |
3 import java.io.IOException; | |
4 import java.lang.reflect.Method; | |
5 import java.net.BindException; | |
6 import java.util.concurrent.locks.ReadWriteLock; | |
7 import java.util.concurrent.locks.ReentrantReadWriteLock; | |
8 import javax.servlet.http.HttpServletRequest; | |
9 import javax.servlet.http.HttpServletResponse; | |
10 import org.slf4j.Logger; | |
11 import org.slf4j.LoggerFactory; | |
12 import org.eclipse.jetty.server.Request; | |
13 import org.eclipse.jetty.server.Server; | |
14 import org.eclipse.jetty.server.handler.AbstractHandler; | |
15 import luan.Luan; | |
16 import luan.LuanState; | |
17 import luan.LuanTable; | |
18 import luan.LuanFunction; | |
19 import luan.LuanJavaFunction; | |
20 import luan.LuanCloner; | |
21 import luan.LuanException; | |
22 import luan.modules.PackageLuan; | |
23 | |
24 | |
25 public class LuanHandler extends AbstractHandler { | |
26 private final LuanState luanInit; | |
27 private final Logger logger; | |
28 private String welcomeFile = "index.html"; | |
29 private final ReadWriteLock lock = new ReentrantReadWriteLock(); | |
30 private LuanState luan; | |
31 | |
32 private static final Method resetLuanMethod; | |
33 static { | |
34 try { | |
35 resetLuanMethod = LuanHandler.class.getMethod("reset_luan"); | |
36 } catch(NoSuchMethodException e) { | |
37 throw new RuntimeException(e); | |
38 } | |
39 } | |
40 | |
41 public LuanHandler(LuanState luan,String loggerRoot) { | |
42 this.luanInit = luan; | |
43 if( loggerRoot==null ) | |
44 loggerRoot = ""; | |
45 logger = LoggerFactory.getLogger(loggerRoot+LuanHandler.class.getName()); | |
46 try { | |
47 LuanTable Http = (LuanTable)PackageLuan.require(luanInit,"luan:http/Http.luan"); | |
48 Http.rawPut( "reset_luan", new LuanJavaFunction(resetLuanMethod,this) ); | |
49 } catch(LuanException e) { | |
50 throw new RuntimeException(e); | |
51 } | |
52 } | |
53 | |
54 @Override public void handle(String target,Request baseRequest,HttpServletRequest request,HttpServletResponse response) | |
55 throws IOException | |
56 { | |
57 if( target.endsWith("/") ) | |
58 target += welcomeFile; | |
59 Thread thread = Thread.currentThread(); | |
60 String oldName = thread.getName(); | |
61 thread.setName(request.getHeader("host")+request.getRequestURI()); | |
62 lock.readLock().lock(); | |
63 try { | |
64 if( !HttpServicer.service(luan,request,response,"site:"+target+".luan") ) | |
65 return; | |
66 } catch(LuanException e) { | |
67 //e.printStackTrace(); | |
68 String err = e.getLuanStackTraceString(); | |
69 logger.error(err); | |
70 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,err); | |
71 } finally { | |
72 lock.readLock().unlock(); | |
73 thread.setName(oldName); | |
74 } | |
75 baseRequest.setHandled(true); | |
76 } | |
77 | |
78 public void setWelcomeFile(String welcomeFile) { | |
79 this.welcomeFile = welcomeFile; | |
80 } | |
81 | |
82 @Override protected void doStart() throws Exception { | |
83 // Thread.dumpStack(); | |
84 //System.out.println("qqqqqqqqqqqqqqqqqqqq doStart "+this); | |
85 setLuan(); | |
86 super.doStart(); | |
87 } | |
88 | |
89 @Override protected void doStop() throws Exception { | |
90 synchronized(luan) { | |
91 luan.close(); | |
92 } | |
93 //System.out.println("qqqqqqqqqqqqqqqqqqqq doStop "+this); | |
94 super.doStop(); | |
95 } | |
96 /* | |
97 @Override public void destroy() { | |
98 System.out.println("qqqqqqqqqqqqqqqqqqqq destroy "+this); | |
99 super.destroy(); | |
100 } | |
101 */ | |
102 | |
103 public Object call_rpc(String fnName,Object... args) throws LuanException { | |
104 lock.readLock().lock(); | |
105 try { | |
106 LuanFunction fn; | |
107 LuanState luan = this.luan; | |
108 synchronized(luan) { | |
109 PackageLuan.enableLoad(luan,"luan:Rpc.luan"); | |
110 LuanTable rpc = (LuanTable)PackageLuan.require(luan,"luan:Rpc.luan"); | |
111 LuanTable fns = (LuanTable)rpc.get(luan,"functions"); | |
112 fn = (LuanFunction)fns.get(luan,fnName); | |
113 if( fn == null ) | |
114 throw new LuanException( "function not found: " + fnName ); | |
115 LuanCloner cloner = new LuanCloner(LuanCloner.Type.INCREMENTAL); | |
116 luan = (LuanState)cloner.clone(luan); | |
117 fn = (LuanFunction)cloner.get(fn); | |
118 } | |
119 return fn.call(luan,args); | |
120 } finally { | |
121 lock.readLock().unlock(); | |
122 } | |
123 } | |
124 | |
125 public void reset_luan() { | |
126 new Thread() { | |
127 public void run() { | |
128 lock.writeLock().lock(); | |
129 try { | |
130 synchronized(luan) { | |
131 luan.close(); | |
132 setLuan(); | |
133 } | |
134 } catch(IOException e) { | |
135 logger.error("reset_luan failed",e); | |
136 } finally { | |
137 lock.writeLock().unlock(); | |
138 } | |
139 } | |
140 }.start(); | |
141 } | |
142 | |
143 private void setLuan() { | |
144 LuanCloner cloner = new LuanCloner(LuanCloner.Type.COMPLETE); | |
145 luan = (LuanState)cloner.clone(luanInit); | |
146 try { | |
147 PackageLuan.load(luan,"site:/init.luan"); | |
148 } catch(LuanException e) { | |
149 String err = e.getLuanStackTraceString(); | |
150 logger.error(err); | |
151 } | |
152 } | |
153 | |
154 public Object runLuan(String sourceText,String sourceName) throws LuanException { | |
155 LuanFunction fn = Luan.load(sourceText,sourceName); | |
156 synchronized(luan) { | |
157 LuanCloner cloner = new LuanCloner(LuanCloner.Type.INCREMENTAL); | |
158 LuanState luan = (LuanState)cloner.clone(this.luan); | |
159 return fn.call(luan); | |
160 } | |
161 } | |
162 | |
163 public static void start(Server server) throws Exception { | |
164 try { | |
165 server.start(); | |
166 } catch(BindException e) { | |
167 throw new LuanException(e.toString()); | |
168 } | |
169 } | |
170 | |
171 } |