Package com.alibaba.citrus.service.requestcontext.session.impl

Source Code of com.alibaba.citrus.service.requestcontext.session.impl.SessionRequestContextImpl$SessionRequestWrapper

/*
* Copyright 2010 Alibaba Group Holding Limited.
* All rights reserved.
*
* 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 com.alibaba.citrus.service.requestcontext.session.impl;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.citrus.service.requestcontext.RequestContext;
import com.alibaba.citrus.service.requestcontext.session.SessionConfig;
import com.alibaba.citrus.service.requestcontext.session.SessionConfig.CookieConfig;
import com.alibaba.citrus.service.requestcontext.session.SessionRequestContext;
import com.alibaba.citrus.service.requestcontext.support.AbstractRequestContextWrapper;
import com.alibaba.citrus.service.requestcontext.support.AbstractRequestWrapper;
import com.alibaba.citrus.service.requestcontext.support.AbstractResponseWrapper;
import com.alibaba.citrus.service.requestcontext.util.CookieSupport;
import com.alibaba.citrus.util.StringUtil;

/**
* ֧��session��<code>HttpRequestContext</code>ʵ�֡�
*/
public class SessionRequestContextImpl extends AbstractRequestContextWrapper implements SessionRequestContext {
    private final static Logger log = LoggerFactory.getLogger(SessionRequestContext.class);
    private SessionConfig sessionConfig;
    private boolean requestedSessionIDParsed;
    private String requestedSessionID;
    private boolean requestedSessionIDFromCookie;
    private boolean requestedSessionIDFromURL;
    private SessionImpl session;
    private boolean sessionReturned;

    /**
     * ���캯����
     */
    public SessionRequestContextImpl(RequestContext wrappedContext, SessionConfig sessionConfig) {
        super(wrappedContext);
        this.sessionConfig = sessionConfig;
        setRequest(new SessionRequestWrapper(wrappedContext.getRequest()));
        setResponse(new SessionResponseWrapper(wrappedContext.getResponse()));
    }

    /**
     * ȡ��<code>SessionConfig</code>ʵ����
     *
     * @return <code>SessionConfig</code>ʵ��
     */
    public SessionConfig getSessionConfig() {
        return sessionConfig;
    }

    /**
     * �ж�session�Ƿ��Ѿ����ϡ�
     *
     * @return �������ϣ��򷵻�<code>true</code>
     */
    public boolean isSessionInvalidated() {
        return session == null ? false : session.isInvalidated();
    }

    /**
     * ���session������<code>invalidate()</code>��������֧�ֺ����������������׳�
     * <code>IllegalStateException</code>��
     */
    public void clear() {
        if (session != null) {
            session.clear();
        }
    }

    /**
     * ȡ�õ�ǰ��session ID��
     *
     * @return session ID
     */
    public String getRequestedSessionID() {
        ensureRequestedSessionID();
        return requestedSessionID;
    }

    /**
     * ��ǰ��session ID�Ǵ�cookie��ȡ�õ���
     *
     * @return ����ǣ��򷵻�<code>true</code>
     */
    public boolean isRequestedSessionIDFromCookie() {
        ensureRequestedSessionID();
        return requestedSessionIDFromCookie;
    }

    /**
     * ��ǰ��session ID�Ǵ�URL��ȡ�õ���
     *
     * @return ����ǣ��򷵻�<code>true</code>
     */
    public boolean isRequestedSessionIDFromURL() {
        ensureRequestedSessionID();
        return requestedSessionIDFromURL;
    }

    /**
     * �жϵ�ǰ��session ID�Ƿ���Ȼ�Ϸ���
     *
     * @return ����ǣ��򷵻�<code>true</code>
     */
    public boolean isRequestedSessionIDValid() {
        HttpSession session = getSession(false);

        return session != null && session.getId().equals(requestedSessionID);
    }

    /**
     * ȷ��session ID�Ѿ���request�б����������ˡ�
     */
    private void ensureRequestedSessionID() {
        if (!requestedSessionIDParsed) {
            if (sessionConfig.getId().isCookieEnabled()) {
                requestedSessionID = decodeSessionIDFromCookie();
                requestedSessionIDFromCookie = requestedSessionID != null;
            }

            if (requestedSessionID == null && sessionConfig.getId().isUrlEncodeEnabled()) {
                requestedSessionID = decodeSessionIDFromURL();
                requestedSessionIDFromURL = requestedSessionID != null;
            }
        }
    }

    /**
     * ��session ID���뵽Cookie��ȥ��
     */
    public void encodeSessionIDIntoCookie() {
        writeSessionIDCookie(session.getId());
    }

    /**
     * ��session ID��Cookie��ɾ����
     */
    public void clearSessionIDFromCookie() {
        writeSessionIDCookie("");
    }

    /**
     * дcookie��
     */
    private void writeSessionIDCookie(String cookieValue) {
        CookieConfig cookieConfig = sessionConfig.getId().getCookie();
        CookieSupport cookie = new CookieSupport(cookieConfig.getName(), cookieValue);
        String cookieDomain = cookieConfig.getDomain();

        if (!StringUtil.isEmpty(cookieDomain)) {
            cookie.setDomain(cookieDomain);
        }

        String cookiePath = cookieConfig.getPath();

        if (!StringUtil.isEmpty(cookiePath)) {
            cookie.setPath(cookiePath);
        }

        int cookieMaxAge = cookieConfig.getMaxAge();

        if (cookieMaxAge > 0) {
            cookie.setMaxAge(cookieMaxAge);
        }

        cookie.setHttpOnly(cookieConfig.isHttpOnly());
        cookie.setSecure(cookieConfig.isSecure());

        log.debug("Set-cookie: {}", cookie);

        cookie.addCookie(getResponse());
    }

    /**
     * ��cookie��ȡ��session ID��
     *
     * @return ������ڣ��򷵻�session ID�����򷵻�<code>null</code>
     */
    public String decodeSessionIDFromCookie() {
        Cookie[] cookies = getRequest().getCookies();

        if (cookies != null) {
            String sessionCookieName = sessionConfig.getId().getCookie().getName();

            for (Cookie cookie : cookies) {
                if (cookie.getName().equals(sessionCookieName)) {
                    String sessionID = StringUtil.trimToNull(cookie.getValue());

                    if (sessionID != null) {
                        return sessionID;
                    }
                }
            }
        }

        return null;
    }

    /**
     * ��session ID���뵽URL��ȥ��
     *
     * @return ����session ID��URL
     */
    public String encodeSessionIDIntoURL(String url) {
        HttpSession session = getRequest().getSession(false);

        if (session != null && (session.isNew() || isRequestedSessionIDFromURL() && !isRequestedSessionIDFromCookie())) {
            String sessionID = session.getId();
            String keyName = getSessionConfig().getId().getUrlEncode().getName();
            int keyNameLength = keyName.length();
            int urlLength = url.length();
            int urlQueryIndex = url.indexOf('?');

            if (urlQueryIndex >= 0) {
                urlLength = urlQueryIndex;
            }

            boolean found = false;

            for (int keyBeginIndex = url.indexOf(';'); keyBeginIndex >= 0 && keyBeginIndex < urlLength; keyBeginIndex = url
                    .indexOf(';', keyBeginIndex + 1)) {
                keyBeginIndex++;

                if (urlLength - keyBeginIndex <= keyNameLength
                        || !url.regionMatches(keyBeginIndex, keyName, 0, keyNameLength)
                        || url.charAt(keyBeginIndex + keyNameLength) != '=') {
                    continue;
                }

                int valueBeginIndex = keyBeginIndex + keyNameLength + 1;
                int valueEndIndex = url.indexOf(';', valueBeginIndex);

                if (valueEndIndex < 0) {
                    valueEndIndex = urlLength;
                }

                if (!url.regionMatches(valueBeginIndex, sessionID, 0, sessionID.length())) {
                    url = url.substring(0, valueBeginIndex) + sessionID + url.substring(valueEndIndex);
                }

                found = true;
                break;
            }

            if (!found) {
                url = url.substring(0, urlLength) + ';' + keyName + '=' + sessionID + url.substring(urlLength);
            }
        }

        return url;
    }

    /**
     * ��URL��ȡ��session ID��
     *
     * @return ������ڣ��򷵻�session ID�����򷵻�<code>null</code>
     */
    public String decodeSessionIDFromURL() {
        String uri = getRequest().getRequestURI();
        String keyName = sessionConfig.getId().getUrlEncode().getName();
        int uriLength = uri.length();
        int keyNameLength = keyName.length();

        for (int keyBeginIndex = uri.indexOf(';'); keyBeginIndex >= 0; keyBeginIndex = uri.indexOf(';',
                keyBeginIndex + 1)) {
            keyBeginIndex++;

            if (uriLength - keyBeginIndex <= keyNameLength
                    || !uri.regionMatches(keyBeginIndex, keyName, 0, keyNameLength)
                    || uri.charAt(keyBeginIndex + keyNameLength) != '=') {
                continue;
            }

            int valueBeginIndex = keyBeginIndex + keyNameLength + 1;
            int valueEndIndex = uri.indexOf(';', valueBeginIndex);

            if (valueEndIndex < 0) {
                valueEndIndex = uriLength;
            }

            return uri.substring(valueBeginIndex, valueEndIndex);
        }

        return null;
    }

    /**
     * ȡ�õ�ǰ��session����������ڣ���<code>create</code>Ϊ<code>true</code>���򴴽�һ���µġ�
     *
     * @param create ��Ҫʱ�Ƿ񴴽��µ�session
     * @return ��ǰ��session���µ�session����������ڣ���<code>create</code>Ϊ
     *         <code>false</code> ���򷵻�<code>null</code>
     */
    public HttpSession getSession(boolean create) {
        // ���getSession�����Ѿ���ִ�й��ˣ���ôֱ�ӷ���
        if (session != null && sessionReturned) {
            return session;
        }

        // ����session�������п��ܴ���ȴ������
        if (session == null) {
            // ��request��ȡ��session ID
            ensureRequestedSessionID();

            String sessionID = requestedSessionID;
            boolean isNew = false;

            // ���sessionIDΪ�գ��򴴽�һ���µ�ID
            if (sessionID == null) {
                if (!create) {
                    return null; // ����create=false��ֱ�ӷ���null
                }

                sessionID = sessionConfig.getId().getGenerator().generateSessionID();
                isNew = true;
            }

            // �����������ȴ���һ��session������˵�������session�п��ܲ����ڻ��ǹ��ڵ�
            session = new SessionImpl(sessionID, this, isNew, create);
        }

        // SessionΪnew���п�����sessionIDΪ�գ�����sessionID��Ӧ��session�����ڣ�����session�ѹ���
        // ���ͬʱcreateΪfalse������null�Ϳ����ˡ�
        if (session.isNew() && !create) {
            return null;
        }

        // ���ԭ��sessionID�Ѵ�����request�У�����session�Ƿ����½�������ø�sessionID��
        // ��ˣ�����������£��Ͳ���Ҫ������cookie�ˡ�
        if (sessionConfig.getId().isCookieEnabled() && !session.getId().equals(requestedSessionID)) {
            if (getResponse().isCommitted()) {
                throw new IllegalStateException(
                        "Failed to create a new session because the responseWrapper was already committed");
            }

            encodeSessionIDIntoCookie();
        }

        sessionReturned = true;
        return session;
    }

    /**
     * ��ʼһ������
     */
    @Override
    public void prepare() {
    }

    /**
     * ����һ������
     */
    @Override
    public void commit() {
        if (!sessionReturned) {
            return;
        }

        if (session.isInvalidated()) {
            // ���cookie�е�session ID
            clearSessionIDFromCookie();
        }

        session.commit();
    }

    /**
     * ֧��session��<code>HttpServletRequestWrapper</code>��
     */
    private class SessionRequestWrapper extends AbstractRequestWrapper {
        /**
         * ���캯����
         *
         * @param request ����װ��<code>HttpServletRequest</code>ʵ��
         */
        public SessionRequestWrapper(HttpServletRequest request) {
            super(SessionRequestContextImpl.this, request);
        }

        /**
         * ȡ�õ�ǰrequest�е�session ID��
         *
         * @return session ID
         */
        @Override
        public String getRequestedSessionId() {
            return SessionRequestContextImpl.this.getRequestedSessionID();
        }

        /**
         * ��ǰ��session ID�Ǵ�cookie��ȡ�õ���
         *
         * @return ����ǣ��򷵻�<code>true</code>
         */
        @Override
        public boolean isRequestedSessionIdFromCookie() {
            return SessionRequestContextImpl.this.isRequestedSessionIDFromCookie();
        }

        /**
         * ��ǰ��session ID�Ǵ�URL��ȡ�õ���
         *
         * @return ����ǣ��򷵻�<code>true</code>
         */
        @Override
        public boolean isRequestedSessionIdFromURL() {
            return SessionRequestContextImpl.this.isRequestedSessionIDFromURL();
        }

        /**
         * �жϵ�ǰ��session ID�Ƿ���Ȼ�Ϸ���
         *
         * @return ����ǣ��򷵻�<code>true</code>
         */
        @Override
        public boolean isRequestedSessionIdValid() {
            return SessionRequestContextImpl.this.isRequestedSessionIDValid();
        }

        /**
         * ȡ�õ�ǰ��session����������ڣ��򴴽�һ���µġ�
         *
         * @return ��ǰ��session���µ�session
         */
        @Override
        public HttpSession getSession() {
            return getSession(true);
        }

        /**
         * ȡ�õ�ǰ��session����������ڣ���<code>create</code>Ϊ<code>true</code>���򴴽�һ���µġ�
         *
         * @param create ��Ҫʱ�Ƿ񴴽��µ�session
         * @return ��ǰ��session���µ�session����������ڣ���<code>create</code>Ϊ
         *         <code>false</code>���򷵻�<code>null</code>
         */
        @Override
        public HttpSession getSession(boolean create) {
            return SessionRequestContextImpl.this.getSession(create);
        }

        /**
         * @deprecated use isRequestedSessionIdFromURL instead
         */
        @Override
        @Deprecated
        public boolean isRequestedSessionIdFromUrl() {
            return isRequestedSessionIdFromURL();
        }
    }

    /**
     * ֧��session��<code>HttpServletResponseWrapper</code>��
     */
    private class SessionResponseWrapper extends AbstractResponseWrapper {
        /**
         * ���캯����
         *
         * @param response ����װ��<code>HttpServletResponse</code>ʵ��
         */
        public SessionResponseWrapper(HttpServletResponse response) {
            super(SessionRequestContextImpl.this, response);
        }

        /**
         * ��session ID���뵽URL�С�
         *
         * @param url Ҫ�����URL
         * @return ����session ID��URL
         */
        @Override
        public String encodeURL(String url) {
            if (sessionConfig.getId().isUrlEncodeEnabled()) {
                url = SessionRequestContextImpl.this.encodeSessionIDIntoURL(url);
            }

            return url;
        }

        /**
         * ��session ID���뵽URL�С�
         *
         * @param url Ҫ�����URL
         * @return ����session ID��URL
         */
        @Override
        public String encodeRedirectURL(String url) {
            if (sessionConfig.getId().isUrlEncodeEnabled()) {
                url = SessionRequestContextImpl.this.encodeSessionIDIntoURL(url);
            }

            return url;
        }

        /**
         * @deprecated use encodeURL instead
         */
        @Override
        @Deprecated
        public String encodeUrl(String url) {
            return encodeURL(url);
        }

        /**
         * @deprecated use encodeRedirectURL instead
         */
        @Override
        @Deprecated
        public String encodeRedirectUrl(String url) {
            return encodeRedirectURL(url);
        }
    }
}
TOP

Related Classes of com.alibaba.citrus.service.requestcontext.session.impl.SessionRequestContextImpl$SessionRequestWrapper

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.