Mercurial Hosting > luan
annotate src/goodjava/webserver/handlers/DomainHandler.java @ 2022:969291201e12
ping lucene backups
| author | Franklin Schmidt <fschmidt@gmail.com> | 
|---|---|
| date | Mon, 20 Oct 2025 17:25:47 -0600 | 
| parents | 64b7076c635c | 
| children | 
| rev | line source | 
|---|---|
| 1402 
27efb1fcbcb5
move luan.lib to goodjava
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1401diff
changeset | 1 package goodjava.webserver.handlers; | 
| 1315 | 2 | 
| 3 import java.io.Closeable; | |
| 4 import java.io.IOException; | |
| 5 import java.util.Map; | |
| 1443 | 6 import java.util.Set; | 
| 1601 | 7 import java.util.Collections; | 
| 1443 | 8 import java.util.Timer; | 
| 9 import java.util.TimerTask; | |
| 10 import java.util.concurrent.ConcurrentHashMap; | |
| 1498 | 11 import goodjava.util.SoftCacheMap; | 
| 1766 | 12 import goodjava.util.WeakCacheMap; | 
| 1402 
27efb1fcbcb5
move luan.lib to goodjava
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1401diff
changeset | 13 import goodjava.logging.Logger; | 
| 
27efb1fcbcb5
move luan.lib to goodjava
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1401diff
changeset | 14 import goodjava.logging.LoggerFactory; | 
| 
27efb1fcbcb5
move luan.lib to goodjava
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1401diff
changeset | 15 import goodjava.webserver.Handler; | 
| 
27efb1fcbcb5
move luan.lib to goodjava
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1401diff
changeset | 16 import goodjava.webserver.Request; | 
| 
27efb1fcbcb5
move luan.lib to goodjava
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1401diff
changeset | 17 import goodjava.webserver.Response; | 
| 1315 | 18 | 
| 19 | |
| 20 public final class DomainHandler implements Handler { | |
| 21 private static final Logger logger = LoggerFactory.getLogger(DomainHandler.class); | |
| 22 | |
| 23 public interface Factory { | |
| 24 public Handler newHandler(String domain); | |
| 25 } | |
| 26 | |
| 1850 
64b7076c635c
better link_to_domain
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1769diff
changeset | 27 public interface HandlerCloseable extends Closeable { | 
| 
64b7076c635c
better link_to_domain
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1769diff
changeset | 28 public boolean isClosed(); | 
| 
64b7076c635c
better link_to_domain
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1769diff
changeset | 29 } | 
| 
64b7076c635c
better link_to_domain
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1769diff
changeset | 30 | 
| 1443 | 31 private static class MyTask extends TimerTask { | 
| 32 private final Set<Handler> dontGc; | |
| 33 | |
| 34 MyTask(Set<Handler> dontGc) { | |
| 35 this.dontGc = dontGc; | |
| 36 } | |
| 37 | |
| 38 public void run() { | |
| 39 dontGc.clear(); | |
| 40 logger.info("dontGc.clear()"); | |
| 1315 | 41 } | 
| 42 } | |
| 43 | |
| 1443 | 44 private static final long HOUR = 1000L*60*60; | 
| 1601 | 45 private final Map<String,Handler> map = Collections.synchronizedMap(new SoftCacheMap<String,Handler>()); | 
| 1443 | 46 private final Set<Handler> dontGc = ConcurrentHashMap.newKeySet(); | 
| 47 private final Timer timer = new Timer(); | |
| 1315 | 48 | 
| 49 private final Factory factory; | |
| 50 | |
| 51 public DomainHandler(Factory factory) { | |
| 52 this.factory = factory; | |
| 1443 | 53 timer.schedule(new MyTask(dontGc),HOUR,HOUR); | 
| 54 } | |
| 55 | |
| 56 protected void finalize() throws Throwable { | |
| 57 timer.cancel(); | |
| 1315 | 58 } | 
| 59 | |
| 60 public Response handle(Request request) { | |
| 61 String host = (String)request.headers.get("host"); | |
| 1331 | 62 if( host == null ) | 
| 63 return null; | |
| 1315 | 64 int i = host.indexOf(':'); | 
| 65 String domain = i == -1 ? host : host.substring(0,i); | |
| 66 Handler handler = getHandler(domain); | |
| 1443 | 67 if( handler==null ) | 
| 68 return null; | |
| 69 dontGc.add(handler); | |
| 70 return handler.handle(request); | |
| 1315 | 71 } | 
| 72 | |
| 73 public Handler getHandler(String domain) { | |
| 1601 | 74 domain = domain.toLowerCase().intern(); | 
| 75 synchronized(domain) { | |
| 1498 | 76 Handler handler = map.get(domain); | 
| 1850 
64b7076c635c
better link_to_domain
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1769diff
changeset | 77 if( handler instanceof HandlerCloseable && ((HandlerCloseable)handler).isClosed() ) { | 
| 
64b7076c635c
better link_to_domain
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1769diff
changeset | 78 removeHandler(domain); | 
| 
64b7076c635c
better link_to_domain
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1769diff
changeset | 79 handler = null; | 
| 
64b7076c635c
better link_to_domain
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1769diff
changeset | 80 } | 
| 1401 | 81 if( handler == null ) { | 
| 82 //if(ref!=null) logger.info("gc "+domain); | |
| 83 handler = factory.newHandler(domain); | |
| 84 if( handler == null ) | |
| 85 return null; | |
| 1498 | 86 map.put(domain,handler); | 
| 1401 | 87 } | 
| 88 return handler; | |
| 89 } | |
| 1315 | 90 } | 
| 91 | |
| 92 public void removeHandler(String domain) { | |
| 1405 | 93 //logger.info("removeHandler "+domain); | 
| 1601 | 94 domain = domain.toLowerCase().intern(); | 
| 95 synchronized(domain) { | |
| 1498 | 96 Handler handler = map.remove(domain); | 
| 1401 | 97 if( handler != null ) { | 
| 98 close(handler); | |
| 1769 | 99 dontGc.remove(handler); | 
| 1315 | 100 } | 
| 101 } | |
| 102 } | |
| 103 | |
| 1443 | 104 private static void close(Handler handler) { | 
| 105 if( handler instanceof Closeable ) { | |
| 106 try { | |
| 107 ((Closeable)handler).close(); | |
| 108 } catch(IOException e) { | |
| 109 logger.error(handler.toString(),e); | |
| 110 } | |
| 111 } | |
| 112 } | |
| 113 | |
| 1315 | 114 } | 
