View Javadoc

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