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]