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

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