View Javadoc

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.rewrite.handler;
20  
21  import java.io.IOException;
22  
23  import javax.servlet.http.HttpServletRequest;
24  import javax.servlet.http.HttpServletResponse;
25  
26  import org.eclipse.jetty.server.Request;
27  import org.eclipse.jetty.util.ArrayUtil;
28  import org.eclipse.jetty.util.URIUtil;
29  import org.eclipse.jetty.util.log.Log;
30  import org.eclipse.jetty.util.log.Logger;
31  
32  /**
33   * Base container to group rules. Can be extended so that the contained rules
34   * will only be applied under certain conditions
35   */
36  public class RuleContainer extends Rule
37  {
38      public static final String ORIGINAL_QUERYSTRING_ATTRIBUTE_SUFFIX = ".QUERYSTRING";
39      private static final Logger LOG = Log.getLogger(RuleContainer.class);
40  
41      protected Rule[] _rules;
42      
43      protected String _originalPathAttribute;
44      protected String _originalQueryStringAttribute;
45      protected boolean _rewriteRequestURI=true;
46      protected boolean _rewritePathInfo=true;
47       
48      /* ------------------------------------------------------------ */
49      /**
50       * Returns the list of rules.
51       * @return an array of {@link Rule}.
52       */
53      public Rule[] getRules()
54      {
55          return _rules;
56      }
57  
58      /* ------------------------------------------------------------ */
59      /**
60       * Assigns the rules to process.
61       * @param rules an array of {@link Rule}. 
62       */
63      public void setRules(Rule[] rules)
64      {
65          _rules = rules;
66      }
67  
68      /* ------------------------------------------------------------ */
69      /**
70       * Add a Rule
71       * @param rule The rule to add to the end of the rules array
72       */
73      public void addRule(Rule rule)
74      {
75          _rules = ArrayUtil.addToArray(_rules,rule,Rule.class);
76      }
77     
78  
79      /* ------------------------------------------------------------ */
80      /**
81       * @return the rewriteRequestURI If true, this handler will rewrite the value
82       * returned by {@link HttpServletRequest#getRequestURI()}.
83       */
84      public boolean isRewriteRequestURI()
85      {
86          return _rewriteRequestURI;
87      }
88  
89      /* ------------------------------------------------------------ */
90      /**
91       * @param rewriteRequestURI true if this handler will rewrite the value
92       * returned by {@link HttpServletRequest#getRequestURI()}.
93       */
94      public void setRewriteRequestURI(boolean rewriteRequestURI)
95      {
96          _rewriteRequestURI=rewriteRequestURI;
97      }
98  
99      /* ------------------------------------------------------------ */
100     /**
101      * @return true if this handler will rewrite the value
102      * returned by {@link HttpServletRequest#getPathInfo()}.
103      */
104     public boolean isRewritePathInfo()
105     {
106         return _rewritePathInfo;
107     }
108 
109     /* ------------------------------------------------------------ */
110     /**
111      * @param rewritePathInfo true if this handler will rewrite the value
112      * returned by {@link HttpServletRequest#getPathInfo()}.
113      */
114     public void setRewritePathInfo(boolean rewritePathInfo)
115     {
116         _rewritePathInfo=rewritePathInfo;
117     }
118 
119     /* ------------------------------------------------------------ */
120     /**
121      * @return the originalPathAttribte. If non null, this string will be used
122      * as the attribute name to store the original request path.
123      */
124     public String getOriginalPathAttribute()
125     {
126         return _originalPathAttribute;
127     }
128 
129     /* ------------------------------------------------------------ */
130     /**
131      * @param originalPathAttribte If non null, this string will be used
132      * as the attribute name to store the original request path.
133      */
134     public void setOriginalPathAttribute(String originalPathAttribte)
135     {
136         _originalPathAttribute=originalPathAttribte;
137         _originalQueryStringAttribute = originalPathAttribte + ORIGINAL_QUERYSTRING_ATTRIBUTE_SUFFIX;
138     }
139     
140     /**
141      * Process the contained rules
142      * @param target target field to pass on to the contained rules
143      * @param request request object to pass on to the contained rules
144      * @param response response object to pass on to the contained rules
145      */
146     @Override
147     public String matchAndApply(String target, HttpServletRequest request, HttpServletResponse response) throws IOException
148     {
149         return apply(target, request, response);
150     }
151 
152     /**
153      * Process the contained rules (called by matchAndApply) 
154      * @param target target field to pass on to the contained rules
155      * @param request request object to pass on to the contained rules
156      * @param response response object to pass on to the contained rules
157      * @return the target
158      * @throws IOException if unable to apply the rule
159      */
160     protected String apply(String target, HttpServletRequest request, HttpServletResponse response) throws IOException
161     {
162         boolean original_set=_originalPathAttribute==null;
163         
164         target = URIUtil.compactPath(target);
165                 
166         for (Rule rule : _rules)
167         {
168             String applied=rule.matchAndApply(target,request, response);
169             if (applied!=null)
170             {
171                 applied = URIUtil.compactPath(applied);
172                 
173                 LOG.debug("applied {}",rule);
174                 LOG.debug("rewrote {} to {}",target,applied);
175                 if (!original_set)
176                 {
177                     original_set=true;
178                     request.setAttribute(_originalPathAttribute, target);
179                     
180                     String query = request.getQueryString();
181                     if (query != null)
182                         request.setAttribute(_originalQueryStringAttribute,query);
183                 }     
184 
185                 if (_rewriteRequestURI)
186                 {
187                     String encoded=URIUtil.encodePath(applied);
188                     if (rule instanceof Rule.ApplyURI)
189                         ((Rule.ApplyURI)rule).applyURI((Request)request,((Request)request).getRequestURI(), encoded);
190                     else
191                         ((Request)request).setURIPathQuery(encoded);
192                 }
193 
194                 if (_rewritePathInfo)
195                     ((Request)request).setPathInfo(applied);
196 
197                 target=applied;
198                 
199                 if (rule.isHandling())
200                 {
201                     LOG.debug("handling {}",rule);
202                     Request.getBaseRequest(request).setHandled(true);
203                 }
204 
205                 if (rule.isTerminating())
206                 {
207                     LOG.debug("terminating {}",rule);
208                     break;
209                 }
210             }
211         }
212 
213         return target;
214     }
215 }