diff src/luan/modules/http/impl/HttpServicer.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/HttpServicer.java@3ef883468fd0
children fef8f0742da9
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/luan/modules/http/impl/HttpServicer.java	Mon Feb 05 22:33:59 2018 -0700
@@ -0,0 +1,98 @@
+package luan.modules.http.impl;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.util.Map;
+import java.util.HashMap;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import luan.webserver.Request;
+import luan.webserver.Response;
+import luan.webserver.Status;
+import luan.Luan;
+import luan.LuanState;
+import luan.LuanFunction;
+import luan.LuanException;
+import luan.LuanTable;
+import luan.LuanCloner;
+import luan.modules.PackageLuan;
+
+
+public final class HttpServicer {
+	private static final Logger logger = LoggerFactory.getLogger(HttpServicer.class);
+
+	public static Response service(LuanState luan,Request request)
+		throws LuanException
+	{
+		if( request.path.endsWith("/") )
+			return null;
+		LuanFunction fn;
+		synchronized(luan) {
+			String modName = "site:" + request.path +".luan";
+			PackageLuan.enableLoad(luan,"luan:http/Http.luan",modName);
+			LuanTable module = (LuanTable)PackageLuan.require(luan,"luan:http/Http.luan");
+			Object mod = PackageLuan.load(luan,modName);
+			if( mod.equals(Boolean.FALSE) )
+				return null;
+			if( !(mod instanceof LuanFunction) )
+				throw new LuanException( "module '"+modName+"' must return a function" );
+			LuanCloner cloner = new LuanCloner(LuanCloner.Type.INCREMENTAL);
+			luan = (LuanState)cloner.clone(luan);
+			fn = (LuanFunction)cloner.get(mod);
+		}
+
+		LuanTable module = (LuanTable)PackageLuan.require(luan,"luan:http/Http.luan");
+
+		// request
+		LuanFunction newRequestFn = (LuanFunction)module.rawGet("new_request");
+		newRequestFn.call( luan, new Object[]{request} );
+
+		// response
+		Response response = new Response();
+		LuanFunction newResponseFn = (LuanFunction)module.rawGet("new_response");
+		LuanTable responseTbl = (LuanTable)newResponseFn.call( luan, new Object[]{response} );
+
+		fn.call(luan);
+
+		response.status = Status.getStatus( Luan.asInteger(responseTbl.rawGet("status")) );
+		LuanTable headersTbl = (LuanTable)responseTbl.rawGet("headers");
+		if( !headersTbl.rawIsEmpty() ) {
+			Map headers = (Map)Luan.toJava(headersTbl);
+			for( Object obj : headers.entrySet() ) {
+				Map.Entry entry = (Map.Entry)obj;
+				String name = (String)entry.getKey();
+				Object value = entry.getValue();
+				response.headers.put(name,value);
+			}
+		}
+		Closeable writer = (Closeable)responseTbl.rawGet("writer");
+		if( writer != null ) {
+			try {
+				((Closeable)writer).close();
+			} catch(IOException e) {
+				throw new RuntimeException(e);
+			}
+		}
+
+		return response;
+	}
+
+	public static void setCookie(LuanState luan,Response response,String name,String value,LuanTable attributesTbl)
+		throws LuanException
+	{
+		Map<String,String> attributes = new HashMap<String,String>();
+		if( attributesTbl != null ) {
+			for( Map.Entry entry : attributesTbl.iterable(luan) ) {
+				String key = (String)entry.getKey();
+				if( !(key instanceof String) )
+					throw new LuanException("cookie attribute name must be string");
+				String val = (String)entry.getValue();
+				if( !(val instanceof String) )
+					throw new LuanException("cookie attribute value must be string");
+				attributes.put(key,val);
+			}
+		}
+		response.setCookie(name,value,attributes);
+	}
+
+}