comparison web/src/luan/modules/web/HttpLuan.java @ 170:7c792a328a83

add web component git-svn-id: https://luan-java.googlecode.com/svn/trunk@171 21e917c8-12df-6dd8-5cb6-c86387c605b9
author fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
date Sun, 22 Jun 2014 05:20:30 +0000
parents src/luan/modules/web/HttpLuan.java@9169581dc8fc
children 58c6ca5d4524
comparison
equal deleted inserted replaced
169:9169581dc8fc 170:7c792a328a83
1 package luan.modules.web;
2
3 import java.io.PrintWriter;
4 import java.io.IOException;
5 import java.util.Map;
6 import java.util.Set;
7 import java.util.Arrays;
8 import java.util.Enumeration;
9 import javax.servlet.ServletOutputStream;
10 import javax.servlet.http.Cookie;
11 import javax.servlet.http.HttpServletRequest;
12 import javax.servlet.http.HttpServletResponse;
13 import javax.servlet.http.HttpSession;
14 import luan.Luan;
15 import luan.LuanState;
16 import luan.LuanFunction;
17 import luan.LuanElement;
18 import luan.LuanException;
19 import luan.LuanTable;
20 import luan.LuanJavaFunction;
21 import luan.LuanExitException;
22 import luan.DeepCloner;
23 import luan.modules.PackageLuan;
24 import luan.modules.IoLuan;
25
26
27 public final class HttpLuan {
28
29 public static final LuanFunction LOADER = new LuanFunction() {
30 @Override public Object call(LuanState luan,Object[] args) {
31 return new LuanTable(); // starts empty
32 }
33 };
34
35 public static void service(LuanState luan,HttpServletRequest request,HttpServletResponse response,String modName)
36 throws LuanException
37 {
38 LuanFunction fn;
39 synchronized(luan) {
40 Object mod = PackageLuan.require(luan,modName);
41 if( !(mod instanceof LuanTable) )
42 throw luan.exception( "module '"+modName+"' must return a table" );
43 LuanTable tbl = (LuanTable)mod;
44 if( Luan.toBoolean( tbl.get("per_session") ) ) {
45 HttpSession session = request.getSession();
46 LuanState sessionLuan = (LuanState)session.getValue("luan");
47 if( sessionLuan!=null ) {
48 luan = sessionLuan;
49 } else {
50 DeepCloner cloner = new DeepCloner();
51 luan = cloner.deepClone(luan);
52 session.putValue("luan",luan);
53 }
54 tbl = (LuanTable)PackageLuan.require(luan,modName);
55 fn = (LuanFunction)tbl.get("page");
56 } else {
57 fn = (LuanFunction)tbl.get("page");
58 if( fn == null )
59 throw luan.exception( "function 'page' is not defined" );
60 DeepCloner cloner = new DeepCloner();
61 luan = cloner.deepClone(luan);
62 fn = cloner.get(fn);
63 }
64 }
65
66 LuanTable module = (LuanTable)luan.loaded().get("Http");
67 if( module == null )
68 throw luan.exception( "module 'Http' not defined" );
69 HttpLuan lib = new HttpLuan(request,response);
70 try {
71 module.put( "request", lib.requestTable() );
72 module.put( "response", lib.responseTable() );
73 /*
74 module.put( "write", new LuanJavaFunction(
75 HttpLuan.class.getMethod( "text_write", LuanState.class, new Object[0].getClass() ), lib
76 ) );
77 */
78 } catch(NoSuchMethodException e) {
79 throw new RuntimeException(e);
80 }
81
82 luan.call(fn,"<http>");
83 }
84
85
86
87 private final HttpServletRequest request;
88 private final HttpServletResponse response;
89 // private PrintWriter writer = null;
90 // private ServletOutputStream sos = null;
91
92 private HttpLuan(HttpServletRequest request,HttpServletResponse response) {
93 this.request = request;
94 this.response = response;
95 }
96
97 private LuanTable requestTable() throws NoSuchMethodException {
98 LuanTable req = new LuanTable();
99 req.put("java",request);
100 req.put( "get_attribute", new LuanJavaFunction(HttpServletRequest.class.getMethod("getAttribute",String.class),request) );
101 req.put( "set_attribute", new LuanJavaFunction(HttpServletRequest.class.getMethod("setAttribute",String.class,Object.class),request) );
102 req.put( "get_parameter", new LuanJavaFunction(HttpServletRequest.class.getMethod("getParameter",String.class),request) );
103 req.put( "get_parameter_values", new LuanJavaFunction(HttpServletRequest.class.getMethod("getParameterValues",String.class),request) );
104 req.put( "get_header", new LuanJavaFunction(HttpServletRequest.class.getMethod("getHeader",String.class),request) );
105 add( req, "get_cookie_value", String.class );
106 req.put( "method", new LuanJavaFunction(HttpServletRequest.class.getMethod("getMethod"),request) );
107 req.put( "servlet_path", new LuanJavaFunction(HttpServletRequest.class.getMethod("getServletPath"),request) );
108 req.put( "server_name", new LuanJavaFunction(HttpServletRequest.class.getMethod("getServerName"),request) );
109 add( req, "current_url" );
110 req.put( "remote_address", new LuanJavaFunction(HttpServletRequest.class.getMethod("getRemoteAddr"),request) );
111 add( req, "get_session_attribute", String.class );
112 add( req, "set_session_attribute", String.class, Object.class );
113 return req;
114 }
115
116 private LuanTable responseTable() throws NoSuchMethodException {
117 LuanTable resp = new LuanTable();
118 resp.put("java",response);
119 add( resp, "send_redirect", String.class );
120 add( resp, "send_error", Integer.TYPE, String.class );
121 resp.put( "contains_header", new LuanJavaFunction(HttpServletResponse.class.getMethod("containsHeader",String.class),response) );
122 resp.put( "set_header", new LuanJavaFunction(HttpServletResponse.class.getMethod("setHeader",String.class,String.class),response) );
123 add( resp, "set_cookie", String.class, String.class, Boolean.TYPE, String.class );
124 add( resp, "remove_cookie", String.class, String.class );
125 resp.put( "set_content_type", new LuanJavaFunction(HttpServletResponse.class.getMethod("setContentType",String.class),response) );
126 add( resp, "text_writer" );
127 return resp;
128 }
129
130 private void add(LuanTable t,String method,Class<?>... parameterTypes) throws NoSuchMethodException {
131 t.put( method, new LuanJavaFunction(HttpLuan.class.getMethod(method,parameterTypes),this) );
132 }
133 /*
134 public void text_write(LuanState luan,Object... args) throws LuanException, IOException {
135 if( writer == null )
136 writer = response.getWriter();
137 for( Object obj : args ) {
138 writer.print( luan.toString(obj) );
139 }
140 }
141 */
142 public LuanTable text_writer() throws IOException {
143 return IoLuan.textWriter(response.getWriter());
144 }
145
146 public String get_cookie_value(String name) {
147 return getCookieValue(request, name);
148 }
149
150 public String current_url() {
151 return getCurrentURL(request);
152 }
153
154 public void send_redirect(String redirectUrl)
155 throws IOException
156 {
157 response.sendRedirect(redirectUrl);
158 throw new LuanExitException();
159 }
160
161 public void send_error(int code,String text)
162 throws IOException
163 {
164 response.sendError(code, text);
165 throw new LuanExitException();
166 }
167
168 public void set_cookie(String name,String value,boolean isPersistent, String domain) {
169 setCookie(request,response,name,value,isPersistent,domain);
170 }
171
172 public void remove_cookie(String name, String domain) {
173 removeCookie(request,response,name,domain);
174 }
175
176 public Object get_session_attribute(String name) {
177 return request.getSession().getAttribute(name);
178 }
179
180 public void set_session_attribute(String name,Object value) {
181 request.getSession().setAttribute(name,value);
182 }
183
184
185 // static utils
186
187 public static String getQueryString(HttpServletRequest request) {
188 return getQueryString(request,0);
189 }
190
191 public static String getQueryString(HttpServletRequest request,int maxValueLen) {
192 String method = request.getMethod();
193 if( method.equals("GET") )
194 return request.getQueryString();
195 if( !method.equals("POST") && !method.equals("HEAD") )
196 throw new RuntimeException(method);
197 Enumeration en = request.getParameterNames();
198 StringBuilder queryBuf = new StringBuilder();
199 if( !en.hasMoreElements() )
200 return null;
201 do {
202 String param = (String)en.nextElement();
203 String value = request.getParameter(param);
204 if( maxValueLen > 0 ) {
205 int len = value.length();
206 if( len > maxValueLen )
207 value = value.substring(0,maxValueLen) + "..." + (len-maxValueLen);
208 }
209 queryBuf.append(param);
210 queryBuf.append('=');
211 queryBuf.append(value);
212 queryBuf.append('&');
213 } while( en.hasMoreElements() );
214 queryBuf.deleteCharAt(queryBuf.length() - 1);
215 return queryBuf.toString();
216 }
217
218 public static String getCurrentURL(HttpServletRequest request) {
219 return getCurrentURL(request,0);
220 }
221
222 public static String getCurrentURL(HttpServletRequest request,int maxValueLen) {
223 // StringBuffer buf = HttpUtils.getRequestURL(request);
224 StringBuffer buf = request.getRequestURL();
225 String qStr = getQueryString(request,maxValueLen);
226 if(qStr != null && qStr.length() > 0) {
227 buf.append('?');
228 buf.append(qStr);
229 }
230 return buf.toString();
231 }
232
233 private static String escape(String value) {
234 return value.replaceAll(";", "%3B");
235 }
236
237 private static String unescape(String value) {
238 return value.replaceAll("%3B", ";");
239 }
240
241 private static Cookie getCookie(HttpServletRequest request,String name) {
242 Cookie[] cookies = request.getCookies();
243 if( cookies == null )
244 return null;
245 for (Cookie cookie : cookies) {
246 if (cookie.getName().equals(name))
247 return cookie;
248 }
249 return null;
250 }
251
252 public static String getCookieValue(HttpServletRequest request,String name) {
253 Cookie cookie = getCookie(request,name);
254 return cookie==null ? null : unescape(cookie.getValue());
255 }
256
257 public static void setCookie(HttpServletRequest request,HttpServletResponse response,String name,String value,boolean isPersistent, String domain) {
258 Cookie cookie = getCookie(request,name);
259 if( cookie==null || !cookie.getValue().equals(value) ) {
260 cookie = new Cookie(name, escape(value));
261 cookie.setPath("/");
262 if (domain != null && domain.length() > 0)
263 cookie.setDomain(domain);
264 if( isPersistent )
265 cookie.setMaxAge(10000000);
266 response.addCookie(cookie);
267 }
268 }
269
270 public static void removeCookie(HttpServletRequest request,
271 HttpServletResponse response,
272 String name,
273 String domain
274
275 ) {
276 Cookie cookie = getCookie(request, name);
277 if(cookie != null) {
278 Cookie delCookie = new Cookie(name, "delete");
279 delCookie.setPath("/");
280 delCookie.setMaxAge(0);
281 if (domain != null && domain.length() > 0)
282 delCookie.setDomain(domain);
283 response.addCookie(delCookie);
284 }
285 }
286
287 }