URL Rewriting

1. Rationale

Traditionally, Web applications developers generate URLs in their Web pages manually. For example, an HTML <a> element contains an href attribute specifying the destination of a link. The default PresentationServer Page Flow Controller epilogue contains a URL rewriting mechanism for HTML and XHTML documents.

1.1 Servlets

Absolute URLs (starting with a scheme such as http:) are usually reserved to refer to external sites or applications. When referring to the current application, relative URLs, in the form of relative paths or absolute paths, are commonly used. Developers must make sure that the URL interpreted by the Web browser and the application server refers to the correct page or resource:

  • Relative paths: such paths are interpreted by the Web browser as relative to a URL base, usually the URL of the page being requested, unless specified differently. For example, if a browser requests /oxf/example1/page1:

    Relative Path Resulting Absolute Path
    page2 /oxf/example1/page2
    ../page3 /oxf/page3
    ../example2/page4 /oxf/example2/page4

    Using relative paths raises the issue that if a page is moved, all the links within that page have to be changed.

  • Absolute paths: such paths start with a "/". The developer can generate the same paths as above by directly writing the resulting absolute paths. The issue with this solution is that it is necessary to write the exact absolute path, often including a J2EE Web applications context path such as /oxf. Hardcoding the context path in every URL makes it impossible to change the application context without changing all the URLs in the application. To alleviate this issue, developers often use relative URLs, with the problem mentioned above.

1.2 Portlets

The issue is even more important with Java Portlets (JSR-168), as URLs must be generated by calling a specific Java API. With page template languages such as JSP, this is done using tag libraries. All the pages in an application must be modified when moved from a deployment as a Servlet to a deployment as a Portlet.

A solution to the issues mentioned above is to post-process all URLs to make the developer's life easier.

2. Default URL Rewriting

This section describes the default URL rewriting implementation in Presentation Server. It is implemented in a pipeline called oxf:/oxf/pfc/oxf-rewrite.xsl bundled within orbeon.jar. It is referred to by the default epilogue under oxf:/config/epilogue.xpl, the default error page under oxf:/config/error.xpl, as well as the JSF epilogue example under oxf:/jsf/config/epilogue.xpl.

2.1 What is Rewritten?

The form, a, link, img, and input elements are rewritten. In addition, their XHTML counterparts in the http://www.w3.org/1999/xhtml namespace are also rewritten. URLs can be parsed by the rewriting algorithm, so developers have to make sure that they are well-formed. Absolute URLs (with a scheme) are left unmodified. The special case of URLs starting with a query string (e.g. ?name=value) is handled. This last syntax is supported by most Web browsers and because of its convenience, it is supported by the default rewriting algorithm as well.

2.2 Servlets

Element / Attribute Action
form/@action If the URL is a relative path, it is left unchanged. If the URL is an absolute path, the context path is pre-pended. Absolute URLs are left unchanged.
a/@href
link/@href
img/@src
input[@type='image']/@src
script/@src

2.3 Portlets

Element / Attribute Action
form/@action Rewritten to an action URL using the Portlet API method RenderResponse.createActionURL(). The resulting URL results in an action URL targeting the current portlet. Absolute URLs are left unchanged.
form/@method If no form/@method is supplied, an HTTP POST is forced, because the Portlet specification recommends submitting forms with POST. If a method is supplied, the method is left unchanged.
a/@href Rewritten to a render URL using the Portlet API method RenderResponse.createRenderURL(). The resulting URL results in a render URL targeting the current portlet. Absolute URLs are left unchanged.
img/@src Rewritten to a resource URL encoding. The resulting URL points to a resource within your Web application. Absolute URLs are left unchanged.
input[@type='image']/@src
script/@src
link/@href
script and SCRIPT In text within those elements or their XHTML counterparts in the http://www.w3.org/1999/xhtml namespace, occurrences of the string wsrp_rewrite_ are replaced with the Portlet namespace as obtained by the Portlet API method RenderResponse.encodeNamespace(null).

3. Working with URL Rewriting

In PresentationServer, URLs come from two different sources:

  • Within XSLT templates, for example single pages or a theme stylesheet. This is the case for most URLs, including links to resources (images, CSS stylesheets, JavaScript files, etc.), links to other pages, etc.
  • Within an XForms' submission-info element, to specify the action to be called when a form is submitted.

In both cases, URLs are subject to the following sections.

3.1 Servlets

URLs can be written as relative paths as usual, but they can also be written as absolute paths without concerns about the context path. For example:

Initial Path Resulting Path
/example1/page2 /oxf/example1/page2
/page3 /oxf/page3
/example2/page4 /oxf/example2/page4

3.2 Portlets

With Portlets, the benefit is even greater. Write your URLs as you would in a regular Servlet-based application, and the rewriting pipeline takes care of calling the Portlet API to encode the URLs. Since portlets do not have the concept of path, URL paths are encoded as a special parameter named oxf.path. Relative paths are resolved against the current path. The following table illustrates action URL and render URL rewriting:

Initial Path Resulting Portlet Parameters
/example1/page1?name1=value1&name2=value2
  • oxf.path=/example1/page1
  • name1=value1
  • name2=value2
?name1=value1&name2=value2
  • name1=value1
  • name2=value2
Assuming the current value of oxf.path is /example1/page1:

../example2/page2?name1=value1&name2=value2
  • oxf.path=/example2/page2
  • name1=value1
  • name2=value2

The following table illustrates resource URL rewriting:

Initial Path Resulting Path
/path/to/my/image.gif?scale=100 /oxf/path/to/my/image.gif?scale=100
Assuming the current value of oxf.path is /example1/page1:

my/image.gif?scale=100
/oxf/example1/my/image.gif?scale=100

Note that using resource URLs relative to an PresentationServer Portlet path (as handled by PresentationServer) does not necessarily make sense unless you define your hierarchy of resources carefully.

4. Customizing URL Rewriting

There are multiple reasons why the default PresentationServer URL rewriting may need to be modified, including:

  • Supporting markup languages other than HTML and XHTML
  • Gaining more control over action URLs and render URLs in Portlets. The current schema considers that only HTML and XHTML form elements generate actions. Modifying the default behavior allows you to enable some or all hyperlinks to generate actions URLs.

To implement your own URL Rewriting, you can either:

  • Modify your Page Flow Controller epilogue to no longer point to the default oxf-rewrite.xpl and implement your own rewriting algorithm, either directly in the epilogue or in a stylesheet, pipeline or processor pointed to by your epilogue.
  • Use oxf-rewrite.xsl as a starting point. To do this, extract oxf-rewrite.xsl from orbeon.jar and make a local copy in your resource directory. Make sure your epilogue points to your version of the rewriting pipeline. Modify your copy according to your needs.

5. Known Limitations

5.1 Portlets

  • The input document should not contain:
    • Elements and attribute containing the string wsrp_rewrite
    • Namespace URIs containing the string wsrp_rewrite
    • Processing instructions containing the string wsrp_rewrite
  • It is not possible to specify:
    • A destination portlet mode
    • A destination window state
    • A secure URL