stevel      2003/01/09 22:56:32

  Modified:    java/src/org/apache/axis/transport/http AxisServlet.java
               java/src/org/apache/axis/i18n resource.properties
  Log:
  Cleanup of exception handling, and some changes to GET handling. We can close a lot 
of bugreps up with this patch.
  
  - Faults get logged to a new org.apache.axis.EXCEPTIONS channel; Faults at debug, 
Exceptions at info (cos they are signs of interior trouble)
  
  - Faults have stack traces stripped from them before they go over the wire, unless 
the system is configured as a development system
  
  - refactored method convertExceptionToAxisFault() turns an exception into a fault
  
  - refactored method configureResponseFromAxisFault() sets the status code from a 
fault
  
  - logException is single place where exceptions (not AxisFaults) are logged (for 
easy override)
  
  - GET of .jws now looks for realpath of file existing and extension matching 
whatever the Constants say it is; raise a 404 if there is no file, else say there is a 
JWS service there (&added i18n strings)
  
  - moved where GET catches exceptions; effect is to include everything inside it in 
fault and exception catching and processing
  
  - reportAvailableServices() new reports trouble to callers because of the previous 
change. To keep stacks off the wire; when a ConfigException nests an AxisFault, we 
extract and throw that fault
  
  - SOAP GET calls to an endpoint's methods are now marked dont-cache
  
  - SOAP GET calls now set the appropriate error codes and return errors in XML format
  
  Revision  Changes    Path
  1.154     +100 -48   
xml-axis/java/src/org/apache/axis/transport/http/AxisServlet.java
  
  Index: AxisServlet.java
  ===================================================================
  RCS file: 
/home/cvs/xml-axis/java/src/org/apache/axis/transport/http/AxisServlet.java,v
  retrieving revision 1.153
  retrieving revision 1.154
  diff -u -r1.153 -r1.154
  --- AxisServlet.java  3 Jan 2003 08:19:38 -0000       1.153
  +++ AxisServlet.java  10 Jan 2003 06:56:31 -0000      1.154
  @@ -106,14 +106,14 @@
        * this log is for timing
        */
       private static Log tlog =
  -        LogFactory.getLog("org.apache.axis.TIME");
  +        LogFactory.getLog(Constants.TIME_LOG_CATEGORY);
   
       /**
        * a separate log for exceptions lets users route them
        * differently from general low level debug info
        */
       private static Log exceptionLog =
  -            LogFactory.getLog("org.apache.axis.EXCEPTIONS");
  +            LogFactory.getLog(Constants.EXCEPTION_LOG_CATEGORY);
   
       public static final String INIT_PROPERTY_TRANSPORT_NAME =
           "transport.name";
  @@ -477,7 +477,8 @@
               if(axisFault.getFaultCode() 
.equals(Constants.QNAME_NO_SERVICE_FAULT_CODE)) {
                   //which we log
                   processAxisFault(axisFault);
  -                //then report
  +                //then report under a 404 error
  +                response.setStatus(HttpURLConnection.HTTP_NOT_FOUND);
                   reportNoWSDL(response, writer, "noWSDL01", axisFault);
               } else {
                   //all other faults get thrown
  @@ -488,20 +489,21 @@
   
       /**
        * invoke an endpoint from a get request by building an XML request and
  -     * handing it down
  +     * handing it down. If anything goes wrong, we generate an XML formatted
  +     * axis fault
        * @param msgContext current message
        * @param response to return data
        * @param writer output stream
        * @param method method to invoke (may be null)
        * @param args argument list in XML form
  -     * @throws AxisFault
  +     * @throws AxisFault iff something goes wrong when turning the response message
  +     * into a SOAP string.
        */
       protected void invokeEndpointFromGet(MessageContext msgContext,
                                          HttpServletResponse response,
                                          PrintWriter writer,
                                          String method,
                                          String args) throws AxisFault {
  -        AxisEngine engine = getEngine();
           String body =
               "<" + method + ">" + args + "</" + method + ">";
   
  @@ -514,20 +516,34 @@
           ByteArrayInputStream istream =
               new ByteArrayInputStream(msgtxt.getBytes());
   
  -        Message msg = new Message(istream, false);
  -        msgContext.setRequestMessage(msg);
  -        engine.invoke(msgContext);
  -        Message respMsg = msgContext.getResponseMessage();
  -        if (respMsg != null) {
  -            response.setContentType("text/xml");
  -            writer.println(respMsg.getSOAPPartAsString());
  -        } else {
  -            //tell the caller that something is wrong
  +        Message responseMsg=null;
  +        try {
  +            AxisEngine engine = getEngine();
  +            Message msg = new Message(istream, false);
  +            msgContext.setRequestMessage(msg);
  +            engine.invoke(msgContext);
  +            responseMsg = msgContext.getResponseMessage();
  +            //turn off caching for GET requests
  +            response.setHeader("Cache-Control", "no-cache");
  +            response.setHeader("Pragma", "no-cache");
  +            if (responseMsg == null) {
  +                //tell everyone that something is wrong
  +                throw new Exception(Messages.getMessage("noResponse01"));
  +            }
  +        } catch (AxisFault fault) {
  +            processAxisFault(fault);
  +            configureResponseFromAxisFault(response, fault);
  +            if (responseMsg == null) {
  +                responseMsg = new Message(fault);
  +            }
  +        } catch (Exception e) {
               response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
  -            writer.println("<p>" +
  -                   Messages.getMessage("noResponse01") +
  -                           "</p>");
  +            responseMsg = convertExceptionToAxisFault(e,responseMsg);
           }
  +        //this call could throw an AxisFault. We delegate it up, because
  +        //if we cant write the message there is not a lot we can do in pure SOAP 
terms.
  +        response.setContentType("text/xml");
  +        writer.println(responseMsg.getSOAPPartAsString());
       }
   
       /**
  @@ -697,20 +713,29 @@
       }
   
       /**
  -     * indicate that there may be a JWS page, and that the user should look
  -     * at the WSDL to se
  +     * probe for a JWS page and report 'no service' if one is not found there
        * @param request the request that didnt have an edpoint
        * @param response response we are generating
        * @param writer open writer for the request
        */
       protected void reportCantGetJWSService(HttpServletRequest request, 
HttpServletResponse response, PrintWriter writer) {
  -        // no such service....
  -        response.setStatus(HttpURLConnection.HTTP_OK);
  +        //first look to see if there is a service
  +        String realpath =
  +                getServletConfig().getServletContext()
  +                .getRealPath(request.getServletPath());
  +        boolean foundJWSFile=(new File(realpath).exists()) &&
  +                (realpath.endsWith(Constants.JWS_DEFAULT_FILE_EXTENSION));
           response.setContentType("text/html");
  -        String urltext= Messages.getMessage("noService08");
  -        String url=request.getRequestURI();
  -        writer.println(Messages.getMessage("noService07") + "<p>");
  -        writer.println("<a href='"+url+"?wsdl'>"+urltext+"</a>");
  +        if(foundJWSFile) {
  +            response.setStatus(HttpURLConnection.HTTP_OK);
  +            writer.println(Messages.getMessage("foundJWS00") + "<p>");
  +            String url = request.getRequestURI();
  +            String urltext = Messages.getMessage("foundJWS01");
  +            writer.println("<a href='"+url+"?wsdl'>"+urltext+"</a>");
  +        } else {
  +            response.setStatus(HttpURLConnection.HTTP_NOT_FOUND);
  +            writer.println(Messages.getMessage("noService06") );
  +        }
       }
   
   
  @@ -813,36 +838,23 @@
                       t2=System.currentTimeMillis();
                   }
                   responseMsg = msgContext.getResponseMessage();
  -            } catch (AxisFault e) {
  +            } catch (AxisFault fault) {
                   //log and sanitize
  -                processAxisFault(e);
  -                // then get the status code
  -                // It's been suggested that a lack of SOAPAction
  -                // should produce some other error code (in the 400s)...
  -                int status = getHttpServletResponseStatus(e);
  -                if (status == HttpServletResponse.SC_UNAUTHORIZED) {
  -                    // unauth access results in authentication request
  -                    // TODO: less generic realm choice?
  -                  res.setHeader("WWW-Authenticate","Basic realm=\"AXIS\"");
  -                }
  -                res.setStatus(status);
  +                processAxisFault(fault);
  +                configureResponseFromAxisFault(res,fault);
                   responseMsg = msgContext.getResponseMessage();
                   if (responseMsg == null) {
  -                    responseMsg = new Message(e);
  +                    responseMsg = new Message(fault);
                   }
               } catch (Exception e) {
                   //other exceptions are internal trouble
  -                logException(e);
  -                res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                   responseMsg = msgContext.getResponseMessage();
  -                if (responseMsg == null) {
  -                    AxisFault fault=AxisFault.makeFault(e);
  -                    processAxisFault(fault);
  -                    responseMsg = new Message(fault);
  -                }
  +                res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
  +                responseMsg = convertExceptionToAxisFault(e, responseMsg);
               }
           } catch (AxisFault fault) {
               processAxisFault(fault);
  +            configureResponseFromAxisFault(res, fault);
               responseMsg = msgContext.getResponseMessage();
               if (responseMsg == null) {
                   responseMsg = new Message(fault);
  @@ -880,6 +892,47 @@
       }
   
       /**
  +     * Configure the servlet response status code and maybe other headers
  +     * from the fault info.
  +     * @param response response to configure
  +     * @param fault what went wrong
  +     */
  +    private void configureResponseFromAxisFault(HttpServletResponse response,
  +                                                AxisFault fault) {
  +        // then get the status code
  +        // It's been suggested that a lack of SOAPAction
  +        // should produce some other error code (in the 400s)...
  +        int status = getHttpServletResponseStatus(fault);
  +        if (status == HttpServletResponse.SC_UNAUTHORIZED) {
  +            // unauth access results in authentication request
  +            // TODO: less generic realm choice?
  +          response.setHeader("WWW-Authenticate","Basic realm=\"AXIS\"");
  +        }
  +        response.setStatus(status);
  +    }
  +
  +    /**
  + * turn any Exception into an AxisFault, log it, set the response
  + * status code according to what the specifications say and
  + * return a response message for posting. This will be the response
  + * message passed in if non-null; one generated from the fault otherwise.
  + *
  + * @param exception what went wrong
  + * @param responseMsg what response we have (if any)
  + * @return a response message to send to the user
  + */
  +    private Message convertExceptionToAxisFault(Exception exception,
  +                                                Message responseMsg) {
  +        logException(exception);
  +        if (responseMsg == null) {
  +            AxisFault fault=AxisFault.makeFault(exception);
  +            processAxisFault(fault);
  +            responseMsg = new Message(fault);
  +        }
  +        return responseMsg;
  +    }
  +
  +    /**
        * Extract information from AxisFault and map it to a HTTP Status code.
        *
        * @param af Axis Fault
  @@ -1033,8 +1086,7 @@
       private String getSoapAction(HttpServletRequest req)
           throws AxisFault
       {
  -        String soapAction =
  -            (String)req.getHeader(HTTPConstants.HEADER_SOAP_ACTION);
  +        String soapAction =req.getHeader(HTTPConstants.HEADER_SOAP_ACTION);
   
           if(isDebug) log.debug("HEADER_SOAP_ACTION:" + soapAction);
   
  
  
  
  1.45      +7 -1      xml-axis/java/src/org/apache/axis/i18n/resource.properties
  
  Index: resource.properties
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/i18n/resource.properties,v
  retrieving revision 1.44
  retrieving revision 1.45
  diff -u -r1.44 -r1.45
  --- resource.properties       8 Jan 2003 02:03:35 -0000       1.44
  +++ resource.properties       10 Jan 2003 06:56:32 -0000      1.45
  @@ -427,8 +427,10 @@
   
   noService06=No service is available at this URL
   # NOTE:  in noService07, do not translate "JWS"
  +#UNUSED
   noService07=There may be a JWS service here. 
   # NOTE:  in noService08, do not translate "WSDL"
  +#UNUSED
   noService08=Click here to look for the WSDL description
   
   # NOTE:  in noSecurity00, do not translate "MessageContext"
  @@ -1118,4 +1120,8 @@
   acUsage23=web services described in these files
   acUsage24=
   acUsage25=If -l or -h -p -s are not set, the AdminClient will invoke
  -acUsage26=http://localhost:8080/axis/servlet/AxisServlet
  \ No newline at end of file
  +acUsage26=http://localhost:8080/axis/servlet/AxisServlet
  +
  +foundJWS00=There is a Web Service here
  +#NOTE in foundJWS01, do not translate WSDL
  +foundJWS01=Click to see the WSDL
  
  
  


Reply via email to