markt 2005/04/30 10:20:51 Modified: catalina/src/share/org/apache/catalina/ssi SSIServletExternalResolver.java webapps/docs changelog.xml ssi-howto.xml Log: Add missing CGI variables to SSi servlet. - Patch submitted by Fritz Schneider. Revision Changes Path 1.7 +182 -75 jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/ssi/SSIServletExternalResolver.java Index: SSIServletExternalResolver.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/ssi/SSIServletExternalResolver.java,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- SSIServletExternalResolver.java 23 Apr 2005 10:22:37 -0000 1.6 +++ SSIServletExternalResolver.java 30 Apr 2005 17:20:50 -0000 1.7 @@ -25,6 +25,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.catalina.connector.Request; +import org.apache.coyote.Constants; /** * An implementation of SSIExternalResolver that is used with servlets. @@ -36,10 +37,14 @@ public class SSIServletExternalResolver implements SSIExternalResolver { protected final String VARIABLE_NAMES[] = {"AUTH_TYPE", "CONTENT_LENGTH", "CONTENT_TYPE", "DOCUMENT_NAME", "DOCUMENT_URI", - "GATEWAY_INTERFACE", "PATH_INFO", "PATH_TRANSLATED", + "GATEWAY_INTERFACE", "HTTP_ACCEPT", "HTTP_ACCEPT_ENCODING", + "HTTP_ACCEPT_LANGUAGE", "HTTP_CONNECTION", "HTTP_HOST", + "HTTP_REFERER", "HTTP_USER_AGENT", "PATH_INFO", "PATH_TRANSLATED", "QUERY_STRING", "QUERY_STRING_UNESCAPED", "REMOTE_ADDR", - "REMOTE_HOST", "REMOTE_USER", "REQUEST_METHOD", "SCRIPT_NAME", - "SERVER_NAME", "SERVER_PORT", "SERVER_PROTOCOL", "SERVER_SOFTWARE"}; + "REMOTE_HOST", "REMOTE_PORT", "REMOTE_USER", "REQUEST_METHOD", + "REQUEST_URI", "SCRIPT_FILENAME", "SCRIPT_NAME", "SERVER_ADDR", + "SERVER_NAME", "SERVER_PORT", "SERVER_PROTOCOL", "SERVER_SOFTWARE", + "UNIQUE_ID"}; protected ServletContext context; protected HttpServletRequest req; protected HttpServletResponse res; @@ -138,85 +143,185 @@ protected String getCGIVariable(String name) { String retVal = null; - if (name.equalsIgnoreCase("AUTH_TYPE")) { - retVal = req.getAuthType(); - } else if (name.equalsIgnoreCase("CONTENT_LENGTH")) { - int contentLength = req.getContentLength(); - if (contentLength >= 0) { - retVal = Integer.toString(contentLength); - } - } else if (name.equalsIgnoreCase("CONTENT_TYPE")) { - retVal = req.getContentType(); - } else if (name.equalsIgnoreCase("DOCUMENT_NAME")) { - String requestURI = req.getRequestURI(); - retVal = requestURI.substring(requestURI.lastIndexOf('/') + 1); - } else if (name.equalsIgnoreCase("DOCUMENT_URI")) { - retVal = req.getRequestURI(); + String[] nameParts = name.toUpperCase().split("_"); + int requiredParts = 2; + if (nameParts.length == 1) { + if (nameParts[0].equals("PATH")) { + requiredParts = 1; + retVal = null; // Not implemented + } + } + else if (nameParts[0].equals("AUTH")) { + if (nameParts[1].equals("TYPE")) { + retVal = req.getAuthType(); + } + } else if(nameParts[0].equals("CONTENT")) { + if (nameParts[1].equals("LENGTH")) { + int contentLength = req.getContentLength(); + if (contentLength >= 0) { + retVal = Integer.toString(contentLength); + } + } else if (nameParts[1].equals("TYPE")) { + retVal = req.getContentType(); + } + } else if (nameParts[0].equals("DOCUMENT")) { + if (nameParts[1].equals("NAME")) { + String requestURI = req.getRequestURI(); + retVal = requestURI.substring(requestURI.lastIndexOf('/') + 1); + } else if (nameParts[1].equals("URI")) { + retVal = req.getRequestURI(); + } } else if (name.equalsIgnoreCase("GATEWAY_INTERFACE")) { retVal = "CGI/1.1"; - } else if (name.equalsIgnoreCase("PATH_INFO")) { - retVal = req.getPathInfo(); - } else if (name.equalsIgnoreCase("PATH_TRANSLATED")) { - retVal = req.getPathTranslated(); - } else if (name.equalsIgnoreCase("QUERY_STRING")) { - //apache displays this as an empty string rather than (none) - retVal = nullToEmptyString(req.getQueryString()); - } else if (name.equalsIgnoreCase("QUERY_STRING_UNESCAPED")) { - String queryString = req.getQueryString(); - if (queryString != null) { - // Use default as a last resort - String queryStringEncoding = - org.apache.coyote.Constants.DEFAULT_CHARACTER_ENCODING; + } else if (nameParts[0].equals("HTTP")) { + if (nameParts[1].equals("ACCEPT")) { + String accept = null; + if (nameParts.length == 2) { + accept = "Accept"; + } else if (nameParts[2].equals("ENCODING")) { + requiredParts = 3; + accept = "Accept-Encoding"; + } else if (nameParts[2].equals("LANGUAGE")) { + requiredParts = 3; + accept = "Accept-Language"; + } + if (accept != null) { + Enumeration acceptHeaders = req.getHeaders(accept); + if (acceptHeaders != null) + if (acceptHeaders.hasMoreElements()) { + StringBuffer rv = new StringBuffer( + (String) acceptHeaders.nextElement()); + while (acceptHeaders.hasMoreElements()) { + rv.append(", "); + rv.append((String) acceptHeaders.nextElement()); + } + retVal = rv.toString(); + } + } + } + else if (nameParts[1].equals("CONNECTION")) { + retVal = req.getHeader("Connection"); + } + else if (nameParts[1].equals("HOST")) { + retVal = req.getHeader("Host"); + } + else if (nameParts[1].equals("REFERER")) { + retVal = req.getHeader("Referer"); + } + else if (nameParts[1].equals("USER")) + if (nameParts.length == 3) + if (nameParts[2].equals("AGENT")) { + requiredParts = 3; + retVal = req.getHeader("User-Agent"); + } + + } else if (nameParts[0].equals("PATH")) { + if (nameParts[1].equals("INFO")) { + retVal = req.getPathInfo(); + } else if (nameParts[1].equals("TRANSLATED")) { + retVal = req.getPathTranslated(); + } + } else if (nameParts[0].equals("QUERY")) { + if (nameParts[1].equals("STRING")) { + String queryString = req.getQueryString(); + if (nameParts.length == 2) { + //apache displays this as an empty string rather than (none) + retVal = nullToEmptyString(queryString); + } else if (nameParts[2].equals("UNESCAPED")) { + requiredParts = 3; + if (queryString != null) { + // Use default as a last resort + String queryStringEncoding = + Constants.DEFAULT_CHARACTER_ENCODING; - String uriEncoding = null; - boolean useBodyEncodingForURI = false; + String uriEncoding = null; + boolean useBodyEncodingForURI = false; - // Get encoding settings from request / connector if possible - String requestEncoding = req.getCharacterEncoding(); - if (req instanceof Request) { - uriEncoding = ((Request)req).getConnector().getURIEncoding(); - useBodyEncodingForURI = - ((Request)req).getConnector().getUseBodyEncodingForURI(); - } + // Get encoding settings from request / connector if + // possible + String requestEncoding = req.getCharacterEncoding(); + if (req instanceof Request) { + uriEncoding = + ((Request)req).getConnector().getURIEncoding(); + useBodyEncodingForURI = ((Request)req) + .getConnector().getUseBodyEncodingForURI(); + } + + // If valid, apply settings from request / connector + if (uriEncoding != null) { + queryStringEncoding = uriEncoding; + } else if(useBodyEncodingForURI) { + if (requestEncoding != null) { + queryStringEncoding = requestEncoding; + } + } - // If valid, apply settings from request / connector - if (uriEncoding != null) { - queryStringEncoding = uriEncoding; - } else if(useBodyEncodingForURI) { - if (requestEncoding != null) { - queryStringEncoding = requestEncoding; + try { + retVal = URLDecoder.decode(queryString, + queryStringEncoding); + } catch (UnsupportedEncodingException e) { + retVal = queryString; + } } } - - try { - retVal = URLDecoder.decode(queryString, queryStringEncoding); - } catch (UnsupportedEncodingException e) { - retVal = queryString; - } - } - } else if (name.equalsIgnoreCase("REMOTE_ADDR")) { - retVal = req.getRemoteAddr(); - } else if (name.equalsIgnoreCase("REMOTE_HOST")) { - retVal = req.getRemoteHost(); - } else if (name.equalsIgnoreCase("REMOTE_USER")) { - retVal = req.getRemoteUser(); - } else if (name.equalsIgnoreCase("REQUEST_METHOD")) { - retVal = req.getMethod(); - } else if (name.equalsIgnoreCase("SCRIPT_NAME")) { - retVal = req.getServletPath(); - } else if (name.equalsIgnoreCase("SERVER_NAME")) { - retVal = req.getServerName(); - } else if (name.equalsIgnoreCase("SERVER_PORT")) { - retVal = Integer.toString(req.getServerPort()); - } else if (name.equalsIgnoreCase("SERVER_PROTOCOL")) { - retVal = req.getProtocol(); - } else if (name.equalsIgnoreCase("SERVER_SOFTWARE")) { - retVal = context.getServerInfo(); + } + } else if(nameParts[0].equals("REMOTE")) { + if (nameParts[1].equals("ADDR")) { + retVal = req.getRemoteAddr(); + } else if (nameParts[1].equals("HOST")) { + retVal = req.getRemoteHost(); + } else if (nameParts[1].equals("IDENT")) { + retVal = null; // Not implemented + } else if (nameParts[1].equals("PORT")) { + retVal = Integer.toString( req.getRemotePort()); + } else if (nameParts[1].equals("USER")) { + retVal = req.getRemoteUser(); + } + } else if(nameParts[0].equals("REQUEST")) { + if (nameParts[1].equals("METHOD")) { + retVal = req.getMethod(); + } + else if (nameParts[1].equals("URI")) { + // If this is an error page, get the original URI + retVal = (String) req.getAttribute( + "javax.servlet.forward.request_uri"); + if (retVal == null) retVal=req.getRequestURI(); + } + } else if (nameParts[0].equals("SCRIPT")) { + String scriptName = req.getServletPath(); + if (nameParts[1].equals("FILENAME")) { + retVal = context.getRealPath(scriptName); + } + else if (nameParts[1].equals("NAME")) { + retVal = scriptName; + } + } else if (nameParts[0].equals("SERVER")) { + if (nameParts[1].equals("ADDR")) { + retVal = req.getLocalAddr(); + } + if (nameParts[1].equals("NAME")) { + retVal = req.getServerName(); + } else if (nameParts[1].equals("PORT")) { + retVal = Integer.toString(req.getServerPort()); + } else if (nameParts[1].equals("PROTOCOL")) { + retVal = req.getProtocol(); + } else if (nameParts[1].equals("SOFTWARE")) { + StringBuffer rv = new StringBuffer(context.getServerInfo()); + rv.append(" "); + rv.append(System.getProperty("java.vm.name")); + rv.append("/"); + rv.append(System.getProperty("java.vm.version")); + rv.append(" "); + rv.append(System.getProperty("os.name")); + retVal = rv.toString(); + } + } else if (name.equalsIgnoreCase("UNIQUE_ID")) { + retVal = req.getRequestedSessionId(); } - return retVal; + if (requiredParts != nameParts.length) return null; + return retVal; } - public Date getCurrentDate() { return new Date(); } @@ -291,7 +396,8 @@ String virtualPath) throws IOException { String path = null; if (!virtualPath.startsWith("/") && !virtualPath.startsWith("\\")) { - return new ServletContextAndPath(context, getAbsolutePath(virtualPath)); + return new ServletContextAndPath(context, + getAbsolutePath(virtualPath)); } else { String normalized = SSIServletRequestUtil.normalize(virtualPath); if (isVirtualWebappRelative) { @@ -434,7 +540,8 @@ protected String path; - public ServletContextAndPath(ServletContext servletContext, String path) { + public ServletContextAndPath(ServletContext servletContext, + String path) { this.servletContext = servletContext; this.path = path; } 1.298 +3 -0 jakarta-tomcat-catalina/webapps/docs/changelog.xml Index: changelog.xml =================================================================== RCS file: /home/cvs/jakarta-tomcat-catalina/webapps/docs/changelog.xml,v retrieving revision 1.297 retrieving revision 1.298 diff -u -r1.297 -r1.298 --- changelog.xml 30 Apr 2005 09:07:12 -0000 1.297 +++ changelog.xml 30 Apr 2005 17:20:50 -0000 1.298 @@ -124,6 +124,9 @@ <fix> Prevent facade objects cloning (remm) </fix> + <update> + Add missing CGI variables to SSI servlet. Patch submitted by Fritz Schneider. (markt) + </update> </changelog> </subsection> 1.5 +261 -5 jakarta-tomcat-catalina/webapps/docs/ssi-howto.xml Index: ssi-howto.xml =================================================================== RCS file: /home/cvs/jakarta-tomcat-catalina/webapps/docs/ssi-howto.xml,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- ssi-howto.xml 23 Apr 2005 10:22:37 -0000 1.4 +++ ssi-howto.xml 30 Apr 2005 17:20:51 -0000 1.5 @@ -4,12 +4,12 @@ ]> <document url="ssi-howto.html"> - &project; +&project; - <properties> - <author email="[EMAIL PROTECTED]">Glenn L. Nielsen</author> - <title>SSI How To</title> - </properties> +<properties> +<author email="[EMAIL PROTECTED]">Glenn L. Nielsen</author> +<title>SSI How To</title> +</properties> <body> @@ -112,6 +112,262 @@ </p> </section> + +<section name="Directives"> +<p>Server Side Includes are invoked by embedding SSI directives in an HTML document + whose type will be processed by the SSI servlet. The directives take the form of an HTML + comment. The directive is replaced by the results of interpreting it before sending the + page to the client. The general form of a directive is: </p> +<p> <code><!--#directive [parm=value] --></code></p> +<p>The directives are: +<ul> +<li> +<strong>config</strong> - <code><!--#config timefmt="%B %Y" --></code> +Used to set the format of dates and other items processed by SSI +</li> +<li> +<strong>echo</strong> - <code><!--#echo var="VARIABLE_NAME" --></code> +will be replaced bt the value of the variable. +</li> +<li> +<strong>exec</strong> - Used to run commands on the host system. +</li> +<li> +<strong>include</strong> - <code><!--#include virtual="file-name" --></code> +inserts the contents +</li> +<li> +<strong>flastmod</strong> - <code><!--#flastmod file="filename.shtml" --></code> +Returns the time that a file was lost modified. +</li> +<li> +<strong>fsize</strong> - <code><!--#fsize file="filename.shtml" --></code> +Returns the size of a file. +</li> +<li> +<strong>printenv</strong> - <code><!--#printenv --></code> +Returns the list of all the defined variables. +</li> +<li> +<strong>set</strong> - <code><!--#set var="foo" value="Bar" --></code> +is used to assign a value to a user-defind variable. +</li> +<li> +<strong>if elif endif else</strong> - Used to create conditional sections. For example:</li> +<code><!--#config timefmt="%A" --><br /> + <!--#if expr="$DATE_LOCAL = /Monday/" --><br /> + <p>Meeting at 10:00 on Mondays</p><br /> + <!--#elif expr="$DATE_LOCAL = /Friday/" --><br /> + <p>Turn in your time card</p><br /> + <!--#else --><br /> + <p>Yoga class at noon.</p><br /> + <!--#endif --></code> + </ul> +</p> +See the +<p> <a href="http://httpd.apache.org/docs/howto/ssi.html#basicssidirectives"> +Apache Introduction to SSI</a> for more information on using SSI directives.</p> +</section> + +<section name="Variables"> +<p>The SSI servlet currently implements the following variables: +</p> +<table border="1"> +<tr> +<th>Variable Name</th> +<th>Description</th> +</tr> + +<tr> +<td>AUTH_TYPE</td> +<td> + The type of authentication used for this user: BASIC, FORM, etc.</td> +</tr> + +<tr> +<td>CONTENT_LENGTH</td> +<td> + The length of the data (in bytes or the number of + characters) passed from a form.</td> +</tr> + +<tr> +<td>CONTENT_TYPE</td> +<td> + The MIME type of the query data, such as "text/html".</td> +</tr> + +<tr> +<td>DATE_GMT</td> +<td> +Current date and time in GMT</td> +</tr> + +<tr> +<td>DATE_LOCAL</td> +<td> +Current date and time in the local time zone</td> +</tr> +<tr> +<td>DOCUMENT_NAME</td> +<td> +The current file</td> +</tr> +<tr> +<td>DOCUMENT_URI</td> +<td> +Virtual path to the file</td> +</tr> + +<tr> +<td>GATEWAY_INTERFACE</td> +<td> + The revision of the Common Gateway Interface that the + server uses if enabled: "CGI/1.1".</td> +</tr> + +<tr> +<td>HTTP_ACCEPT</td> +<td> + A list of the MIME types that the client can accept.</td> +</tr> + +<tr> +<td>HTTP_ACCEPT_ENCODING</td> +<td> + A list of the compression types that the client can accept.</td> +</tr> + +<tr> +<td>HTTP_ACCEPT_LANGUAGE</td> +<td> + A list of the laguages that the client can accept.</td> +</tr> +<tr> +<td>HTTP_CONNECTION</td> +<td> + The way that the connection from the client is being managed: + "Close" or "Keep-Alive".</td> +</tr> +<tr> +<td>HTTP_HOST</td> +<td> + The web site that the client requested.</td> +</tr> +<tr> +<td>HTTP_REFERER</td> +<td> + The URL of the document that the client linked from.</td> +</tr> +<tr> +<td>HTTP_USER_AGENT</td> +<td> + The browser the client is using to issue the request.</td> +</tr> +<tr> +<td>LAST_MODIFIED</td> +<td> +Last modification date and time for current file</td> +</tr> +<tr> +<td>PATH_INFO</td> +<td> + Extra path information passed to a servlet.</td> +</tr> +<tr> +<td>PATH_TRANSLATED</td> +<td> + The translated version of the path given by the + variable PATH_INFO.</td> +</tr> +<tr> +<td>QUERY_STRING</td> +<td> +The query string that follows the "?" in the URL. +</td> +</tr> +<tr> +<td>QUERY_STRING_UNESCAPED</td> +<td> +Undecoded query string with all shell metacharacters escaped +with "\"</td> +</tr> +<tr> +<td>REMOTE_ADDR</td> +<td> + The remote IP address of the user making the request.</td> +</tr> +<tr> +<td>REMOTE_HOST</td> +<td> + The remote hostname of the user making the request.</td> +</tr> +<tr> +<td>REMOTE_PORT</td> +<td> + The port number at remote IP address of the user making the request.</td> +</tr> +<tr> +<td>REMOTE_USER</td> +<td> + The authenticated name of the user.</td> +</tr> +<tr> +<td>REQUEST_METHOD</td> +<td> + The method with which the information request was + issued: "GET", "POST" etc.</td> +</tr> +<tr> +<td>REQUEST_URI</td> +<td> + The web page originally requested by the client.</td> +</tr> +<tr> +<td>SCRIPT_FILENAME</td> +<td> + The location of the current web page on the server.</td> +</tr> +<tr> +<td>SCRIPT_NAME</td> +<td> + The name of the web page.</td> +</tr> +<tr> +<td>SERVER_ADDR</td> +<td> + The server's IP address.</td> +</tr> +<tr> +<td>SERVER_NAME</td> +<td> + The server's hostname or IP address.</td> +</tr> +<tr> +<td>SERVER_PORT</td> +<td> + The port on which the server received the request.</td> +</tr> +<tr> +<td>SERVER_PROTOCOL</td> +<td> + The protocol used by the server. E.g. "HTTP/1.1".</td> +</tr> +<tr> +<td>SERVER_SOFTWARE</td> +<td> + The name and version of the server software that is + answering the client request.</td> +</tr> +<tr> +<td>UNIQUE_ID</td> +<td> + A token used to identify the current session if one + has been established.</td> +</tr> +</table> +</section> + </body> </document>
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]