Embedding xmlsh as a Servlet
Xmlsh comes with a generic Servlet class which can be used, extended, or you can write your own.
This is based on J2EE Servlet Containers but is only tested with Tomcat 6.
The Servlet is registered using the standard WAR file structure which you must create youself.
When the servlet is bound to a URI, the file portion of the URI is mapped to a server side directory and executes xmlsh scripts from within that directory.
For example, given this example web.xml file
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee web-app_2_4.xsd"
version="2.4">
<description>xmlsh tomcat application</description>
<servlet>
<servlet-name>XmlshServlet</servlet-name>
<servlet-class>org.xmlsh.servlet.XmlshServlet</servlet-class>
<init-param>
<param-name>root</param-name>
<param-value>/var/xmlsh</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>XmlshServlet</servlet-name>
<url-pattern>*.xsh</url-pattern>
</servlet-mapping>
</web-app>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee web-app_2_4.xsd"
version="2.4">
<description>xmlsh tomcat application</description>
<servlet>
<servlet-name>XmlshServlet</servlet-name>
<servlet-class>org.xmlsh.servlet.XmlshServlet</servlet-class>
<init-param>
<param-name>root</param-name>
<param-value>/var/xmlsh</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>XmlshServlet</servlet-name>
<url-pattern>*.xsh</url-pattern>
</servlet-mapping>
</web-app>
Request to http://host/xmlsh/script.xsh then the corresponding script in /var/xmlsh/script.xsh is executed.
If a GET request is performed then the input to the script is null. If a POST command is performed then the input to the script is the body of the POST command. The output of the script becomes the response body.
The content-type of the response body is set to the content-type property of the shell after invocation of the script.
Starting with version 1.0.3 of xmlsh any POST or QUERY parameters are passed as an XML variable "HTTP_PARAMETERS"
The format of the variable is an XML document of the form
<parameters>
<param name="keyname">
<value>value 1</value>
<value>value 2</value>
</param>
</parameters>
<param name="keyname">
<value>value 1</value>
<value>value 2</value>
</param>
</parameters>
Starting with version 1.0.3 of xmlsh all HTTP headers are passed as an XML variable "HTTP_HEADERS"
The format of the variable is an XML document of the form
<headers>
<header name="host">
<value>localhost:8280</value>
</header>
<header name="connection">
<value>keep-alive</value>
</header>
<header name="user-agent">
<value>Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/532.5 (KHTML, like Gecko) Chrome/4.1.249.1036 Safari/532.5</value>
</header>
<header name="cache-control">
<value>max-age=0</value>
</header>
<header name="authorization">
<value>Basic eG1sc2g6eG1sc2g=</value>
</header>
<header name="accept">
<value>application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5</value>
</header>
<header name="accept-encoding">
<value>gzip,deflate,sdch</value>
</header>
<header name="accept-language">
<value>en-US,en;q=0.8</value>
</header>
<header name="accept-charset">
<value>ISO-8859-1,utf-8;q=0.7,*;q=0.3</value>
</header>
</headers>
<header name="host">
<value>localhost:8280</value>
</header>
<header name="connection">
<value>keep-alive</value>
</header>
<header name="user-agent">
<value>Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/532.5 (KHTML, like Gecko) Chrome/4.1.249.1036 Safari/532.5</value>
</header>
<header name="cache-control">
<value>max-age=0</value>
</header>
<header name="authorization">
<value>Basic eG1sc2g6eG1sc2g=</value>
</header>
<header name="accept">
<value>application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5</value>
</header>
<header name="accept-encoding">
<value>gzip,deflate,sdch</value>
</header>
<header name="accept-language">
<value>en-US,en;q=0.8</value>
</header>
<header name="accept-charset">
<value>ISO-8859-1,utf-8;q=0.7,*;q=0.3</value>
</header>
</headers>
For example the following script for "index.xsh" in the "xmlsh" servlet
xecho $HTTP_PARAMETERS
Given the following URL
http://host:port/xmlsh?foo=bar&spam=value1&spam=value2
Results in
<parameters>
<param name="foo">
<value>bar</value>
</param>
<param name="spam">
<value>value1</value>
<value>value2</value>
</param>
</parameters>
<param name="foo">
<value>bar</value>
</param>
<param name="spam">
<value>value1</value>
<value>value2</value>
</param>
</parameters>
You can configure a default index page "index.xsh" by adding this servlet mapping
<servlet-mapping>
<servlet-name>XmlshServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<servlet-name>XmlshServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
This maps the root directory to the xmlsh servlet, which then looks for "index.xsh" as the default welcome file.
For servlets hosted in Tomcat you can use tomcat's authentication like any other servlet.
For example, adding the following to the web.xml will request BASIC authentication.
<security-role>
<description>xmlsh users</description>
<role-name>xmlsh</role-name>
</security-role>
<security-constraint>
<web-resource-collection>
<web-resource-name>
Entire Application
</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>xmlsh</role-name>
</auth-constraint>
</security-constraint>
<!-- Define the Login Configuration for this Application -->
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>XMLSH Realm</realm-name>
</login-config>
<description>xmlsh users</description>
<role-name>xmlsh</role-name>
</security-role>
<security-constraint>
<web-resource-collection>
<web-resource-name>
Entire Application
</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>xmlsh</role-name>
</auth-constraint>
</security-constraint>
<!-- Define the Login Configuration for this Application -->
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>XMLSH Realm</realm-name>
</login-config>
You must edit the tomcat-users.xml file to add a user for the specified realm.
Session Variables
Starting with release 1.0.3 J2EE Session variables are supported via the httpsession command.Examples
ExampleThe following script invokes an xslt command on the input and outputs the result to the output, setting the content type to "text/html"
set -content-type text/html xslt -f /test/spl.xsl
Set up the WAR
To create a working xmlsh servlet, a standard WAR structure needs to be created. Above is a sample web.xml, although the servlet can be configured in an existing WAR application, it need not be its own application.The servlet class is org.xmlsh.servlet.XmlshServlet
There is a required servlet parameter *root* which specifies the directory where xmlsh scripts are located.
All libraries (jars) required by xmlsh need to be available in the classpath for the servlet. Recommended that these get put into the WEB-INF/lib directory.