/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You 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.ajp;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;

import org.apache.tomcat.util.buf.ByteChunk;
import org.apache.tomcat.util.buf.MessageBytes;
import org.apache.tomcat.util.http.BaseRequest;
import org.apache.tomcat.util.http.HttpMessages;
import org.apache.tomcat.util.http.MimeHeaders;


/**
 * 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 )
 * - "PING REQUEST" input message (sent by the web server to determine if tomcat is not frozen,
 *                                 a PONG REPLY will be sent back)
 * - "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 RequestHandler extends AjpHandler
{
    // 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_KEY_SIZE  = 11; // ajp14 originally, now in ajp13 with jk 1.2/2.0
    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;

    // 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"
    };

    public RequestHandler() 
    {
    }

    public void init( Ajp13 ajp14 ) {
	// register incoming message handlers
	ajp14.registerMessageType( JK_AJP13_FORWARD_REQUEST,
				   "JK_AJP13_FORWARD_REQUEST",
				   this, null); // 2
	// register outgoing messages handler
	ajp14.registerMessageType( JK_AJP13_SEND_BODY_CHUNK, // 3
				   "JK_AJP13_SEND_BODY_CHUNK",
				   this,null );
	ajp14.registerMessageType( JK_AJP13_SEND_HEADERS,  // 4
				   "JK_AJP13_SEND_HEADERS",
				   this,null );
	ajp14.registerMessageType( JK_AJP13_END_RESPONSE, // 5
				   "JK_AJP13_END_RESPONSE",
				   this,null );
	ajp14.registerMessageType( JK_AJP13_GET_BODY_CHUNK, // 6
				   "JK_AJP13_GET_BODY_CHUNK",
				   this, null );
	ajp14.registerMessageType( JK_AJP13_CPING_REQUEST,
				   "JK_AJP13_PING_REQUEST",
				   this, null); // 10
	ajp14.registerMessageType( JK_AJP13_CPONG_REPLY,
				   "JK_AJP13_PONG_REPLY",
				   this, null); // 9
    }
    
    /**
     * Send a CPONG REPLY to web server to its CPING request
     * 
     * @param ch the Ajp13 channel
     * @param outBuf the Ajp13Packet output packet to use
     */
    public int sendCPong(Ajp13 ch, Ajp13Packet outBuf)
    {
		outBuf.reset();
		outBuf.appendByte(JK_AJP13_CPONG_REPLY);
    	
    	try
    	{
			ch.send(outBuf);
    	}
    	catch (IOException ioe)
    	{
    		log("can't send pong reply");
    	}
    	
    	return (999);	// success but no need to process farther
    }
    
    // -------------------- Incoming message --------------------
    public int handleAjpMessage( int type, Ajp13 channel,
				 Ajp13Packet ajp, BaseRequest req )
	throws IOException
    {
	switch( type ) {
	case RequestHandler.JK_AJP13_FORWARD_REQUEST:
	    return decodeRequest(channel, channel.hBuf, req );
		
	default:
	    return UNKNOWN;
	}
    }
    
    /**
     * Parse a FORWARD_REQUEST packet from the web server and store its
     * properties in the passed-in request object.
     *
     * @param req An empty (newly-recycled) request object.
     * @param msg Holds the packet which has just been sent by the web
     * server, with its read position just past the packet header (which in
     * this case includes the prefix code for FORWARD_REQUEST).
     *
     * @return 200 in case of a successful decoduing, 500 in case of error.  
     */
    protected int decodeRequest(Ajp13 ch, Ajp13Packet msg, BaseRequest req)
        throws IOException
    {
        
        if (debug > 0) {
            log("decodeRequest()");
        }

	// XXX Awful return values

        boolean isSSL = false;

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

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

        msg.getMessageBytes(req.remoteAddr());
        msg.getMessageBytes(req.remoteHost());
        msg.getMessageBytes(req.serverName());
        req.setServerPort(msg.getInt());

	isSSL = msg.getBool();

	// Decode headers
	MimeHeaders headers = req.headers();
	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) {
                //
                // header name is encoded as an int
                //
                msg.getInt(); // To advance the read position
                hName = headerTransArray[hId - 1];
		vMB= headers.addValue(hName);
                msg.getMessageBytes(vMB);

                if (hId == SC_REQ_CONTENT_LENGTH) {
                    // just read content-length header
                    int contentLength = (vMB == null) ? -1 : vMB.getInt();
                    req.setContentLength(contentLength);
                } else if (hId == SC_REQ_CONTENT_TYPE) {
                    // just read content-type header
                    ByteChunk bchunk = vMB.getByteChunk();
                    req.contentType().setBytes(bchunk.getBytes(),
                                               bchunk.getOffset(),
                                               bchunk.getLength());
                } else if (hId == SC_REQ_AUTHORIZATION) {
                    ByteChunk bchunk = vMB.getByteChunk();
                    req.authorization().setBytes(bchunk.getBytes(),
                                               bchunk.getOffset(),
                                               bchunk.getLength());
                }
            } else {
                //
                // header name is a string
                //
		// XXX Not very elegant
		vMB = msg.addHeader(headers);
		if (vMB == null) {
                    return 500; // wrong packet
                }
                msg.getMessageBytes(vMB);
            }
        }

	byte attributeCode;
        for(attributeCode = msg.getByte() ;
            attributeCode != SC_A_ARE_DONE ;
            attributeCode = msg.getByte()) {
            switch(attributeCode) {
	    case SC_A_CONTEXT      :
                break;
		
	    case SC_A_SERVLET_PATH :
                break;
		
	    case SC_A_REMOTE_USER  :
                msg.getMessageBytes(req.remoteUser());
                break;
		
	    case SC_A_AUTH_TYPE    :
                msg.getMessageBytes(req.authType());
                break;
		
	    case SC_A_QUERY_STRING :
		msg.getMessageBytes(req.queryString());
                break;
		
	    case SC_A_JVM_ROUTE    :
                msg.getMessageBytes(req.jvmRoute());
                break;
		
	    case SC_A_SSL_CERT     :
		isSSL = true;
                // Transform the string into certificate.
                String certString = msg.getString();
                byte[] certData = certString.getBytes();
                ByteArrayInputStream bais = new ByteArrayInputStream(certData);
 
                // Fill the first element.
                X509Certificate jsseCerts[] = null;
                try {
                    CertificateFactory cf =
                        CertificateFactory.getInstance("X.509");
                    X509Certificate cert = (X509Certificate)
                        cf.generateCertificate(bais);
                    jsseCerts =  new X509Certificate[1];
                    jsseCerts[0] = cert;
                } catch(java.security.cert.CertificateException e) {
                    log("Certificate convertion failed" + e );
                }
 
                req.setAttribute("javax.servlet.request.X509Certificate",
                                 jsseCerts);
                break;
		
	    case SC_A_SSL_CIPHER   :
		isSSL = true;
		req.setAttribute("javax.servlet.request.cipher_suite",
				 msg.getString());
                break;
		
	    case SC_A_SECRET   :
                // If a request has a secret attribute, set it on
                // channel - it'll be visible to the caller ( Interceptor,
                // Connector ) and it can check it against its settings before
                // trusting us.
                String secret=msg.getString();
                if(secret!=null) {
                    ch.setSecret( secret );
                }
                break;
		
	    case SC_A_SSL_SESSION  :
		isSSL = true;
		req.setAttribute("javax.servlet.request.ssl_session",
				  msg.getString());
                break;
		
	    case SC_A_REQ_ATTRIBUTE :
		req.setAttribute(msg.getString(), 
				 msg.getString());
                break;

	    case SC_A_SSL_KEY_SIZE: // Ajp13 !
                isSSL = true;
		req.setAttribute("javax.servlet.request.key_size",
				 Integer.toString(msg.getInt()));
		break;
    
        case SC_A_STORED_METHOD:
                req.method().setString(msg.getString());
                break;
    
	    default:
                // Ignore. Assume a single-string value - we shouldn't
                // allow anything else.
                msg.getString();
                break;
	    }
        }

        if(isSSL) {
            req.setScheme(req.SCHEME_HTTPS);
            req.setSecure(true);
        }

        // set cookies on request now that we have all headers
        req.cookies().setHeaders(req.headers());

        // Check to see if there should be a body packet coming along
        // immediately after
        if(req.getContentLength() > 0) {

            /* Read present data */
            int bytesRead = ch.receive(ch.inBuf);
            if(bytesRead < 0) {
                return 500;
            }

            // First two bytes are length, rest is real data
            if (bytesRead < 2) {
                ch.blen = 0;
            } else {
                ch.blen = bytesRead - 2;
            }
            ch.pos = 0;
            ch.inBuf.getBytes(ch.bodyBuff);
        }
    
        if (debug > 5) {
            log(req.toString());
        }

        return 200; // Success
    }
    

    // -------------------- Messages from container to server ------------------
    
    /**
     * Send the HTTP headers back to the web server and on to the browser.
     *
     * @param status The HTTP status code to send.
     * @param statusMessage the HTTP status message to send.
     * @param headers The set of all headers.
     */
    public void sendHeaders(Ajp13 ch, Ajp13Packet outBuf,
			    int status, String statusMessage,
                            MimeHeaders headers)
        throws IOException
    {
	// XXX if more headers that MAX_SIZE, send 2 packets!
	if( statusMessage==null ) statusMessage=HttpMessages.getMessage(status);
	outBuf.reset();
        outBuf.appendByte(JK_AJP13_SEND_HEADERS);
        outBuf.appendInt(status);
	
	outBuf.appendString(statusMessage);
        
	int numHeaders = headers.size();
        outBuf.appendInt(numHeaders);
        
	for( int i=0 ; i < numHeaders ; i++ ) {
	    String headerName = headers.getName(i).toString();
	    int sc = headerNameToSc(headerName);
            if(-1 != sc) {
                outBuf.appendInt(sc);
            } else {
                outBuf.appendString(headerName);
            }
            outBuf.appendString(headers.getValue(i).toString() );
        }

        outBuf.end();
        ch.send(outBuf);
    } 


    /**
     * Signal the web server that the servlet has finished handling this
     * request, and that the connection can be reused.
     */
    public void finish(Ajp13 ch, Ajp13Packet outBuf) throws IOException {
        if (debug > 0)  log("finish()");

	outBuf.reset();
        outBuf.appendByte(JK_AJP13_END_RESPONSE);
        outBuf.appendBool(true); // Reuse this connection
        outBuf.end();
        ch.send(outBuf);
    }

    /**
     * Send a chunk of response body data to the web server and on to the
     * browser.
     *
     * @param b A huffer of bytes to send.
     * @param off The offset into the buffer from which to start sending.
     * @param len The number of bytes to send.
     */    
    public void doWrite(Ajp13 ch, Ajp13Packet outBuf,
			byte b[], int off, int len)
	throws IOException
    {
        if (debug > 0) log("doWrite(byte[], " + off + ", " + len + ")");

	int sent = 0;
	while(sent < len) {
	    int to_send = len - sent;
	    to_send = to_send > Ajp13.MAX_SEND_SIZE ? Ajp13.MAX_SEND_SIZE : to_send;

	    outBuf.reset();
	    outBuf.appendByte(JK_AJP13_SEND_BODY_CHUNK);	        	
	    outBuf.appendBytes(b, off + sent, to_send);	        
	    ch.send(outBuf);
	    sent += to_send;
	}
    }

    // -------------------- Utils -------------------- 

    /**
     * Translate an HTTP response header name to an integer code if
     * possible.  Case is ignored.
     * 
     * @param name The name of the response header to translate.
     *
     * @return The code for that header name, or -1 if no code exists.
     */
    protected int headerNameToSc(String name)
    {       
        switch(name.charAt(0)) {
	case 'c':
	case 'C':
	    if(name.equalsIgnoreCase("Content-Type")) {
		return SC_RESP_CONTENT_TYPE;
	    } else if(name.equalsIgnoreCase("Content-Language")) {
		return SC_RESP_CONTENT_LANGUAGE;
	    } else if(name.equalsIgnoreCase("Content-Length")) {
		return SC_RESP_CONTENT_LENGTH;
	    }
            break;
            
	case 'd':
	case 'D':
	    if(name.equalsIgnoreCase("Date")) {
                return SC_RESP_DATE;
	    }
            break;
            
	case 'l':
	case 'L':
	    if(name.equalsIgnoreCase("Last-Modified")) {
		return SC_RESP_LAST_MODIFIED;
	    } else if(name.equalsIgnoreCase("Location")) {
		return SC_RESP_LOCATION;
	    }
            break;

	case 's':
	case 'S':
	    if(name.equalsIgnoreCase("Set-Cookie")) {
		return SC_RESP_SET_COOKIE;
	    } else if(name.equalsIgnoreCase("Set-Cookie2")) {
		return SC_RESP_SET_COOKIE2;
	    }
            break;
            
	case 'w':
	case 'W':
	    if(name.equalsIgnoreCase("WWW-Authenticate")) {
		return SC_RESP_WWW_AUTHENTICATE;
	    }
            break;          
        }
        
        return -1;
    }
   
    private int debug=0;
    private Logger logger = new Logger();
    
    public void setDebug(int debug) {
        this.debug = debug;
    }

    public void setLogger(Logger l) {
        this.logger = l;
    }
    
    void log(String s) {
        logger.log("[RequestHandler] " + s );
    }

    // ==================== Servlet Input Support =================
    // XXX DEPRECATED
    
    public int available(Ajp13 ch) throws IOException {
        if (debug > 0) {
            log("available()");
        }

        if (ch.pos >= ch.blen) {
            if( ! refillReadBuffer(ch)) {
		return 0;
	    }
        }
        return ch.blen - ch.pos;
    }

    /**
     * Return the next byte of request body data (to a servlet).
     */
    public int doRead(Ajp13 ch) throws IOException 
    {
        if (debug > 0) {
            log("doRead()");
        }

        if(ch.pos >= ch.blen) {
            if( ! refillReadBuffer(ch)) {
		return -1;
	    }
        }
        return ch.bodyBuff[ch.pos++] & 0xFF;
    }
    
    /**
     * Store a chunk of request data into the passed-in byte buffer.
     *
     * @param b A buffer to fill with data from the request.
     * @param off The offset in the buffer at which to start filling.
     * @param len The number of bytes to copy into the buffer.
     *
     * @return The number of bytes actually copied into the buffer, or -1
     * if the end of the stream has been reached.
     */
    public int doRead(Ajp13 ch, byte[] b, int off, int len) throws IOException 
    {
        if (debug > 0) {
            log("doRead(byte[], int, int)");
        }

	if(ch.pos >= ch.blen) {
	    if( ! refillReadBuffer(ch)) {
		return -1;
	    }
	}

	if(ch.pos + len <= ch.blen) { // Fear the off by one error
	    // Sanity check b.length > off + len?
	    System.arraycopy(ch.bodyBuff, ch.pos, b, off, len);
	    ch.pos += len;
	    return len;
	}

	// Not enough data (blen < pos + len)
	int toCopy = len;
	while(toCopy > 0) {
	    int bytesRemaining = ch.blen - ch.pos;
	    if(bytesRemaining < 0) 
		bytesRemaining = 0;
	    int c = bytesRemaining < toCopy ? bytesRemaining : toCopy;
            
	    System.arraycopy(ch.bodyBuff, ch.pos, b, off, c);

	    toCopy    -= c;

	    off       += c;
	    ch.pos       += c; // In case we exactly consume the buffer

	    if(toCopy > 0) 
		if( ! refillReadBuffer(ch)) { // Resets blen and pos
		    break;
		}
	}

	return len - toCopy;
    }
    
    /**
     * Get more request body data from the web server and store it in the 
     * internal buffer.
     *
     * @return true if there is more data, false if not.    
     */
    public boolean refillReadBuffer(Ajp13 ch) throws IOException 
    {
        if (debug > 0) {
            log("refillReadBuffer()");
        }

	// If the server returns an empty packet, assume that that end of
	// the stream has been reached (yuck -- fix protocol??).

	// Why not use outBuf??
	ch.inBuf.reset();
	ch.inBuf.appendByte(JK_AJP13_GET_BODY_CHUNK);
	ch.inBuf.appendInt(Ajp13.MAX_READ_SIZE);
	ch.send(ch.inBuf);
	
	int err = ch.receive(ch.inBuf);
        if(err < 0) {
	    throw new IOException();
	}
	
        // check for empty packet, which means end of stream
        if (ch.inBuf.getLen() == 0) {
            if (debug > 0) {
                log("refillReadBuffer():  "
                    + "received empty packet -> end of stream");
            }
            ch.blen = 0;
            ch.pos = 0;
            return false;
        }

    	ch.blen = ch.inBuf.peekInt();
    	ch.pos = 0;
    	ch.inBuf.getBytes(ch.bodyBuff);

	return (ch.blen > 0);
    }    

    // ==================== Servlet Output Support =================
    
    /**
     */
    public void beginSendHeaders(Ajp13 ch, Ajp13Packet outBuf,
				 int status,
                                 String statusMessage,
                                 int numHeaders) throws IOException {

        if (debug > 0) {
            log("sendHeaders()");
        }

	// XXX if more headers that MAX_SIZE, send 2 packets!

	outBuf.reset();
        outBuf.appendByte(JK_AJP13_SEND_HEADERS);

        if (debug > 0) {
            log("status is:  " + status +
                       "(" + statusMessage + ")");
        }

        // set status code and message
        outBuf.appendInt(status);
        outBuf.appendString(statusMessage);

        // write the number of headers...
        outBuf.appendInt(numHeaders);
    }

    public void sendHeader(Ajp13Packet outBuf,
			   String name, String value)
	throws IOException
    {
        int sc = headerNameToSc(name);
        if(-1 != sc) {
            outBuf.appendInt(sc);
        } else {
            outBuf.appendString(name);
        }
        outBuf.appendString(value);
    }

    public void endSendHeaders(Ajp13 ch, Ajp13Packet outBuf)
	throws IOException
    {
        outBuf.end();
        ch.send(outBuf);
    }

    /**
     * Send the HTTP headers back to the web server and on to the browser.
     *
     * @param status The HTTP status code to send.
     * @param headers The set of all headers.
     */
    public void sendHeaders(Ajp13 ch, Ajp13Packet outBuf,
			    int status, MimeHeaders headers)
        throws IOException
    {
        sendHeaders(ch, outBuf, status, HttpMessages.getMessage(status),
                    headers);
    }
    

 }
