001/*
002 *  Licensed to the Apache Software Foundation (ASF) under one
003 *  or more contributor license agreements.  See the NOTICE file
004 *  distributed with this work for additional information
005 *  regarding copyright ownership.  The ASF licenses this file
006 *  to you under the Apache License, Version 2.0 (the
007 *  "License"); you may not use this file except in compliance
008 *  with the License.  You may obtain a copy of the License at
009 *
010 *    http://www.apache.org/licenses/LICENSE-2.0
011 *
012 *  Unless required by applicable law or agreed to in writing,
013 *  software distributed under the License is distributed on an
014 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 *  KIND, either express or implied.  See the License for the
016 *  specific language governing permissions and limitations
017 *  under the License.
018 *
019 */
020package org.apache.mina.proxy.handlers.http;
021
022import java.util.List;
023import java.util.Map;
024
025import org.apache.mina.core.filterchain.IoFilter.NextFilter;
026import org.apache.mina.proxy.ProxyAuthException;
027import org.apache.mina.proxy.handlers.ProxyRequest;
028import org.apache.mina.proxy.session.ProxyIoSession;
029import org.apache.mina.proxy.utils.StringUtilities;
030import org.slf4j.Logger;
031import org.slf4j.LoggerFactory;
032
033/**
034 * AbstractAuthLogicHandler.java - Abstract class that handles an authentication 
035 * mechanism logic.
036 * 
037 * @author <a href="http://mina.apache.org">Apache MINA Project</a>
038 * @since MINA 2.0.0-M3
039 */
040public abstract class AbstractAuthLogicHandler {
041    private final static Logger logger = LoggerFactory.getLogger(AbstractAuthLogicHandler.class);
042
043    /**
044     * The request to be handled by the proxy.
045     */
046    protected ProxyRequest request;
047
048    /**
049     * Object that contains all the proxy authentication session informations.
050     */
051    protected ProxyIoSession proxyIoSession;
052
053    /**
054     * The current handshake step.
055     */
056    protected int step = 0;
057
058    /**
059     * Instantiates a handler for the given proxy session.
060     * 
061     * @param proxyIoSession the proxy session object
062     * @throws ProxyAuthException If we get an error during the proxy authentication
063     */
064    protected AbstractAuthLogicHandler(final ProxyIoSession proxyIoSession) throws ProxyAuthException {
065        this.proxyIoSession = proxyIoSession;
066        this.request = proxyIoSession.getRequest();
067
068        if (this.request == null || !(this.request instanceof HttpProxyRequest)) {
069            throw new IllegalArgumentException("request parameter should be a non null HttpProxyRequest instance");
070        }
071    }
072
073    /**
074     * Method called at each step of the handshaking process.
075     * 
076     * @param nextFilter the next filter
077     * @throws ProxyAuthException If we get an error during the proxy authentication
078     */
079    public abstract void doHandshake(final NextFilter nextFilter) throws ProxyAuthException;
080
081    /**
082     * Handles a HTTP response from the proxy server.
083     * 
084     * @param response The HTTP response.
085     * @throws ProxyAuthException If we get an error during the proxy authentication
086     */
087    public abstract void handleResponse(final HttpProxyResponse response) throws ProxyAuthException;
088
089    /**
090     * Sends an HTTP request.
091     * 
092     * @param nextFilter the next filter
093     * @param request the request to write
094     * @throws ProxyAuthException If we get an error during the proxy authentication
095     */
096    protected void writeRequest(final NextFilter nextFilter, final HttpProxyRequest request) throws ProxyAuthException {
097        logger.debug("  sending HTTP request");
098
099        ((AbstractHttpLogicHandler) proxyIoSession.getHandler()).writeRequest(nextFilter, request);
100    }
101
102    /**
103     * Try to force proxy connection to be kept alive.
104     * 
105     * @param headers the request headers
106     */
107    public static void addKeepAliveHeaders(Map<String, List<String>> headers) {
108        StringUtilities.addValueToHeader(headers, "Keep-Alive", HttpProxyConstants.DEFAULT_KEEP_ALIVE_TIME, true);
109        StringUtilities.addValueToHeader(headers, "Proxy-Connection", "keep-Alive", true);
110    }
111
112}