Mercurial Hosting > luan
view src/luan/webserver/handlers/DomainHandler.java @ 1331:02fe660e7748
minor fix
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Mon, 11 Feb 2019 02:17:41 -0700 |
parents | 5763597ca5c0 |
children | 8b61c8c4e07a |
line wrap: on
line source
package luan.webserver.handlers; import java.io.Closeable; import java.io.IOException; import java.lang.ref.Reference; import java.lang.ref.SoftReference; import java.lang.ref.ReferenceQueue; import java.util.Map; import java.util.HashMap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import luan.webserver.Handler; import luan.webserver.Request; import luan.webserver.Response; public final class DomainHandler implements Handler { private static final Logger logger = LoggerFactory.getLogger(DomainHandler.class); public interface Factory { public Handler newHandler(String domain); } private static class Ref { private final Handler handler; private Ref(Handler handler) { this.handler = handler; } } private final ReferenceQueue<Ref> queue = new ReferenceQueue<Ref>(); private class MyReference extends SoftReference<Ref> { private Handler handler; private MyReference(Ref r) { super(r,queue); this.handler = r.handler; } } private static void close(Handler handler) { if( handler instanceof Closeable ) { try { ((Closeable)handler).close(); } catch(IOException e) { logger.error(handler.toString(),e); } } } private void sweep() { while(true) { MyReference ref = (MyReference)queue.poll(); if( ref == null ) return; //logger.info("sweep"); close(ref.handler); ref.handler = null; } } private final Map<String,MyReference> map = new HashMap<String,MyReference>(); private final Factory factory; public DomainHandler(Factory factory) { this.factory = factory; } public Response handle(Request request) { String host = (String)request.headers.get("host"); if( host == null ) return null; int i = host.indexOf(':'); String domain = i == -1 ? host : host.substring(0,i); Handler handler = getHandler(domain); return handler==null ? null : handler.handle(request); } public Handler getHandler(String domain) { Ref r = getRef(domain); return r==null ? null : r.handler; } public void removeHandler(String domain) { domain = domain.toLowerCase(); synchronized(map) { Reference<Ref> ref = map.remove(domain); Ref r = ref==null ? null : ref.get(); if( r != null ) { close(r.handler); } } } private Ref getRef(String domain) { domain = domain.toLowerCase(); synchronized(map) { Reference<Ref> ref = map.get(domain); Ref r = ref==null ? null : ref.get(); if( r == null ) { //if(ref!=null) logger.info("gc "+domain); sweep(); Handler handler = factory.newHandler(domain); if( handler == null ) return null; r = new Ref(handler); map.put(domain,new MyReference(r)); } return r; } } }