Mercurial Hosting > luan
comparison src/luan/lib/webserver/handlers/DomainHandler.java @ 1347:643cf1c37723
move webserver to lib and bug fixes
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Mon, 25 Feb 2019 13:02:33 -0700 |
parents | src/luan/webserver/handlers/DomainHandler.java@8b61c8c4e07a |
children | 221eedb0f54e |
comparison
equal
deleted
inserted
replaced
1346:efd1c6380f2c | 1347:643cf1c37723 |
---|---|
1 package luan.lib.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 luan.lib.logging.Logger; | |
11 import luan.lib.logging.LoggerFactory; | |
12 import luan.lib.webserver.Handler; | |
13 import luan.lib.webserver.Request; | |
14 import luan.lib.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 if( host == null ) | |
75 return null; | |
76 int i = host.indexOf(':'); | |
77 String domain = i == -1 ? host : host.substring(0,i); | |
78 Handler handler = getHandler(domain); | |
79 return handler==null ? null : handler.handle(request); | |
80 } | |
81 | |
82 public Handler getHandler(String domain) { | |
83 Ref r = getRef(domain); | |
84 return r==null ? null : r.handler; | |
85 } | |
86 | |
87 public void removeHandler(String domain) { | |
88 domain = domain.toLowerCase(); | |
89 synchronized(map) { | |
90 Reference<Ref> ref = map.remove(domain); | |
91 Ref r = ref==null ? null : ref.get(); | |
92 if( r != null ) { | |
93 close(r.handler); | |
94 } | |
95 } | |
96 } | |
97 | |
98 private Ref getRef(String domain) { | |
99 domain = domain.toLowerCase(); | |
100 synchronized(map) { | |
101 Reference<Ref> ref = map.get(domain); | |
102 Ref r = ref==null ? null : ref.get(); | |
103 if( r == null ) { | |
104 //if(ref!=null) logger.info("gc "+domain); | |
105 sweep(); | |
106 Handler handler = factory.newHandler(domain); | |
107 if( handler == null ) | |
108 return null; | |
109 r = new Ref(handler); | |
110 map.put(domain,new MyReference(r)); | |
111 } | |
112 return r; | |
113 } | |
114 } | |
115 | |
116 } |