Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
   /*
    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    *
    * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
    *
    * The contents of this file are subject to the terms of either the GNU
    * General Public License Version 2 only ("GPL") or the Common Development
    * and Distribution License("CDDL") (collectively, the "License").  You
    * may not use this file except in compliance with the License.  You can
   * obtain a copy of the License at
   * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
   * or packager/legal/LICENSE.txt.  See the License for the specific
   * language governing permissions and limitations under the License.
   *
   * When distributing the software, include this License Header Notice in each
   * file and include the License file at packager/legal/LICENSE.txt.
   *
   * GPL Classpath Exception:
   * Oracle designates this particular file as subject to the "Classpath"
   * exception as provided by Oracle in the GPL Version 2 section of the License
   * file that accompanied this code.
   *
   * Modifications:
   * If applicable, add the following below the License Header, with the fields
   * enclosed by brackets [] replaced by your own identifying information:
   * "Portions Copyright [year] [name of copyright owner]"
   *
   * Contributor(s):
   * If you wish your version of this file to be governed by only the CDDL or
   * only the GPL Version 2, indicate your decision by adding "[Contributor]
   * elects to include this software in this distribution under the [CDDL or GPL
   * Version 2] license."  If you don't indicate a single choice of license, a
   * recipient has the option to distribute your version of this file under
   * either the CDDL, the GPL Version 2 or to extend the choice of license to
   * its licensees as provided above.  However, if you add GPL Version 2 code
   * and therefore, elected the GPL Version 2 license, then the option applies
   * only if the new code is made subject to such option by the copyright
   * holder.
   *
   *
   * This file incorporates work covered by the following copyright and
   * permission notice:
   *
   * Copyright 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.coyote.http11;
  
  import java.net.Socket;
  // START SJSAS 6415934
  // END SJSAS 6415934
  
  
  //import org.apache.coyote.http11.filters.GzipInputFilter;
Processes HTTP requests.

Author(s):
Remy Maucherat
 
 public class Http11Processor implements ProcessorActionHook {
 
 
     // ----------------------------------------------------------- Constructors
 

    
Default constructor.
 
     public Http11Processor() {
     }
 
 
     public Http11Processor(int headerBufferSize) {
 
          = new Request();
         // START OF SJSAS PE 8.1 6172948
         //inputBuffer = new InternalInputBuffer(request, headerBufferSize);
         // END OF SJSAS PE 8.1 6172948
 
 
          = new Response();
         .setHook(this);
          = new InternalOutputBuffer(headerBufferSize,true);
         .setResponse();
 
         initializeFilters();
 
 
         // START OF SJSAS PE 8.1 5036984
         if (System.getProperty() != null) {
              = 
                         Boolean.valueOf(
                             System.getProperty()).booleanValue();
 
             if (!)
                 .warn("Keep Alive algorith will no be used"); 
         }
         // END OF SJSAS PE 8.1 5036984
 
     }
 
 
     // ----------------------------------------------------- Instance Variables
 

    
Associated adapter.
 
     protected Adapter adapter = null;


    
Request object.
 
     protected Request request = null;


    
Response object.
 
     protected Response response = null;


    
Input.
 
     protected InternalInputBuffer inputBuffer = null;


    
Output.
 
     protected InternalOutputBuffer outputBuffer = null;


    
State flag.
 
     protected boolean started = false;


    
Error flag.
 
     protected boolean error = false;


    
Keep-alive.
 
     protected boolean keepAlive = true;


    
HTTP/1.1 flag.
 
     protected boolean http11 = true;


    
HTTP/0.9 flag.
 
     protected boolean http09 = false;


    
Content delimitator for the request (if false, the connection will be closed at the end of the request).
 
     protected boolean contentDelimitation = true;


    
List of restricted user agents.
 
     protected String[] restrictedUserAgents = null;


    
Logger.
 
     protected static final com.sun.org.apache.commons.logging.Log log 
         = com.sun.org.apache.commons.logging.LogFactory.getLog(Http11Processor.class);


    
Maximum number of Keep-Alive requests to honor.
 
     protected int maxKeepAliveRequests = -1;


    
SSL information.
 
     protected SSLSupport sslSupport;


    
Socket associated with the current connection.
 
     protected Socket socket;


    
Remote Address associated with the current connection.
 
     protected String remoteAddr = null;


    
Remote Host associated with the current connection.
 
     protected String remoteHost = null;


    
Local Host associated with the current connection.
 
     protected String localName = null;


    
Local port to which the socket is connected
 
     protected int localPort = -1;

    
    
Remote port to which the socket is connected
 
     protected int remotePort = -1;
    
    
    
The local Host address.
 
     protected String localAddr = null
    
    
Maximum timeout on uploads.
 
     protected int timeout = 300000;   // 5 minutes as in Apache HTTPD server
 

    
Flag to disable setting a different time-out on uploads.
 
     protected boolean disableUploadTimeout = false;


    
Allowed compression level.
 
     protected int compressionLevel = 0;


    
Minimum contentsize to make compression.
 
     protected int compressionMinSize = 2048;


    
Max post size.
 
     protected int maxPostSize = 2 * 1024 * 1024;


    
List of user agents to not use gzip with
 
     protected String[] noCompressionUserAgents = null;


    
List of MIMES which could be gzipped
 
     protected String[] compressableMimeTypes = { "text/html""text/xml""text/plain" };


    
Host name (used to avoid useless B2C conversion on the host name).
 
     protected char[] hostNameC = new char[0];
 
     protected ThreadPool threadPool;
 
 
     // START OF SJSAS PE 8.1 5036984
     private final static String USE_KEEP_ALIVE =
                 "com.sun.enterprise.web.connector.coyote.useKeepAliveAlgorithm";
 
     private boolean useKeepAliveAlgorithm = true;
     // END OF SJSAS PE 8.1 5036984
 
     // START OF SJSAS PE 8.1 6172948
     
The input request buffer size.
 
     private int requestBufferSize = 4096;
     // END OF SJSAS PE 8.1 6172948
 
     // ------------------------------------------------------------- Properties
 

    
Return compression level.
 
     public String getCompression() {
         switch () {
         case 0:
             return "off";
         case 1:
             return "on";
         case 2:
             return "force";
         }
         return "off";
     }


    
Set compression level.
 
     public void setCompression(String compression) {
         if (compression.equals("on")) {
             this. = 1;
         } else if (compression.equals("force")) {
             this. = 2;
         } else if (compression.equals("off")) {
             this. = 0;
         } else {
             try {
                 // Try to parse compression as an int, which would give the
                 // minimum compression size
                  = Integer.parseInt(compression);
                 this. = 1;
             } catch (Exception e) {
                 this. = 0;
             }
         }
     }
 
     public void setThreadPool(ThreadPool threadPool) {
         this. = threadPool;
     }

    
Add user-agent for which gzip compression didn't works The user agent String given will be exactly matched to the user-agent header submitted by the client.

Parameters:
userAgent user-agent string
 
     public void addNoCompressionUserAgent(String userAgent) {
     }


    
Set no compression user agent list (this method is best when used with a large number of connectors, where it would be better to have all of them referenced a single array).
 
     public void setNoCompressionUserAgents(String[] noCompressionUserAgents) {
         this. = noCompressionUserAgents;
     }


    
Return the list of no compression user agents.
 
     public String[] findNoCompressionUserAgents() {
         return ();
     }


    
Add a mime-type which will be compressable The mime-type String will be exactly matched in the response mime-type header .

Parameters:
userAgent user-agent string
 
     public void addCompressableMimeType(String mimeType) {
     }


    
Set compressable mime-type list (this method is best when used with a large number of connectors, where it would be better to have all of them referenced a single array).
 
     public void setCompressableMimeType(String[] compressableMimeTypes) {
         this. = compressableMimeTypes;
     }


    
Return the list of restricted user agents.
 
     public String[] findCompressableMimeTypes() {
         return ();
     }
 
 
 
     // --------------------------------------------------------- Public Methods
 

    
Add input or output filter.

Parameters:
className class name of the filter
 
     protected void addFilter(String className) {
         try {
             Class clazz = Class.forName(className);
             Object obj = clazz.newInstance();
             if (obj instanceof InputFilter) {
                 .addFilter((InputFilterobj);
             } else if (obj instanceof OutputFilter) {
                 .addFilter((OutputFilterobj);
             } else {
                 // Not a valid filter: log and ignore
             }
         } catch (Exception e) {
             // Log and ignore
         }
     }


    
General use method

Parameters:
sArray the StringArray
value string
 
     private void addStringArray(String sArray[], String value) {
         if (sArray == null)
             sArray = new String[0];
         String[] results = new String[sArray.length + 1];
         for (int i = 0; i < sArray.lengthi++)
             results[i] = sArray[i];
         results[sArray.length] = value;
         sArray = results;
     }

    
General use method

Parameters:
sArray the StringArray
value string
 
     private boolean inStringArray(String sArray[], String value) {
         for (int i = 0; i < sArray.lengthi++) {
             if (sArray[i].equals(value)) {
                 return true;
             }
         }
         return false;
     }


    
Add restricted user-agent (which will downgrade the connector to HTTP/1.0 mode). The user agent String given will be exactly matched to the user-agent header submitted by the client.

Parameters:
userAgent user-agent string
 
     public void addRestrictedUserAgent(String userAgent) {
     	addStringArray(userAgent);
     }


    
Set restricted user agent list (this method is best when used with a large number of connectors, where it would be better to have all of them referenced a single array).
 
     public void setRestrictedUserAgents(String[] restrictedUserAgents) {
         this. = restrictedUserAgents;
     }


    
Return the list of restricted user agents.
 
     public String[] findRestrictedUserAgents() {
         return ();
     }


    
Set the maximum number of Keep-Alive requests to honor. This is to safeguard from DoS attacks. Setting to a negative value disables the check.
 
     public void setMaxKeepAliveRequests(int mkar) {
          = mkar;
     }


    
Return the number of Keep-Alive requests that we will honor.
 
     public int getMaxKeepAliveRequests() {
         return ;
     }


    
Set the maximum size of a POST which will be buffered in SSL mode.
 
     public void setMaxPostSize(int mps) {
          = mps;
     }


    
Return the maximum size of a POST which will be buffered in SSL mode.
 
     public int getMaxPostSize() {
         return ;
     }


    
Set the SSL information for this HTTP connection.
 
     public void setSSLSupport(SSLSupport sslSupport) {
         this. = sslSupport;
     }


    
Set the socket associated with this HTTP connection.
 
     public void setSocket(Socket socket)
         throws IOException {
         this. = socket;
     }

    
Set the flag to control upload time-outs.
 
     public void setDisableUploadTimeout(boolean isDisabled) {
          = isDisabled;
     }

    
Get the flag that controls upload time-outs.
 
     public boolean getDisableUploadTimeout() {
         return ;
     }

    
Set the upload timeout.
 
     public void setTimeoutint timeouts ) {
          = timeouts ;
     }

    
Get the upload timeout.
 
     public int getTimeout() {
         return ;
     }

    
Get the request associated with this processor.

Returns:
 
     public Request getRequest() {
         return ;
     }

    
Process pipelined HTTP requests using the specified input and output streams.

Parameters:
input stream from which the HTTP requests will be read
output stream which will be used to output the HTTP responses
Throws:
java.io.IOException error during an I/O operation
     
     // START OF SJSAS 6231069
     //  public void process(InputStream input, OutputStream output)
     public boolean process(InputStream inputOutputStream output)
         throws Exception {
     // END OF SJSAS 6231069
         ThreadWithAttributes thrA=
                 (ThreadWithAttributes)Thread.currentThread();
         RequestInfo rp = .getRequestProcessor();
         thrA.setCurrentStage("parsing http request");
 
         // Set the remote address
          = null;
          = null;
          = null;
          = -1;
 
         // Setting up the I/O
         .setInputStream(input);
         .setOutputStream(output);
 
         // Error flag
          = false;
          = true;
 
         int keepAliveLeft = ;
         int soTimeout = .getSoTimeout();
 
         // START OF SJSAS PE 8.1 5036984
         if (  ) {
         // END OF SJSAS PE 8.1 5036984
             float threadRatio = 
                 (float.getCurrentThreadsBusy() 
                 / (float.getMaxThreads();
             if ((threadRatio > 0.33) && (threadRatio <= 0.66)) {
                 soTimeout = soTimeout / 2;
             } else if (threadRatio > 0.66) {
                 soTimeout = soTimeout / 5;
                 keepAliveLeft = 1;
             }
         // START OF SJSAS PE 8.1 5036984
         }
         // END OF SJSAS PE 8.1 5036984
 
         boolean keptAlive = false;
 
         while ( && ! && ) {
             try {
                 if( ! && keptAlive && soTimeout > 0 ) {
                     .setSoTimeout(soTimeout);
                 }
                 .parseRequestLine();
                 .setStartTime(System.currentTimeMillis());
                 thrA.setParam.requestURI() );
                 keptAlive = true;
                 if (!) {
                     .setSoTimeout();
                 }
                 .parseHeaders();
             } catch (IOException e) {
                  = true;
                 break;
             } catch (Exception e) {
                 .debug("Error parsing HTTP request"e);
                 // 400 - Bad Request
                 .setStatus(400);
                  = true;
             }
 
             // Setting up filters, and parse some request headers
             thrA.setCurrentStage("prepareRequest");
             rp.setStage(....);
             try {
                 prepareRequest();
             } catch (Throwable t) {
                 .debug("Error preparing request"t);
                 // 400 - Internal Server Error
                 .setStatus(400);
                  = true;
             }
 
             // START OF SJSAS PE 8.1 5036984
             if (  ) {
             // END OF SJSAS PE 8.1 5036984
                 if ( > 0 && --keepAliveLeft == 0)
                      = false;
             // START OF SJSAS PE 8.1 5036984
             } else {
                  = false;
             }
             // END OF SJSAS PE 8.1 5036984
 
             // Process the request in the adapter
             if (!) {
                 try {
                     thrA.setCurrentStage("service");
                     rp.setStage(....);
                     .service();
                     
                     // START GlassFish Issue 798
                     .afterService();
                     // END GlassFish Issue 798
                     
                     // Handle when the response was committed before a serious
                     // error occurred.  Throwing a ServletException should both
                     // set the status to 500 and set the errorException.
                     // If we fail here, then the response is likely already 
                     // committed, so we can't try and set headers.
                     if( && !) { // Avoid checking twice.
                          = .getErrorException() != null ||
                                 statusDropsConnection(.getStatus());
                     }
 
                 } catch (InterruptedIOException e) {
                      = true;
                 } catch (Throwable t) {
                     .error("Error processing request"t);
                     // 500 - Internal Server Error
                     .setStatus(500);
                      = true;
                 }
             }
 
             // Finish the handling of the request
             try {
                 thrA.setCurrentStage("endRequestIB");
                 rp.setStage(....);
                 .endRequest();
             } catch (IOException e) {
                  = true;
             } catch (Throwable t) {
                 .error("Error finishing request"t);
                 // 500 - Internal Server Error
                 .setStatus(500);
                  = true;
             }
             try {
                 thrA.setCurrentStage("endRequestOB");
                 rp.setStage(....);
                 .endRequest();
             } catch (IOException e) {
                  = true;
             } catch (Throwable t) {
                 .error("Error finishing response"t);
                  = true;
             }
 
             thrA.setCurrentStage("ended");
             rp.setStage(....);
 
             // Don't reset the param - we'll see it as ended. Next request
             // will reset it
             // thrA.setParam(null);
             // Next request
             .nextRequest();
             .nextRequest();
 
         }
 
 
         // Recycle
         .recycle();
         .recycle();
 
         // Recycle ssl info
          = null;
         
         return true;
     }
 
 
     // ----------------------------------------------------- ActionHook Methods
 

    
Send an action to the connector.

Parameters:
actionCode Type of the action
param Action parameter
 
     public void action(ActionCode actionCodeObject param) {
 
         if (actionCode == .) {
             // Commit current response
 
             if (.isCommitted())
                 return;
 
             // Validate and write response headers
             prepareResponse();
             try {
                 .commit();
             } catch (IOException e) {
                 // Set error flag
                  = true;
             }
 
         } else if (actionCode == .) {
 
             // Acknowlege request
 
             // Send a 100 status back if it makes sense (response not committed
             // yet, and client specified an expectation for 100-continue)
 
             if (.isCommitted())
                 return;
 
             MessageBytes expectMB = 
                 .getMimeHeaders().getValue("expect");
             if ((expectMB != null)
                 && (expectMB.indexOfIgnoreCase("100-continue", 0) != -1)) {
                 try {
                     .sendAck();
                 } catch (IOException e) {
                     // Set error flag
                      = true;
                     .setErrorException(e);
                 }
             }
 
         } else if (actionCode == .) {
             // Close
 
             // End the processing of the current request, and stop any further
             // transactions with the client
 
             try {
                 .endRequest();
             } catch (IOException e) {
                 // Set error flag
                  = true;
             }
 
         } else if (actionCode == .) {
 
             // Reset response
 
             // Note: This must be called before the response is committed
 
             .reset();
 
         } else if (actionCode == .) {
 
             // Do nothing
 
         } else if (actionCode == .) {
 
              = true;
 
         } else if (actionCode == .) {
 
              = false;
 
         } else if (actionCode == . ) {
 
             try {
                 if ( != null) {
                     Object sslO = .getCipherSuite();
                     if (sslO != null)
                         .setAttribute
                             (.sslO);
                     sslO = .getPeerCertificateChain(false);
                     if (sslO != null)
                         .setAttribute
                             (.sslO);
                     sslO = .getKeySize();
                     if (sslO != null)
                         .setAttribute
                             (.sslO);
                     sslO = .getSessionId();
                     if (sslO != null)
                         .setAttribute
                             (.sslO);
                 }
             } catch (Exception e) {
                 .warn("Exception getting SSL attributes " ,e);
             }
 
         } else if (actionCode == .) {
 
             if (( == null) && ( != null)) {
                 InetAddress inetAddr = .getInetAddress();
                  = inetAddr.getHostAddress();
                 .remoteAddr().setString();
             }
 
         } else if (actionCode == .) {
 
             if (( == null) && ( != null)) {
                 InetAddress inetAddr = .getLocalAddress();
                 if (inetAddr != null) {
                      = inetAddr.getHostName();
                 }
             }
             .localName().setString();
 
         } else if (actionCode == .) {
 
             if (( == null) && ( != null)) {
                 InetAddress inetAddr = .getInetAddress();
                 if (inetAddr != null) {
                      = inetAddr.getHostName();
                 }
             }
             .remoteHost().setString();
 
         } else if (actionCode == .) {
 
             if ( == null)
                 = .getLocalAddress().getHostAddress();
 
             .localAddr().setString();
 
         } else if (actionCode == .) {
 
             if (( == -1 ) && ( !=null)) {
                  = .getPort();
             }
             .setRemotePort();
 
         } else if (actionCode == .) {
 
             if (( == -1 ) && ( !=null)) {
                  = .getLocalPort();
             }
             .setLocalPort();
 
         } else if (actionCode == .) {
             if != null) {
                 /*
                  * Consume and buffer the request body, so that it does not
                  * interfere with the client's handshake messages
                  */
                 InputFilter[] inputFilters = .getFilters();
                 ((BufferedInputFilterinputFilters[.])
                     .setLimit();
                 .addActiveFilter
                     (inputFilters[.]);
                 try {
                     Object sslO = .getPeerCertificateChain(true);
                     ifsslO != null) {
                         .setAttribute
                             (.sslO);
                     }
                 } catch (Exception e) {
                     .warn("Exception getting SSL Cert",e);
                 }
             }
         }
 
     }
 
 
     // ------------------------------------------------------ Connector Methods
 

    
Set the associated adapter.

Parameters:
adapter the new adapter
    public void setAdapter(Adapter adapter) {
        this. = adapter;
    }


    
Get the associated adapter.

Returns:
the associated adapter
    public Adapter getAdapter() {
        return ;
    }
    // ------------------------------------------------------ Protected Methods


    
After reading the request headers, we have to setup the request filters.
    protected void prepareRequest() {
         = true;
         = false;
         = false;
        if ( != null) {
            .scheme().setString("https");
        }
        MessageBytes protocolMB = .protocol();
        if (protocolMB.equals(.)) {
             = true;
            protocolMB.setString(.);
        } else if (protocolMB.equals(.)) {
             = false;
             = false;
            protocolMB.setString(.);
        } else if (protocolMB.equals("")) {
            // HTTP/0.9
             = true;
             = false;
             = false;
        } else {
            // Unsupported protocol
             = false;
             = true;
            // Send 505; Unsupported HTTP version
            .setStatus(505);
        }
        MessageBytes methodMB = .method();
        if (methodMB.equals(.)) {
            methodMB.setString(.);
        } else if (methodMB.equals(.)) {
            methodMB.setString(.);
        }
        // Check connection header
        MessageBytes connectionValueMB = 
            .getMimeHeaders().getValue("connection");
        if (connectionValueMB != null) {
            ByteChunk connectionValueBC = connectionValueMB.getByteChunk();
            if (findBytes(connectionValueBC.) != -1) {
                 = false;
            } else if (findBytes(connectionValueBC
                                 .) != -1) {
                 = true;
            }
        }
        // Check user-agent header
        if (( != null) && (() || ())) {
            MessageBytes userAgentValueMB =  
                .getMimeHeaders().getValue("user-agent");
            // Check in the restricted list, and adjust the http11 
            // and keepAlive flags accordingly
            String userAgentValue = userAgentValueMB.toString();
            for (int i = 0; i < .i++) {
                if ([i].equals(userAgentValue)) {
                     = false;
                     = false;
                }
            }
        }
        // Check for a full URI (including protocol://host:port/)
        ByteChunk uriBC = .requestURI().getByteChunk();
        if (uriBC.startsWithIgnoreCase("http", 0)) {
            int pos = uriBC.indexOf("://", 0, 3, 4);
            int uriBCStart = uriBC.getStart();
            int slashPos = -1;
            if (pos != -1) {
                byte[] uriB = uriBC.getBytes();
                slashPos = uriBC.indexOf('/'pos + 3);
                if (slashPos == -1) {
                    slashPos = uriBC.getLength();
                    // Set URI as "/"
                    .requestURI().setBytes
                        (uriBuriBCStart + pos + 1, 1);
                } else {
                    .requestURI().setBytes
                        (uriBuriBCStart + slashPos
                         uriBC.getLength() - slashPos);
                }
                MessageBytes hostMB = 
                    .getMimeHeaders().setValue("host");
                hostMB.setBytes(uriBuriBCStart + pos + 3, 
                                slashPos - pos - 3);
            }
        }
        // Input filter setup
        InputFilter[] inputFilters = .getFilters();
        // Parse content-length header
        long contentLength = .getContentLengthLong();
        if (contentLength >= 0) {
            .addActiveFilter
                (inputFilters[.]);
             = true;
        }
        // Parse transfer-encoding header
        MessageBytes transferEncodingValueMB = null;
        if ()
            transferEncodingValueMB = 
                .getMimeHeaders().getValue("transfer-encoding");
        if (transferEncodingValueMB != null) {
            String transferEncodingValue = transferEncodingValueMB.toString();
            // Parse the comma separated list. "identity" codings are ignored
            int startPos = 0;
            int commaPos = transferEncodingValue.indexOf(',');
            String encodingName = null;
            while (commaPos != -1) {
                encodingName = transferEncodingValue.substring
                    (startPoscommaPos).toLowerCase().trim();
                if (!addInputFilter(inputFiltersencodingName)) {
                    // Unsupported transfer encoding
                     = true;
                    // 501 - Unimplemented
                    .setStatus(501);
                }
                startPos = commaPos + 1;
                commaPos = transferEncodingValue.indexOf(','startPos);
            }
            encodingName = transferEncodingValue.substring(startPos)
                .toLowerCase().trim();
            if (!addInputFilter(inputFiltersencodingName)) {
                // Unsupported transfer encoding
                 = true;
                // 501 - Unimplemented
                .setStatus(501);
            }
        }
        MessageBytes valueMB = .getMimeHeaders().getValue("host");
        // Check host header
        if ( && (valueMB == null)) {
             = true;
            // 400 - Bad request
            .setStatus(400);
        }
        parseHost(valueMB);
        if (!) {
            // If there's no content length and we're using keep-alive 
            // (HTTP/1.0 with keep-alive or HTTP/1.1), assume
            // the client is not broken and didn't send a body
            if () {
                .addActiveFilter
                    (inputFilters[.]);
                 = true;
            }
        }
        if (!)
             = false;
    }


    
Parse host.
    public void parseHost(MessageBytes valueMB) {
        if (valueMB == null || valueMB.isNull()) {
            // HTTP/1.0
            // Default is what the socket tells us. Overriden if a host is 
            // found/parsed
            .setServerPort(.getLocalPort());
            InetAddress localAddress = .getLocalAddress();
            // Setting the socket-related fields. The adapter doesn't know 
            // about socket.
            .setLocalHost(localAddress.getHostName());
            .serverName().setString(localAddress.getHostName());
            return;
        }
        ByteChunk valueBC = valueMB.getByteChunk();
        byte[] valueB = valueBC.getBytes();
        int valueL = valueBC.getLength();
        int valueS = valueBC.getStart();
        int colonPos = -1;
        if (. < valueL) {
             = new char[valueL];
        }
        boolean ipv6 = (valueB[valueS] == '[');
        boolean bracketClosed = false;
        for (int i = 0; i < valueLi++) {
            char b = (charvalueB[i + valueS];
            [i] = b;
            if (b == ']') {
                bracketClosed = true;
            } else if (b == ':') {
                if (!ipv6 || bracketClosed) {
                    colonPos = i;
                    break;
                }
            }
        }
        if (colonPos < 0) {
            if ( == null) {
                // 80 - Default HTTTP port
                .setServerPort(80);
            } else {
                // 443 - Default HTTPS port
                .setServerPort(443);
            }
            .serverName().setChars(, 0, valueL);
        } else {
            .serverName().setChars(, 0, colonPos);
            int port = 0;
            int mult = 1;
            for (int i = valueL - 1; i > colonPosi--) {
                int charValue = .[(intvalueB[i + valueS]];
                if (charValue == -1) {
                    // Invalid character
                     = true;
                    // 400 - Bad request
                    .setStatus(400);
                    break;
                }
                port = port + (charValue * mult);
                mult = 10 * mult;
            }
            .setServerPort(port);
        }
    }
    /*
     * Check for compression
     *
     */
	private boolean isCompressable()
        // Compression only since HTTP 1.1
        if (! )
            return false;
        // Check if browser support gzip encoding
        MessageBytes acceptEncodingMB = 
            .getMimeHeaders().getValue("accept-encoding");
            
        if ((acceptEncodingMB == null
            || (acceptEncodingMB.indexOf("gzip") == -1))
            return false;
        // Check if content is not allready gzipped
        MessageBytes contentEncodingMB =
            .getMimeHeaders().getValue("Content-Encoding");
        if ((contentEncodingMB != null
            && (contentEncodingMB.indexOf("gzip") != -1))
            return false;
        // If force mode, allways compress (test purposes only)
        if ( == 2)
           return true;
        // Check for incompatible Browser
        if ( != null) {
            MessageBytes userAgentValueMB =  
                .getMimeHeaders().getValue("user-agent");
            String userAgentValue = userAgentValueMB.toString();
        	if (inStringArray(userAgentValue))
        		return false;
        }
        // Check if suffisant len to trig the compression        
        int contentLength = .getContentLength();
        if ((contentLength == -1) 
            || (contentLength > )) {
            // Check for compatible MIME-TYPE
            if ( != null)
                return (inStringArray(.getContentType()));
        }
		return false;
	}

    
When committing the response, we have to validate the set of headers, as well as setup the response filters.
    protected void prepareResponse() {
        boolean entityBody = true;
         = false;
        OutputFilter[] outputFilters = .getFilters();
        if ( == true) {
            // HTTP/0.9
            .addActiveFilter
                (outputFilters[.]);
            return;
        }
        int statusCode = .getStatus();
        if ((statusCode == 204) || (statusCode == 205) 
            || (statusCode == 304)) {
            // No entity body
            .addActiveFilter
                (outputFilters[.]);
            entityBody = false;
             = true;
        }
        MessageBytes methodMB = .method();
        if (methodMB.equals("HEAD")) {
            // No entity body
            .addActiveFilter
    &nb