Short URLs

Last modified by Vincent Massol on 2017/09/06

This tutorial shows you how to tune your XWiki platform by replacing the default URL scheme with a shorter scheme.

A short URL is an URL without the xwiki/bin/view parts.

I. Application name

The /xwiki/ part of the URL is the application name. It identifies the application that should process the request, and it allows a container to host more than one application. To change it you must refer to your container's documentation and find how to map the context path of a web application. For example on Tomcat it's enough to simply deploy the XWiki webapp in the webapps directory, in a sub directory named after the application name you wish to use (e.g. webapps/myappname).

Deploying as ROOT

A special case is when deploying XWiki as the ROOT application, which actually allows the application name part to be empty, so an URL can take the form server.com/bin/view/Space/Document

Achieving this depends on the container, as there's no standard regarding the ROOT application (Refer to your container's documentation for more details).

Some examples:

  • In Tomcat, with the default configuration, all it takes is to deploy the XWiki web application in webapps, in a sub directory named ROOT (i.e. webapps/ROOT).
  • In Jetty, with the default configuration, all it takes is to deploy the XWiki web application in webapps, in a sub directory named root. Note that if you're using the Standalone distribution (which packages Jetty and HSQLDB) then you'll also need to:
    • Remove the existing webapps/root directory which contains a redirect Servlet that automatically redirects root URLs to the xwiki context. You won't need that anymore.
    • Rename the existing webapps/xwiki directory into webapps/root.
    • Remove the jetty/contexts/xwiki.xml file and thus keep only the jetty/contexts/root.xml file. Otherwise you'll get a warning in the console.

In addition, starting with XWiki 6.2.8/6.4.3/7.0 you must tell XWiki that it's deployed as ROOT by setting the xwiki.webapppath to empty in your xwiki.cfg configuration file as in:

xwiki.webapppath=

The reason is that XWiki cannot guess the webapp context from the URL in this case. This seemed to work on previous versions but it was actually leading to errors from time to time, depending on what URL was used when doing the first request on the XWiki instance.

When using the XWiki Debian Package

See Installation using Debian (.DEB) packages.

II. Servlet mapping name

The second part is the hardest part to remove. It identifies the servlet that should process the page, which, for /bin/, is the Struts servlet. Generically speaking, to get rid of /bin/, you need to configure your system so that URLs matching /* are mapped to the Struts Servlet (by default only /bin/* URLs are mapped to the Struts Servlet). 

However you need to be careful that the following prefixes do NOT go through the Struts Servlet (see your web.xml to check their current mappings):

  • /resources/* and /skins/*: Statically served resources. These need to be served directly as static resources.
  • /rest/*: REST resources, served by the XWiki REST Servlet
  • /xmlrpc/*: XML-RPC resources, served by the XWiki XMLRPC Servlet Not part of XE anymore since 7.3
  • /resources/**/*.gwtrpc: GWT-RPC calls, served by the XWiki GWT Servlet
  • /webdav/*: WebDav  calls, served by the XWiki WebDAV Servlet
  • /XWikiService: Another XWiki GWT Servlet
  • /redirect: The XWiki Redirect Servlet used to redirect to the home page when no page is specified in the URL

There are various alternate to achieve this:

You might be tempted to configure just your XWiki's web.xml file but this won't work.

UrlRewriteFilter

This is the simplest solution of all but you'll need XWiki 5.2+ because of this issue that was fixed in XWiki 5.2.

"UrlRewriteFilter" is a framework offering a Servlet Filter allowing to rewrite URLs. 

Install steps:

  1. Download the JAR and put it in WEB-INF/lib
  2. Edit your WEB-INF/web.xml and add the <filter> and filter-mapping definitions as documented
  3. Drop the following content in a file at WEB-INF/urlrewrite.xml:
    <?xml version="1.0" encoding="utf-8"?>
    <!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 4.0//EN"
            "http://www.tuckey.org/res/dtds/urlrewrite4.0.dtd">

    <urlrewrite decode-using="null">

     <rule>
       <note>
         Ensure that URLs ending with .gwtrpc are not modified.
       </note>
       <from>^/(.*)\.gwtrpc$</from>
       <to type="forward" last="true">-</to>
     </rule>

     <rule>
       <note>
          Ensure that URLs that must not be served by the Struts Servlet are not modified.
       </note>
       <from>^/((bin|resources|skins|rest|webdav|xmlrpc|wiki|webjars)/(.*)|robots\.txt)$</from>  
       <to type="forward" last="true">-</to>
     </rule>

     <rule>
       <note>
          For all other URLs we prepend the "/bin/" prefix so that they get routed to the XWiki Action Servlet.
       </note>
       <from>^/(.*)$</from>
       <to type="forward">/bin/$1</to>
     </rule>

     <outbound-rule>
       <note>
          Rewrite outbound URLs to remove the "/bin" part when there are two paths after it.
       </note>
       <from>/bin/(.*)/(.*)$</from>
       <to>/$1/$2</to>
     </outbound-rule>

     <outbound-rule>
       <note>
          Rewrite outbound URLs to remove the "/bin" part when there's a single path after it.
       </note>
       <from>/bin/(.*)$</from>
       <to>/$1</to>
     </outbound-rule>

     <outbound-rule>
       <note>
          Rewrite outbound URLs to remove the "/bin" part it's the last path.
       </note>
       <from>/bin$</from>
       <to>/</to>
     </outbound-rule>

    </urlrewrite>

Note: for debugging of URL Rewrite filter, set the logLevel parameter as described in http://urlrewritefilter.googlecode.com/svn/trunk/src/doc/manual/4.0/index.html#filterparams (using the value sysout:DEBUG, the logs can be read in tomcat logs).

Apache

Strategy:

  • Tell Apache that /skins and /resources URLs  (except for /resources/**/*.gwtrpc ones) are served statically so that they don't go through the Servlet container
  • Configure web.xml so that /* URLs go through the Struts Servlet and so that /resources/**/*.gwtrpc URLs go through the GWT Servlet
  • Tell XWiki to not generate URLs with bin in the path

Configuration steps:

  • Setup the following Apache configuration:
    Alias /skins /usr/local/xwiki/skins
    Alias /resources /usr/local/xwiki/resources

    RewriteEngine on

    RewriteRule     ^/+skins                -                                       [L]
    RewriteCond     %{REQUEST_URI}          !\.gwtrpc$
    RewriteRule     ^/+resources($|/.*)     -                                       [L]

    RewriteRule     .*                      http://localhost:8080%{REQUEST_URI}    [P,L]
    ProxyPassReverse        /               http://localhost:8080/
  • Edit web.xml and add:
    <servlet-mapping>
     <servlet-name>action</servlet-name>
     <url-pattern>/*</url-pattern>
    </servlet-mapping>
  • Edit web.xml and replace the existing mapping:
    <servlet-mapping>
     <servlet-name>gwtrpc</servlet-name>
     <url-pattern>*.gwtrpc</url-pattern>
    </servlet-mapping>

    by

    <servlet-mapping>
     <servlet-name>gwtrpc</servlet-name>
     <url-pattern>/resources/*</url-pattern>
    </servlet-mapping>
  • Add the following in xwiki.cfg (empty value after the equal sign):
    xwiki.defaultservletpath=
  • Only for XWiki 5.2+ Add the following in xwiki.properties (empty value after the equal sign):
    url.standard.getEntityPathPrefix=

There's a regression in XWiki 5.1 that will prevent this to work correctly. To overcome it, we recommend that you upgrade to XWiki 5.2. If you cannot, you could do the following:

III. Struts action name

The third part, /view/, identifies the struts action that should process a request. So this tells what we want to do with the document, /view/ it, /edit/ it or /delete/ it, for example. 

It's possible to configure XWiki to allow omitting this action when you wish to imply view and also to have XWiki generate URLs without the view action. This is achieved by editing xwiki.cfg and setting xwiki.showviewaction=0.

Before XWiki 7.2 and Nested Pages, XWiki was supporting dropping view in the URL without changing the configuration. However this was broken in 7.2 in order to support Nested Pages.

IV. Error Page

At the WEB-INF/web.xml, the location of the 404 error code needs to be changed accordingly. For example:

<error-page>
   <error-code>404</error-code>
   <!--<location>/xwiki/bin/view/Main/DocumentDoesNotExist</location>-->
   <location>/bin/Main/DocumentDoesNotExist</location>
 </error-page>

V. Conclusion

After performing all these changes, you should be able to access documents with URLs like:

  • server.com/Space/Document
  • server.com/Space/ (pointing to Space.WebHome)
  • server.com/Document (pointing to Main.Document)
  • server.com/ will show Main.WebHome, without any redirect.

As a bonus, these changes are backwards compatible, meaning that any currently working URL will also work with these changes performed, so you won't have any broken bookmarks.

Other solutions

Some XWiki users have contributed other solutions but they've not been verified by a XWiki Development Team member at this stage so use at your own risk emoticon_wink

Tags:
Created by Ecaterina Moraru (Valica) on 2017/09/06
   

Get Connected