Package org.apache.axis2.transport.http

Source Code of org.apache.axis2.transport.http.HTTPWorker

/*
* Copyright 2004,2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/


package org.apache.axis2.transport.http;

import org.apache.axis2.AxisFault;
import org.apache.axis2.Constants;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.context.OperationContext;
import org.apache.axis2.context.SessionContext;
import org.apache.axis2.description.AxisService;
import org.apache.axis2.description.Parameter;
import org.apache.axis2.description.TransportOutDescription;
import org.apache.axis2.engine.AxisConfiguration;
import org.apache.axis2.engine.AxisEngine;
import org.apache.axis2.i18n.Messages;
import org.apache.axis2.transport.http.server.HttpRequestHandler;
import org.apache.axis2.transport.http.server.SimpleHttpServerConnection;
import org.apache.axis2.transport.http.server.SimpleRequest;
import org.apache.axis2.transport.http.server.SimpleResponse;
import org.apache.axis2.util.UUIDGenerator;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpVersion;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.xml.namespace.QName;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.SocketException;
import java.util.Date;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;

public class HTTPWorker implements HttpRequestHandler {

    protected Log log = LogFactory.getLog(getClass().getName());
    private ConfigurationContext configurationContext;
    // to store session object
    private Hashtable sessionContextTable = new Hashtable();

    public HTTPWorker(ConfigurationContext configurationContext) {
        this.configurationContext = configurationContext;
    }

    public boolean processRequest(final SimpleHttpServerConnection conn,
                                  final SimpleRequest request)
            throws IOException {
        MessageContext msgContext = null;
        SimpleResponse response = new SimpleResponse();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();

        try {
            if (configurationContext == null) {
                throw new AxisFault(Messages.getMessage("cannotBeNullConfigurationContext"));
            }
            InputStream inStream = request.getBody();
            TransportOutDescription transportOut =
                    configurationContext.getAxisConfiguration().getTransportOut(
                            new QName(Constants.TRANSPORT_HTTP));
            String cookieID = request.getCookieID();
            SessionContext sessionContext = getSessionContext(cookieID);

            msgContext = new MessageContext();
            msgContext.setIncomingTransportName(Constants.TRANSPORT_HTTP);
            msgContext.setConfigurationContext(configurationContext);
            msgContext.setSessionContext(sessionContext);
            msgContext.setTransportIn(configurationContext.getAxisConfiguration().getTransportIn(
                    new QName(Constants.TRANSPORT_HTTP)));
            msgContext.setTransportOut(transportOut);
            msgContext.setServerSide(true);

            HttpVersion ver = request.getRequestLine().getHttpVersion();

            if (ver == null) {
                throw new AxisFault("HTTP version can not be Null");
            }


            if (HttpVersion.HTTP_1_0.equals(ver)) {
//                httpVersion = HTTPConstants.HEADER_PROTOCOL_10;
            } else if (HttpVersion.HTTP_1_1.equals(ver)) {
//                httpVersion = HTTPConstants.HEADER_PROTOCOL_11;

                /**
                 * Transport Sender configuration via axis2.xml
                 */
                this.transportOutConfiguration(configurationContext, response);
            } else {
                throw new AxisFault("Unknown supported protocol version " + ver);
            }

            msgContext.setProperty(MessageContext.TRANSPORT_OUT, baos);

            // set the transport Headers
            msgContext.setProperty(MessageContext.TRANSPORT_HEADERS, getHeaders(request));
            msgContext.setServiceGroupContextId(UUIDGenerator.getUUID());

            // This is way to provide access to the transport information to the transport Sender
            msgContext.setProperty(Constants.OUT_TRANSPORT_INFO,
                    new SimpleHTTPOutTransportInfo(response));
            msgContext.setProperty(Constants.Configuration.TRANSPORT_IN_URL, request.getRequestLine().getUri());


            String soapAction = null;

            if (request.getFirstHeader(HTTPConstants.HEADER_SOAP_ACTION) != null) {
                soapAction = request.getFirstHeader(HTTPConstants.HEADER_SOAP_ACTION).getValue();
            }

            if (HTTPConstants.HEADER_GET.equals(request.getRequestLine().getMethod())) {
                String uri = request.getRequestLine().getUri();
                log.debug("HTTP GET:" + uri);
                if (uri.equals("/favicon.ico")) {
                    response.setStatusLine(request.getRequestLine().getHttpVersion(), 301, "Redirect");
                    response.addHeader(new Header("Location", "http://ws.apache.org/favicon.ico"));
                    conn.writeResponse(response);
                    return true;
                }
                if (!uri.startsWith("/axis2/services/")) {
                    response.setStatusLine(request.getRequestLine().getHttpVersion(), 301, "Redirect");
                    response.addHeader(new Header("Location", "/axis2/services/"));
                    conn.writeResponse(response);
                    return true;
                }

                if (uri.indexOf("?") < 0) {
                    if (!(uri.endsWith("/axis2/services/") || uri.endsWith("/axis2/services"))) {
                        String serviceName = uri.replaceAll("/axis2/services/", "");
                        if (serviceName.indexOf("/") < 0) {
                            response.addHeader(new Header("Content-Type", "text/html"));
                            String res = HTTPTransportReceiver.printServiceHTML(serviceName, configurationContext);
                            byte[] buf = res.getBytes();
                            response.setBody(new ByteArrayInputStream(buf));
                            conn.writeResponse(response);
                            return true;
                        }
                    }
                }

                if (uri.endsWith("?wsdl")) {
                    String serviceName = uri.substring(uri.lastIndexOf("/") + 1, uri.length() - 5);
                    HashMap services = configurationContext.getAxisConfiguration().getServices();
                    AxisService service = (AxisService) services.get(serviceName);
                    if (service != null) {
                        response.addHeader(new Header("Content-Type", "text/xml"));
//                        String url = conn.getURL(uri.substring(1, uri.length() - 5));
                        String url = conn.getURL("");
                        int ipindex = url.indexOf("//");
                        String ip = null;
                        if (ipindex >= 0) {
                            ip = url.substring(ipindex + 2, url.length());
                            int seperatorIndex = ip.indexOf(":");
                            if (seperatorIndex > 0) {
                                ip = ip.substring(0, seperatorIndex);
                            }
                        }
                        service.printWSDL(baos, ip);
                        byte[] buf = baos.toByteArray();
                        response.setBody(new ByteArrayInputStream(buf));
                        conn.writeResponse(response);
                        return true;
                    }
                }
                if (uri.endsWith("?xsd")) {
                    String serviceName = uri.substring(uri.lastIndexOf("/") + 1, uri.length() - 4);
                    HashMap services = configurationContext.getAxisConfiguration().getServices();
                    AxisService service = (AxisService) services.get(serviceName);
                    if (service != null) {
                        response.addHeader(new Header("Content-Type", "text/xml"));
                        service.printSchema(baos);
                        byte[] buf = baos.toByteArray();
                        response.setBody(new ByteArrayInputStream(buf));
                        conn.writeResponse(response);
                        return true;
                    }
                }

                // It is GET handle the Get request
                boolean processed = HTTPTransportUtils.processHTTPGetRequest(
                        msgContext, inStream, baos, request.getContentType(),
                        soapAction, request.getRequestLine().getUri(),
                        configurationContext,
                        HTTPTransportReceiver.getGetRequestParameters(
                                request.getRequestLine().getUri()));

                if (!processed) {
                    response.setStatusLine(request.getRequestLine().getHttpVersion(), 200, "OK");
                    response.addHeader(new Header("Content-Type", "text/html"));
                    response.setBodyString(
                            HTTPTransportReceiver.getServicesHTML(configurationContext));
                    setResponseHeaders(conn, request, response, 0, msgContext);
                    conn.writeResponse(response);

                    return true;
                }
            } else {
                ByteArrayOutputStream baosIn = new ByteArrayOutputStream();
                byte[]                bytes = new byte[8192];
                int size;

                while ((size = inStream.read(bytes)) > 0) {
                    baosIn.write(bytes, 0, size);
                }

                inStream = new ByteArrayInputStream(baosIn.toByteArray());

                // It is POST, handle it
                HTTPTransportUtils.processHTTPPostRequest(msgContext, inStream, baos,
                        request.getContentType(), soapAction, request.getRequestLine().getUri());
            }

            OperationContext operationContext = msgContext.getOperationContext();
            Object contextWritten = null;

            if (operationContext != null) {
                contextWritten = operationContext.getProperty(Constants.RESPONSE_WRITTEN);
            }

            if ((contextWritten != null) && Constants.VALUE_TRUE.equals(contextWritten)) {
                response.setStatusLine(request.getRequestLine().getHttpVersion(), 200, "OK");
            } else {
                response.setStatusLine(request.getRequestLine().getHttpVersion(), 202, "OK");
            }

            byte[] buf = baos.toByteArray();
            response.setBody(new ByteArrayInputStream(buf));
            setResponseHeaders(conn, request, response, buf.length, msgContext);

            conn.writeResponse(response);
        } catch (Throwable e) {
            if (!(e instanceof java.net.SocketException)) {
                log.debug(e.getMessage(), e);
            }

            try {
                AxisEngine engine = new AxisEngine(configurationContext);

                if (msgContext != null) {
                    msgContext.setProperty(MessageContext.TRANSPORT_OUT, baos);

                    MessageContext faultContext = engine.createFaultMessageContext(msgContext, e);

                    response.setStatusLine(request.getRequestLine().getHttpVersion(), 500,
                            "Internal server error");
                    engine.sendFault(faultContext);
                    byte[] buf = baos.toByteArray();
                    response.setBody(new ByteArrayInputStream(buf));
                    setResponseHeaders(conn, request, response, buf.length, msgContext);
                    conn.writeResponse(response);
                }
            } catch (SocketException e1) {
                log.debug(e1.getMessage(), e1);
            } catch (Exception e1) {
                log.warn(e1.getMessage(), e1);
            }
        }

        return true;
    }

    /**
     * Simple Axis Transport Selection via deployment
     *
     * @param configContext
     * @param response
     */
    private void transportOutConfiguration(ConfigurationContext configContext,
                                           SimpleResponse response) {
        AxisConfiguration axisConf = configContext.getAxisConfiguration();
        HashMap transportOuts = axisConf.getTransportsOut();
        Iterator values = transportOuts.values().iterator();

        while (values.hasNext()) {
            TransportOutDescription transportOut = (TransportOutDescription) values.next();

            // reading axis2.xml for transport senders..
            Parameter version = transportOut.getParameter(HTTPConstants.PROTOCOL_VERSION);

            if (version != null) {
                if (HTTPConstants.HEADER_PROTOCOL_11.equals(version.getValue())) {

                    Parameter transferEncoding =
                            transportOut.getParameter(HTTPConstants.HEADER_TRANSFER_ENCODING);

                    if (transferEncoding != null) {
                        if (HTTPConstants.HEADER_TRANSFER_ENCODING_CHUNKED.equals(
                                transferEncoding.getValue())) {
                            response.setHeader(
                                    new Header(
                                            HTTPConstants.HEADER_TRANSFER_ENCODING,
                                            HTTPConstants.HEADER_TRANSFER_ENCODING_CHUNKED));
                        }
                    }
                }
            }
        }
    }

    private Map getHeaders(SimpleRequest request) {
        HashMap headerMap = new HashMap();
        Header[] headers = request.getHeaders();

        for (int i = 0; i < headers.length; i++) {
            headerMap.put(headers[i].getName(), headers[i].getValue());
        }

        return headerMap;
    }

    private void setResponseHeaders(final SimpleHttpServerConnection conn, SimpleRequest request,
                                    SimpleResponse response, long contentLength, MessageContext msgContext) {
        if (!response.containsHeader("Connection")) {

            // See if the the client explicitly handles connection persistence
            Header connheader = request.getFirstHeader("Connection");

            if (connheader != null) {
                if (connheader.getValue().equalsIgnoreCase("keep-alive")) {
                    Header header = new Header("Connection", "keep-alive");

                    response.addHeader(header);
                    conn.setKeepAlive(true);
                }

                if (connheader.getValue().equalsIgnoreCase("close")) {
                    Header header = new Header("Connection", "close");

                    response.addHeader(header);
                    conn.setKeepAlive(false);
                }
            } else {

                // Use protocol default connection policy
                if (response.getHttpVersion().greaterEquals(HttpVersion.HTTP_1_1)) {
                    conn.setKeepAlive(true);
                } else {
                    conn.setKeepAlive(false);
                }
            }
        }
        //TODO : provide a way to enable and diable cookies
        //setting the coolie in the out path
        Object cookieString = msgContext.getProperty(Constants.COOKIE_STRING);
        if (cookieString != null) {
            response.addHeader(new Header(HTTPConstants.HEADER_SET_COOKIE, (String) cookieString));
            response.addHeader(new Header(HTTPConstants.HEADER_SET_COOKIE2, (String) cookieString));
        }

        if (!response.containsHeader("Transfer-Encoding")) {
            if (contentLength != 0) {
                Header header = new Header("Content-Length", String.valueOf(contentLength));

                response.addHeader(header);
            }
        }
    }

    /**
     * To get the sessioncontext , if its not there in the hashtable , new one will be created and
     * added to the list.
     *
     * @param cookieID
     * @return <code>SessionContext</code>
     */
    private synchronized SessionContext getSessionContext(String cookieID) {
        SessionContext sessionContext = null;
        if (!(cookieID == null || cookieID.trim().equals(""))) {
            sessionContext = (SessionContext) sessionContextTable.get(cookieID);
        }
        if (sessionContext == null) {
            String cookieString = UUIDGenerator.getUUID();
            sessionContext = new SessionContext(null);
            sessionContext.setCookieID(cookieString);
            sessionContextTable.put(cookieString, sessionContext);
        }
        sessionContext.touch();
        cleanupServiceGroupContexts();
        return sessionContext;
    }

    private void cleanupServiceGroupContexts() {
        synchronized (sessionContextTable) {
            long currentTime = new Date().getTime();
            Iterator sgCtxtMapKeyIter = sessionContextTable.keySet().iterator();
            while (sgCtxtMapKeyIter.hasNext()) {
                String cookieID = (String) sgCtxtMapKeyIter.next();
                SessionContext sessionContext = (SessionContext) sessionContextTable.get(cookieID);
                if ((currentTime - sessionContext.getLastTouchedTime()) >
                        sessionContext.sessionContextTimeoutInterval) {
                    sgCtxtMapKeyIter.remove();
                }
            }
        }
    }

}
TOP

Related Classes of org.apache.axis2.transport.http.HTTPWorker

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.