Package org.apache.catalina.connector.warp

Source Code of org.apache.catalina.connector.warp.WarpRequestHandler$BasicPrincipal

/*
*  Copyright 1999-2004 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.catalina.connector.warp;

import java.io.IOException;
import java.security.Principal;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Locale;
import java.util.TreeMap;

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

import org.apache.catalina.Context;
import org.apache.catalina.Globals;
import org.apache.catalina.Host;
import org.apache.catalina.util.RequestUtil;
import org.apache.catalina.util.StringParser;

public class WarpRequestHandler {

    private StringParser parser = new StringParser();
    private static final String match=";"+Globals.SESSION_PARAMETER_NAME+"=";

    /* ==================================================================== */
    /* Constructor                                                          */
    /* ==================================================================== */

    public WarpRequestHandler() {
        super();
    }

    public boolean handle(WarpConnection connection, WarpPacket packet)
    throws IOException {
        WarpLogger logger=new WarpLogger(this);
        WarpConnector connector=connection.getConnector();
        logger.setContainer(connector.getContainer());
        WarpRequest request=new WarpRequest();
        WarpResponse response=new WarpResponse();
        response.setRequest(request);
        response.setConnection(connection);
        response.setPacket(packet);
        request.setConnection(connection);
        request.setConnector(connector);

        // Prepare the Proceed packet
        packet.reset();
        packet.setType(Constants.TYPE_CONF_PROCEED);
        connection.send(packet);

        // Loop for configuration packets
        while (true) {
            connection.recv(packet);

            switch (packet.getType()) {
                case Constants.TYPE_REQ_INIT: {
                    int id=packet.readInteger();
                    String meth=packet.readString();
                    String ruri=packet.readString();
                    String args=packet.readString();
                    String prot=packet.readString();
                    if (Constants.DEBUG)
                        logger.debug("Request ID="+id+" \""+meth+" "+ruri+
                                     "?"+args+" "+prot+"\"");

                    request.recycle();
                    response.recycle();
                    response.setRequest(request);
                    response.setConnection(connection);
                    response.setPacket(packet);

                    request.setMethod(meth);
                    this.processUri(logger,request,ruri);
                    if (args.length()>0) request.setQueryString(args);
                    else request.setQueryString(null);
                    request.setProtocol(prot);
                    request.setConnection(connection);
                    Context ctx=connector.applicationContext(id);
                    if (ctx!=null) {
                        request.setContext(ctx);
                        request.setContextPath(ctx.getPath());
                        request.setHost((Host)ctx.getParent());
                    }
                    break;
                }

                case Constants.TYPE_REQ_CONTENT: {
                    String ctyp=packet.readString();
                    int clen=packet.readInteger();
                    if (Constants.DEBUG)
                        logger.debug("Request content type="+ctyp+" length="+
                                     clen);
                    if (ctyp.length()>0) request.setContentType(ctyp);
                    if (clen>0) request.setContentLength(clen);
                    break;
                }

                case Constants.TYPE_REQ_SCHEME: {
                    String schm=packet.readString();
                    if (Constants.DEBUG)
                        logger.debug("Request scheme="+schm);
                    request.setScheme(schm);
                    if (schm.equals("https"))
                       request.setSecure(true);
                    break;
                }

                case Constants.TYPE_REQ_AUTH: {
                    String user=packet.readString();
                    String auth=packet.readString();
                    if (Constants.DEBUG)
                        logger.debug("Request user="+user+" auth="+auth);
                    request.setAuthType(auth);
                    // What to do for user name?
                    if(user != null && auth != null && auth.equals("Basic")) {
                        Principal prin = new BasicPrincipal(user);
                        request.setUserPrincipal(prin);
                    }

                    break;
                }

                case Constants.TYPE_REQ_HEADER: {
                    String hnam=packet.readString();
                    String hval=packet.readString();
                    this.processHeader(logger,request,hnam,hval);
                    break;
                }

                case Constants.TYPE_REQ_SERVER: {
                    String host=packet.readString();
                    String addr=packet.readString();
                    int port=packet.readUnsignedShort();
                    if (Constants.DEBUG)
                        logger.debug("Server detail "+host+":"+port+
                                     " ("+addr+")");
                    request.setServerName(host);
                    request.setServerPort(port);
                    break;
                }

                case Constants.TYPE_REQ_CLIENT: {
                    String host=packet.readString();
                    String addr=packet.readString();
                    int port=packet.readUnsignedShort();
                    if (Constants.DEBUG)
                        logger.debug("Client detail "+host+":"+port+
                                     " ("+addr+")");
                    request.setRemoteHost(host);
                    request.setRemoteAddr(addr);
                    break;
                }

                case Constants.TYPE_REQ_PROCEED: {
                    if (Constants.DEBUG)
                        logger.debug("Request is about to be processed");
                    try {
                        connector.getContainer().invoke(request,response);
                    } catch (Exception e) {
                        logger.log(e);
                    }
                    request.finishRequest();
                    response.finishResponse();
                    if (Constants.DEBUG)
                        logger.debug("Request has been processed");
                    break;
                }

                default: {
                    String msg="Invalid packet "+packet.getType();
                    logger.log(msg);
                    packet.reset();
                    packet.setType(Constants.TYPE_FATAL);
                    packet.writeString(msg);
                    connection.send(packet);
                    return(false);
                }
            }
        }
    }

    private void processUri(WarpLogger logger, WarpRequest req, String uri) {

        // Parse any requested session ID out of the request URI
        int semicolon = uri.indexOf(match);
        if (semicolon >= 0) {
            String rest = uri.substring(semicolon + match.length());
            int semicolon2 = rest.indexOf(';');
            if (semicolon2 >= 0) {
                req.setRequestedSessionId(rest.substring(0, semicolon2));
                rest = rest.substring(semicolon2);
            } else {
                req.setRequestedSessionId(rest);
                rest = "";
            }
            req.setRequestedSessionURL(true);
            uri = uri.substring(0, semicolon) + rest;
            if (Constants.DEBUG) {
                logger.log("Requested URL session id is " +
                    ((HttpServletRequest) req.getRequest())
                    .getRequestedSessionId());
            }
        } else {
            req.setRequestedSessionId(null);
            req.setRequestedSessionURL(false);
        }

        req.setRequestURI(uri);
    }

    private void processHeader(WarpLogger logger, WarpRequest req,
                 String name, String value) {

        if (Constants.DEBUG)
            logger.debug("Request header "+name+": "+value);

        if ("cookie".equalsIgnoreCase(name)) {
            Cookie cookies[] = RequestUtil.parseCookieHeader(value);
            for (int i = 0; i < cookies.length; i++) {
                if (cookies[i].getName().equals
                    (Globals.SESSION_COOKIE_NAME)) {
                    // Override anything requested in the URL
                    if (!req.isRequestedSessionIdFromCookie()) {
                        // Accept only the first session id cookie
                        req.setRequestedSessionId
                            (cookies[i].getValue());
                        req.setRequestedSessionCookie(true);
                        req.setRequestedSessionURL(false);
                        if (Constants.DEBUG) {
                            logger.debug("Requested cookie session id is " +
                                ((HttpServletRequest) req.getRequest())
                                .getRequestedSessionId());
                        }
                    }
                }
                if (Constants.DEBUG) {
                    logger.debug("Adding cookie "+cookies[i].getName()+"="+
                        cookies[i].getValue());
                }
                req.addCookie(cookies[i]);
            }
        }
        if (name.equalsIgnoreCase("Accept-Language"))
            parseAcceptLanguage(logger,req,value);

        if (name.equalsIgnoreCase("Authorization"))
            req.setAuthorization(value);

        req.addHeader(name,value);
    }

    /**
     * Parse the value of an <code>Accept-Language</code> header, and add
     * the corresponding Locales to the current request.
     *
     * @param value The value of the <code>Accept-Language</code> header.
     */
    private void parseAcceptLanguage(WarpLogger logger, WarpRequest request,
                                     String value) {

        // Store the accumulated languages that have been requested in
        // a local collection, sorted by the quality value (so we can
        // add Locales in descending order).  The values will be ArrayLists
        // containing the corresponding Locales to be added
        TreeMap locales = new TreeMap();

        // Preprocess the value to remove all whitespace
        int white = value.indexOf(' ');
        if (white < 0)
            white = value.indexOf('\t');
        if (white >= 0) {
            StringBuffer sb = new StringBuffer();
            int len = value.length();
            for (int i = 0; i < len; i++) {
                char ch = value.charAt(i);
                if ((ch != ' ') && (ch != '\t'))
                    sb.append(ch);
            }
            value = sb.toString();
        }

        // Process each comma-delimited language specification
        parser.setString(value);        // ASSERT: parser is available to us
        int length = parser.getLength();
        while (true) {

            // Extract the next comma-delimited entry
            int start = parser.getIndex();
            if (start >= length)
                break;
            int end = parser.findChar(',');
            String entry = parser.extract(start, end).trim();
            parser.advance();   // For the following entry

            // Extract the quality factor for this entry
            double quality = 1.0;
            int semi = entry.indexOf(";q=");
            if (semi >= 0) {
                try {
                    quality = Double.parseDouble(entry.substring(semi + 3));
                } catch (NumberFormatException e) {
                    quality = 0.0;
                }
                entry = entry.substring(0, semi);
            }

            // Skip entries we are not going to keep track of
            if (quality < 0.00005)
                continue;       // Zero (or effectively zero) quality factors
            if ("*".equals(entry))
                continue;       // FIXME - "*" entries are not handled

            // Extract the language and country for this entry
            String language = null;
            String country = null;
            int dash = entry.indexOf('-');
            if (dash < 0) {
                language = entry;
                country = "";
            } else {
                language = entry.substring(0, dash);
                country = entry.substring(dash + 1);
            }

            // Add a new Locale to the list of Locales for this quality level
            Locale locale = new Locale(language, country);
            Double key = new Double(-quality)// Reverse the order
            ArrayList values = (ArrayList) locales.get(key);
            if (values == null) {
                values = new ArrayList();
                locales.put(key, values);
            }
            values.add(locale);

        }

        // Process the quality values in highest->lowest order (due to
        // negating the Double value when creating the key)
        Iterator keys = locales.keySet().iterator();
        while (keys.hasNext()) {
            Double key = (Double) keys.next();
            ArrayList list = (ArrayList) locales.get(key);
            Iterator values = list.iterator();
            while (values.hasNext()) {
                Locale locale = (Locale) values.next();
                if (Constants.DEBUG) {
                    logger.debug("Adding locale '" + locale + "'");
                }
                request.addLocale(locale);
            }
        }
    }

    class BasicPrincipal implements Principal {
        private String user;

        BasicPrincipal(String user) {
            this.user = user;
        }

        public boolean equals(Object another) {
            return (another instanceof Principal &&
                ((Principal)another).getName().equals(user));
        }

        public String getName() {
            return user;
        }

        public String toString() {
            return getName();
        }
    }
}
TOP

Related Classes of org.apache.catalina.connector.warp.WarpRequestHandler$BasicPrincipal

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.