view 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 source

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);
	}

}