Mercurial Hosting > luan
comparison src/luan/webserver/handlers/DomainHandler.java @ 1315:5763597ca5c0
add DomainHandler
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Wed, 30 Jan 2019 01:21:49 -0700 |
parents | |
children | 02fe660e7748 |
comparison
equal
deleted
inserted
replaced
1314:51a1987b55a3 | 1315:5763597ca5c0 |
---|---|
1 package luan.webserver.handlers; | |
2 | |
3 import java.io.Closeable; | |
4 import java.io.IOException; | |
5 import java.lang.ref.Reference; | |
6 import java.lang.ref.SoftReference; | |
7 import java.lang.ref.ReferenceQueue; | |
8 import java.util.Map; | |
9 import java.util.HashMap; | |
10 import org.slf4j.Logger; | |
11 import org.slf4j.LoggerFactory; | |
12 import luan.webserver.Handler; | |
13 import luan.webserver.Request; | |
14 import luan.webserver.Response; | |
15 | |
16 | |
17 public final class DomainHandler implements Handler { | |
18 private static final Logger logger = LoggerFactory.getLogger(DomainHandler.class); | |
19 | |
20 public interface Factory { | |
21 public Handler newHandler(String domain); | |
22 } | |
23 | |
24 private static class Ref { | |
25 private final Handler handler; | |
26 | |
27 private Ref(Handler handler) { | |
28 this.handler = handler; | |
29 } | |
30 } | |
31 | |
32 private final ReferenceQueue<Ref> queue = new ReferenceQueue<Ref>(); | |
33 | |
34 private class MyReference extends SoftReference<Ref> { | |
35 private Handler handler; | |
36 | |
37 private MyReference(Ref r) { | |
38 super(r,queue); | |
39 this.handler = r.handler; | |
40 } | |
41 } | |
42 | |
43 private static void close(Handler handler) { | |
44 if( handler instanceof Closeable ) { | |
45 try { | |
46 ((Closeable)handler).close(); | |
47 } catch(IOException e) { | |
48 logger.error(handler.toString(),e); | |
49 } | |
50 } | |
51 } | |
52 | |
53 private void sweep() { | |
54 while(true) { | |
55 MyReference ref = (MyReference)queue.poll(); | |
56 if( ref == null ) | |
57 return; | |
58 //logger.info("sweep"); | |
59 close(ref.handler); | |
60 ref.handler = null; | |
61 } | |
62 } | |
63 | |
64 private final Map<String,MyReference> map = new HashMap<String,MyReference>(); | |
65 | |
66 private final Factory factory; | |
67 | |
68 public DomainHandler(Factory factory) { | |
69 this.factory = factory; | |
70 } | |
71 | |
72 public Response handle(Request request) { | |
73 String host = (String)request.headers.get("host"); | |
74 int i = host.indexOf(':'); | |
75 String domain = i == -1 ? host : host.substring(0,i); | |
76 Handler handler = getHandler(domain); | |
77 return handler==null ? null : handler.handle(request); | |
78 } | |
79 | |
80 public Handler getHandler(String domain) { | |
81 Ref r = getRef(domain); | |
82 return r==null ? null : r.handler; | |
83 } | |
84 | |
85 public void removeHandler(String domain) { | |
86 domain = domain.toLowerCase(); | |
87 synchronized(map) { | |
88 Reference<Ref> ref = map.remove(domain); | |
89 Ref r = ref==null ? null : ref.get(); | |
90 if( r != null ) { | |
91 close(r.handler); | |
92 } | |
93 } | |
94 } | |
95 | |
96 private Ref getRef(String domain) { | |
97 domain = domain.toLowerCase(); | |
98 synchronized(map) { | |
99 Reference<Ref> ref = map.get(domain); | |
100 Ref r = ref==null ? null : ref.get(); | |
101 if( r == null ) { | |
102 //if(ref!=null) logger.info("gc "+domain); | |
103 sweep(); | |
104 Handler handler = factory.newHandler(domain); | |
105 if( handler == null ) | |
106 return null; | |
107 r = new Ref(handler); | |
108 map.put(domain,new MyReference(r)); | |
109 } | |
110 return r; | |
111 } | |
112 } | |
113 | |
114 } |