Wiki source code of Short XWiki URLs

Version 38.1 by Vincent Massol on 2013/09/19

Hide last authors
Manuel Smeria 19.4 1 {{box cssClass="floatinginfobox" title="**Contents**"}}
2 {{toc/}}
3 {{/box}}
Jerome 14.1 4
Manuel Smeria 19.4 5 This tutorial shows you how to tune your XWiki platform by replacing the default URL scheme with a shorter scheme.
Jerome 15.1 6
Jerome 14.1 7 {{info}}
8 A short URL is an URL without the ##xwiki/bin/view## parts.
9 {{/info}}
maalej 2.1 10
Dmitry Bakbardin 20.1 11 = I. Application name =
maalej 1.1 12
Jerome 14.1 13 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##).
maalej 1.1 14
Vincent Massol 26.1 15 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. For example:
16 * 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##).
17 * 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:
18 ** 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.
19 ** Rename the existing ##webapps/xwiki## directory into ##webapps/root##.
20 ** 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.
Vincent Massol 10.2 21
Vincent Massol 26.1 22 Refer to your container's documentation for more details.
23
Dmitry Bakbardin 20.1 24 = II. Servlet mapping name =
maalej 1.1 25
Vincent Massol 29.1 26 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).
maalej 1.1 27
Vincent Massol 35.1 28 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):
Vincent Massol 29.1 29 * ##/resources/*## and ##/skins/*##: Statically served resources. These need to be served directly as static resources.
Vincent Massol 35.1 30 * ##/rest/*##: REST resources, served by the XWiki REST Servlet
31 * ##/xmlrpc/*##: XML-RPC resources, served by the XWiki XMLRPC Servlet
Vincent Massol 35.2 32 * ##/resources/*~*/*.gwtrpc##: GWT-RPC calls, served by the XWiki GWT Servlet
Vincent Massol 35.1 33 * ##/webdav/*##: WebDav calls, served by the XWiki WebDAV Servlet
34 * ##/XWikiService##: Another XWiki GWT Servlet
Vincent Massol 29.1 35 * ##/redirect##: The XWiki Redirect Servlet used to redirect to the home page when no page is specified in the URL
maalej 1.1 36
Vincent Massol 38.1 37 There are various alternate to achieve this:
Dmitry Bakbardin 20.1 38
Vincent Massol 38.1 39 {{toc scope="local"/}}
40
Vincent Massol 37.1 41 {{info}}
42 You might be tempted to configure just your XWiki's ##web.xml## file [[but this won't work>>ShortURLsInvalid]].
43 {{/info}}
44
Vincent Massol 35.1 45 XWiki also generates URL and you can tell it to generate URLs without the ##bin/## part by adding this piece of code in ##xwiki.cfg##: {{code language="none"}}xwiki.defaultservletpath={{/code}} (Note that this is not required with the UrlRewriteFilter solution described below since it rewrites outbound URLs too).
Vincent Massol 29.1 46
47 == UrlRewriteFilter ==
48
Vincent Massol 36.1 49 {{info}}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>>http://jira.xwiki.org/browse/XWIKI-9430]].{{/info}}
Vincent Massol 29.1 50
Vincent Massol 36.1 51 "UrlRewriteFilter" is a [[framework offering a Servlet Filter>>http://www.tuckey.org/urlrewrite/]] allowing to rewrite URLs.
52
53 Install steps:
54 1. [[Download the JAR>>http://www.tuckey.org/urlrewrite/]] and put it in ##WEB-INF/lib##
55 1. Edit your ##WEB-INF/web.xml## and add the ##<filter>## and ##filter-mapping## definitions [[as documented>>http://www.tuckey.org/urlrewrite/]]
56 1. Drop the following content in a file at ##WEB-INF/urlrewrite.xml##:(((
Jerome 14.1 57 {{code language="xml"}}
Vincent Massol 29.1 58 <?xml version="1.0" encoding="utf-8"?>
59 <!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 4.0//EN"
60 "http://www.tuckey.org/res/dtds/urlrewrite4.0.dtd">
61 <urlrewrite>
62
63 <rule>
64 <note>
65 Ensure that URLs ending with .gwtrpc are not modified.
66 </note>
67 <from>^/(.*)\.gwtrpc$</from>
68 <to type="forward" last="true">-</to>
69 </rule>
70
71 <rule>
72 <note>
73 En sure that URLs that must not be served by the Struts Servlet are not modified.
74 </note>
75 <from>^/(bin|resources|skins|rest|webdav|xmlrpc)/(.*)$</from>
76 <to type="forward" last="true">-</to>
77 </rule>
78
79 <rule>
80 <note>
81 For all other URLs we prepend the "/bin/" prefix so that they get routed to the XWiki Action Servlet.
82 </note>
83 <from>^/(.*)$</from>
84 <to type="forward">/bin/$1</to>
85 </rule>
86
Vincent Massol 32.1 87 <outbound-rule>
88 <note>
89 Rewrite outbound URLs to remove the "/bin" part.
90 </note>
91 <from>/bin/(.*)/(.*)$</from>
92 <to>/$1/$2</to>
93 </outbound-rule>
94
Vincent Massol 29.1 95 </urlrewrite>
96 {{/code}}
Vincent Massol 36.1 97 )))
Vincent Massol 29.1 98
99 == web.xml + Apache ==
Jerome 16.1 100
Vincent Massol 29.2 101 Do as above but instead of mapping the Default Servlet, bypass the Servlet container at the web front-end level. For example, if you are using Apache httpd as a front-end, and assuming a webapp deployed as a ROOT webapp and an AJP connection between httpd and the servlet container, the following configuration allows you to serve skin files and static resources directly from httpd:
Sergiu Dumitriu 4.1 102
Jerome 19.1 103 {{code}}
Manuel Smeria 19.4 104 Alias /skins /usr/local/xwiki/skins
105 Alias /resources /usr/local/xwiki/resources
106 ProxyPass /skins/ !
107 ProxyPass /resources/ !
Jerome 19.1 108 {{/code}}
109
Vincent Massol 34.1 110 Note that this solution will not work for the WYSIWYG editor since it needs that the ##.gwtrpc## URLs are directed to the XWiki Servlet. The following Apache configuration using URL rewriting achieves this:
111
112 {{code}}
113 Alias /skins /usr/local/xwiki/skins
114 Alias /resources /usr/local/xwiki/resources
115
116 RewriteEngine on
117
118 RewriteRule ^/+skins - [L]
119 RewriteCond %{REQUEST_URI} !\.gwtrpc$
120 RewriteRule ^/+resources($|/.*) - [L]
121
122 RewriteRule .* http://localhost:8080%{REQUEST_URI} [P,L]
123 ProxyPassReverse / http://localhost:8080/
124 {{/code}}
125
126 {{warning}}Note that while this has been tested to work with XWiki 3.1, it seems it [[doesn't work with 4.5.4 and later>>http://jira.xwiki.org/browse/XWIKI-9455]].{{/warning}}
127
Vincent Massol 29.1 128 == Lighttpd + Jetty ==
Dmitry Bakbardin 20.1 129
Manuel Smeria 19.4 130 I used lighttpd, but I assume it can be done with other webservers too. This is the configuration I used in the lighttpd config (note that my xwiki folder has been moved to ##/usr/share/jetty/webapps/root## (no 'xwiki' at all)):
PaulHarris 12.1 131
Jerome 14.1 132 {{code language="none"}}
PaulHarris 12.1 133 $HTTP["host"] =~ "^www\.domain\.com$" {
134 # ensure all requests for .gwtrpc files go through to java server
135 # we can put this rule first as a higher priority, which java couldn't do
136 $HTTP["url"] =~ "\.gwtrpc$" {
137 proxy.server = ( "" => (( "host" => "127.0.0.1", "port" => 8080 )))
138 }
139 # otherwise, we can handle the static resources
140 else $HTTP["url"] =~ "^/resources/" {
141 alias.url += ( "/resources" => "/usr/share/jetty/webapps/root/resources" )
142 }
143 # otherwise, we can handle the static resources
144 else $HTTP["url"] =~ "^/skins/" {
145 alias.url += ( "/skins" => "/usr/share/jetty/webapps/root/skins" )
146 }
147 # and here is the primary server
148 else $HTTP["host"] =~ "^www\.domain\.com$" {
149 proxy.server = ( "" => (( "host" => "127.0.0.1", "port" => 8080 )))
150 }
151 }
152 # redirect anything.domain.com to www.domain.com
153 else $HTTP["host"] =~ "\.domain\.com$" {
154 url.redirect = ( "^/(.*)" => "http://www.domain.com/$1" )
155 server.name = "www.domain.com"
156 }
157 # redirect domain.com to www.domain.com
158 else $HTTP["host"] =~ "domain\.com$" {
159 url.redirect = ( "^/(.*)" => "http://www.domain.com/$1" )
160 server.name = "www.domain.com"
161 }
Jerome 14.1 162 {{/code}}
PaulHarris 12.1 163
Vincent Massol 29.1 164 So lighttpd will serve any static content unless it has ##.gwtrpc## on the end of the URL.
PaulHarris 12.1 165
Vincent Massol 29.1 166 If you use Nginx as a web-server, just add three more locations and set ##root## to them. By ##try_files## Nginx checks static content presence and if doesn't exist, redirect it to the Tomcat (we expect dynamic content in this case, including all ##*.gwtrpc## requests).
Dmitry Bakbardin 23.1 167
168 {{code}}
169 location /skins/ {
170 root /var/lib/tomcat7/webapps/ROOT;
171 }
172
173 location /resources/ {
174 try_files $uri $uri/ @fallback;
175 root /var/lib/tomcat7/webapps/ROOT;
176 }
177
178 location @fallback {
179 proxy_pass http://localhost:8080;
180 }
181 {{/code}}
182
Dmitry Bakbardin 25.1 183 In the example above XWiki installed as ROOT application in Tomcat. Change path to your XWiki application accordingly.
Dmitry Bakbardin 24.1 184
Vincent Massol 29.1 185 Then in ##web.xml##, I changed the ##gwtrpc## mapping to:
Dmitry Bakbardin 24.1 186
Jerome 14.1 187 {{code language="xml"}}
188 <servlet-mapping>
PaulHarris 12.1 189 <servlet-name>gwtrpc</servlet-name>
190 <url-pattern>/resources/*</url-pattern>
191 <url-pattern>/skins/*</url-pattern>
192 </servlet-mapping>
Jerome 14.1 193 {{/code}}
PaulHarris 12.1 194
Vincent Massol 29.1 195 Since we are using a url-pattern of ##/path/##, it will be specific enough to be a higher priority than the ##/## pattern we'll use next. And since the only thing that will come through via resources or skins will be ##gwtrpc##, then we can be sure it's ok. Note that only ##resources## is required, but I did both anyway.
PaulHarris 12.1 196
Vincent Massol 29.1 197 Now, as described above, add a rule to catch everything else and redirect it to your XWiki servlet:
Jerome 14.1 198
199 {{code language="xml"}}
200 <servlet-mapping>
PaulHarris 12.1 201 <servlet-name>action</servlet-name>
202 <url-pattern>/*</url-pattern>
203 </servlet-mapping>
Jerome 14.1 204 {{/code}}
PaulHarris 12.1 205
Dmitry Bakbardin 20.1 206 = III. Struts action name =
Jerome 14.1 207
Manuel Smeria 19.4 208 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. The XWiki platform allows this part to be missing, considering that the default action is to just display the document, so an URL like ##server.com/bin/Space/Document## will work out of the box.
209
210 Even more, the URL factory, the component that generates URLs, can be configured to skip this part when the action is ##/view/##. To do this write this code in ##xwiki.cfg##: {{code language="none"}}xwiki.showviewaction=0{{/code}}.
211
Dmitry Bakbardin 20.1 212 = IV. Error Page =
Manuel Smeria 19.4 213
Jerome 14.1 214 At the ##WEB-INF/web.xml##, the ##location## of the 404 error code needs to be changed accordingly. For example:
215
216 {{code language="xml"}}
217 <error-page>
mingfai 9.1 218 <error-code>404</error-code>
219 <!--<location>/xwiki/bin/view/Main/DocumentDoesNotExist</location>-->
220 <location>/bin/Main/DocumentDoesNotExist</location>
221 </error-page>
Jerome 14.1 222 {{/code}}
mingfai 9.1 223
Dmitry Bakbardin 20.1 224 = V. Conclusion =
Sergiu Dumitriu 4.1 225
226 After performing all these changes, you should be able to access documents with URLs like:
Jerome 14.1 227
Sergiu Dumitriu 4.1 228 * server.com/Space/Document
229 * server.com/Space/ (pointing to Space.WebHome)
230 * server.com/Document (pointing to Main.Document)
231 * server.com/ will show Main.WebHome, without any redirect.
232
Vincent Massol 5.1 233 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.

Get Connected