<document>
  <header>
    <product>resin</product>
    <title>Servlets</title>
    <type>contents</type>
    <description>
      <p>Servlets are Java classes which service HTTP requests.  The only
        requirement for writing a servlet is that it implements the
        javax.servlet.Servlet interface.</p>

      <p>Servlets are loaded from the classpath like all Java classes.
        Normally, users put servlets in <var>WEB-INF/classes</var> so Resin will
          automatically reload them when they change.</p>
      
      <p><a href="jsp.xtp">JSP</a> pages are implemented as
        Servlets, and tend to be more efficient for pages with lots of text.</p>
    </description>
  </header>

  <body>

<localtoc/>

<s1 title="Configuration">

<s2 title="Configuring the web.xml">

<p>The following is a complete working web.xml to run this example.</p>

<p>The <var>servlet-mapping</var> tells Resin that the URL
<var>/hello</var> should invoke the <var>hello-world</var> servlet.</p>

<p>The <var>servlet</var> tells Resin that <var>hello-world</var> uses the
<var>test.HelloWorld</var> class and that the value of the <var>greeting</var>
init parameter is <var>Hello World</var>.</p>

<example title="Example: WEB-INF/resin-web.xml">
&lt;web-app xmlns="http://caucho.com/ns/resin"&gt;
  &lt;servlet servlet-name='hello-world'
           servlet-class='test.HelloWorld'&gt;
    &lt;init-param greeting='Hello, World'/&gt;
  &lt;/servlet&gt;

  &lt;servlet-mapping url-pattern='/hello'
                   servlet-name='hello-world'/&gt;
&lt;/web-app&gt;
</example>

<p>The Java code, <var>HelloWorld.java</var> belongs in</p>
<def>
$app-dir/WEB-INF/classes/test/HelloWorld.java
</def>

<p>Or, if you're compiling the servlet yourself, the class file belongs in</p>
<def>
$app-dir/WEB-INF/classes/test/HelloWorld.class
</def>

<p>Following is the actual servlet code.  It just prints a trivial
HTML page filled with the greeting specified in the web.xml.</p>

<p><var>init()</var> and <var>destroy()</var> are included mostly for
illustration.  Resin will call <var>init()</var> when it starts the servlet
and <var>destroy</var> before Resin destroys it.</p>

<example>
package test;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class HelloWorld extends HttpServlet {
  private String greeting;

  public void init()
    throws ServletException
  {
    greeting = getInitParameter("greeting");
  }

  public void doGet(HttpServletRequest request,
                    HttpServletResponse response)
    throws ServletException, IOException
  {
    PrintWriter out = response.getWriter();

    out.println("&lt;title&gt;" + greeting + "&lt;/title&gt;");
    out.println("&lt;h1&gt;" + greeting + "&lt;/h1&gt;");
  }
  
  public void destroy()
  {
    // nothing to do
  }
}
</example>

</s2>

<s2 title="Servlet Example for JSP Programmers">

<p>Because Resin compiles JSP pages into servlets, programmers familiar
with JSP can start writing servlets fairly easily.  The following template
can be used to see how to write a servlet for someone familiar with JSP.
</p>

<example>
package test;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class HelloWorld extends HttpServlet {
  public void service(HttpServletRequest request,
                      HttpServletResponse response)
    throws ServletException, IOException
  {
    PrintWriter out = response.getWriter();
    ServletContext application = getServletContext();
    HttpSession session = request.getSession();

    try {
      // <var>code goes here</var>

      // The equivalent of jsp:include:
      // request.getRequestDispatcher("/inc.jsp").include(request, response);
    } catch (ServletException e) {
      throw e;
    } catch (Exception e) {
      throw new ServletException(e);
    }
  }
}
</example>

</s2>

<s2 title="Using Databases from a Servlet">

<p>The following is a sample design pattern for getting new database
connections.  The <var>try ... finally</var> block is very important.  Without
the close in the finally block, Resin's database pool can loose connections.</p>

<p>Configuring the database is described in the
<a href="config-database.xtp">database configuration</a> page.</p>

<example title="TestDatabase.java">
package test;

import java.io.*;

import java.sql.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.naming.*;
import javax.sql.*;

public class TestDatabase extends HttpServlet {
  DataSource pool;

  public void init()
    throws ServletException
  {
    try {
      Context env = (Context) new InitialContext().lookup("java:comp/env");

      pool = (DataSource) env.lookup("jdbc/test");

      if (pool == null)
        throw new ServletException("`jdbc/test' is an unknown DataSource");
    } catch (NamingException e) {
      throw new ServletException(e);
    }
  }

  public void doGet(HttpServletRequest request,
                    HttpServletResponse response)
    throws IOException, ServletException
  {
    response.setContentType("text/html");
    PrintWriter out = response.getWriter();

    Connection conn = null;
    try {
      conn = pool.getConnection();

      // <var>code for the servlet using the database goes here</var>

      rs.close();
      stmt.close();
    } catch (SQLException e) {
      throw new ServletException(e);
    } finally {
      try {
        if (conn != null)
          conn.close();
      } catch (SQLException e) {
      }
    }
  }
}
</example>

</s2>

</s1>


<s1 title="Servlet Configuration">

<s2 title="init" version="Resin 2.1.3" type="defun">
<p>Configures servlets using bean-style initialization.
Each entry in an &lt;init&gt; tag will configure a <code>setFoo</code>
method in a Servlet. JSP EL expressions are allowed.</p>

<p>The <code>init(config)</code> method is called after
all the bean setters are called.</p>

<example title="Bean-style Configuration">
&lt;web-app xmlns="http://caucho.com/ns/resin">

&lt;servlet servlet-name='test.HelloWorld'&gt;
  &lt;init&gt;
    &lt;greeting&gt;Hello, ${host.url}&lt;/greeting&gt;
  &lt;/init&gt;
&lt;/servlet&gt;

&lt;/web-app>
</example>

<example title="HelloWorld bean">
public HelloWorld extends GenericServlet {
  private String _greeting;

  public void setGreeting(String greeting)
  {
    _greeting = greeting;
  }

  public void service(ServletRequest req,
                      ServletResponse res)
    throws IOException, ServletException
  {
    PrintWriter out = res.getWriter();

    out.println("Greeting: " + _greeting);
  }
}
</example>

</s2>

<s2 title="init-param" type="defun">
<p>Initializes servlet variables. <code>servlet-param</code>
defines initial values for <code>getServletConfig().getInitParameter("foo")</code>.
</p>

<p>The full servlet 2.2 syntax is supported and allows a simple shortcut.</p>
<example>
&lt;web-app id='/'&gt;

&lt;servlet servlet-name='test.HelloWorld'&gt;
  &lt;init-param foo='bar'/&gt;

  &lt;init-param&gt;
    &lt;param-name&gt;baz&lt;/param-name&gt;
    &lt;param-value&gt;value&lt;/param-value&gt;
  &lt;/init-param&gt;
&lt;/servlet&gt;

&lt;/web-app&gt;
</example>
</s2>

<s2 title="load-on-startup" type="defun">
<p>If present, starts the servlet when the server starts.</p>
<example>
&lt;web-app id='/'&gt;

&lt;servlet servlet-name='hello'
         servlet-class='test.HelloWorld'&gt;
  &lt;load-on-startup/&gt;
&lt;/servlet&gt;

&lt;/web-app&gt;
</example>
</s2>

<s2 title="run-at" version="Resin 1.1" type="defun">
<p>If present, calls the servlet's <var>service()</var> method
at the specified times.
&lt;run-at&gt; lets servlet writers execute periodic tasks without worrying
about creating a new Thread.</p>

<p>The value is a list of 24-hour times when the
servlet should be automatically executed.  To run the servlet every 6
hours, you could use:</p>

<example>
&lt;servlet servlet-name='test.HelloWorld'&gt;
  &lt;run-at&gt;0:00, 6:00, 12:00, 18:00&lt;/run-at&gt;
&lt;/servlet&gt;
</example>

<p>If the hour is omitted, the servlet runs every hour at the
specified minute.  To run the server every 15 minutes, you could use:
</p>

<example>
&lt;servlet servlet-name='test.HelloWorld'&gt;
  &lt;run-at&gt;:00, :15, :30, :45&lt;/run-at&gt;
&lt;/servlet&gt;
</example>
</s2>

<s2 title="servlet" type="defun">
<p>Defines a servlet alias for later mapping.</p>

<deftable>
<tr><th>Attribute</th><th>Description
</th></tr><tr><td>servlet-name</td><td>The servlet's name (alias)
</td></tr><tr><td>servlet-class</td><td>The servlet's class (defaults to servlet-name)
</td></tr><tr><td>init-param</td><td>Initialization parameters
</td></tr><tr><td>load-on-startup</td><td>Initializes the servlet when the server starts.
</td></tr><tr><td>run-at</td><td>Times to execute the servlet automatically
</td></tr></deftable>

<p>The following example defines a servlet alias 'hello'</p>
<example>
&lt;web-app id='/'&gt;

&lt;servlet-mapping url-pattern='/hello.html'
                 servlet-name='hello'/&gt;

&lt;servlet servlet-name='hello'
         servlet-class='test.HelloWorld'&gt;
  &lt;init-param title='Hello, World'/&gt;
&lt;/servlet&gt;

&lt;servlet servlet-name='cron'
         servlet-class='test.DailyChores'&gt;
  &lt;run-at&gt;3:00&lt;/run-at&gt;
&lt;/servlet&gt;

&lt;/web-app&gt;
</example>
</s2>

<s2 title="servlet-class" type="defun">
<p>Class of the servlet.  The CLASSPATH for servlets includes
the WEB-INF/classes directory and all jars in the WEB-INF/lib directory.
</p>
</s2>

<s2 title="servlet-name" type="defun">
<p>Alias of the servlet, uniquely naming a servlet configuration.
Several &lt;servlet&gt; configurations might configure the same
servlet class with different &lt;init-param&gt; values.  Each will
have a separate servlet-name.</p>

<example title="Multiple Servlets">
&lt;web-app&gt;
  &lt;servlet servlet-name='foo-a'&gt;
    &lt;servlet-class&gt;test.FooServlet&lt;/servlet-class&gt;
    &lt;init-param name='foo-a sample'/&gt;
  &lt;/servlet&gt;

  &lt;servlet servlet-name='foo-b'&gt;
    &lt;servlet-class&gt;test.FooServlet&lt;/servlet-class&gt;
    &lt;init-param name='foo-b sample'/&gt;
  &lt;/servlet&gt;
&lt;/web-app&gt;
</example>

</s2>

<s2 title="servlet-mapping" type="defun">
<p>Maps from a URL to the servlet to execute.  The servlet-mapping
has a url-pattern to match the URL and a servlet-name to match the
configured servlet.</p>

<example title="typical servlet-mapping">
&lt;servlet&gt;
  &lt;servlet-name&gt;hello&lt;/servlet-name&gt;
  &lt;servlet-class&gt;test.HelloServlet&lt;/servlet-class&gt;
&lt;/servlet&gt;

&lt;servlet-mapping&gt;
  &lt;url-pattern&gt;/hello/*&lt;/url-pattern&gt;
  &lt;servlet-name&gt;hello&lt;/servlet-name&gt;
&lt;/servlet-mapping&gt;
</example>

<p>Resin allows for a shortcut combining the servlet and
the servlet mapping:</p>

<example title="shortcut servlet-mapping">
&lt;servlet-mapping url-pattern="/hello/*"
                 servlet-class="test.HelloServlet"/&gt;
</example>
</s2>

<s2 title="url-pattern" version="Servlet 2.2" type="defun">
<p>Matches a set of URLs for servlet-mapping.</p>

<deftable>
<tr><th width="25%">Pattern</th><th>Description
</th></tr><tr><td>/foo/bar.html</td><td>Matches exactly the /foo/bar.html URL.
</td></tr><tr><td>/foo/*</td><td>Matches /foo and any children
</td></tr><tr><td>*.foo</td><td>Matches any URL with a .foo extension
</td></tr><tr><td>/</td><td>Replaces the default servlet.
</td></tr></deftable>

<p><var>/</var> defines a default handler and <var>/*</var> defines a prefix handler.
<var>/*</var> will override extension handlers like <var>*.foo</var>. <var>/</var>
will only be used if no other pattern matches.</p>

<p>No default.  Either url-pattern or url-regexp is required.</p>
</s2>

</s1>

<s1 title="ErrorStatusServlet">

<p>Sends an HTTP error code and optionally an error message back
to the client.</p>  

<deftable-parameters>
<tr><td>status-code</td><td>the HTTP status code to send</td><td>404
</td></tr><tr><td>message</td><td>the message to send</td><td>no message
</td></tr></deftable-parameters>

<p>This servlet is particularily useful for blocking access to portions of your
web-app that contain files not meant to be accessible to users. In this
example, the default 404 (meaning "Not Found") is used as the error
message; the user cannot even determine if the file they are trying to access
exists.</p>

<example title="Blocking access to files using the ErrorStatusServlet">
&lt;web-app&gt;
  &lt;servlet&gt;
    &lt;servlet-name&gt;block-access&lt;/servlet-name&gt;
    &lt;servlet-class&gt;com.caucho.servlets.ErrorStatusServlet&lt;/servlet-class&gt;
  &lt;servlet&gt;

  &lt;servlet-mapping&gt;
    &lt;servlet-name&gt;block-access&lt;/servlet-name&gt;
    &lt;url-pattern&gt;/config/*&lt;/url-pattern&gt;
  &lt;/servlet-mapping&gt;
  &lt;servlet-mapping&gt;
    &lt;servlet-name&gt;block-access&lt;/servlet-name&gt;
    &lt;url-pattern&gt;*.properties&lt;/url-pattern&gt;
  &lt;/servlet-mapping&gt;

  ...

&lt;/web-app&gt;
</example>

<p>See <a href="javadoc|com.caucho.servlets.ErrorStatusServlet|"/>.</p>
</s1>


<s1 title="LoadBalanceServlet">

<p>Configures a front-end Resin instance to load-balance requests to
backend Resin instances.  Each LoadBalanceServlet instance will
distribute the requests to a configured cluster.</p>

<p>The urls that get load balanced are the ones that are mapped to the LoadBalancedServlet, using the usual servlet-mapping. </p>

<p>LoadBalanceServlet supports sticky-sessions. If the request already has a
session, the backend server matching that session will be used.  Otherwise, the
least busy backend server will be used as counted by
number of active requests.  If several backend servers are
equally busy, the selection uses a round-robin to distribute the load.
</p>


<deftable-parameters>
<tr><td>cluster-id</td><td>the cluster that gets the matching requests</td><td>required
</td></tr><tr><td>sticky-sessions</td><td>whether or not sessions should be sticky</td><td>true
</td></tr><tr><td>strategy</td><td>the load balancing strategy, `round-robin' or `least-connection'</td><td>least-connection
</td></tr></deftable-parameters>

<p>The usual case balances all requests to backend servers.  The front-end Resin
instance has a resin.xml similar to the one shown here.  It configures
the front-end instance to balance the load to the backend
servers.  The backend Resin instances have a resin.xml file that
configures the web site, similar to a conf file that is used when only one
instance of Resin used for the server.</p>

<example title="frontend.conf">
&lt;resin xmlns="http://caucho.com/ns/resin"&gt;
  &lt;server&gt;

    &lt;http id='frontend' port='8080'/&gt;

    &lt;cluster id='backend'&gt;
      &lt;srun id='a' host='192.168.0.11' port='6810'/&gt;
      &lt;srun id='b' host='192.168.0.12' port='6810'/&gt;
    &lt;/cluster&gt;

    &lt;!-- the front-end does the access logging --&gt;
    &lt;access-log path='log/access.log'&gt;
      &lt;rollover-period&gt;2W&lt;/rollover-period&gt;
    &lt;/access-log&gt;

    &lt;!-- all urls are load balanced to the backend --&gt;
    &lt;host id=''&gt;
      &lt;web-app id='/'&gt;
        &lt;servlet&gt;
          &lt;servlet-name&gt;backend&lt;/servlet-name&gt;
          &lt;servlet-class&gt;com.caucho.servlets.LoadBalanceServlet&lt;/servlet-class&gt;
          &lt;init&gt;
            &lt;cluster&gt;backend&lt;/cluster&gt;
          &lt;/init&gt;
        &lt;/servlet&gt;

        &lt;servlet-mapping url-pattern='/*' servlet-name='backend'/&gt;
      &lt;/web-app&gt;
   &lt;/host&gt;
  &lt;/server&gt;
&lt;/resin&gt;
</example>

<p>LoadBalanceServlet is also used to allow a separate JVM for a web-app or a
host.</p>

<p>
The <var>strategy</var> determines the strategy to use for choosing a backend
server for a request that does not have a sticky-session.  The
`least-connection' strategy chooses the backend server that has the least
number of connections at the time the decision is made.  This is a good general
purpose strategy, and compensates for differences in a backend server's ability
to service connections.  The `round-robin' strategy does a straight round
robin, choosing the backend server that follows the last backend server chosen.
</p>

<p>
See <a href="javadoc|com.caucho.servlets.LoadBalanceServlet|"/>.
</p>
</s1>

<s1 title="CGIServlet">

<p>Implements CGI calls.  The url is assumed to refer to an executable file,
and the operating system is instructed to execute the program or script.  The
usual CGI environment variables are set, and the current directory is 
the value of <code>$RESIN_HOME</code></p>

<deftable-parameters>
<tr><td>executable</td><td>Path to the script program</td><td>default exec
</td></tr><tr><td>ignore-exit-code</td><td>If true, do not treat a non-zero exit code as an error</td><td>false
</td></tr><tr><td>stderr-is-exception</td><td>If false, ignore output on stderr instead of triggering an exception</td><td>true
</td></tr></deftable-parameters>

<example title="WEB-INF/resin-web.xml">
&lt;web-app xmlns="http://caucho.com/ns/resin"&gt;
  &lt;servlet&gt;
    &lt;servlet-name&gt;cgi&lt;/servlet-name&gt;
    &lt;servlet-class&gt;com.caucho.servlets.CGIServlet&lt;/servlet-class&gt;
  &lt;/servlet&gt;

  &lt;servlet-mapping servlet-name="cgi" url-pattern="/cgi-bin/*.exe"/&gt;
&lt;/web-app&gt;
</example>

<p>
The <code>servlet-mapping</code> specifies the requests that will be treated as
CGI exectutables.  In the example above, only files in the /cgi-bin directory
with an extension of ".exe" will be executed.  It is important to limit the
url-pattern as much as possible to avoid allowing unintended execution of
scripts or binaries on the system.
</p>

<p>
A CGI script must output a blank line between the HTTP header(s) and the
rest of the response.  If no blank line is encountered, the contents of your
browser page will be blank.  Usually a CGI script will output a
<code>Content-Type:</code> header and then a blank line before the content:
</p>

<example title="Minimal CGI script">
#!/bin/sh

echo "Content-Type: text/html"
echo
echo "&lt;h&gt;CGI Test&lt;h1&gt;"
echo "CGI Test"

echo "&lt;pre&gt;"
env
echo "&lt;/pre&gt;"

</example>

</s1>

<s1 title="DirectoryServlet">

<p>The directory servlet provides the basic directory browsing.
The servlet-name must be "directory" for the servlet to take effect.
Sites will normally disable it.</p>

<deftable-parameters>
<tr>
  <td>enable</td>
  <td>Enable or disable the servlet</td>
  <td>true</td>
</tr>
</deftable-parameters>

<example>
&lt;servlet servlet-name="directory"
         servlet-class="com.caucho.servlets.DirectoryServlet"&gt;
  &lt;init enable="false"/&gt;
&lt;/servlet&gt;
</example>

</s1>

<s1 title="FastCGIServlet">

<p>Implements the FastCGI protocol.  FastCGI allows some CGI clients
like PHP to run quicker and more efficiently.</p>

<deftable-parameters>
<tr><td>server-address</td><td>the host and port number, in the form host:port</td><td>required
</td></tr></deftable-parameters>

<p>
The FastCGIServlet creates a socket connection from Resin to the backend
program that supports the fastcgi protocol.  <a config-tag="servlet-mapping"/>
is used to configure the filename patterns of scripts that are handled by the
backend program.
</p>

<p>
The following example configures Resin so that any files within a single webapp
matching the pattern"*.php" are handled by the backend program:
</p>

<example title="WEB-INF/web.xml">
&lt;web-app&gt;
  &lt;servlet&gt;
    &lt;servlet-name&gt;php-fastcgi&lt;/servlet-name&gt;
    &lt;servlet-class&gt;com.caucho.servlets.FastCGIServlet&lt;/servlet-class&gt;
    &lt;init&gt;
      &lt;server-address&gt;localhost:6666&lt;/server-address&gt;
    &lt;/init&gt;
  &lt;/servlet&gt;
  &lt;servlet-mapping&gt;
    &lt;servlet-name&gt;php-fastcgi&lt;/servlet-name&gt;
    &lt;url-pattern&gt;*.php&lt;/url-pattern&gt;
  &lt;/servlet-mapping&gt;
&lt;/web-app&gt;
</example>

<p>Assuming PHP has been compiled with -fastcgi enabled, you might
start PHP like:</p>

<example>
unix&gt; php -b 6666 
</example>

<p>
Mapping is enabled for all web-apps with the use of 
<a config-tag="web-app-default"/>.  In this example, filenames with the pattern
"*.php" and the pattern "*.phtml" are handled by the backend program: 
</p>

<example title="resin.xml">
&lt;web-app-default&gt;
  &lt;servlet&gt;
    &lt;servlet-name&gt;php-fastcgi&lt;/servlet-name&gt;
    &lt;servlet-class&gt;com.caucho.servlets.FastCGIServlet&lt;/servlet-class&gt;
    &lt;init&gt;
      &lt;server-address&gt;localhost:6666&lt;/server-address&gt;
    &lt;/init&gt;
  &lt;/servlet&gt;

  &lt;servlet-mapping url-pattern="*.php"   servlet-name="php-fastcgi"/&gt;
  &lt;servlet-mapping url-pattern="*.phtml" servlet-name="php-fastcgi"/&gt;

&lt;/web-app&gt;
</example>

<p>See <a href="javadoc|com.caucho.servlets.FastCGIServlet|"/>.</p>
</s1>

<s1 title="HttpProxyServlet">

<p>
<a href="javadoc|com.caucho.servlets.HttpProxyServlet|"/> is a servlet that
proxies to another server.  This can be useful for providing access to legacy
backend servers.
</p>

<example title="HttpProxyServlet">
  &lt;servlet&gt;
    &lt;servlet-name&gt;http-proxy&lt;/servlet-name&gt;
    &lt;servlet-class&gt;com.caucho.servlets.HttpProxyServlet&lt;/servlet-class&gt;
    &lt;init host='localhost:8081'/&gt;
  &lt;/servlet&gt;

  &lt;servlet-mapping url-pattern="/foo/*" servlet-name="http-proxy"/&gt;
  &lt;servlet-mapping url-pattern="/bar/*" servlet-name="http-proxy"/&gt;
</example>


<p>
There is a bit more power using servlet-regexp and regular expressions:
</p>

<example title="HttpProxyServlet with regexp">
&lt;servlet-regexp url-regexp="^/foo(/.*)?"
                servlet-class="com.caucho.servlets.HttpProxyServlet"&gt;
  &lt;init host='localhost:8081'/&gt;
&lt;/servlet-regexp&gt;
</example>
</s1>

<s1 title="SSIServlet">

<p>
<a href="javadoc|com.caucho.servlets.ssi.SSIServlet|"/> is a servlet that
processes server side include directives.  The syntax for server side includes
is the same as the syntax used in <a href="http://httpd.apache.org/docs/1.3/mod/mod_include.html">Apache httpd</a>.
</p>

<example title="resin-web.xml SSIServlet">
&lt;web-app xmlns="http://caucho.com/ns/resin"&gt;
  &lt;servlet-mapping url-pattern="*.shtml"
                   servlet-class="com.caucho.servlets.ssi.SSIServlet"/&gt;
&lt;/web-app&gt;
</example>

<example title="test.shtml">
&lt;h1&gt;A little test&lt;/h1&gt;

&lt;!--#config timefmt="%Y-%m-%d" --&gt;
&lt;!--#echo var="DATE_GMT" --&gt;

&lt;!--#include virtual="inc.jsp" --&gt;

&lt;!--#set var="a" value="$REQUEST_METHOD" --&gt;
&lt;!--#include virtual="inc.jsp?q=$a" --&gt;

</example>
</s1>

<s1 title="WebDAVServlet">

<p>WebDAV, web-based distributed authoring and versioning, is a set
of extensions to the HTTP protocol that is a convenient replacement
for FTP when developing web sites.  Many editing tools can save to a
WebDAV server directly and several operating systems can provide a
filesystem to a WebDAV server.</p>

<p>From <a href="http://www.webdav.org">www.webdav.org</a>:
</p><blockquote>
<b>What is WebDAV?</b><br/>

Briefly: WebDAV stands for "Web-based Distributed Authoring and Versioning".
It is a set of extensions to the HTTP protocol which allows users to
collaboratively edit and manage files on remote web servers.
</blockquote>

<p>The WebDAV site also contains pointers to programs which
understand WebDAV.</p>

<p>The WebDAV servlet must be enabled explicitly.  By default, it also
requires a logged in user playing the 'webdav' role and requires a
secure (SSL) connection.  These can be relaxed, but having
the defaults require security makes it unlikely that a webmaster will
enable WebDAV by mistake.</p>

<deftable-parameters>
<tr><td>enable</td><td>Enable webdav servlet for read ("read") or read/write ("write")</td><td>false (disabled)
</td></tr><tr><td>role</td><td>The role required for webdav, '*' means no role required</td><td>webdav
</td></tr><tr><td>user</td><td>A specific user required for webdav</td><td>none
</td></tr><tr><td>secure</td><td>If true, only allow updates over a secure connection
(SSL)</td><td>true
</td></tr><tr><td>root</td><td>Configures the root directory for webdav</td><td>The application root
</td></tr><tr><td>path-source</td><td>The jndi name of a custom path backing previously defined as a resource.  This allows a custom path backing, e.g. a database source</td><td>an instance of  <a href="javadoc|com.caucho.servlets.webdav.ApplicationPath|"/>

</td></tr></deftable-parameters>


<p>The following example is a typical WebDAV configuration.  The explicit
servlet-mapping and setting <var>enable</var> to 'write' is necessary.  Since
<var>secure</var> is left as the default, it will require an SSL connection.</p>

<example title="Enabling WebDAV">
&lt;servlet&gt;
  &lt;servlet-name&gt;webdav&lt;/servlet-name&gt;
  &lt;servlet-class&gt;com.caucho.servlets.webdav.WebDavServlet&lt;/servlet-class&gt;
  &lt;init&gt;
    &lt;enable&gt;write&lt;/enable&gt;
  &lt;/init&gt;
&lt;/servlet&gt;

&lt;servlet-mapping url-pattern='/webdav/*' servlet-name='webdav'/&gt;

&lt;authenticator&gt;
  &lt;type&gt;com.caucho.server.security.XmlAuthenticator&lt;/type&gt;
  &lt;init&gt;
    &lt;user&gt;Harry Potter:quidditch:webdav&lt;/user&gt;
    &lt;password-digest&gt;none&lt;/password-digest&gt;
  &lt;/init&gt;
&lt;/authenticator&gt;

&lt;login-config&gt;
  &lt;auth-method&gt;basic&lt;/auth-method&gt;
&lt;/login-config&gt;

&lt;security-constraint url-pattern='/webdav/*' role-name='webdav'/&gt;
</example>

<p>The following example is not recommended because it would allow anyone to
update the site:</p>

<example title="WebDAV with no security">
&lt;servlet&gt;
  &lt;servlet-name&gt;webdav&lt;/servlet-name&gt;
  &lt;servlet-class&gt;com.caucho.servlets.webdav.WebDavServlet&lt;/servlet-class&gt;
  &lt;init&gt;
    &lt;enable&gt;write&lt;/enable&gt;
    &lt;secure&gt;false&lt;/secure&gt;
    &lt;role&gt;*&lt;/role&gt;
  &lt;/init&gt;
&lt;/servlet&gt;

&lt;servlet-mapping url-pattern='/webdav/*' servlet-name='webdav'/&gt;
</example>

<p>The WebDAV servlet can point to a different directory by
setting the <var>root</var> parameter.  The path is relative to the
web-app, and allows path variables.  For example, the following would
read and write files from WEB-INF/webdav:</p>

<example title="WebDAV based on WEB-INF/webdav">
&lt;servlet&gt;
  &lt;servlet-name&gt;webdav&lt;/servlet-name&gt;
  &lt;servlet-class&gt;com.caucho.servlets.webdav.WebDavServlet&lt;/servlet-class&gt;
  &lt;init&gt;
    &lt;root&gt;WEB-INF/webdav&lt;/root&gt;
    &lt;enable&gt;write&lt;/enable&gt;
    &lt;role&gt;webdav&lt;/role&gt;
  &lt;/init&gt;
&lt;/servlet&gt;

&lt;servlet-mapping url-pattern='/webdav/*' servlet-name='webdav'/&gt;
</example>

<s2 title="Configuring Windows">

<p>Recent versions of Windows and the Windows Office suite directly
support WebDAV.  WebDAV is configured in "My Network Places".</p>

<p>When browsing "My Network Places" in IE, click on Tools/Map Network
Drive from the menu.  IE will open a dialog.  The dialog contains a
link to "Create a shortcut to Web folder or FTP site".  Clicking on
that will open the "Add Network Place Wizard".</p>

<p>The Add Network Place Wizard will ask for the location of the
WebDAV server.  Type the full URL, e.g. http://www.foo.com/webdav and
complete the dialog.</p>

<p>Adding the WebDAV link will let you save directly to your server.
Windows programs can load and save to the server.  You can also open an
IE window to the mapped folder and use it as a normal folder.</p>

</s2>

<s2 name="customize" title="Custom Path Sources">

<p>The WebDAV servlet can be customized to use a source other than the
default path source.  For example, it would be possible to use WebDAV
with files stored in a database.</p>

<p>There's a <code>&lt;path-source&gt;java:comp/env/my-path&lt;/path-source&gt;
</code> parameter in the WebDavServlet(see <a href="#configure">Configuring the
WebDAV Servlet</a>).  You configure an object with the JNDI name
<code>java:comp/env/my-path</code> using <a config-tag="resource"/> to
configure a custom class that extends <a href="javadoc|com.caucho.servlets.webdav.AbstractPath|"/></p>

<example title="WebDAV with a custom source">
&lt;resource jndi-name='resin/webdav'&gt;
  &lt;type&gt;test.foo.MyDataSource&lt;/type&gt;
  &lt;init&gt;
    &lt;my-foo&gt;bar&lt;/my-foo&gt;
  &lt;/init&gt;
&lt;/resource&gt;

&lt;servlet&gt;
  &lt;servlet-name&gt;webdav&lt;/servlet-name&gt;
  &lt;servlet-class&gt;com.caucho.servlets.webdav.WebDavServlet&lt;/servlet-class&gt;
  &lt;init&gt;
    &lt;enable&gt;write&lt;/enable&gt;
    &lt;path-source&gt;resin/webdav&lt;/path-source&gt;
  &lt;/init&gt;
&lt;/servlet&gt;

&lt;servlet-mapping url-pattern='/webdav/*' servlet-name='webdav'/&gt;
</example>

<p>You can completely customize your WebDav backend, 
linking it to databases or some EJB-based data source or whatever.</p>

</s2>

<s2 title="Configuring the WebDAV servlet to recognize more than one root folder?" type="faq">
 
<p>There's a "root" parameter for the WebDavServlet (see <a href="#configure">Configuring the WebDAV Servlet</a>).  You can
set that and use several separate webdav instances.</p>

<example>
&lt;servlet&gt;
  &lt;servlet-name&gt;webdav1&lt;/servlet-name&gt;
  &lt;servlet-class&gt;com.caucho.servlets.webdav.WebDavServlet&lt;/servlet-class&gt;
  &lt;init&gt;
    &lt;root&gt;/opt/root1&lt;/root&gt;
  &lt;/init&gt;
&lt;/servlet&gt;

&lt;servlet&gt;
  &lt;servlet-name&gt;webdav2&lt;/servlet-name&gt;
  &lt;servlet-class&gt;com.caucho.servlets.webdav.WebDavServlet&lt;/servlet-class&gt;
  &lt;init&gt;
    &lt;root&gt;/opt/root1&lt;/root&gt;
  &lt;/init&gt;
&lt;/servlet&gt;

&lt;servlet-mapping url-pattern='/root1' servlet-name='webdav1'/&gt;
&lt;servlet-mapping url-pattern='/root2' servlet-name='webdav2'/&gt;
</example>
</s2>

<s2 title="Making the root path match a user name?" type="faq">
<p>
What if one wants to make the root user-dependant? i.e. have user "ferg"
have the root in "/somefolder/ferg" and user "jeff" have the root in
"/somefolder/jeff"
</p>

<p>It's possible, but you need to write a bit of code.</p>

<p>As discussed in <a href="#customize">Custom Path Sources</a>, you
can customize the data source by creating your own ApplicationPath.</p>

<p>In this case, you probably want to extend 
<a href="javadoc|com.caucho.servlets.webdav.FilePath|"/> and override the 
getPath method.</p>

</s2>
</s1>

<s1 title="run-at">

<p>The "run-at" capability should now be configured using the
<a href="resources.xtp">&lt;scheduled-task></a> capability.</p>

</s1>

  </body>
</document>
