1 package org.eclipse.jetty.rewrite.handler;
2
3 import java.io.IOException;
4 import java.util.Collections;
5 import java.util.List;
6 import java.util.concurrent.CopyOnWriteArrayList;
7 import java.util.regex.Matcher;
8 import java.util.regex.Pattern;
9
10 import javax.servlet.ServletException;
11 import javax.servlet.http.HttpServletRequest;
12 import javax.servlet.http.HttpServletResponse;
13
14 import org.eclipse.jetty.server.Request;
15 import org.eclipse.jetty.server.handler.ContextHandler;
16 import org.eclipse.jetty.server.handler.ContextHandler.Context;
17 import org.eclipse.jetty.server.handler.ScopedHandler;
18 import org.eclipse.jetty.util.component.AggregateLifeCycle;
19 import org.eclipse.jetty.util.log.Log;
20 import org.eclipse.jetty.util.log.Logger;
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 public class RegexTargetHandler extends ScopedHandler
36 {
37 private final static Logger LOG = Log.getLogger(RegexTargetHandler.class);
38 public final static String REGEX_MAPPINGS="org.eclipse.jetty.rewrite.handler.REGEX_MAPPINGS";
39 static class RegexMapping
40 {
41 RegexMapping(String regex,String target)
42 {
43 _pattern=Pattern.compile(regex);
44 _target=target;
45 }
46 final Pattern _pattern;
47 final String _target;
48
49 public String toString()
50 {
51 return _pattern+"=="+_target;
52 }
53 }
54
55 final private List<RegexTargetHandler.RegexMapping> _patterns = new CopyOnWriteArrayList<RegexTargetHandler.RegexMapping>();
56
57
58
59
60
61
62 public void addPatternTarget(String pattern,String target)
63 {
64 _patterns.add(new RegexMapping(pattern,target));
65 }
66
67
68 @Override
69 protected void doStart() throws Exception
70 {
71 super.doStart();
72
73 Context context = ContextHandler.getCurrentContext();
74 if (context!=null)
75 {
76 String config=context.getInitParameter(REGEX_MAPPINGS);
77 LOG.debug("{}={}",REGEX_MAPPINGS,config);
78 String[] mappings=config.split("\\s*,\\s*");
79 for (String mapping : mappings)
80 {
81 mapping=mapping.trim();
82 String[] parts=mapping.split("\\s*==\\s*");
83 if (parts.length==2)
84 {
85 String pattern=parts[0];
86 String target=parts[1];
87 addPatternTarget(pattern,target);
88 }
89 else
90 LOG.warn("Bad regex mapping: "+mapping);
91 }
92 }
93 }
94
95
96 @Override
97 public void doScope(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
98 {
99 for (RegexTargetHandler.RegexMapping rm : _patterns)
100 {
101 Matcher m=rm._pattern.matcher(target);
102 if (m.matches())
103 {
104 String new_target = rm._target;
105 final String sp;
106 final String pi;
107
108 if (m.groupCount()==1&&target.endsWith(m.group(1)))
109 {
110 pi=m.group(1);
111 sp=target.substring(0,target.length()-pi.length());
112 }
113 else
114 {
115 sp=target;
116 pi=null;
117 }
118 baseRequest.setServletPath(sp);
119 baseRequest.setPathInfo(pi);
120 baseRequest.setAttribute("org.eclipse.jetty.servlet.REGEX_PATH",target);
121 super.nextScope(new_target,baseRequest,request,response);
122 return;
123 }
124 }
125 super.nextScope(target,baseRequest,request,response);
126 }
127
128
129 @Override
130 public void doHandle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
131 {
132 String path=(String)baseRequest.getAttribute("org.eclipse.jetty.servlet.REGEX_PATH");
133 if (path==null)
134 path=target;
135 else
136 baseRequest.setAttribute("org.eclipse.jetty.servlet.REGEX_PATH",null);
137
138 super.nextHandle(path,baseRequest,request,response);
139 }
140
141
142 public void dump(Appendable out, String indent) throws IOException
143 {
144 AggregateLifeCycle.dumpObject(out,this);
145 AggregateLifeCycle.dump(out,indent,_patterns,Collections.singletonList(getHandler()));
146 }
147
148
149 }