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