costin      01/10/04 13:18:08

  Modified:    src/facade22/org/apache/tomcat/facade
                        HttpServletRequestFacade.java
               src/share/org/apache/tomcat/util/buf UEncoder.java
  Log:
  getRequestURI returns an encoded request. Fix is slightly modified from what
  Bill Barker sent, I was thinking to do some optimizations ( avoid use of Writer, and
  do the encoding directly in the buffer), but given that this happens only
  when it's needed - it should be ok. Probably for 3.3.1 we can do this ( and
  the date formating which is another hotspot ).
  
  Note that we do not encode contextPath. This is against the spec, but I think
  we should leave it this way:
  - that's how it was in 3.1, 3.2, etc
  - 4.0 is also broken ( well, it returns 404 if I try any encoded char in the context
  path )
  - it can raise a large number of bugs, if users expect the contextPath to be unique
  ( with encoding - there are many ways you can encode a string, without
  even considering charsets ).
  - it would be very hard to write an app that is consistent between 3.3 and 3.2
  ( which most people use ).
  
  I don't know how other containers are doing this, but I suspect most will
  return the context path decoded - if you can find one that is not decoding the
  CP - we can reconsider this.
  
  Revision  Changes    Path
  1.29      +51 -8     
jakarta-tomcat/src/facade22/org/apache/tomcat/facade/HttpServletRequestFacade.java
  
  Index: HttpServletRequestFacade.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-tomcat/src/facade22/org/apache/tomcat/facade/HttpServletRequestFacade.java,v
  retrieving revision 1.28
  retrieving revision 1.29
  diff -u -r1.28 -r1.29
  --- HttpServletRequestFacade.java     2001/09/22 00:53:47     1.28
  +++ HttpServletRequestFacade.java     2001/10/04 20:18:08     1.29
  @@ -63,6 +63,7 @@
   import org.apache.tomcat.util.res.StringManager;
   import org.apache.tomcat.util.io.FileUtil;
   import org.apache.tomcat.util.buf.DateTool;
  +import org.apache.tomcat.util.buf.UEncoder;
   import org.apache.tomcat.util.http.*;
   import org.apache.tomcat.core.*;
   import org.apache.tomcat.facade.*;
  @@ -95,11 +96,8 @@
       ServletInputStreamFacade isFacade=new ServletInputStreamFacade();
       boolean isFacadeInitialized=false;
       BufferedReader reader;
  -    DateFormat []dateFormats = {
  -     new SimpleDateFormat(DateTool.RFC1123_PATTERN, Locale.US),
  -     new SimpleDateFormat(DateTool.rfc1036Pattern, Locale.US),
  -     new SimpleDateFormat(DateTool.asctimePattern, Locale.US)
  -    };
  +    DateFormat []dateFormats;
  +    UEncoder uencoder;
   
       private boolean usingStream = false;
       private boolean usingReader = false;
  @@ -111,6 +109,31 @@
       HttpServletRequestFacade(Request request) {
           this.request = request;
        isFacade.setRequest( request );
  +     try {
  +         // we may create facades more often than requests 
  +         Object o=request.getNote( "req.dateFormats" );
  +         if( o==null ) {
  +             o=new DateFormat[] {
  +                 new SimpleDateFormat(DateTool.RFC1123_PATTERN, Locale.US),
  +                 new SimpleDateFormat(DateTool.rfc1036Pattern, Locale.US),
  +                 new SimpleDateFormat(DateTool.asctimePattern, Locale.US)
  +             };
  +             request.setNote( "req.dateFormats", o );
  +         }
  +         dateFormats=(DateFormat[])o;
  +         o=request.getNote( "req.uencoder" );
  +         if( o==null ) {
  +             uencoder=new UEncoder();
  +             uencoder.addSafeCharacter(';');
  +             uencoder.addSafeCharacter('/');
  +             request.setNote( "req.uencoder", uencoder );
  +         } else {
  +             uencoder=(UEncoder)o;
  +         }
  +     } catch( TomcatException ex ) {
  +         ex.printStackTrace();
  +     }
  +
       }
   
       /** Not public - is called only from FacadeManager on behalf of Request
  @@ -288,10 +311,12 @@
       }
       
       public String getPathInfo() {
  +     // DECODED
           return request.pathInfo().toString();
       }
   
       public String getPathTranslated() {
  +     // DECODED
        // Servlet 2.2 spec differs from what Apache and
        // all other web servers consider to be PATH_TRANSLATED.
        // It's important not to use CGI PATH_TRANSLATED - this
  @@ -309,7 +334,8 @@
       }
   
       public String getQueryString() {
  -     // unprocessed
  +     // ENCODED. We don't decode the original query string,
  +     // we we can return the same thing
        String qS=request.queryString().toString();
        if( "".equals(qS) )
            return null;
  @@ -379,11 +405,22 @@
       }
   
       public String getRequestURI() {
  -     if( request.unparsedURI().isNull() )
  -         return request.requestURI().toString();
  +     // ENCODED
  +     if( request.unparsedURI().isNull() ) {
  +         // unparsed URI is used as a cache.
  +         // request.unparsedURI().duplicate( request.requestURI() );
  +         String decoded=request.requestURI().toString();
  +         // XXX - I'm not sure what encoding should we use - maybe output ?,
  +         // since this will probably be used for the output
  +         uencoder.setEncoding(request.getCharacterEncoding());
  +         String encoded= uencoder.encodeURL( decoded );
  +         
  +         request.unparsedURI().setString( encoded );
  +     }
           return request.unparsedURI().toString();
       }
   
  +    
       /** Facade: we delegate to the right object ( the context )
        */
       public RequestDispatcher getRequestDispatcher(String path) {
  @@ -423,10 +460,16 @@
       /** Delegate to Context
        */
       public String getContextPath() {
  +     // Should be ENCODED ( in 2.3 ). tomcat4.0 doesn't seem to do that
  +     // ( it's in fact returning 404 on any encoded context paths ), and
  +     // is very likely to result in user errors - if anyone expects it to
  +     // be decoded, as it allways was in 3.x or if anyone will use it as
  +     // a key.
           return request.getContext().getPath();
       }
   
       public String getServletPath() {
  +     // DECODED
           return request.servletPath().toString();
       }
   
  
  
  
  1.4       +18 -2     
jakarta-tomcat/src/share/org/apache/tomcat/util/buf/UEncoder.java
  
  Index: UEncoder.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/buf/UEncoder.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- UEncoder.java     2001/07/19 05:49:02     1.3
  +++ UEncoder.java     2001/10/04 20:18:08     1.4
  @@ -158,8 +158,24 @@
            buf.write(ch);
        }
       }
  -
  -
  +    
  +    /**
  +     * Utility funtion to re-encode the URL.
  +     * Still has problems with charset, since UEncoder mostly
  +     * ignores it.
  +     */
  +    public String encodeURL(String uri) {
  +     String outUri=null;
  +     try {
  +         // XXX optimize - recycle, etc
  +         CharArrayWriter out = new CharArrayWriter();
  +         urlEncode(out, uri);
  +         outUri=out.toString();
  +     } catch (IOException iex) {
  +     }
  +     return outUri;
  +    }
  +    
   
       // -------------------- Internal implementation --------------------
       
  
  
  


Reply via email to