Package com.ericsson.ssa.sip

Source Code of com.ericsson.ssa.sip.ConvergedHttpSessionFacade

/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 1997-2009 Sun Microsystems, Inc. All rights reserved.
* Copyright (c) Ericsson AB, 2004-2008. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License").  You
* may not use this file except in compliance with the License. You can obtain
* a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
* or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
* Sun designates this particular file as subject to the "Classpath" exception
* as provided by Sun in the GPL Version 2 section of the License file that
* accompanied this code.  If applicable, add the following below the License
* Header, with the fields enclosed by brackets [] replaced by your own
* identifying information: "Portions Copyrighted [year]
* [name of copyright owner]"
*
* Contributor(s):
*
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license."  If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above.  However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.ericsson.ssa.sip;

import com.ericsson.ssa.config.Constants;
import com.ericsson.ssa.config.ConvergedContext;
import com.ericsson.ssa.config.ConvergedContextImpl;
import com.ericsson.ssa.sip.SipApplicationSessionImpl;
import com.ericsson.ssa.sip.SipApplicationSessionUtil;
import com.ericsson.ssa.sip.persistence.ReplicationUnitOfWork;

import com.ericsson.ssa.utils.UUIDUtil;
import org.apache.catalina.Globals;
import org.apache.catalina.session.StandardSession;
import org.apache.catalina.session.StandardSessionFacade;
import org.apache.catalina.util.RequestUtil;
import org.jvnet.glassfish.comms.util.LogUtil;

import java.net.MalformedURLException;
import java.net.URL;

import java.util.HashMap;
import java.util.UUID;
import java.util.logging.Logger;
import java.util.logging.Level;

import javax.servlet.ServletContext;
import javax.servlet.sip.ConvergedHttpSession;
import javax.servlet.sip.SipApplicationSession;

/**
* Class representing a ConvergedHttpSession.
*
* @author jluehe
*/
public class ConvergedHttpSessionFacade extends StandardSessionFacade
    implements ConvergedHttpSession {

    private static final Logger logger = LogUtil.SIP_LOGGER.getLogger();
   
    private static final String HTTP_PROTOCOL = "http";
    private static final String HTTPS_PROTOCOL = "https";

    // The parent SipApplicationSession
    private SipApplicationSessionImpl sipAppSession;

    // The nested HTTP session for which this object acts as a facade
    private StandardSession httpSession;

    /*
     * The servlet context associated with the session manager of the session
     * for which this object acts as a facade
     */
    private ServletContext servletCtxt;
   
    private ConvergedContext convergedCtxt;

    // The SipSessionManager to look up the SipApplicationSession parent
    private SipSessionManager sipSessionManager;

    public void invalidate() {
        try {
            super.invalidate();
        } finally {
            removeFromSAS();
        }
    }

    private void removeFromSAS() {
        try {
            SipApplicationSessionImpl sas =
                    (SipApplicationSessionImpl) getApplicationSession(false);
            if (sas != null) {
                // don't attempt to remove the httpsession again from its sessionmanager,
                // super.invalidate() would already have removed it.
                sas.removeSession(httpSession, false);
            }
        } catch (Exception e) { // could be remotelock or illegalstate exception.
            logger.log(Level.WARNING, e.getMessage(), e);
        }
    }


    /**
     * Constructor
     */
    public ConvergedHttpSessionFacade(StandardSession httpSession,
        ConvergedContextImpl ctxt) {
        super(httpSession);
        this.httpSession = httpSession;
        this.convergedCtxt = ctxt;
        this.sipSessionManager = ctxt.getSipSessionManager();
        this.servletCtxt = ctxt.getServletContext();
    }

    /**
     * Returns the parent <code>SipApplicationSession</code> if it exists.
     * If none exists, a new one is created (and this ConvergedHttpSession
     * added as its child) and returned.
     *
     * @return the parent SipApplicationSession
     */
    public SipApplicationSession getApplicationSession() {
        return getApplicationSession(true);
    }

    /**
     * Returns the parent <code>SipApplicationSession</code> if it exists.
     * If none exists, and <code>create</code> is set to true, a new one is
     * created (and this ConvergedHttpSession added as its child) and returned.
     *
     * @param create true if new SipApplicationSession is to be created if
     * none already exists, false otherwise
     *
     * @return the parent SipApplicationSession
     */
    public SipApplicationSession getApplicationSession(boolean create) {
        if (sipAppSession != null) {
            return sipAppSession;
        }

        // Check to see if our nested HTTP session already has any
        // SipApplicationSession id associated with it.
        String sipAppSessionId = httpSession.getSipApplicationSessionId();

        if (sipAppSessionId == null) {
            // Check to see if the request URL that was used to resume the
            // HTTP session contains an encoded SipApplicationSession id.
            sipAppSessionId = parseRequestParameter(
                Constants.SAS_ID_URI_PARAMETER);
        }

        if (sipAppSessionId != null) {
            // Look up the SipApplicationSession with the given id
            try {
                sipAppSession = sipSessionManager.findSipApplicationSession(sipAppSessionId);
            } catch (RemoteLockException e) {
                throw new RemoteLockRuntimeException(e);
            }
        } else if (create) {
            // Create a new SipApplicationSession
            String bekey = (String) httpSession.getBeKey();
            if (bekey != null) {
                sipAppSession = sipSessionManager.createSipApplicationSession(
                    SipApplicationSessionUtil.createSasId(bekey,
                        convergedCtxt.getAppName(), UUIDUtil.randomUUID()),
                    convergedCtxt.getSipApplicationListeners());
            } else {
                sipAppSession = sipSessionManager.createSipApplicationSession(
                    convergedCtxt.getSipApplicationListeners());
            }

            ReplicationUnitOfWork uow =
                ReplicationUnitOfWork.getThreadLocalUnitOfWork();
            if (uow != null) {
                uow.lockApplicationSession(sipAppSession);
            }
        }

        if ((sipAppSession != null) &&
                (httpSession.getSipApplicationSessionId() == null)) {
            // Associate the nested HTTP session with the SipApplicationSession
            httpSession.setSipApplicationSessionId(sipAppSession.getId());
            ((SipApplicationSessionImpl) sipAppSession).addSession(this);
        }

        return sipAppSession;
    }

    /**
     * Encodes the HTTP URL with the jsessionid. ";jsessionid=http-session-id".
     * The URL parameter should be an absolute URL. For example,
     * http://server:7001/mywebapp/foo.jsp. Where "/mywebapp" is the context
     * path of the the current ServletContext, because that is where the
     * httpSession belongs to.
     *
     * @param url the HTTP URL String to be encoded
     *
     * @return encoded URL with jsessionid
     */
    public String encodeURL(String url) {

        if (!isEncodeable(url)) {
            return url;
        } else {
            return toEncoded(url);
        }
    }

    /**
     * Converts the given relative path to an absolute URL by prepending
     * the contextPath for the current ServletContext, the given scheme
     * ("http" or "https"), and the host:port, and then encoding the
     * resulting URL with the jsessionid.
     *
     * For example, this method converts:
     *
     *   from: "/foo.jsp"
     *   to: "http://server:8888/mywebapp/foo.jsp;jsessionid=http-session-id"
     *
     * Where, "/mywebapp" is the contextPath for the current ServletContext
     * server is the front end host defined for the web server.
     *
     * @param relativePath relative to the current webapp
     * @param scheme the scheme ("http" or "https")
     *
     * @return encoded URL with jsessionid
     */
    public String encodeURL(String relativePath, String scheme) {
        if ((relativePath == null) || !relativePath.startsWith("/")) {
            throw new IllegalArgumentException("Illegal relative path: " +
                relativePath); // XXX LOC
        }

        if ((scheme == null) ||
                (!scheme.equals(HTTP_PROTOCOL) &&
                !scheme.equals(HTTPS_PROTOCOL))) {
            throw new IllegalArgumentException("Invalid protocol: " + scheme); // XXX LOC
        }

        String requestUrlString = (String) httpSession.getNote(
            Constants.REQUEST_URL_SESSION_NOTE);
        if (requestUrlString == null) {
            return null;
        }

        URL requestUrl = null;
        try {
            requestUrl = new URL(requestUrlString);
        } catch (MalformedURLException e) {
            throw new RuntimeException(e);
        }

        StringBuilder sb = new StringBuilder(scheme);
        sb.append("://");
        sb.append(requestUrl.getHost());
        sb.append(':');
        sb.append(requestUrl.getPort());
        sb.append(servletCtxt.getContextPath());
        sb.append(relativePath);

        return encodeURL(sb.toString());
    }

    /**
     * @param urlString The URL to be encoded
     *
     * @return true if the given URL needs to be encoded, false otherwise
     */
    private boolean isEncodeable(String urlString) {

        if (convergedCtxt != null && convergedCtxt.getCookies()) {
            return false;
        }

        // Is the given (absolute) URL valid?
        URL url = null;
        try {
            url = new URL(urlString);
        } catch (MalformedURLException e) {
            return false;
        }

        String myContextPath = servletCtxt.getContextPath();

        if (myContextPath != null) {
            String file = url.getFile();

            // Make sure the context path in the given URL matches our own
            if ((file == null) || !file.startsWith(myContextPath)) {
                return false;
            }
            if (file.indexOf(";jsessionid=" + httpSession.getIdInternal()) >= 0) {
                return false;
            }
        }

        return true;
    }

    /**
     * Encodes the given URL with the HTTP session id and the beroute
     * (or bekey, whichever is present)
     *
     * @param url The URL to be encoded
     *
     * @return The encoded URL
     */
    private String toEncoded(String url) {
        if (url == null) {
            return url;
        }

        String path = url;
        String query = "";
        String anchor = "";

        int question = url.indexOf('?');
        if (question >= 0) {
            path = url.substring(0, question);
            query = url.substring(question);
        }

        int pound = path.indexOf('#');
        if (pound >= 0) {
            anchor = path.substring(pound);
            path = path.substring(0, pound);
        }

        StringBuilder encoded = new StringBuilder(path);
        if (encoded.length() > 0) { // Encoded params can't be first.
            // http session id and version
            encoded.append(";jsessionid=");
            encoded.append(httpSession.getIdInternal());
            HashMap<String, String> sessionVersions = (HashMap<String, String>)
                httpSession.getNote(Constants.SESSION_VERSIONS_SESSION_NOTE);
            if (sessionVersions != null) {
                String sessionVersion = RequestUtil.makeSessionVersionString(
                    sessionVersions);
                if (sessionVersion != null) {
                    encoded.append(Globals.SESSION_VERSION_PARAMETER);
                    encoded.append(sessionVersion);
                }
            }
            // beroute
            String beroute = (String) httpSession.getNote(
                Constants.BEROUTE_SESSION_NOTE);
            if (beroute != null) {
                encoded.append(Constants.BEROUTE_URI_PARAMETER);
                encoded.append(beroute);
            }
            // bekey
            String bekey = (String) httpSession.getBeKey();
            if (bekey != null) {
                encoded.append(Constants.BEKEY_URI_PARAMETER);
                encoded.append(bekey);
            }
        }

        encoded.append(anchor);
        encoded.append(query);

        return encoded.toString();
    }

    /*
     * Checks to see if the request url of the request that was used to
     * create or resume the underlying HTTP session contains, in encoded
     * form, any parameter with the given name, and if so, returns its value.
     */
    private String parseRequestParameter(String search) {

        String requestUrlString = (String) httpSession.getNote(
            Constants.REQUEST_URL_SESSION_NOTE);
        if (requestUrlString == null) {
            return null;
        }

        String value = null;

        int index = requestUrlString.indexOf(search);
        if (index != -1) {
            int beginId = index + search.length();
            int semicolon = requestUrlString.indexOf(';', beginId);
            if (semicolon != -1) {
                value = requestUrlString.substring(beginId, semicolon);
            } else {
                value = requestUrlString.substring(beginId);
            }
        }

        return value;
    }

    public boolean isValid() {
        return httpSession.isValid();
    }
}
TOP

Related Classes of com.ericsson.ssa.sip.ConvergedHttpSessionFacade

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.