]> WPIA git - gigi.git/blob - lib/jetty/org/eclipse/jetty/http/pathmap/RegexPathSpec.java
Merge "Update notes about password security"
[gigi.git] / lib / jetty / org / eclipse / jetty / http / pathmap / RegexPathSpec.java
1 //
2 //  ========================================================================
3 //  Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
4 //  ------------------------------------------------------------------------
5 //  All rights reserved. This program and the accompanying materials
6 //  are made available under the terms of the Eclipse Public License v1.0
7 //  and Apache License v2.0 which accompanies this distribution.
8 //
9 //      The Eclipse Public License is available at
10 //      http://www.eclipse.org/legal/epl-v10.html
11 //
12 //      The Apache License v2.0 is available at
13 //      http://www.opensource.org/licenses/apache2.0.php
14 //
15 //  You may elect to redistribute this code under either of these licenses.
16 //  ========================================================================
17 //
18
19 package org.eclipse.jetty.http.pathmap;
20
21 import java.util.regex.Matcher;
22 import java.util.regex.Pattern;
23
24 public class RegexPathSpec extends PathSpec
25 {
26     protected Pattern pattern;
27
28     protected RegexPathSpec()
29     {
30         super();
31     }
32
33     public RegexPathSpec(String regex)
34     {
35         super.pathSpec = regex;
36         boolean inGrouping = false;
37         this.pathDepth = 0;
38         this.specLength = pathSpec.length();
39         // build up a simple signature we can use to identify the grouping
40         StringBuilder signature = new StringBuilder();
41         for (char c : pathSpec.toCharArray())
42         {
43             switch (c)
44             {
45                 case '[':
46                     inGrouping = true;
47                     break;
48                 case ']':
49                     inGrouping = false;
50                     signature.append('g'); // glob
51                     break;
52                 case '*':
53                     signature.append('g'); // glob
54                     break;
55                 case '/':
56                     if (!inGrouping)
57                     {
58                         this.pathDepth++;
59                     }
60                     break;
61                 default:
62                     if (!inGrouping)
63                     {
64                         if (Character.isLetterOrDigit(c))
65                         {
66                             signature.append('l'); // literal (exact)
67                         }
68                     }
69                     break;
70             }
71         }
72         this.pattern = Pattern.compile(pathSpec);
73
74         // Figure out the grouping based on the signature
75         String sig = signature.toString();
76
77         if (Pattern.matches("^l*$",sig))
78         {
79             this.group = PathSpecGroup.EXACT;
80         }
81         else if (Pattern.matches("^l*g+",sig))
82         {
83             this.group = PathSpecGroup.PREFIX_GLOB;
84         }
85         else if (Pattern.matches("^g+l+$",sig))
86         {
87             this.group = PathSpecGroup.SUFFIX_GLOB;
88         }
89         else
90         {
91             this.group = PathSpecGroup.MIDDLE_GLOB;
92         }
93     }
94
95     public Matcher getMatcher(String path)
96     {
97         return this.pattern.matcher(path);
98     }
99
100     @Override
101     public String getPathInfo(String path)
102     {
103         // Path Info only valid for PREFIX_GLOB types
104         if (group == PathSpecGroup.PREFIX_GLOB)
105         {
106             Matcher matcher = getMatcher(path);
107             if (matcher.matches())
108             {
109                 if (matcher.groupCount() >= 1)
110                 {
111                     String pathInfo = matcher.group(1);
112                     if ("".equals(pathInfo))
113                     {
114                         return "/";
115                     }
116                     else
117                     {
118                         return pathInfo;
119                     }
120                 }
121             }
122         }
123         return null;
124     }
125
126     @Override
127     public String getPathMatch(String path)
128     {
129         Matcher matcher = getMatcher(path);
130         if (matcher.matches())
131         {
132             if (matcher.groupCount() >= 1)
133             {
134                 int idx = matcher.start(1);
135                 if (idx > 0)
136                 {
137                     if (path.charAt(idx - 1) == '/')
138                     {
139                         idx--;
140                     }
141                     return path.substring(0,idx);
142                 }
143             }
144             return path;
145         }
146         return null;
147     }
148
149     public Pattern getPattern()
150     {
151         return this.pattern;
152     }
153
154     @Override
155     public String getRelativePath(String base, String path)
156     {
157         // TODO Auto-generated method stub
158         return null;
159     }
160
161     @Override
162     public boolean matches(final String path)
163     {
164         int idx = path.indexOf('?');
165         if (idx >= 0)
166         {
167             // match only non-query part
168             return getMatcher(path.substring(0,idx)).matches();
169         }
170         else
171         {
172             // match entire path
173             return getMatcher(path).matches();
174         }
175     }
176 }