Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * JBoss, Home of Professional Open Source.
   * Copyright 2012 Red Hat, Inc., and individual contributors
   * as indicated by the @author tags.
   *
   * 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.jboss.web.php;
 
 import java.io.File;
 
 
Encapsulates the Script Environment and rules to derive that environment from the servlet container and request information.

Author(s):
Mladen Turk
Version:
$Revision: 1473 $, $Date: 2010-05-17 19:46:58 +0200 (Mon, 17 May 2010) $
Since:
1.0
 
 public class ScriptEnvironment {

    
The Request attribute key for the client certificate chain.
 
     private static final String CERTIFICATE_KEY = "javax.servlet.request.X509Certificate";
     private static final String CIPHER_SUITE    = "javax.servlet.request.cipher_suite";
     private static final String SSL_SESSION     = "javax.servlet.request.ssl_session";
     private static final String KEY_SIZE        = "javax.servlet.request.key_size";

    
context of the enclosing servlet
 
     private ServletContext context = null;

    
full path to the script file
 
     private String scriptFullPath = null;

    
context path of enclosing servlet
 
     private String contextPath = null;

    
servlet URI of the enclosing servlet
 
     private String servletPath = null;

    
pathInfo for the current request
 
     private String pathInfo = null;

    
real file system directory of the enclosing servlet's web app
 
     private String webAppRootDir = null;

    
tempdir for context - used to expand scripts in unexpanded wars
 
     private File tempDir = null;

    
derived script environment
 
     private Hashtable env = null;

    
script's desired working directory
 
     private File workingDirectory = null;

    
script's desired working directory
 
     private File scriptFile = null;

    
query parameters
 
     private ArrayList queryParameters = new ArrayList();

    
whether or not this object is valid or not
 
     private boolean valid = false;

    
object used to ensure multiple threads don't try to expand same file
 
     private static Object expandFileLock = new Object();

    
The Script search path will start at webAppRootDir + File.separator + scriptPathPrefix (or webAppRootDir alone if scriptPathPrefix is null)
    private String scriptPathPrefix = null;

    
Resolves core information about the php script.

Example URI:

 /servlet/scriptGateway/dir1/realScript/pathinfo1 
  • path = $CATALINA_HOME/mywebapp/dir1/realScript
  • scriptName = /servlet/scriptGateway/dir1/realScript
  • fullName = /dir1/realScript
  • name = realScript

Script search algorithm: search the real path below <my-webapp-root> and find the first non-directory in the getPathTranslated("/"), reading/searching from left-to-right.

The Script search path will start at webAppRootDir + File.separator + scriptPathPrefix (or webAppRootDir alone if scriptPathPrefix is null).

scriptPathPrefix is defined by setting this servlet's scriptPathPrefix init parameter

Parameters:
pathInfo String from HttpServletRequest.getPathInfo()
webAppRootDir String from context.getRealPath("/")
contextPath String as from HttpServletRequest.getContextPath()
servletPath String as from HttpServletRequest.getServletPath()
scriptPathPrefix Subdirectory of webAppRootDir below which the web app's Scripts may be stored; can be null. The Script search path will start at webAppRootDir + File.separator + scriptPathPrefix (or webAppRootDir alone if scriptPathPrefix is null). scriptPathPrefix is defined by setting the servlet's scriptPathPrefix init parameter.
Returns:
  • path - full file-system path to valid script file, or null if no script file was found
  • scriptName - Script variable SCRIPT_NAME; the full URL path to valid script file or null if no script was found
  • fullName - servlet pathInfo fragment corresponding to the script itself, or null if not found
  • name - simple name (no directories) of the script, or null if no script was found
    protected String[] findScript(String pathInfoString webAppRootDir,
                                  String contextPathString servletPath,
                                  String scriptPathPrefix)
    {
        String path = null;
        String name = null;
        String scriptName = null;
        String fullName = null;
        if ((webAppRootDir != null)
            && (webAppRootDir.lastIndexOf(.) ==
                (webAppRootDir.length() - 1))) {
                //strip the trailing "/" from the webAppRootDir
                webAppRootDir =
                webAppRootDir.substring(0, (webAppRootDir.length() - 1));
        }
        if (scriptPathPrefix != null) {
            webAppRootDir = webAppRootDir + .
                + scriptPathPrefix;
        }
        File currentLocation = new File(webAppRootDir);
        StringTokenizer dirWalker = new StringTokenizer(pathInfo"/");
        while (!currentLocation.isFile() && dirWalker.hasMoreElements()) {
            currentLocation = new File(currentLocation,
                                       (String)dirWalker.nextElement());
        }
        if (!currentLocation.isFile()) {
            return new String[] { nullnullnullnull };
        }
        else {
            path = currentLocation.getAbsolutePath();
            name = currentLocation.getName();
            fullName =
            currentLocation.getParent().substring(webAppRootDir.length())
                + . + name;
            // NOTE: Original CGI messes the Win path.
            fullName = fullName.replace(.'/');
            if (contextPath != null && ! "".equals(contextPath) && ! "/".equals(contextPath)) {
                scriptName = contextPath + fullName;
            }
            else {
                // NOTE: set scriptName to fullName
                scriptName = fullName;
            }
        }
        return new String[] { pathscriptNamefullNamename };
    }

    
Extracts requested resource from web app archive to context work directory to enable script to be executed.
    protected void expandScript()
    {
        StringBuffer srcPath = new StringBuffer();
        StringBuffer dstPath = new StringBuffer();
        InputStream is = null;
        // paths depend on mapping
        if ( == null) {
            srcPath.append();
            is = .getResourceAsStream(srcPath.toString());
            dstPath.append();
            dstPath.append();
        }
        else {
            // essentially same search algorithm as findScript()
            srcPath.append();
            StringTokenizer dirWalker = new StringTokenizer("/");
            // start with first element
            while (dirWalker.hasMoreElements() && (is == null)) {
                srcPath.append("/");
                srcPath.append(dirWalker.nextElement());
                is = .getResourceAsStream(srcPath.toString());
            }
            dstPath.append();
            dstPath.append("/");
            dstPath.append(srcPath);
        }
        if (is == null) {
            // didn't find anything, give up now
            return;
        }
        File f = new File(dstPath.toString());
        if (f.exists()) {
            // Don't need to expand if it already exists
            return;
        }
        // create directories
        String dirPath = new String(dstPath.toString().substring( 0,
                                    dstPath.toString().lastIndexOf("/")));
        File dir = new File(dirPath);
        dir.mkdirs();
        try {
            synchronized () {
                // make sure file doesn't exist
                if (f.exists()) {
                    return;
                }
                // create file
                if (!f.createNewFile()) {
                    return;
                }
                FileOutputStream fos = new FileOutputStream(f);
                // copy data
                IOTools.flow(isfos);
                is.close();
                fos.close();
            }
        } catch (IOException ioe) {
            // delete in case file is corrupted
            if (f.exists()) {
                f.delete();
            }
        }
    }

    
Constructs the CGI environment to be supplied to the invoked CGI script; relies heavliy on Servlet API methods and findCGI

Parameters:
req request associated with the CGI invokation
Returns:
true if environment was set OK, false if there was a problem and no environment was set
    protected boolean setEnvironment(HttpServletRequest req)
        throws IOException
    {
        /*
         * This method is slightly ugly; c'est la vie.
         * "You cannot stop [ugliness], you can only hope to contain [it]"
         * (apologies to Marv Albert regarding MJ)
         */
        Hashtable envp = new Hashtable();
        // Add the shell environment variables (if any)
        // envp.putAll(shellEnv);
        // Add the Script environment variables
        String sPathInfoOrig = null;
        String sPathTranslatedOrig = null;
        String sPathInfo = null;
        String sPathTranslated = null;
        String sFullPath = null;
        String sScriptName = null;
        String sFullName = null;
        String sName = null;
        String[] sScriptNames;
        sPathInfoOrig = this.;
        sPathInfoOrig = sPathInfoOrig == null ? "" : sPathInfoOrig;
        sPathTranslatedOrig = req.getPathTranslated();
        sPathTranslatedOrig =
            sPathTranslatedOrig == null ? "" : sPathTranslatedOrig;
        if ( == null ) {
            // The app has not been deployed in exploded form
             = .toString();
            expandScript();
        }
        sScriptNames = findScript(sPathInfoOrig,
                                  ,
                                  ,
                                  ,
                                  );
        sFullPath = sScriptNames[0];
        sScriptName = sScriptNames[1];
        sFullName = sScriptNames[2];
        sName = sScriptNames[3];
        if (sFullPath == null
            || sScriptName == null
            || sFullName == null
            || sName == null) {
            ..invalidScriptNames();
            return false;
        }
        envp.put("SERVER_SOFTWARE""JBossWebServer");
        envp.put("SERVER_NAME"nullsToBlanks(req.getServerName()));
        envp.put("GATEWAY_INTERFACE""CGI/1.1");
        envp.put("SERVER_PROTOCOL"nullsToBlanks(req.getProtocol()));
        int port = req.getServerPort();
        Integer sPort = (port == 0 ? new Integer(-1) : new Integer(port));
        envp.put("SERVER_PORT"sPort.toString());
        /*
         * Local addres and port
         */
        envp.put("LOCAL_NAME"nullsToBlanks(req.getLocalName()));
        port = req.getLocalPort();
        Integer iPort = (port == 0 ? new Integer(-1) : new Integer(port));
        envp.put("LOCAL_PORT"iPort.toString());
        envp.put("LOCAL_ADDR"nullsToBlanks(req.getLocalAddr()));
        envp.put("REQUEST_METHOD"nullsToBlanks(req.getMethod()));
        /*-
         * PATH_INFO should be determined by using sFullName:
         * 1) Let sFullName not end in a "/" (see method findScript)
         * 2) Let sFullName equal the pathInfo fragment which
         *    corresponds to the actual script.
         * 3) Thus, PATH_INFO = request.getPathInfo().substring(
         *                      sFullName.length())
         *
         * (see method findScript, where the real work is done)
         *
         */
        if ( == null
            || (.substring(sFullName.length()).length() <= 0)) {
            sPathInfo = "";
        }
        else {
            sPathInfo = .substring(sFullName.length());
        }
        envp.put("PATH_INFO"sPathInfo);
        /*-
         * PATH_TRANSLATED must be determined after PATH_INFO (and the
         * implied real cgi-script) has been taken into account.
         *
         * The following example demonstrates:
         *
         * servlet info   = /servlet/cgigw/dir1/dir2/cgi1/trans1/trans2
         * cgifullpath    = /servlet/cgigw/dir1/dir2/cgi1
         * path_info      = /trans1/trans2
         * webAppRootDir  = servletContext.getRealPath("/")
         *
         * path_translated = servletContext.getRealPath("/trans1/trans2")
         *
         * That is, PATH_TRANSLATED = webAppRootDir + sPathInfo
         * (unless sPathInfo is null or blank, then the CGI
         * specification dictates that the PATH_TRANSLATED metavariable
         * SHOULD NOT be defined.
         *
         */
        if (sPathInfo != null && !("".equals(sPathInfo))) {
            sPathTranslated = .getRealPath(sPathInfo);
        }
        else {
            sPathTranslated = null;
        }
        if (sPathTranslated == null || "".equals(sPathTranslated)) {
            // Nothing.
        }
        else {
            envp.put("PATH_TRANSLATED"nullsToBlanks(sPathTranslated));
        }
        envp.put("SCRIPT_NAME"nullsToBlanks(sScriptName));
        envp.put("QUERY_STRING"nullsToBlanks(req.getQueryString()));
        envp.put("REMOTE_HOST"nullsToBlanks(req.getRemoteHost()));
        envp.put("REMOTE_ADDR"nullsToBlanks(req.getRemoteAddr()));
        envp.put("AUTH_TYPE"nullsToBlanks(req.getAuthType()));
        envp.put("REMOTE_USER"nullsToBlanks(req.getRemoteUser()));
        envp.put("REMOTE_IDENT"""); //not necessary for full compliance
        envp.put("CONTENT_TYPE"nullsToBlanks(req.getContentType()));
        /* Note CGI spec says CONTENT_LENGTH must be NULL ("") or undefined
         * if there is no content, so we cannot put 0 or -1 in as per the
         * Servlet API spec.
         */
        int contentLength = req.getContentLength();
        String sContentLength = (contentLength <= 0 ? "" :
                                 (new Integer(contentLength)).toString());
        envp.put("CONTENT_LENGTH"sContentLength);
        Enumeration headers = req.getHeaderNames();
        String header = null;
        while (headers.hasMoreElements()) {
            header = null;
            header = ((String)headers.nextElement()).toUpperCase(.);
            //REMIND: rewrite multiple headers as if received as single
            //REMIND: change character set
            //REMIND: I forgot what the previous REMIND means
            if ("AUTHORIZATION".equalsIgnoreCase(header) ||
                "PROXY_AUTHORIZATION".equalsIgnoreCase(header)) {
                //NOOP per CGI specification section 11.2
            }
            else {
                envp.put("HTTP_" + header.replace('-''_'),
                         req.getHeader(header));
            }
        }
         = new File(sFullPath);
         = new File(.substring(0,
                                .lastIndexOf(.)));
        envp.put("SCRIPT_FILENAME");
        envp.put("CONTEXT_PATH"nullsToBlanks());
        String self = "";
        if ( != null && ! "".equals() && ! "/".equals()) {
            self = ;
        }
        if ( != null && ! "".equals() && ! "/".equals()) {
            self = self.concat();
        }
        
        envp.put("PHP_SELF"nullsToBlanks(self));
        if (req.isSecure()) {
            envp.put("HTTPS""ON");
            envp.put("SSL_CIPHER"req.getAttribute());
            envp.put("SSL_SESSION_ID"req.getAttribute());
            envp.put("SSL_CIPHER_USEKEYSIZE", String.valueOf(req.getAttribute()));
            X509Certificate[] certs =
                (X509Certificate[])req.getAttribute();
            if (certs != null) {
                // Well use the first, normaly the client certificate.
                envp.put("SSL_SERVER_V_START"certs[0].getNotAfter().toString());
                envp.put("SSL_SERVER_V_END",  certs[0].getNotBefore().toString());
                
                envp.put("SSL_CLIENT_A_KEY",  certs[0].getSigAlgName());
                
                // Oops getEncoded gives a DER not PEM encoded ... envp.put("SSL_CLIENT_CERT",  certs[0].getEncoded());
                envp.put("SSL_SERVER_M_SERIAL"certs[0].getSerialNumber().toString());
                envp.put("SSL_SERVER_M_VERSION", String.valueOf(certs[0].getVersion()));
                // Subject
                envp.put("SSL_CLIENT_S_DN"certs[0].getSubjectX500Principal().getName());
                // To fill the elements C,ST... Email
                String pr = certs[0].getSubjectX500Principal().getName();
                String prs[] = pr.split(", ");
                for (int c = 0; c < prs.lengthc++) {
                    String pprs[] = prs[c].split("=");
                    envp.put("SSL_CLIENT_S_DN_" + pprs[0], pprs[1]);
                }
                // Issuer
                envp.put("SSL_CLIENT_I_DN"certs[0].getIssuerX500Principal().getName());
                // To fill the elements C,ST... Email Still to TODO.
                pr = certs[0].getSubjectX500Principal().getName();
                prs = pr.split(", ");
                for (int c = 0; c < prs.lengthc++) {
                    String pprs[] = prs[c].split("=");
                    envp.put("SSL_CLIENT_I_DN_" + pprs[0], pprs[1]);
                }
                // envp.put("CERT_ISSUER",
                //         nullsToBlanks(certs[c].getIssuerX500Principal().getName()));
            }
        }
        this. = envp;
        return true;
    }


    
Creates a CGIEnvironment and derives the necessary environment, query parameters, working directory, cgi command, etc.

Parameters:
req HttpServletRequest for information provided by the Servlet API
context ServletContext for information provided by the Servlet API
                             ServletContext context,
                             String scriptPathPrefix)
        throws IOException
    {
        this. = scriptPathPrefix;
        this. = context;
        this. = context.getRealPath("/");
        this. = (File)context.getAttribute(.);
        if (req.getAttribute(.) != null) {
           // Include
           this. = (Stringreq.getAttribute(.);
        }
        else {
           // Direct call
           this. = req.getContextPath();
           this. = req.getServletPath();
           this. = req.getPathInfo();
        }
        // If getPathInfo() returns null, must be using extension mapping
        // In this case, pathInfo should be same as servletPath
        if (this. == null) {
            this. = this.;
        }
        this. = setEnvironment(req);
    }


    
Gets derived script full path

Returns:
full script path
    public String getFullPath()
    {
        return ;
    }

    
Gets derived Script file

Returns:
Script file
    public File getScriptFile()
    {
        return ;
    }

    
Gets derived Script working directory

Returns:
working directory
    public File getWorkingDirectory()
    {
        return ;
    }

    
Gets derived Script environment

Returns:
Script environment
    public Hashtable getEnvironment()
    {
        return ;
    }

    
Gets derived Script query parameters

Returns:
Script query parameters
    public ArrayList getParameters()
    {
        return ;
    }

    
Gets validity status

Returns:
true if this environment is valid, false otherwise
    public boolean isValid()
    {
        return ;
    }

    
Converts null strings to blank strings ("")

Parameters:
s string to be converted if necessary
Returns:
a non-null string, either the original or the empty string ("") if the original was null
    protected String nullsToBlanks(String s)
    {
        return nullsToString(s"");
    }

    
Converts null strings to another string

Parameters:
couldBeNull string to be converted if necessary
subForNulls string to return instead of a null string
Returns:
a non-null string, either the original or the substitute string if the original was null
    protected String nullsToString(String couldBeNull,
                                   String subForNulls)
    {
        return (couldBeNull == null ? subForNulls : couldBeNull);
    }

    
Converts blank strings to another string

Parameters:
couldBeBlank string to be converted if necessary
subForBlanks string to return instead of a blank string
Returns:
a non-null string, either the original or the substitute string if the original was null or empty ("")
    protected String blanksToString(String couldBeBlank,
                                    String subForBlanks)
    {
        return (("".equals(couldBeBlank) || couldBeBlank == null)
                ? subForBlanks
                : couldBeBlank);
    }

    
Converts Environment Hastable to String array

Returns:
Srring array containing name value pairs.
Throws:
java.lang.NullPointerException if a hash key has a null value
    public String[] getEnvironmentArray()
        throws NullPointerException
    {
        return hashToStringArray();
    }

    
Converts a Hashtable to a String array by converting each key/value pair in the Hashtable to two consecutive Strings

Parameters:
h Hashtable to convert
Returns:
converted string array
Throws:
java.lang.NullPointerException if a hash key has a null value
    public static String[] hashToStringArray(Hashtable h)
        throws NullPointerException
    {
        Vector v = new Vector();
        Enumeration e = h.keys();
        while (e.hasMoreElements()) {
            String k = e.nextElement().toString();
            v.add(k);
            v.add(h.get(k));
        }
        String[] strArr = new String[v.size()];
        v.copyInto(strArr);
        return strArr;
    }
New to GrepCode? Check out our FAQ X