You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by Peter Costello <pe...@yahoo.com> on 2001/05/23 17:55:34 UTC

8 Patches for Win2k, Forte2.0 & JDK1.3.0_01

The following patches were made to get
jakarta-tomcat4.0-b5 to
compile and work properly in an environment using
Win2000, 
JDK1.3.0_01 and Forte2.0 IDE.

Could an active developer please review and check
out/in the changes?

===========================================================================
1) org.apache.catalina.authenticator.FormAuthenticate

   The following enhancement allows the IE5.0 browser
to maintain the
   correct URL in its history list.  For example, if
browser fetches
   'index.jsp' and tomcat returns 'login.jsp', then
when browser submits
   username and password it sends a 'POST
j_security_check'.  Method
   'authenticate()' does its work and then restores
the original request
   and returns. However, now the browser thinks that
page 'GET index.jsp'
   is 'POST j_security_check' and using the
back/forward on the browser
   will result in an error when we get back to the
'POST'.
   
   My fix was to send a redirect to the original page
after authenticate
   does its work.  
   
   
    /**
     * Authenticate the user making this request,
based on the specified
     * login configuration.  Return <code>true</code>
if any specified
     * constraint has been satisfied, or
<code>false</code> if we have
     * created a response challenge already.
     *
     * @param request Request we are processing
     * @param response Response we are creating
     * @param login Login configuration describing how
authentication
     *              should be performed
     *
     * @exception IOException if an input/output error
occurs
     */
    public boolean authenticate(HttpRequest request,
        HttpResponse response,
        LoginConfig config)
    throws IOException {
      
        ..... UNCHANGED .....

        if (restoreRequest(request, session)) {
            if (debug >= 1)
                log("Proceed to restored request");

    /* Added code */
            // If we merely serve the original
request, then IE5 browser
            // shows "POST j_security_check" in
address field, and future
            // "back" submits the POST rather than the
original GET.
            // ToDo: the 'restoreRequest' above does
some extra/unnecessary
            // work that could be cleaned up.
            String uri =
hreq.getRequestURI()+"?"+hreq.getQueryString();
            hres.sendRedirect(uri);
    /* End added code */

            return (true);                // Perform
the original request
        } else {
            if (debug >= 1)
                log("Restore of original request
failed");
           
hres.sendError(HttpServletResponse.SC_BAD_REQUEST);
            //            hres.flushBuffer();
            return (false);
        }

===========================================================================
2) org.apache.catalina.core.ApplicationDispatcher

    This implementation of RequestDispatcher makes a
call to the protected
    service method of the servlet.  I'm not sure why
it is doing that, but
    as a servlet developer, I know I'm expecting
service calls to come
    through the public method.
    
    This change is needed to get Forte2.0 to compile
the file.
    
    private void invoke(ServletRequest request,
ServletResponse response)
                        throws IOException,
ServletException {

        .... UNCHANGED ....                           
          
        // Call the service() method for the allocated
servlet instance
        try {
            if (servlet != null) {
                  /* REMOVED CODE ... */
                    /* The call to 'protected void
service(HttpServletRequest,HttpServletResponse)'
                        will not compile. This is a
protected method, so calls to service should go
                        through the public method.
Changed 5/17/01 to get it to compile. 
                    if ((servlet instanceof
HttpServlet) &&
                            (hrequest != null) &&
(hresponse != null)) {
                            (HttpServlet
servlet).service(hrequest,hresponse);
                    } else {
                            servlet.service(request,
response);
                    } */
                  /* END REMOVED CODE */
                  
                  /* added CODE */
                     servlet.service(request,
response);
                  /* END Added CODE */
           
                }
        } catch (IOException e) {
           
log(sm.getString("applicationDispatcher.serviceException",
                             wrapper.getName()), e);
            ioException = e;
        } catch (UnavailableException e) {
 
        .... UNCHANGED ....                           
          

===========================================================================
3) org.apache.catalina.startup.Catalina

   This is an enhancement.  Currently, usage is
reported if any of the 
   arguments are not defined, but at least one
argument is required
   (eg run), and there is no usage call if no
arguments are supplied
    
    protected boolean arguments(String args[]) {
        /* Begin added code */
        if (args.length==0) usage();    // Added
        /* End added code */
        
        .... Rest unchanged ....
        
        
===========================================================================
4) org.apache.catalina.util.xml.XmlMapper

   While trying to debug my code, I was seeing some
double error messages
   printed XmlMapper, and I thought this was some
mistake of mine.  Instead,
   XmlMapper was printing these messages.  They were
something like...
          ...XmlMapper LoadOnStartup(1)
          ...XmlMapper LoadOnStartup( )    // This was
the double
          
   To remove the double messages....
   
    class  MethodSetter extends       XmlAction {  
        public void end( SaxContext ctx) throws
Exception {
            .... UNCHANGED .....
           if(ctx.getDebug() > 0 ) {                  
  // DELETED CODE
          if ((paramC>0)&&(ctx.getDebug()>0)) {       
  // ADDED CODE, line 876
             // debug
             StringBuffer sb=new StringBuffer();
             sb.append("" +
parent.getClass().getName() + "." + mName + "( " );
             for(int i=0; i<paramC; i++ ) {
                 if(i>0) sb.append( ", ");
                 sb.append(params[i]);
             }
             sb.append(")");
             if( ctx.getDebug() > 0 )
ctx.log(sb.toString());
         }
    }

     
===========================================================================
5) org.apache.catalina.valves.RequestDumperValve

   Bug. Fix NullPointerException.

    public void invoke(Request request, Response
response,
                       ValveContext context)
           ... UNCHANGED ....
           
        Cookie cookies[] = hreq.getCookies();
        if (cookies != null) {                  //
ADDED CODE on line 177
            for (int i = 0; i < cookies.length; i++)
            log("            cookie=" +
cookies[i].getName() + "=" +
            cookies[i].getValue());
         }                                      //
Added end bracket.
         
===========================================================================
6) org.apache.jasper.compiler.JspCompiler

   The routine 'isOutDated()' was not converting from
windows File.separatorChar
   to URL's "/".  The end result is that the ".jsp"
file was not found on disk,
   it's 'lastModified()' was zero, and a modified
".jsp" was never reloaded.
   
    public boolean isOutDated() {
        long jspRealLastModified = 0;

        try {
       /* Begin added code */
          // In Windows,
jspUrl="/localhost/fun\app\index.jsp
          // I think this is correct place to fix
because
          //    1) jsp instanceof File
          //    2) ctxt.getResource(String) instanceof
URL, and getResource()
          //       does not do any checking for
windows file separator.
          // Second problem is that if a JSP file uses
'include', then
          // dates on any 'included' files are not
checked. One fix is 
          // to have a parameter to prevent cacheing.
Another fix is to 
          // nuke cache tree when needed for
debugging.
          String path = jsp.getPath();
          if (File.separatorChar=='\\')
path=path.replace('\\','/');
                URL jspUrl = ctxt.getResource(path);
                if (jspUrl == null) return true;
                jspRealLastModified =
jspUrl.openConnection().getLastModified();
          if (jspRealLastModified<=0) return true;
       /* End added code */
       /* Original code
            URL jspUrl =
ctxt.getResource(jsp.getPath());
            if (jspUrl == null)
                return true;
            jspRealLastModified =
jspUrl.openConnection().getLastModified();
        */
        } catch (Exception e) {
            e.printStackTrace();
            return true;
        }
        
        ... Rest Unchanged ....
        
===========================================================================
7) org.apache.jasper.logging.JasperLogger

   Forte2.0, Win2K & JDK1.3.0_01 won't compile the
class Flusher inside of LogDaemon.
   I changed Flusher to not be an in-line class and it
compiles OK. Functionality
   is not changed.
   
    /**
    * The daemon thread that looks in a queue and if
it is not empty
    * writes out everything in the queue to the sink.
    */
    class LogDaemon extends Thread {
        Runnable flusher;

        LogDaemon(Queue logQueue, ServletContext
servletContext) {
            flusher = new
Flusher(logQueue,servletContext);
            setDaemon(true);
        }

        static char[] newline;
        static String separator;
        static {
            separator =
System.getProperty("line.separator", "\n");
            newline = separator.toCharArray();
        }
        
        /* PWC modified to get it to compile */
        class Flusher implements Runnable {
            private Queue logQueue;
            private ServletContext servletContext;
            public Flusher(Queue lq,ServletContext sc)
{
                logQueue=lq; 
                servletContext=sc;
            }
            public void run() {
                do {
                    JasperLogger.LogEntry logEntry =
(JasperLogger.LogEntry) logQueue.pull();
                    if (servletContext != null) {
                       
servletContext.log(logEntry.toString());
                        servletContext.log(separator);
                    } else {
                        Writer writer =
logEntry.getWriter();
                        if (writer != null) {
                            try {
                               
writer.write(logEntry.toString());
                                writer.write(newline);
                                writer.flush();
                            } catch (Exception ex) {
// IOException
                                ex.printStackTrace();
// nowhere else to write it
                            }
                        }
                    }
                } while (!logQueue.isEmpty());
            }
        }

        public void run() {
            while (true)
              flusher.run();
        }

         public void flush() {
            Thread workerThread = new Thread(flusher);
            workerThread.start();
        }
    }
       
===========================================================================
8) org.apache.jasper.servlet.JspServlet

   Performance improvement. Methods
"compiler.compile()" and "compiler.isOutDated()"
   are called more than once from method "loadJSP()".
In addition, routine
   "compiler.compile()" also calls
"compiler.isOutDated()".  As best as I can figure,
   the developer added a 'syncronize', and shuffled
the order of the calls to 
   minimize how often 'syncronize' was called, and
then forget to delete the 
   old code.
   
    boolean loadJSP(String jspUri, String classpath, 
                    boolean isErrorPage,
HttpServletRequest req, HttpServletResponse res) 
                    throws JasperException,
FileNotFoundException {

        ... Unchanged code ....
        
        boolean outDated = false; 
        Compiler compiler = ctxt.createCompiler();
        try {
            // Begin Added code
           if ( (jsw.servletClass == null) ||
(compiler.isOutDated()) ) {
               synchronized ( this ) {
                  outDated = compiler.compile();
               }
            }
            // End added code
            
            /* Original Code
            outDated = compiler.compile();
            if ( (jsw.servletClass == null) ||
(compiler.isOutDated()) ) {
                synchronized ( this ) {
                   if ((jsw.servletClass == null) ||
(compiler.isOutDated() ))  {
                       outDated = compiler.compile();
                   }
                }
            }
            */
            
        } catch (FileNotFoundException ex) {
        ... Unchanged code ...

__________________________________________________
Do You Yahoo!?
Yahoo! Auctions - buy the things you want at great prices
http://auctions.yahoo.com/

Re: 8 Patches for Win2k, Forte2.0 & JDK1.3.0_01

Posted by "Craig R. McClanahan" <cr...@apache.org>.

On Wed, 23 May 2001, Mark.Abbott wrote:

> 
> 
> Peter Costello wrote:
> > 
> > 
> > ===========================================================================
> > 1) org.apache.catalina.authenticator.FormAuthenticate
> > 
> >    The following enhancement allows the IE5.0 browser
> > to maintain the
> >    correct URL in its history list.  For example, if
> > browser fetches
> >    'index.jsp' and tomcat returns 'login.jsp', then
> > when browser submits
> >    username and password it sends a 'POST
> > j_security_check'.  Method
> >    'authenticate()' does its work and then restores
> > the original request
> >    and returns. However, now the browser thinks that
> > page 'GET index.jsp'
> >    is 'POST j_security_check' and using the
> > back/forward on the browser
> >    will result in an error when we get back to the
> > 'POST'.
> > 
> >    My fix was to send a redirect to the original page
> > after authenticate
> >    does its work.
> > 
> 
> But what if the original request was not a GET, but rather
> a POST?  How can you redirect to that?
> 
>       Cheers - Mark
> 
> 
> 

The change to use a redirect will be necessary to meet the new 2.3 spec
requirements.  However, Mark's point is critical -- if the original
request is a POST, we still need this to work.  That can be done, but it's
a little more complicated than just the current patch.

Craig



Re: 8 Patches for Win2k, Forte2.0 & JDK1.3.0_01

Posted by "Mark.Abbott" <Ma...@openwave.com>.

Peter Costello wrote:
> 
> 
> ===========================================================================
> 1) org.apache.catalina.authenticator.FormAuthenticate
> 
>    The following enhancement allows the IE5.0 browser
> to maintain the
>    correct URL in its history list.  For example, if
> browser fetches
>    'index.jsp' and tomcat returns 'login.jsp', then
> when browser submits
>    username and password it sends a 'POST
> j_security_check'.  Method
>    'authenticate()' does its work and then restores
> the original request
>    and returns. However, now the browser thinks that
> page 'GET index.jsp'
>    is 'POST j_security_check' and using the
> back/forward on the browser
>    will result in an error when we get back to the
> 'POST'.
> 
>    My fix was to send a redirect to the original page
> after authenticate
>    does its work.
> 

But what if the original request was not a GET, but rather
a POST?  How can you redirect to that?

      Cheers - Mark



Re: 8 Patches for Win2k, Forte2.0 & JDK1.3.0_01

Posted by "Craig R. McClanahan" <cr...@apache.org>.
On Wed, 23 May 2001, Peter Costello wrote:

> The following patches were made to get
> jakarta-tomcat4.0-b5 to
> compile and work properly in an environment using
> Win2000, 
> JDK1.3.0_01 and Forte2.0 IDE.
> 
> Could an active developer please review and check
> out/in the changes?
> 

Hi Peter,

Thanks for supplying these patches.  I've taken care of the easy ones (2,
3, 4, 5) and wanted to update you on the status of the others:

(1) As was briefly discussed on the list, more is going to be necessary
    than just using a redirect in order to ensure that a POST transaction
    that triggers form-based login is handled correctly.  I'm going to
    continue working on that.

(6) This was recently fixed (since Beta 5), and should work correctly in
    recent nightly builds.  You might want to wait until tonight, to
    make sure that the other fixes now work for you.

(7) This code compiles for me on Windows using JDK 1.3.0_02 (not using
    Forte, but I don't think that matters).  Would it be possible for you
    to try that version (and/or 1.3.1)?  I know there were some recent
    bugfixes related to inner classes, and I think these were the revs
    that fixed them.

(8) As you've observed, the code in JspServlet is a little, um, er,
    obtuse :-).  I want to spend some more time understanding what's
    actually happening here before changing anything.

Craig McClanahan