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>&lt;!--#directive [parm=value] --&gt;</code></p>
  +<p>The directives are:
  +<ul>
  +<li>
  +<strong>config</strong> - <code>&lt;!--#config timefmt=&quot;%B %Y&quot; 
--&gt;</code>
  +Used to set the format of dates and other items processed by SSI
  +</li>
  +<li>
  +<strong>echo</strong> -   <code>&lt;!--#echo var=&quot;VARIABLE_NAME&quot; 
--&gt;</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>&lt;!--#include 
virtual=&quot;file-name&quot; --&gt;</code>
  +inserts the contents
  +</li>
  +<li>
  +<strong>flastmod</strong> - <code>&lt;!--#flastmod 
file=&quot;filename.shtml&quot; --&gt;</code>
  +Returns the time that a file was lost modified.
  +</li>
  +<li>
  +<strong>fsize</strong> - <code>&lt;!--#fsize file=&quot;filename.shtml&quot; 
--&gt;</code>
  +Returns the size of a file.
  +</li>
  +<li>
  +<strong>printenv</strong> - <code>&lt;!--#printenv --&gt;</code>
  +Returns the list of all the defined variables.
  +</li>
  +<li>
  +<strong>set</strong> - <code>&lt;!--#set var="foo" value="Bar" --&gt;</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>&lt;!--#config timefmt="%A" --&gt;<br />
  +  &lt;!--#if expr="$DATE_LOCAL = /Monday/" --&gt;<br />
  +  &lt;p&gt;Meeting at 10:00 on Mondays&lt;/p&gt;<br />
  +  &lt;!--#elif expr="$DATE_LOCAL = /Friday/" --&gt;<br />
  +  &lt;p&gt;Turn in your time card&lt;/p&gt;<br />
  +  &lt;!--#else --&gt;<br />
  +  &lt;p&gt;Yoga class at noon.&lt;/p&gt;<br />
  +  &lt;!--#endif --&gt;</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 &quot;text/html&quot;.</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: &quot;CGI/1.1&quot;.</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:
  +  &quot;Close&quot; or &quot;Keep-Alive&quot;.</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 &quot;?&quot; in the URL.
  +</td>
  +</tr>
  +<tr>
  +<td>QUERY_STRING_UNESCAPED</td>
  +<td>
  +Undecoded query string with all shell metacharacters escaped 
  +with &quot;\&quot;</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: &quot;GET&quot;, &quot;POST&quot; 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. &quot;HTTP/1.1&quot;.</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]

Reply via email to