Package org.apache.tomcat.modules.server

Source Code of org.apache.tomcat.modules.server.Ajp12

/*
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation.  All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in
*    the documentation and/or other materials provided with the
*    distribution.
*
* 3. The end-user documentation included with the redistribution, if
*    any, must include the following acknowlegement:
*       "This product includes software developed by the
*        Apache Software Foundation (http://www.apache.org/)."
*    Alternately, this acknowlegement may appear in the software itself,
*    if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
*    Foundation" must not be used to endorse or promote products derived
*    from this software without prior written permission. For written
*    permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
*    nor may "Apache" appear in their names without prior written
*    permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation.  For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/


/*
  Based on Ajp11ConnectionHandler and Ajp12 implementation of JServ
*/
package org.apache.tomcat.modules.server;

import java.io.*;
import java.net.*;
import java.util.*;
import org.apache.tomcat.core.*;
import org.apache.tomcat.util.net.*;
import org.apache.tomcat.util.*;
import org.apache.tomcat.util.aaa.SimplePrincipal;

class Ajp12 {
    Socket socket;
    InputStream sin;
    BufferedInputStream ajpin;
    private boolean tomcatAuthentication=true;
    boolean shutdown=false;
    boolean isPing=false;
    boolean doLog;
    String secret=null;

    public Ajp12() {
    }

    // Debug only - use only to debug this component
    void d( String s ) {
  System.out.print("Ajp12: ");
  System.out.println( s );
    }
   
    public int doRead() throws IOException {
  return ajpin.read();
    }

    public  int doRead( byte b[], int off, int len ) throws IOException {
  return ajpin.read( b,off,len);
    }

    public void setSocket( Socket s ) throws IOException {
  this.socket = s;
  sin = s.getInputStream();
  ajpin = new BufferedInputStream(sin);
    }

    public void setSecret( String s ) {
  secret=s;
    }
   
    public void readNextRequest(Request req) throws IOException {
  String dummy,token1,token2;
  int marker;
  int signal;

  try {
      boolean more=true;
            while (more) {
    marker = ajpin.read();
    switch (marker) {
    case 0:       //NOP marker useful for testing if stream is OK
        break;
       
    case 1: //beginning of request
        req.method().setStringreadString(ajpin, null));
        
        //Zone
        String contextPath = readString(ajpin, null);

        // GS, the following commented line causes the Apache +
        // Jserv + Tomcat combination to hang with a 404!!!
        // if("ROOT".equals( contextPath ) ) contextPath="";
        if("ROOT".equalsIgnoreCase( contextPath ) ) contextPath=null;

        // XXX Do not set the context - we need extra info.
        // this have to be rewritten !!!
        //        if( contextPath!= null )
        //  req.setContext( contextM.getContext( contextPath ));
       
        //Servlet - not used
        dummy=readString(ajpin, null);
       
        //Server hostname
        req.serverName().setString(readString(ajpin, null) );
        //System.out.println("XXX hostname: " + req.serverName());
       
        //Apache document root
        dummy = readString(ajpin, null);              
        req.pathInfo().setString( readString(ajpin, null));                       //Apache parsed path-translated XXX Bug in mod_jserv !!!!!
        dummy = readString(ajpin, null);
        req.queryString().setString( readString(ajpin, null))
        req.remoteAddr().setString(readString(ajpin, ""));
        req.remoteHost().setString( readString(ajpin, ""));
                    if (isTomcatAuthentication())
                        dummy=readString(ajpin, null);
                    else {
                        req.setRemoteUser( readString(ajpin, null));
                        // Note that roles are not integrated with apache
                        req.setUserPrincipal( new SimplePrincipal( req.getRemoteUser() ));
                    }
        req.setAuthType(readString(ajpin, null));
        //remote port
        dummy = readString(ajpin, null);
        //        System.out.println("XXX rport " + dummy );

        req.method().setString( readString(ajpin, null));
        req.requestURI().setString( readString(ajpin, ""));

        // XXX don't set lookup path - problems with URL rewriting.
        // need to be fixed.
        //if(contextPath!=null && contextPath.length() >0 )
        //lookupPath=requestURI.substring( contextPath.length()+1 );

        //script filename
        dummy = readString(ajpin, null);
        //script name
        dummy = readString(ajpin, null);                  
        req.serverName().setString( readString(ajpin, ""));      

        int serverPort=80;
        try {
      String p=readString(ajpin, null);
      //System.out.println("XXX p " + p);
      if(p==null ) p="80";
      serverPort= Integer.parseInt(p);
        } catch (Exception any) {
      any.printStackTrace();
        }
        req.setServerPort( serverPort );

                    /* Quick and dirty patch to set https scheme in ajp12
                     * but I recommand using ajp13 instead
                     */
                    if (serverPort == 443)
                       req.scheme().setString("https");

        // System.out.println("XXX port: " + req.getServerPort());

        //server protocol
        String proto=readString(ajpin,null);
        if( proto==null ) proto="HTTP/1.0";
        req.protocol().setString (proto)
        //server signature
        dummy = readString(ajpin, "");
        //server software
        dummy = readString(ajpin, "");
        req.setJvmRoute( readString(ajpin, null));                  

        dummy = readString(ajpin, "");
        dummy = readString(ajpin, "");
        break;


                    /**
                     * Marker = 5 will be used by mod_jserv to send environment
         * vars as key+value (dynamically configurable).
                     * can be considered as "reserved", and safely ignored by
         * other connectors.
         * env_vars is (above in this  code) commented out for
         * performance issues. so theses env vars are simply
         * ignored. (just here for compatibility)
                     * but it is where mod_jserv would place SSL_* env vars
         * (by exemple)
                     * See the new parameter for mod_jserv (version > 1.1):
                     * ApJServEnvVar localname remotename
                     *                                            - jluc
                     */
                case 5: // Environment vars
                    token1 = readString(ajpin, null);
                    token2 = readString(ajpin, "");
                    /*
                     * Env variables should go into the request attributes
                     * table.
         *
         * Also, if one of the request attributes is HTTPS=on
                     * assume that there is an SSL connection.
         */
                    req.setAttribute(token1, token2);
                    if(token1.equals("HTTPS") && token2.equals("on")) {
                        req.scheme().setString("https");
                    }
                    break;

    case 3: // Header
        token1 = readString(ajpin, null);
        token2 = readString(ajpin, "");
//         if( "Host".equalsIgnoreCase( token1 )) {
//       System.out.println("XXX Host: " + token2);
//         }
        req.getMimeHeaders().addValue(token1).setString(token2);
        break;

    case 254: // Signal
        signal = ajpin.read();

        if (signal == 0) { // PING implemented as signal
      try {
          // close the socket connection after we send reply
          socket.getOutputStream().write(0); // PING reply
          sin.close();
      } catch (IOException ignored) {
          req.getContextManager().log("Exception closing, ignored",  ignored);
      }
                        isPing = true;
                        return;
        } else {
      try {
          // close the socket connection before handling any
          // signal but get the addresses first so they are
          // not corrupted
          InetAddress serverAddr = socket.getLocalAddress();
          InetAddress clientAddr = socket.getInetAddress();
          if ( (signal== 15) &&
         isSameAddress(serverAddr, clientAddr) ) {
        if( secret!=null ) {
            String stopMsg=readString(ajpin, "");
            if( ! secret.equals( stopMsg ) ) {
          req.getContextManager().log("Attempt to stop with the wrong secret");
          return;
            }
        }
                                ContextManager cm=req.getContextManager();
        cm.shutdown();
        cm.log("Exiting" );
        // same behavior as in past, because it seems
        // that stopping everything doesn't work -
        // need to figure
        // out what happens with the threads ( XXX )
                                // until we remove the System.exit() call we
                                // also need to close the socket to allow the
                                // underlying layer to shutdown the connection
                                // properly.  Setting soLinger small will
                                // speed this up.
                                socket.setSoLinger(true, 0);
                                sin.close();
        System.exit(0);
        shutdown=true;
        return;
          }
          sin.close();
      } catch (Exception ignored) {
          req.getContextManager().log("Ignored exception " +
                  "processing signal " +
                  signal, ignored);
      }
        }
        return;
       
    case 4:
    case 255:
        more=false;
        break;
       
    case -1:
        throw new java.io.IOException("Stream closed prematurely");
       
       
    default:
        throw new java.io.IOException("Stream broken");
    } // switch
            } // while
  } catch (IOException ioe) {
      throw ioe;
        } catch (Exception e) {
      req.getContextManager().log("Uncaught exception handling request", e);
        }
 
  // REQUEST_URI may includes query string
  String requestURI=req.requestURI().toString();
  int indexQ=requestURI.indexOf("?");
  int rLen=requestURI.length();
  if ( (indexQ >-1) && ( indexQ  < rLen) ) {
      req.queryString().
    setString( requestURI.substring(indexQ + 1,
            requestURI.length()));
      req.requestURI().setString( requestURI.substring(0, indexQ));
  }
    }

    /**
     * Return <code>true</code> if the specified client and server addresses
     * are the same.  This method works around a bug in the IBM 1.1.8 JVM on
     * Linux, where the address bytes are returned reversed in some
     * circumstances.
     *
     * @param server The server's InetAddress
     * @param client The client's InetAddress
     */
    public static boolean isSameAddress(InetAddress server, InetAddress client) {
  // Compare the byte array versions of the two addresses
  byte serverAddr[] = server.getAddress();
  byte clientAddr[] = client.getAddress();
  if (serverAddr.length != clientAddr.length)
      return (false);
  boolean match = true;
  for (int i = 0; i < serverAddr.length; i++) {
      if (serverAddr[i] != clientAddr[i]) {
    match = false;
    break;
      }
  }
  if (match)
      return (true);

  // Compare the reversed form of the two addresses
  for (int i = 0; i < serverAddr.length; i++) {
      if (serverAddr[i] != clientAddr[(serverAddr.length-1)-i])
    return (false);
  }
  return (true);
    }

   
    public static int readWord(InputStream in ) throws java.io.IOException {
        int b1 = in.read();
        if( b1 == -1)
            return -1;

        int b2 = in.read();
        if ( b2==-1)
            return -1;

        return ((int)((b1 << 8) | b2)) & 0xffff;
    }

    // UTF8 is a strict superset of ASCII.
    final static String CHARSET = "UTF8";

    public static String readString(InputStream in, String def)
  throws java.io.IOException {
        int len = readWord(in);

        if( len == 0xffff)
            return def;

        if( len == -1)
            throw new java.io.IOException("Stream broken");

        byte[] b = new byte[len];
        int p = 0;
        int r;
        while(p<len) {
            r = in.read(b,p, len - p);
            if( r< 0) {
                throw new IOException("Stream broken, couldn't " +
              "demarshal string :"+len+":"+p);
            }
            p = p+r;
        }
        return new String(b, CHARSET);
    }

    public boolean isTomcatAuthentication() {
        return tomcatAuthentication;
    }

    public void setTomcatAuthentication(boolean newTomcatAuthentication) {
        tomcatAuthentication = newTomcatAuthentication;
    }

   
}

TOP

Related Classes of org.apache.tomcat.modules.server.Ajp12

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.