Save This Page
Home » axis2-1.5-src » org.apache » axis2 » transport » http » [javadoc | source]
    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one
    3    * or more contributor license agreements. See the NOTICE file
    4    * distributed with this work for additional information
    5    * regarding copyright ownership. The ASF licenses this file
    6    * to you under the Apache License, Version 2.0 (the
    7    * "License"); you may not use this file except in compliance
    8    * with the License. You may obtain a copy of the License at
    9    *
   10    * http://www.apache.org/licenses/LICENSE-2.0
   11    *
   12    * Unless required by applicable law or agreed to in writing,
   13    * software distributed under the License is distributed on an
   14    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   15    * KIND, either express or implied. See the License for the
   16    * specific language governing permissions and limitations
   17    * under the License.
   18    */
   19   
   20   
   21   package org.apache.axis2.transport.http;
   22   
   23   import org.apache.axiom.om.OMElement;
   24   import org.apache.axiom.om.impl.builder.StAXBuilder;
   25   import org.apache.axiom.soap.SOAP12Constants;
   26   import org.apache.axiom.soap.SOAPEnvelope;
   27   import org.apache.axiom.soap.SOAPFaultCode;
   28   import org.apache.axis2.AxisFault;
   29   import org.apache.axis2.Constants;
   30   import org.apache.axis2.addressing.AddressingHelper;
   31   import org.apache.axis2.addressing.EndpointReference;
   32   import org.apache.axis2.context.ConfigurationContext;
   33   import org.apache.axis2.context.ConfigurationContextFactory;
   34   import org.apache.axis2.context.MessageContext;
   35   import org.apache.axis2.context.SessionContext;
   36   import org.apache.axis2.deployment.WarBasedAxisConfigurator;
   37   import org.apache.axis2.description.AxisBindingMessage;
   38   import org.apache.axis2.description.AxisBindingOperation;
   39   import org.apache.axis2.description.Parameter;
   40   import org.apache.axis2.description.TransportInDescription;
   41   import org.apache.axis2.description.TransportOutDescription;
   42   import org.apache.axis2.description.WSDL2Constants;
   43   import org.apache.axis2.engine.AxisConfiguration;
   44   import org.apache.axis2.engine.AxisEngine;
   45   import org.apache.axis2.engine.Handler.InvocationResponse;
   46   import org.apache.axis2.engine.ListenerManager;
   47   import org.apache.axis2.transport.RequestResponseTransport;
   48   import org.apache.axis2.transport.TransportListener;
   49   import org.apache.axis2.transport.TransportUtils;
   50   import org.apache.axis2.transport.http.server.HttpUtils;
   51   import org.apache.axis2.transport.http.util.QueryStringParser;
   52   import org.apache.axis2.transport.http.util.RESTUtil;
   53   import org.apache.axis2.util.JavaUtils;
   54   import org.apache.axis2.util.MessageContextBuilder;
   55   import org.apache.axis2.util.Utils;
   56   import org.apache.commons.logging.Log;
   57   import org.apache.commons.logging.LogFactory;
   58   
   59   import javax.servlet.ServletConfig;
   60   import javax.servlet.ServletContext;
   61   import javax.servlet.ServletException;
   62   import javax.servlet.http.HttpServlet;
   63   import javax.servlet.http.HttpServletRequest;
   64   import javax.servlet.http.HttpServletResponse;
   65   import javax.xml.namespace.QName;
   66   import java.io.BufferedInputStream;
   67   import java.io.BufferedOutputStream;
   68   import java.io.IOException;
   69   import java.io.OutputStream;
   70   import java.io.PrintWriter;
   71   import java.net.SocketException;
   72   import java.util.Arrays;
   73   import java.util.HashSet;
   74   import java.util.Map;
   75   import java.util.Set;
   76   import java.util.concurrent.CountDownLatch;
   77   
   78   /**
   79    * Class AxisServlet
   80    */
   81   public class AxisServlet extends HttpServlet implements TransportListener {
   82   
   83       private static final Log log = LogFactory.getLog(AxisServlet.class);
   84       public static final String CONFIGURATION_CONTEXT = "CONFIGURATION_CONTEXT";
   85       public static final String SESSION_ID = "SessionId";
   86       
   87       private static final Set<String> metadataQueryParamNames = new HashSet<String>(
   88               Arrays.asList("wsdl2", "wsdl", "xsd", "policy"));
   89       
   90       protected transient ConfigurationContext configContext;
   91       protected transient AxisConfiguration axisConfiguration;
   92   
   93       protected transient ServletConfig servletConfig;
   94   
   95       protected transient ListingAgent agent;
   96       protected transient String contextRoot = null;
   97   
   98       protected boolean disableREST = false;
   99       private static final String LIST_SERVICES_SUFFIX = "/services/listServices";
  100       private static final String LIST_FAULTY_SERVICES_SUFFIX = "/services/ListFaultyServices";
  101       private boolean closeReader = true;
  102   
  103       private static final int BUFFER_SIZE = 1024 * 8;
  104       
  105       private boolean initCalled = false;
  106   
  107       /**
  108        * Implementaion of POST interface
  109        *
  110        * @param request
  111        * @param response
  112        * @throws ServletException
  113        * @throws IOException
  114        */
  115       protected void doPost(HttpServletRequest request, HttpServletResponse response)
  116               throws ServletException, IOException {
  117           //set the initial buffer for a larger value
  118           try {
  119           response.setBufferSize(BUFFER_SIZE);
  120           } catch (Throwable t){
  121               log.info("Old Servlet API :" + t);
  122           }
  123   
  124           initContextRoot(request);
  125   
  126           MessageContext msgContext;
  127           OutputStream out = response.getOutputStream();
  128           String contentType = request.getContentType();
  129           if (!HTTPTransportUtils.isRESTRequest(contentType)) {
  130               msgContext = createMessageContext(request, response);
  131               msgContext.setProperty(Constants.Configuration.CONTENT_TYPE, contentType);
  132               try {
  133                   // adding ServletContext into msgContext;
  134                   String url;
  135                   try {
  136                       url = request.getRequestURL().toString();
  137                   } catch (Throwable t){
  138                       log.info("Old Servlet API (fallback to HttpServletRequest.getRequestURI) :" + t);    
  139                       url = request.getRequestURI();
  140                   }
  141                   
  142                   InvocationResponse pi = HTTPTransportUtils.
  143                           processHTTPPostRequest(msgContext,
  144                                   new BufferedInputStream(request.getInputStream()),
  145                                   new BufferedOutputStream(out),
  146                                   contentType,
  147                                   request.getHeader(HTTPConstants.HEADER_SOAP_ACTION),
  148                                   url);
  149   
  150                   Boolean holdResponse =
  151                           (Boolean) msgContext.getProperty(RequestResponseTransport.HOLD_RESPONSE);
  152   
  153                   if (pi.equals(InvocationResponse.SUSPEND) ||
  154                           (holdResponse != null && Boolean.TRUE.equals(holdResponse))) {
  155                       ((RequestResponseTransport) msgContext
  156                               .getProperty(RequestResponseTransport.TRANSPORT_CONTROL))
  157                               .awaitResponse();
  158                   }
  159                   response.setContentType("text/xml; charset="
  160                           + msgContext
  161                           .getProperty(Constants.Configuration.CHARACTER_SET_ENCODING));
  162                   // if data has not been sent back and this is not a signal response
  163                   if (!TransportUtils.isResponseWritten(msgContext)  
  164                   		&& (((RequestResponseTransport) 
  165                   				msgContext.getProperty(
  166                   						RequestResponseTransport.TRANSPORT_CONTROL)).
  167                   						getStatus() != RequestResponseTransport.
  168                   						RequestResponseTransportStatus.SIGNALLED)) {
  169                       response.setStatus(HttpServletResponse.SC_ACCEPTED);
  170                   }
  171   
  172               } catch (AxisFault e) {
  173                   setResponseState(msgContext, response);
  174                   log.debug(e);
  175                   if (msgContext != null) {
  176                       processAxisFault(msgContext, response, out, e);
  177                   } else {
  178                       throw new ServletException(e);
  179                   }
  180               } catch (Throwable t) {
  181                   log.error(t.getMessage(), t);
  182                   try {
  183                       // If the fault is not going along the back channel we should be 202ing
  184                       if (AddressingHelper.isFaultRedirected(msgContext)) {
  185                           response.setStatus(HttpServletResponse.SC_ACCEPTED);
  186                       } else {
  187                           response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
  188   
  189                           AxisBindingOperation axisBindingOperation =
  190                                   (AxisBindingOperation) msgContext
  191                                           .getProperty(Constants.AXIS_BINDING_OPERATION);
  192                           if (axisBindingOperation != null) {
  193                               AxisBindingMessage axisBindingMessage = axisBindingOperation.getFault(
  194                                       (String) msgContext.getProperty(Constants.FAULT_NAME));
  195                               if(axisBindingMessage != null){
  196                                   Integer code = (Integer) axisBindingMessage
  197                                           .getProperty(WSDL2Constants.ATTR_WHTTP_CODE);
  198                                   if (code != null) {
  199                                       response.setStatus(code.intValue());
  200                                   }
  201                               }
  202                           }
  203                       }
  204                       handleFault(msgContext, out, new AxisFault(t.toString(), t));
  205                   } catch (AxisFault e2) {
  206                       log.info(e2);
  207                       throw new ServletException(e2);
  208                   }
  209               } finally {
  210                   closeStaxBuilder(msgContext);
  211                   TransportUtils.deleteAttachments(msgContext);
  212               }
  213           } else {
  214               if (!disableREST) {
  215                   new RestRequestProcessor(Constants.Configuration.HTTP_METHOD_POST, request, response)
  216                           .processXMLRequest();
  217               } else {
  218                   showRestDisabledErrorMessage(response);
  219               }
  220           }
  221       }
  222   
  223       /**
  224        * Implementation for GET interface
  225        *
  226        * @param request
  227        * @param response
  228        * @throws ServletException
  229        * @throws IOException
  230        */
  231   
  232       protected void doGet(HttpServletRequest request,
  233                            HttpServletResponse response) throws ServletException, IOException {
  234   
  235           initContextRoot(request);
  236   
  237           // this method is also used to serve for the listServices request.
  238   
  239           String requestURI = request.getRequestURI();
  240           String query = request.getQueryString();
  241   
  242           // There can be three different request coming to this.
  243           // 1. wsdl, wsdl2 and xsd requests
  244           // 2. list services requests
  245           // 3. REST requests.
  246           if ((query != null) && new QueryStringParser(query).search(metadataQueryParamNames)) {
  247               // handling meta data exchange stuff
  248               agent.initTransportListener(request);
  249               agent.processListService(request, response);
  250           } else if (requestURI.endsWith(".xsd") ||
  251                   requestURI.endsWith(".wsdl")) {
  252               agent.processExplicitSchemaAndWSDL(request, response);
  253           } else if (requestURI.endsWith(LIST_SERVICES_SUFFIX) ||
  254                   requestURI.endsWith(LIST_FAULTY_SERVICES_SUFFIX)) {
  255               // handling list services request
  256               try {
  257                   agent.handle(request, response);
  258               } catch (Exception e) {
  259                   throw new ServletException(e);
  260               }
  261           } else if (!disableREST) {
  262               new RestRequestProcessor(Constants.Configuration.HTTP_METHOD_GET, request, response)
  263                       .processURLRequest();
  264           } else {
  265               showRestDisabledErrorMessage(response);
  266           }
  267       }
  268   
  269       /**
  270        * Implementation of DELETE interface
  271        *
  272        * @param request
  273        * @param response
  274        * @throws ServletException
  275        * @throws IOException
  276        */
  277   
  278       protected void doDelete(HttpServletRequest request,
  279                               HttpServletResponse response) throws ServletException, IOException {
  280   
  281           initContextRoot(request);
  282           // this method is also used to serve for the listServices request.
  283           if (!disableREST) {
  284               new RestRequestProcessor(Constants.Configuration.HTTP_METHOD_DELETE, request, response)
  285                       .processURLRequest();
  286           } else {
  287               showRestDisabledErrorMessage(response);
  288           }
  289       }
  290   
  291       /**
  292        * Implementation of PUT interface
  293        *
  294        * @param request
  295        * @param response
  296        * @throws ServletException
  297        * @throws IOException
  298        */
  299       protected void doPut(HttpServletRequest request,
  300                            HttpServletResponse response) throws ServletException, IOException {
  301   
  302           initContextRoot(request);
  303           // this method is also used to serve for the listServices request.
  304           if (!disableREST) {
  305               new RestRequestProcessor(Constants.Configuration.HTTP_METHOD_PUT, request, response)
  306                       .processXMLRequest();
  307           } else {
  308               showRestDisabledErrorMessage(response);
  309           }
  310       }
  311   
  312       /**
  313        * Private method that deals with disabling of REST support.
  314        *
  315        * @param response
  316        * @throws IOException
  317        */
  318       protected void showRestDisabledErrorMessage(HttpServletResponse response) throws IOException {
  319           PrintWriter writer = new PrintWriter(response.getOutputStream());
  320           writer.println("<html><body><h2>Please enable REST support in WEB-INF/conf/axis2.xml " +
  321                   "and WEB-INF/web.xml</h2></body></html>");
  322           writer.flush();
  323           response.setStatus(HttpServletResponse.SC_ACCEPTED);
  324       }
  325   
  326       /**
  327        * Close the builders.
  328        *
  329        * @param messageContext
  330        * @throws ServletException
  331        */
  332       private void closeStaxBuilder(MessageContext messageContext) throws ServletException {
  333           if (closeReader && messageContext != null) {
  334               try {
  335                   SOAPEnvelope envelope = messageContext.getEnvelope();
  336                   if(envelope != null) {
  337                       StAXBuilder builder = (StAXBuilder) envelope.getBuilder();
  338                       if (builder != null) {
  339                           builder.close();
  340                       }
  341                   }
  342               } catch (Exception e) {
  343                   log.debug(e.toString(), e);
  344               }
  345           }
  346       }
  347   
  348       /**
  349        * Processing for faults
  350        *
  351        * @param msgContext
  352        * @param res
  353        * @param out
  354        * @param e
  355        */
  356       private void processAxisFault(MessageContext msgContext, HttpServletResponse res,
  357                                     OutputStream out, AxisFault e) {
  358           try {
  359               // If the fault is not going along the back channel we should be 202ing
  360               if (AddressingHelper.isFaultRedirected(msgContext)) {
  361                   res.setStatus(HttpServletResponse.SC_ACCEPTED);
  362               } else {
  363   
  364                   String status =
  365                           (String) msgContext.getProperty(Constants.HTTP_RESPONSE_STATE);
  366                   if (status == null) {
  367                       res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
  368                   } else {
  369                       res.setStatus(Integer.parseInt(status));
  370                   }
  371   
  372                   AxisBindingOperation axisBindingOperation =
  373                           (AxisBindingOperation) msgContext
  374                                   .getProperty(Constants.AXIS_BINDING_OPERATION);
  375                   if (axisBindingOperation != null) {
  376                       AxisBindingMessage fault = axisBindingOperation
  377                               .getFault((String) msgContext.getProperty(Constants.FAULT_NAME));
  378                       if (fault != null) {
  379                           Integer code = (Integer) fault.getProperty(WSDL2Constants.ATTR_WHTTP_CODE);
  380                           if (code != null) {
  381                               res.setStatus(code.intValue());
  382                           }
  383                       }
  384                   }
  385               }
  386               handleFault(msgContext, out, e);
  387           } catch (AxisFault e2) {
  388               log.info(e2);
  389           }
  390       }
  391   
  392       protected void handleFault(MessageContext msgContext, OutputStream out, AxisFault e)
  393               throws AxisFault {
  394           msgContext.setProperty(MessageContext.TRANSPORT_OUT, out);
  395   
  396           MessageContext faultContext =
  397                   MessageContextBuilder.createFaultMessageContext(msgContext, e);
  398           // SOAP 1.2 specification mentions that we should send HTTP code 400 in a fault if the
  399           // fault code Sender
  400           HttpServletResponse response =
  401                   (HttpServletResponse) msgContext.getProperty(HTTPConstants.MC_HTTP_SERVLETRESPONSE);
  402           if (response != null) {
  403   
  404               //TODO : Check for SOAP 1.2!
  405               SOAPFaultCode code = faultContext.getEnvelope().getBody().getFault().getCode();
  406   
  407               OMElement valueElement = null;
  408               if (code != null) {
  409                   valueElement = code.getFirstChildWithName(new QName(
  410                           SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI,
  411                           SOAP12Constants.SOAP_FAULT_VALUE_LOCAL_NAME));
  412               }
  413   
  414               if (valueElement != null) {
  415                   if (SOAP12Constants.FAULT_CODE_SENDER.equals(valueElement.getTextAsQName().getLocalPart())
  416                           && !msgContext.isDoingREST()) {
  417                       response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
  418                   }
  419               }
  420           }
  421   
  422   
  423           AxisEngine.sendFault(faultContext);
  424       }
  425   
  426       /**
  427        * Main init method
  428        *
  429        * @param config
  430        * @throws ServletException
  431        */
  432       public void init(ServletConfig config) throws ServletException {
  433           
  434           // prevent this method from being called more than once per instance
  435           initCalled = true;
  436           super.init(config);
  437           try {
  438               this.servletConfig = config;
  439               ServletContext servletContext = servletConfig.getServletContext();
  440               this.configContext =
  441                       (ConfigurationContext) servletContext.getAttribute(CONFIGURATION_CONTEXT);
  442               if(configContext == null){
  443                   configContext = initConfigContext(config);
  444                   config.getServletContext().setAttribute(CONFIGURATION_CONTEXT, configContext);
  445               }
  446               axisConfiguration = configContext.getAxisConfiguration();
  447   
  448               ListenerManager listenerManager = new ListenerManager();
  449               listenerManager.init(configContext);
  450               TransportInDescription transportInDescription = new TransportInDescription(
  451                       Constants.TRANSPORT_HTTP);
  452               transportInDescription.setReceiver(this);
  453               listenerManager.addListener(transportInDescription, true);
  454               listenerManager.start();
  455               ListenerManager.defaultConfigurationContext = configContext;
  456               agent = new ListingAgent(configContext);
  457   
  458               initParams();
  459   
  460           } catch (Exception e) {
  461               throw new ServletException(e);
  462           }
  463       }
  464   
  465       /**
  466        * distroy the ConfigurationContext
  467        */
  468       public void destroy() {
  469           //stoping listner manager
  470           try {
  471               if (configContext != null) {
  472                   configContext.terminate();
  473               }
  474           } catch (AxisFault axisFault) {
  475               log.info(axisFault.getMessage());
  476           }
  477           try {
  478               super.destroy();
  479           } catch (Exception e) {
  480               log.info(e.getMessage());
  481           }
  482       }
  483   
  484       /**
  485        * Initializes the Axis2 parameters.
  486        */
  487       protected void initParams() {
  488           Parameter parameter;
  489           // do we need to completely disable REST support
  490           parameter = axisConfiguration.getParameter(Constants.Configuration.DISABLE_REST);
  491           if (parameter != null) {
  492               disableREST = !JavaUtils.isFalseExplicitly(parameter.getValue());
  493           }
  494   
  495           // Should we close the reader(s)
  496           parameter = axisConfiguration.getParameter("axis2.close.reader");
  497           if (parameter != null) {
  498               closeReader = JavaUtils.isTrueExplicitly(parameter.getValue());
  499           }
  500   
  501       }
  502   
  503       /**
  504        * Convenient method to re-initialize the ConfigurationContext
  505        *
  506        * @throws ServletException
  507        */
  508       public void init() throws ServletException {
  509           if (this.servletConfig != null
  510                   &&
  511                   !initCalled) {
  512               init(this.servletConfig);
  513           }
  514       }
  515   
  516       /**
  517        * Initialize the Axis configuration context
  518        *
  519        * @param config Servlet configuration
  520        * @return ConfigurationContext
  521        * @throws ServletException
  522        */
  523       protected ConfigurationContext initConfigContext(ServletConfig config) throws ServletException {
  524           try {
  525               ConfigurationContext configContext =
  526                       ConfigurationContextFactory
  527                               .createConfigurationContext(new WarBasedAxisConfigurator(config));
  528               configContext.setProperty(Constants.CONTAINER_MANAGED, Constants.VALUE_TRUE);
  529               return configContext;
  530           } catch (Exception e) {
  531               log.info(e);
  532               throw new ServletException(e);
  533           }
  534       }
  535   
  536       /**
  537        * Set the context root if it is not set already.
  538        *
  539        * @param req
  540        */
  541       public void initContextRoot(HttpServletRequest req) {
  542           if (contextRoot != null && contextRoot.trim().length() != 0) {
  543               return;
  544           }
  545           String contextPath = null;
  546           // Support older servlet API's
  547           try {
  548               contextPath = req.getContextPath();
  549           } catch (Throwable t) {
  550               log.info("Old Servlet API (Fallback to HttpServletRequest.getServletPath) :" + t);    
  551               contextPath = req.getServletPath();
  552           }
  553           //handling ROOT scenario, for servlets in the default (root) context, this method returns ""
  554           if (contextPath != null && contextPath.length() == 0) {
  555               contextPath = "/";
  556           }
  557           this.contextRoot = contextPath;
  558   
  559           configContext.setContextRoot(contextRoot);
  560       }
  561   
  562       /**
  563        * Get all transport headers.
  564        *
  565        * @param req
  566        * @return Map
  567        */
  568       protected Map getTransportHeaders(HttpServletRequest req) {
  569           return new TransportHeaders(req);
  570       }
  571   
  572   
  573       public EndpointReference getEPRForService(String serviceName, String ip) throws AxisFault {
  574           return getEPRsForService(serviceName, ip)[0];
  575       }
  576   
  577       public EndpointReference[] getEPRsForService(String serviceName, String ip) throws AxisFault {
  578           //RUNNING_PORT
  579           String port = (String) configContext.getProperty(ListingAgent.RUNNING_PORT);
  580           if (port == null) {
  581               port = "8080";
  582           }
  583           if (ip == null) {
  584               try {
  585                   ip = Utils.getIpAddress(axisConfiguration);
  586                   if (ip == null) {
  587                       ip = "localhost";
  588                   }
  589               } catch (SocketException e) {
  590                   throw AxisFault.makeFault(e);
  591               }
  592           }
  593   
  594           String endpointRefernce = "http://" + ip + ":" + port;
  595           if (configContext.getServiceContextPath().startsWith("/")) {
  596               endpointRefernce = endpointRefernce +
  597                       configContext.getServiceContextPath() + "/" + serviceName;
  598           } else {
  599               endpointRefernce = endpointRefernce + '/' +
  600                       configContext.getServiceContextPath() + "/" + serviceName;
  601           }
  602           EndpointReference endpoint = new EndpointReference(endpointRefernce + "/");
  603   
  604           return new EndpointReference[]{endpoint};
  605       }
  606   
  607       /**
  608        * init(); start() and stop() wouldn't do anything.
  609        *
  610        * @param axisConf
  611        * @param transprtIn
  612        * @throws AxisFault
  613        */
  614       public void init(ConfigurationContext axisConf,
  615                        TransportInDescription transprtIn) throws AxisFault {
  616       }
  617   
  618       public void start() throws AxisFault {
  619       }
  620   
  621       public void stop() throws AxisFault {
  622       }
  623   
  624       /**
  625        * @param request
  626        * @param response
  627        * @param invocationType : If invocationType=true; then this will be used in SOAP message
  628        *                       invocation. If invocationType=false; then this will be used in REST message invocation.
  629        * @return MessageContext
  630        * @throws IOException
  631        */
  632       protected MessageContext createMessageContext(HttpServletRequest request,
  633                                                     HttpServletResponse response,
  634                                                     boolean invocationType) throws IOException {
  635           MessageContext msgContext = configContext.createMessageContext();
  636           String requestURI = request.getRequestURI();
  637   
  638           String trsPrefix = null;
  639           int sepindex = -1;
  640           // Support older servlet API's
  641           try { 
  642               trsPrefix = request.getRequestURL().toString();
  643           } catch (Throwable t){
  644               log.info("Old Servlet API (Fallback to HttpServletRequest.getRequestURI) :" + t);    
  645               trsPrefix = request.getRequestURI();
  646           }
  647           sepindex = trsPrefix.indexOf(':');
  648           if (sepindex > -1) {
  649               trsPrefix = trsPrefix.substring(0, sepindex);
  650               msgContext.setIncomingTransportName(trsPrefix);
  651           } else {
  652               msgContext.setIncomingTransportName(Constants.TRANSPORT_HTTP);
  653               trsPrefix = Constants.TRANSPORT_HTTP;
  654           }
  655           TransportInDescription transportIn =
  656                   axisConfiguration.getTransportIn(msgContext.getIncomingTransportName());
  657           //set the default output description. This will be http
  658   
  659           TransportOutDescription transportOut = axisConfiguration.getTransportOut(trsPrefix);
  660           if (transportOut == null) {
  661               // if the req coming via https but we do not have a https sender
  662               transportOut = axisConfiguration.getTransportOut(Constants.TRANSPORT_HTTP);
  663           }
  664   
  665   
  666           msgContext.setTransportIn(transportIn);
  667           msgContext.setTransportOut(transportOut);
  668           msgContext.setServerSide(true);
  669   
  670           if (!invocationType) {
  671               String query = request.getQueryString();
  672               if (query != null) {
  673                   requestURI = requestURI + "?" + query;
  674               }
  675           }
  676   
  677           msgContext.setTo(new EndpointReference(requestURI));
  678           msgContext.setFrom(new EndpointReference(request.getRemoteAddr()));
  679           msgContext.setProperty(MessageContext.REMOTE_ADDR, request.getRemoteAddr());
  680           msgContext.setProperty(Constants.OUT_TRANSPORT_INFO,
  681                   new ServletBasedOutTransportInfo(response));
  682           // set the transport Headers
  683           msgContext.setProperty(MessageContext.TRANSPORT_HEADERS, getTransportHeaders(request));
  684           msgContext.setProperty(HTTPConstants.MC_HTTP_SERVLETREQUEST, request);
  685           msgContext.setProperty(HTTPConstants.MC_HTTP_SERVLETRESPONSE, response);
  686           try {
  687               ServletContext context = getServletContext();
  688               if(context != null) {
  689                   msgContext.setProperty(HTTPConstants.MC_HTTP_SERVLETCONTEXT, context);
  690               }
  691           } catch (Exception e){
  692               log.debug(e.getMessage(), e);
  693           }
  694   
  695           //setting the RequestResponseTransport object
  696           msgContext.setProperty(RequestResponseTransport.TRANSPORT_CONTROL,
  697                   new ServletRequestResponseTransport(response));
  698   
  699           return msgContext;
  700       }
  701   
  702       /**
  703        * This method assumes, that the created MessageContext will be used in only SOAP invocation.
  704        *
  705        * @param req
  706        * @param resp
  707        * @return MessageContext
  708        * @throws IOException
  709        */
  710   
  711       protected MessageContext createMessageContext(HttpServletRequest req,
  712                                                     HttpServletResponse resp) throws IOException {
  713           return createMessageContext(req, resp, true);
  714       }
  715   
  716       /**
  717        * Transport session management.
  718        *
  719        * @param messageContext
  720        * @return SessionContext
  721        */
  722       public SessionContext getSessionContext(MessageContext messageContext) {
  723           HttpServletRequest req = (HttpServletRequest) messageContext.getProperty(
  724                   HTTPConstants.MC_HTTP_SERVLETREQUEST);
  725           SessionContext sessionContext =
  726                   (SessionContext) req.getSession(true).getAttribute(
  727                           Constants.SESSION_CONTEXT_PROPERTY);
  728           String sessionId = req.getSession().getId();
  729           if (sessionContext == null) {
  730               sessionContext = new SessionContext(null);
  731               sessionContext.setCookieID(sessionId);
  732               req.getSession().setAttribute(Constants.SESSION_CONTEXT_PROPERTY,
  733                       sessionContext);
  734           }
  735           messageContext.setSessionContext(sessionContext);
  736           messageContext.setProperty(SESSION_ID, sessionId);
  737           return sessionContext;
  738       }
  739   
  740       protected class ServletRequestResponseTransport implements RequestResponseTransport {
  741           private HttpServletResponse response;
  742           private boolean responseWritten = false;
  743           private CountDownLatch responseReadySignal = new CountDownLatch(1);
  744   		// The initial status must be WAITING, as the main servlet will do some other
  745   		// work after setting this RequestResponseTransport up, and we don't want to miss
  746   		// signals that come in before this thread gets to the awaitResponse call.
  747           private RequestResponseTransportStatus status = RequestResponseTransportStatus.WAITING;
  748           AxisFault faultToBeThrownOut = null;
  749   
  750           ServletRequestResponseTransport(HttpServletResponse response) {
  751               this.response = response;
  752           }
  753   
  754           public void acknowledgeMessage(MessageContext msgContext) throws AxisFault {
  755               status = RequestResponseTransportStatus.ACKED;
  756               responseReadySignal.countDown();
  757           }
  758   
  759           public void awaitResponse()
  760                   throws InterruptedException, AxisFault {
  761               log.debug("Blocking servlet thread -- awaiting response");
  762               responseReadySignal.await();
  763   
  764               if (faultToBeThrownOut != null) {
  765                   throw faultToBeThrownOut;
  766               }
  767           }
  768   
  769           public void signalResponseReady() {
  770               log.debug("Signalling response available");
  771               status = RequestResponseTransportStatus.SIGNALLED;
  772               responseReadySignal.countDown();
  773           }
  774   
  775           public RequestResponseTransportStatus getStatus() {
  776               return status;
  777           }
  778   
  779           public void signalFaultReady(AxisFault fault) {
  780               faultToBeThrownOut = fault;
  781               signalResponseReady();
  782           }
  783           
  784           public boolean isResponseWritten() {
  785           	return responseWritten;
  786           }
  787           
  788           public void setResponseWritten(boolean responseWritten) {
  789           	this.responseWritten = responseWritten;
  790           }
  791           
  792       }
  793   
  794       private void setResponseState(MessageContext messageContext, HttpServletResponse response) {
  795           String state = (String) messageContext.getProperty(Constants.HTTP_RESPONSE_STATE);
  796           if (state != null) {
  797               int stateInt = Integer.parseInt(state);
  798               if (stateInt == HttpServletResponse.SC_UNAUTHORIZED) { // Unauthorized
  799                   String realm = (String) messageContext.getProperty(Constants.HTTP_BASIC_AUTH_REALM);
  800                   response.addHeader("WWW-Authenticate",
  801                           "basic realm=\"" + realm + "\"");
  802               }
  803           }
  804       }
  805   
  806       /**
  807        * Ues in processing REST related Requests.
  808        * This is the helper Class use in processing of doGet, doPut , doDelete and doPost.
  809        */
  810       protected class RestRequestProcessor {
  811           protected MessageContext messageContext;
  812           private HttpServletRequest request;
  813           private HttpServletResponse response;
  814   
  815           public RestRequestProcessor(String httpMethodString,
  816                                       HttpServletRequest request,
  817                                       HttpServletResponse response) throws IOException {
  818               this.request = request;
  819               this.response = response;
  820               messageContext = createMessageContext(this.request, this.response, false);
  821               messageContext.setProperty(org.apache.axis2.transport.http.HTTPConstants.HTTP_METHOD,
  822                       httpMethodString);
  823           }
  824   
  825           public void processXMLRequest() throws IOException, ServletException {
  826               try {
  827                   RESTUtil.processXMLRequest(messageContext, request.getInputStream(),
  828                           response.getOutputStream(), request.getContentType());
  829                   this.checkResponseWritten();
  830               } catch (AxisFault axisFault) {
  831                   processFault(axisFault);
  832               }
  833               closeStaxBuilder(messageContext);
  834           }
  835   
  836           public void processURLRequest() throws IOException, ServletException {
  837               try {
  838                   RESTUtil.processURLRequest(messageContext, response.getOutputStream(),
  839                           request.getContentType());
  840                   this.checkResponseWritten();
  841               } catch (AxisFault e) {
  842                   setResponseState(messageContext, response);
  843                   processFault(e);
  844               }
  845               closeStaxBuilder(messageContext);
  846   
  847           }
  848   
  849           private void checkResponseWritten() {
  850           	if (!TransportUtils.isResponseWritten(messageContext)) {
  851           		response.setStatus(HttpServletResponse.SC_ACCEPTED);
  852               }
  853           }
  854   
  855           private void processFault(AxisFault e) throws ServletException, IOException {
  856               log.debug(e);
  857               if (messageContext != null) {
  858                   processAxisFault(messageContext, response, response.getOutputStream(), e);
  859               } else {
  860                   throw new ServletException(e);
  861               }
  862   
  863           }
  864   
  865       }
  866   }

Save This Page
Home » axis2-1.5-src » org.apache » axis2 » transport » http » [javadoc | source]