/*
 *  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.jk.common;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.CharConversionException;
import java.net.InetAddress;
import java.util.Properties;
import javax.management.ObjectName;

import org.apache.commons.modeler.Registry;
import org.apache.coyote.Request;
import org.apache.coyote.RequestGroupInfo;
import org.apache.coyote.RequestInfo;
import org.apache.coyote.Response;
import org.apache.coyote.Constants;
import org.apache.jk.core.JkHandler;
import org.apache.jk.core.Msg;
import org.apache.jk.core.MsgContext;
import org.apache.jk.core.WorkerEnv;
import org.apache.jk.core.JkChannel;
import org.apache.tomcat.util.buf.ByteChunk;
import org.apache.tomcat.util.buf.CharChunk;
import org.apache.tomcat.util.buf.HexUtils;
import org.apache.tomcat.util.buf.MessageBytes;
import org.apache.tomcat.util.http.MimeHeaders;
import org.apache.tomcat.util.net.SSLSupport;
import org.apache.tomcat.util.threads.ThreadWithAttributes;

/**
 * Handle messages related with basic request information.
 *
 * This object can handle the following incoming messages:
 * - "FORWARD_REQUEST" input message ( sent when a request is passed from the
 *   web server )
 * - "RECEIVE_BODY_CHUNK" input ( sent by container to pass more body, in
 *   response to GET_BODY_CHUNK )
 *
 * It can handle the following outgoing messages:
 * - SEND_HEADERS. Pass the status code and headers.
 * - SEND_BODY_CHUNK. Send a chunk of body
 * - GET_BODY_CHUNK. Request a chunk of body data
 * - END_RESPONSE. Notify the end of a request processing.
 *
 * @author Henri Gomez [hgomez@apache.org]
 * @author Dan Milstein [danmil@shore.net]
 * @author Keith Wannamaker [Keith@Wannamaker.org]
 * @author Costin Manolache
 */
public class HandlerRequest extends JkHandler
{
    private static org.apache.commons.logging.Log log=
        org.apache.commons.logging.LogFactory.getLog( HandlerRequest.class );

    // XXX Will move to a registry system.
    
    // Prefix codes for message types from server to container
    public static final byte JK_AJP13_FORWARD_REQUEST   = 2;
        public static final byte JK_AJP13_SHUTDOWN          = 7;
        public static final byte JK_AJP13_PING_REQUEST      = 8;
        public static final byte JK_AJP13_CPING_REQUEST     = 10;

    // Prefix codes for message types from container to server
    public static final byte JK_AJP13_SEND_BODY_CHUNK   = 3;
    public static final byte JK_AJP13_SEND_HEADERS      = 4;
    public static final byte JK_AJP13_END_RESPONSE      = 5;
        public static final byte JK_AJP13_GET_BODY_CHUNK    = 6;
        public static final byte JK_AJP13_CPONG_REPLY       = 9;
    
    // Integer codes for common response header strings
    public static final int SC_RESP_CONTENT_TYPE        = 0xA001;
    public static final int SC_RESP_CONTENT_LANGUAGE    = 0xA002;
    public static final int SC_RESP_CONTENT_LENGTH      = 0xA003;
    public static final int SC_RESP_DATE                = 0xA004;
    public static final int SC_RESP_LAST_MODIFIED       = 0xA005;
    public static final int SC_RESP_LOCATION            = 0xA006;
    public static final int SC_RESP_SET_COOKIE          = 0xA007;
    public static final int SC_RESP_SET_COOKIE2         = 0xA008;
    public static final int SC_RESP_SERVLET_ENGINE      = 0xA009;
    public static final int SC_RESP_STATUS              = 0xA00A;
    public static final int SC_RESP_WWW_AUTHENTICATE    = 0xA00B;
        
    // Integer codes for common (optional) request attribute names
    public static final byte SC_A_CONTEXT       = 1;  // XXX Unused
    public static final byte SC_A_SERVLET_PATH  = 2;  // XXX Unused
    public static final byte SC_A_REMOTE_USER   = 3;
    public static final byte SC_A_AUTH_TYPE     = 4;
    public static final byte SC_A_QUERY_STRING  = 5;
    public static final byte SC_A_JVM_ROUTE     = 6;
    public static final byte SC_A_SSL_CERT      = 7;
    public static final byte SC_A_SSL_CIPHER    = 8;
    public static final byte SC_A_SSL_SESSION   = 9;
    public static final byte SC_A_SSL_KEYSIZE   = 11;
    public static final byte SC_A_SECRET        = 12;
    public static final byte SC_A_STORED_METHOD = 13;

    // Used for attributes which are not in the list above
    public static final byte SC_A_REQ_ATTRIBUTE = 10; 

    // Terminates list of attributes
    public static final byte SC_A_ARE_DONE      = (byte)0xFF;
    
    // Translates integer codes to names of HTTP methods
    public static final String []methodTransArray = {
        "OPTIONS",
        "GET",
        "HEAD",
        "POST",
        "PUT",
        "DELETE",
        "TRACE",
        "PROPFIND",
        "PROPPATCH",
        "MKCOL",
        "COPY",
        "MOVE",
        "LOCK",
        "UNLOCK",
        "ACL",
        "REPORT",
        "VERSION-CONTROL",
        "CHECKIN",
        "CHECKOUT",
        "UNCHECKOUT",
        "SEARCH",
        "MKWORKSPACE",
        "UPDATE",
        "LABEL",
        "MERGE",
        "BASELINE-CONTROL",
        "MKACTIVITY"
    };
    public static final int SC_M_JK_STORED = (byte) 0xFF;
    
    // id's for common request headers
    public static final int SC_REQ_ACCEPT          = 1;
    public static final int SC_REQ_ACCEPT_CHARSET  = 2;
    public static final int SC_REQ_ACCEPT_ENCODING = 3;
    public static final int SC_REQ_ACCEPT_LANGUAGE = 4;
    public static final int SC_REQ_AUTHORIZATION   = 5;
    public static final int SC_REQ_CONNECTION      = 6;
    public static final int SC_REQ_CONTENT_TYPE    = 7;
    public static final int SC_REQ_CONTENT_LENGTH  = 8;
    public static final int SC_REQ_COOKIE          = 9;
    public static final int SC_REQ_COOKIE2         = 10;
    public static final int SC_REQ_HOST            = 11;
    public static final int SC_REQ_PRAGMA          = 12;
    public static final int SC_REQ_REFERER         = 13;
    public static final int SC_REQ_USER_AGENT      = 14;
    // AJP14 new header
    public static final byte SC_A_SSL_KEY_SIZE  = 11; // XXX ??? 

    // Translates integer codes to request header names    
    public static final String []headerTransArray = {
        "accept",
        "accept-charset",
        "accept-encoding",
        "accept-language",
        "authorization",
        "connection",
        "content-type",
        "content-length",
        "cookie",
        "cookie2",
        "host",
        "pragma",
        "referer",
        "user-agent"
    };

    /*
     * Note for Host parsing.
     */
    public static final int HOSTBUFFER = 10;

    HandlerDispatch dispatch;
    String ajpidDir="conf";
    

    public HandlerRequest() 
    {
    }

    public void init() {
        dispatch=(HandlerDispatch)wEnv.getHandler( "dispatch" );
        if( dispatch != null ) {
            // register incoming message handlers
            dispatch.registerMessageType( JK_AJP13_FORWARD_REQUEST,
                                          "JK_AJP13_FORWARD_REQUEST",
                                          this, null); // 2
            
            dispatch.registerMessageType( JK_AJP13_SHUTDOWN,
                                          "JK_AJP13_SHUTDOWN",
                                          this, null); // 7
            
            dispatch.registerMessageType( JK_AJP13_CPING_REQUEST,
                                          "JK_AJP13_CPING_REQUEST",
                                           this, null); // 10
            dispatch.registerMessageType( HANDLE_THREAD_END,
                                         "HANDLE_THREAD_END",
                                         this, null);
            // register outgoing messages handler
            dispatch.registerMessageType( JK_AJP13_SEND_BODY_CHUNK, // 3
                                          "JK_AJP13_SEND_BODY_CHUNK",
                                          this,null );
        }

        bodyNote=wEnv.getNoteId( WorkerEnv.ENDPOINT_NOTE, "jkInputStream" );
        tmpBufNote=wEnv.getNoteId( WorkerEnv.ENDPOINT_NOTE, "tmpBuf" );
        secretNote=wEnv.getNoteId( WorkerEnv.ENDPOINT_NOTE, "secret" );

        if( next==null )
            next=wEnv.getHandler( "container" );
        if( log.isDebugEnabled() )
            log.debug( "Container handler " + next + " " + next.getName() +
                       " " + next.getClass().getName());

        // should happen on start()
        generateAjp13Id();
    }

    public void setSecret( String s ) {
        requiredSecret=s;
    }

    public void setUseSecret( boolean b ) {
        requiredSecret=Double.toString(Math.random());
    }

    public void setDecodedUri( boolean b ) {
        decoded=b;
    }

    public boolean isTomcatAuthentication() {
        return tomcatAuthentication;
    }

    public void setShutdownEnabled(boolean se) {
        shutdownEnabled = se;
    }

    public boolean getShutdownEnabled() {
        return shutdownEnabled;
    }

    public void setTomcatAuthentication(boolean newTomcatAuthentication) {
        tomcatAuthentication = newTomcatAuthentication;
    }
    
    public void setAjpidDir( String path ) {
        if( "".equals( path ) ) path=null;
        ajpidDir=path;
    }

    /**
     * Set the flag to tell if we JMX register requests.
     */
    public void setRegisterRequests(boolean srr) {
        registerRequests = srr;
    }

    /**
     * Get the flag to tell if we JMX register requests.
     */
    public boolean getRegisterRequests() {
        return registerRequests;
    }

    // -------------------- Ajp13.id --------------------

    private void generateAjp13Id() {
        int portInt=8009; // tcpCon.getPort();
        InetAddress address=null; // tcpCon.getAddress();

        if( requiredSecret == null )
            return;
        
        File f1=new File( wEnv.getJkHome() );
        File f2=new File( f1, "conf" );
        
        if( ! f2.exists() ) {
            log.error( "No conf dir for ajp13.id " + f2 );
            return;
        }
        
        File sf=new File( f2, "ajp13.id");
        
        if( log.isDebugEnabled())
            log.debug( "Using stop file: "+sf);

        try {
            Properties props=new Properties();

            props.put( "port", Integer.toString( portInt ));
            if( address!=null ) {
                props.put( "address", address.getHostAddress() );
            }
            if( requiredSecret !=null ) {
                props.put( "secret", requiredSecret );
            }

            FileOutputStream stopF=new FileOutputStream( sf );
            props.save( stopF, "Automatically generated, don't edit" );
        } catch( IOException ex ) {
            log.debug( "Can't create stop file: "+sf );
            ex.printStackTrace();
        }
    }
    
    // -------------------- Incoming message --------------------
    String requiredSecret=null;
    int bodyNote;
    int tmpBufNote;
    int secretNote;

    boolean decoded=true;
    boolean tomcatAuthentication=true;
    boolean registerRequests=true;
    boolean shutdownEnabled=false;
    
    public int invoke(Msg msg, MsgContext ep ) 
        throws IOException
    {
        int type=msg.getByte();
        ThreadWithAttributes twa = null;
        if (Thread.currentThread() instanceof ThreadWithAttributes) {
            twa = (ThreadWithAttributes) Thread.currentThread();
        }
        Object control=ep.getControl();

        MessageBytes tmpMB=(MessageBytes)ep.getNote( tmpBufNote );
        if( tmpMB==null ) {
            tmpMB=new MessageBytes();
            ep.setNote( tmpBufNote, tmpMB);
        }
        if( log.isDebugEnabled() )
            log.debug( "Handling " + type );
        
        switch( type ) {
        case JK_AJP13_FORWARD_REQUEST:
            try {
                if (twa != null) {
                    twa.setCurrentStage(control, "JkDecode");
                }
                decodeRequest( msg, ep, tmpMB );
                if (twa != null) {
                    twa.setCurrentStage(control, "JkService");
                    twa.setParam(control,
                                 ((Request)ep.getRequest()).unparsedURI());
                }
            } catch( Exception ex ) {
                log.error( "Error decoding request ", ex );
                msg.dump( "Incomming message");
                return ERROR;
            }

            if( requiredSecret != null ) {
                String epSecret=(String)ep.getNote( secretNote );
                if( epSecret==null || ! requiredSecret.equals( epSecret ) )
                    return ERROR;
            }
            /* XXX it should be computed from request, by workerEnv */
            if(log.isDebugEnabled() )
                log.debug("Calling next " + next.getName() + " " +
                  next.getClass().getName());

            int err= next.invoke( msg, ep );
            if (twa != null) {
                twa.setCurrentStage(control, "JkDone");
            }

            if( log.isDebugEnabled() )
                log.debug( "Invoke returned " + err );
            return err;
        case JK_AJP13_SHUTDOWN:
            String epSecret=null;
            if( msg.getLen() > 3 ) {
                // we have a secret
                msg.getBytes( tmpMB );
                epSecret=tmpMB.toString();
            }
            
            if( requiredSecret != null &&
                requiredSecret.equals( epSecret ) ) {
                if( log.isDebugEnabled() )
                    log.debug("Received wrong secret, no shutdown ");
                return ERROR;
            }

            // XXX add isSameAddress check
            JkChannel ch=ep.getSource();
	    if( !ch.isSameAddress(ep) ) {
		log.error("Shutdown request not from 'same address' ");
		return ERROR;
            }

            if( !shutdownEnabled ) {
                log.warn("Ignoring shutdown request: shutdown not enabled");
                return ERROR;
            }
            // forward to the default handler - it'll do the shutdown
            checkRequest(ep);
            next.invoke( msg, ep );

            log.info("Exiting");
            System.exit(0);
            
            return OK;

            // We got a PING REQUEST, quickly respond with a PONG
        case JK_AJP13_CPING_REQUEST:
            msg.reset();
            msg.appendByte(JK_AJP13_CPONG_REPLY);
            ep.setType( JkHandler.HANDLE_SEND_PACKET );
            ep.getSource().send( msg, ep );
	    return OK;

        case HANDLE_THREAD_END:
            return OK;

        default:
            log.info("Unknown message " + type);
        }

        return OK;
    }

    static int count = 0;

    private Request checkRequest(MsgContext ep) {
        Request req=(Request)ep.getRequest();
        if( req==null ) {
            req=new Request();
            Response res=new Response();
            req.setResponse(res);
            ep.setRequest( req );
            if( registerRequests ) {
                ep.getSource().registerRequest(req, ep, count++);
            }
        }
        return req;
    }

    private int decodeRequest( Msg msg, MsgContext ep, MessageBytes tmpMB )
        throws IOException
    {
        // FORWARD_REQUEST handler
        Request req = checkRequest(ep);

	RequestInfo rp = req.getRequestProcessor();
	rp.setStage(Constants.STAGE_PARSE);
        MessageBytes tmpMB2 = (MessageBytes)req.getNote(WorkerEnv.SSL_CERT_NOTE);
        if(tmpMB2 != null) {
            tmpMB2.recycle();
        }
        req.setStartTime(System.currentTimeMillis());
        JkInputStream jkBody=(JkInputStream)ep.getNote( bodyNote );
        if( jkBody==null ) {
            jkBody=new JkInputStream();
            jkBody.setMsgContext( ep );

            ep.setNote( bodyNote, jkBody );
        }

        jkBody.recycle();
        
        // Translate the HTTP method code to a String.
        byte methodCode = msg.getByte();
        if (methodCode != SC_M_JK_STORED) {
            String mName=methodTransArray[(int)methodCode - 1];
            req.method().setString(mName);
        }

        msg.getBytes(req.protocol()); 
        msg.getBytes(req.requestURI());

        msg.getBytes(req.remoteAddr());
        msg.getBytes(req.remoteHost());
        msg.getBytes(req.localName());
        req.setLocalPort(msg.getInt());

        boolean isSSL = msg.getByte() != 0;
        if( isSSL ) {
            // XXX req.setSecure( true );
            req.scheme().setString("https");
        }

        decodeHeaders( ep, msg, req, tmpMB );

        decodeAttributes( ep, msg, req, tmpMB );

	rp.setStage(Constants.STAGE_PREPARE);
        MessageBytes valueMB = req.getMimeHeaders().getValue("host");
        parseHost(valueMB, req);
        // set cookies on request now that we have all headers
        req.getCookies().setHeaders(req.getMimeHeaders());

        // Check to see if there should be a body packet coming along
        // immediately after
        int cl=req.getContentLength();
        if(cl > 0) {
            jkBody.setContentLength( cl );
            jkBody.receive();
        }
    
        if (log.isTraceEnabled()) {
            log.trace(req.toString());
         }

        return OK;
    }
        
    private int decodeAttributes( MsgContext ep, Msg msg, Request req,
                                  MessageBytes tmpMB) {
        boolean moreAttr=true;

        while( moreAttr ) {
            byte attributeCode=msg.getByte();
            if( attributeCode == SC_A_ARE_DONE )
                return 200;

            /* Special case ( XXX in future API make it separate type !)
             */
            if( attributeCode == SC_A_SSL_KEY_SIZE ) {
                // Bug 1326: it's an Integer.
                req.setAttribute(SSLSupport.KEY_SIZE_KEY,
                                 new Integer( msg.getInt()));
               //Integer.toString(msg.getInt()));
            }

            if( attributeCode == SC_A_REQ_ATTRIBUTE ) {
                // 2 strings ???...
                msg.getBytes( tmpMB );
                String n=tmpMB.toString();
                msg.getBytes( tmpMB );
                String v=tmpMB.toString();
                req.setAttribute(n, v );
            }


            // 1 string attributes
            switch(attributeCode) {
            case SC_A_CONTEXT      :
                msg.getBytes( tmpMB );
                // nothing
                break;
                
            case SC_A_SERVLET_PATH :
                msg.getBytes( tmpMB );
                // nothing 
                break;
                
            case SC_A_REMOTE_USER  :
                if( tomcatAuthentication ) {
                    // ignore server
                    msg.getBytes( tmpMB );
                } else {
                    msg.getBytes(req.getRemoteUser());
                }
                break;
                
            case SC_A_AUTH_TYPE    :
                if( tomcatAuthentication ) {
                    // ignore server
                    msg.getBytes( tmpMB );
                } else {
                    msg.getBytes(req.getAuthType());
                }
                break;
                
            case SC_A_QUERY_STRING :
                msg.getBytes(req.queryString());
                break;
                
            case SC_A_JVM_ROUTE    :
                msg.getBytes(req.instanceId());
                break;
                
            case SC_A_SSL_CERT     :
                req.scheme().setString( "https" );
                // Transform the string into certificate.
                MessageBytes tmpMB2 = (MessageBytes)req.getNote(WorkerEnv.SSL_CERT_NOTE);
                if(tmpMB2 == null) {
                    tmpMB2 = new MessageBytes();
                    req.setNote(WorkerEnv.SSL_CERT_NOTE, tmpMB2);
                }
                // SSL certificate extraction is costy, moved to JkCoyoteHandler
                msg.getBytes(tmpMB2);
                break;
                
            case SC_A_SSL_CIPHER   :
                req.scheme().setString( "https" );
                msg.getBytes(tmpMB);
                req.setAttribute(SSLSupport.CIPHER_SUITE_KEY,
                                 tmpMB.toString());
                break;
                
            case SC_A_SSL_SESSION  :
                req.scheme().setString( "https" );
                msg.getBytes(tmpMB);
                req.setAttribute(SSLSupport.SESSION_ID_KEY, 
                                  tmpMB.toString());
                break;
                
            case SC_A_SECRET  :
                msg.getBytes(tmpMB);
                String secret=tmpMB.toString();
                log.info("Secret: " + secret );
                // endpoint note
                ep.setNote( secretNote, secret );
                break;
                
            case SC_A_STORED_METHOD:
                msg.getBytes(req.method()); 
                break;
                
            default:
                break; // ignore, we don't know about it - backward compat
            }
        }
        return 200;
    }
    
    private void decodeHeaders( MsgContext ep, Msg msg, Request req,
                                MessageBytes tmpMB ) {
        // Decode headers
        MimeHeaders headers = req.getMimeHeaders();

        int hCount = msg.getInt();
        for(int i = 0 ; i < hCount ; i++) {
            String hName = null;

            // Header names are encoded as either an integer code starting
            // with 0xA0, or as a normal string (in which case the first
            // two bytes are the length).
            int isc = msg.peekInt();
            int hId = isc & 0xFF;

            MessageBytes vMB=null;
            isc &= 0xFF00;
            if(0xA000 == isc) {
                msg.getInt(); // To advance the read position
                hName = headerTransArray[hId - 1];
                vMB=headers.addValue( hName );
            } else {
                // reset hId -- if the header currently being read
                // happens to be 7 or 8 bytes long, the code below
                // will think it's the content-type header or the
                // content-length header - SC_REQ_CONTENT_TYPE=7,
                // SC_REQ_CONTENT_LENGTH=8 - leading to unexpected
                // behaviour.  see bug 5861 for more information.
                hId = -1;
                msg.getBytes( tmpMB );
                ByteChunk bc=tmpMB.getByteChunk();
                //hName=tmpMB.toString();
                //                vMB=headers.addValue( hName );
                vMB=headers.addValue( bc.getBuffer(),
                                      bc.getStart(), bc.getLength() );
            }

            msg.getBytes(vMB);

            if (hId == SC_REQ_CONTENT_LENGTH ||
                tmpMB.equalsIgnoreCase("Content-Length")) {
                // just read the content-length header, so set it
                int contentLength = (vMB == null) ? -1 : vMB.getInt();
                req.setContentLength(contentLength);
            } else if (hId == SC_REQ_CONTENT_TYPE ||
                       tmpMB.equalsIgnoreCase("Content-Type")) {
                // just read the content-type header, so set it
                ByteChunk bchunk = vMB.getByteChunk();
                req.contentType().setBytes(bchunk.getBytes(),
                                           bchunk.getOffset(),
                                           bchunk.getLength());
            }
        }
    }

    /**
     * Parse host.
     */
    private void parseHost(MessageBytes valueMB, Request request) 
        throws IOException {

        if (valueMB == null || valueMB.isNull()) {
            // HTTP/1.0
            // Default is what the socket tells us. Overriden if a host is 
            // found/parsed
            request.setServerPort(request.getLocalPort());
            request.serverName().duplicate(request.localName());
            return;
        }

        ByteChunk valueBC = valueMB.getByteChunk();
        byte[] valueB = valueBC.getBytes();
        int valueL = valueBC.getLength();
        int valueS = valueBC.getStart();
        int colonPos = -1;
        CharChunk hostNameC = (CharChunk)request.getNote(HOSTBUFFER);
        if(hostNameC == null) {
            hostNameC = new CharChunk(valueL);
            request.setNote(HOSTBUFFER, hostNameC);
        }
        hostNameC.recycle();

        boolean ipv6 = (valueB[valueS] == '[');
        boolean bracketClosed = false;
        for (int i = 0; i < valueL; i++) {
            char b = (char) valueB[i + valueS];
            hostNameC.append(b);
            if (b == ']') {
                bracketClosed = true;
            } else if (b == ':') {
                if (!ipv6 || bracketClosed) {
                    colonPos = i;
                    break;
                }
            }
        }

        if (colonPos < 0) {
            if (request.scheme().equalsIgnoreCase("https")) {
                // 80 - Default HTTTP port
                request.setServerPort(443);
            } else {
                // 443 - Default HTTPS port
                request.setServerPort(80);
            }
            request.serverName().setChars(hostNameC.getChars(), 
                                          hostNameC.getStart(), 
                                          hostNameC.getLength());
        } else {

            request.serverName().setChars(hostNameC.getChars(), 
                                          hostNameC.getStart(), colonPos);

            int port = 0;
            int mult = 1;
            for (int i = valueL - 1; i > colonPos; i--) {
                int charValue = HexUtils.DEC[(int) valueB[i + valueS]];
                if (charValue == -1) {
                    // Invalid character
                    throw new CharConversionException("Invalid char in port: " + valueB[i + valueS]); 
                }
                port = port + (charValue * mult);
                mult = 10 * mult;
            }
            request.setServerPort(port);

        }

    }

}
