Xwiki url rewriter needs bin in url

I’ve gotten the url rewritwer to work (I think) in

But none of the links on the site work without also adding /bin/ to the url. I’m not sure why that is.

See https://beta.folkeverkstedet.com for the site in question.

URL rewriting does not seem to be using with the docker image above.

Going to the /wiki page on https://beta.folkeverkstedet.com leads to a message telling me there’s no page named that. adding bin /bin/ to the front goes to the proper page.

The url rewriter filter seems to be working. Going to 127.0.0.1:8080/rewrite-status shows the rules like the example in the admin guide https://www.xwiki.org/xwiki/bin/view/Documentation/AdminGuide/ShortURLs/

If anyone has any suggestions on what could be wrong, I would be grateful.

Configs:

cat /usr/local/tomcat/webapps/ROOT/WEB-INF/web.xml
<?xml version="1.0" encoding="UTF-8"?>

<!--
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-->

<!-- Notes:
     * metadata-complete="true" is used to disable scanning the web application and its libraries for classes that use
       annotations to define components of a web application (Servlets etc.). Thus leading to a faster startup.
-->
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
  version="3.1"
  metadata-complete="true">

  <filter>
    <filter-name>UrlRewriteFilter</filter-name>
    <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>UrlRewriteFilter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
  </filter-mapping>

  <!-- "absolute-ordering" specifies which web fragment JARs (according to the names in their WEB-INF/web-fragment.xml
       files) have to be scanned for SCIs (javax.servlet.ServletContainerInitializer), fragments and annotations.
       An empty <absolute-ordering/> element configures that none are to be scanned, thus leading to a faster
       startup. -->
  <absolute-ordering />

  <display-name>XWiki</display-name>
  <description>XWiki Application</description>

  <!-- Filter in charge of deciding whether to call the ResourceReferenceHandler Servlet (currently used to handle new
       Resource Types registered as Components) or instead to continue with the rest of the filters and mappings below.
       In the future, the goal is to move more and more Resource handling using the ResourceReferenceHandler Servlet and
       remove the Struts Action Servlet at some point.

       Note: it is important that this filter be the first filter declared (and thus executed). -->
  <filter>
    <filter-name>RoutingFilter</filter-name>
    <filter-class>org.xwiki.resource.servlet.RoutingFilter</filter-class>
  </filter>

  <!-- Filter that sets a custom encoding to all requests, since usually clients don't specify
       the encoding used for submitting the request, so by default containers fall back to the
       encoding globally configured in their settings. This allows XWiki to use a custom encoding,
       without affecting the whole container (and the other applications hosted). -->
  <filter>
    <filter-name>Set Character Encoding</filter-name>
    <filter-class>org.xwiki.container.servlet.filters.internal.SetCharacterEncodingFilter</filter-class>
    <!-- The encoding to use. This must be the same as the one in xwiki.cfg (hopefully only one
         encoding will be used later). -->
    <init-param>
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
    <!-- Whether to ignore and override the encoding specified by the client, when this actually
         happens. For example, AJAX requests made through XmlHttpRequests specify UTF-8. When this
         is set to false, the custom encoding is used only when there wasn't any encoding specified
         by the client. -->
    <init-param>
      <param-name>ignore</param-name>
      <param-value>false</param-value>
    </init-param>
  </filter>

  <!-- A filter that allows requests to be saved and reused later. For example when the current request contains an
       expired authentication token, and the authorization module redirects to the login page, all the information sent
       by the client would be lost; this filter allows to save all that information, and after a successful login,
       injects the saved data in the new request. -->
  <filter>
    <filter-name>RequestRestorer</filter-name>
    <filter-class>org.xwiki.container.servlet.filters.internal.SavedRequestRestorerFilter</filter-class>
  </filter>

  <!-- This filter is used to convert the HTML generated by the WYSIWYG editor to wiki syntax -->
  <filter>
    <filter-name>ConversionFilter</filter-name>
    <filter-class>org.xwiki.wysiwyg.filter.ConversionFilter</filter-class>
  </filter>

  <!-- A filter that dispatches requests to the right action depending on the button pressed in the editing form. This
       is needed when javascript is disabled, since the browser cannot send the form data to different URLs depending on
       the button pressed. -->
  <filter>
    <filter-name>ActionDispatcher</filter-name>
    <filter-class>com.xpn.xwiki.web.ActionFilter</filter-class>
  </filter>

  <!-- This filter is used to initialize the XWiki context before processing a request. -->
  <filter>
    <filter-name>XWikiContextInitializationFilter</filter-name>
    <filter-class>org.xwiki.wysiwyg.filter.XWikiContextInitializationFilter</filter-class>
  </filter>

  <!-- This filter is used to initialize the XWiki context before processing a REST request. -->
  <filter>
    <filter-name>XWikiXmlRpcContextInitializationFilter</filter-name>
    <filter-class>org.xwiki.wysiwyg.filter.XWikiContextInitializationFilter</filter-class>
    <!-- A parameter used to identify the request as a an XML-RPC call -->
    <init-param>
      <param-name>mode</param-name>
      <param-value>2</param-value>
    </init-param>
  </filter>

  <!-- This filter is used to add the 'Content-Type-Script' header to the HTTP response. -->
  <filter>
    <filter-name>Set Content-Script-Type</filter-name>
    <filter-class>org.xwiki.container.servlet.filters.internal.SetHTTPHeaderFilter</filter-class>
    <init-param>
      <param-name>name</param-name>
      <param-value>Content-Script-Type</param-value>
    </init-param>
    <init-param>
      <param-name>value</param-name>
      <param-value>text/javascript</param-value>
    </init-param>
  </filter>
  
  <!-- We need this filter because cross domain request for fonts are not allowed if some headers are not set.
       See https://jira.xwiki.org/browse/XWIKI-11300 for more informations. -->
  <filter>
    <filter-name>Set CORS policy for fonts</filter-name>
    <filter-class>org.xwiki.container.servlet.filters.internal.SetHTTPHeaderFilter</filter-class>
    <init-param>
      <param-name>name</param-name>
      <param-value>Access-Control-Allow-Origin</param-value>
    </init-param>
    <init-param>
      <param-name>value</param-name>
      <param-value>*</param-value>
    </init-param>
  </filter>

  <!-- The Routing Fitler decides how to route all requests and thus must be mapped to handle all incoming requests -->
  <filter-mapping>
    <filter-name>RoutingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

  <!-- The encoding filter MUST always be the first one, as setting the encoding does not work after accessing the
       request data. -->
  <filter-mapping>
    <filter-name>Set Character Encoding</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>INCLUDE</dispatcher>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>ERROR</dispatcher>
  </filter-mapping>

  <filter-mapping>
    <filter-name>RequestRestorer</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>INCLUDE</dispatcher>
    <dispatcher>FORWARD</dispatcher>
  </filter-mapping>

  <filter-mapping>
    <filter-name>ConversionFilter</filter-name>
    <servlet-name>action</servlet-name>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>INCLUDE</dispatcher>
    <dispatcher>FORWARD</dispatcher>
  </filter-mapping>

  <filter-mapping>
    <filter-name>ActionDispatcher</filter-name>
    <servlet-name>action</servlet-name>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>INCLUDE</dispatcher>
    <dispatcher>FORWARD</dispatcher>
  </filter-mapping>

  <!-- TODO: This should be fixed. It's not normal that the REST module depends on the WYSIWYG module.
       "XWikiXmlRpcContextInitializationFilter" points to
       org.xwiki.wysiwyg.filter.XWikiContextInitializationFilter -->
  <filter-mapping>
    <filter-name>XWikiXmlRpcContextInitializationFilter</filter-name>
    <servlet-name>RestletServlet</servlet-name>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>INCLUDE</dispatcher>
    <dispatcher>FORWARD</dispatcher>
  </filter-mapping>

  <filter-mapping>
    <filter-name>Set Content-Script-Type</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  
  <!-- We set the CORS policy globally for webjars.

       TODO: We currently use a <servlet-name> mapping since we've noticed that <url-pattern> ones have no effect.
       The problem is described at http://stackoverflow.com/questions/31142302/getnameddispatcher-forward-and-filters-using-url-pattern
       Right now it means that all URLs handled by a ResourceReferenecHandler<ResourceType> will have this filter
       applied when it should only be applied to "webjars" URLs. We need to find a solution to fix this. It happens
       that at this point in time, only "webjars" URLs are handled using a ResourceReferenecHandler<ResourceType>.
  -->
  <filter-mapping>
    <filter-name>Set CORS policy for fonts</filter-name>
    <servlet-name>resourceReferenceHandler</servlet-name>
    <url-pattern>/webjars/*</url-pattern>
    <url-pattern>*.woff</url-pattern>
    <url-pattern>*.eot</url-pattern>
    <url-pattern>*.ttf</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
  </filter-mapping>

  <!-- Initializes XWiki -->
  <listener>
    <listener-class>org.xwiki.container.servlet.XWikiServletContextListener</listener-class>
  </listener>

  <listener>
    <listener-class>org.xwiki.container.servlet.SetThreadNameServletRequestListener</listener-class>
  </listener>

  <!-- Handles Resource Types registered as Components (e.g. WebJars) -->
  <servlet>
    <servlet-name>resourceReferenceHandler</servlet-name>
    <servlet-class>org.xwiki.resource.servlet.ResourceReferenceHandlerServlet</servlet-class>
  </servlet>

  <servlet>
    <servlet-name>action</servlet-name>
    <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
    <init-param>
      <param-name>application</param-name>
      <param-value>ApplicationResources</param-value>
    </init-param>
    <init-param>
      <param-name>xwiki</param-name>
      <param-value>com.xpn.xwiki.XWiki</param-value>
    </init-param>
    <init-param>
      <param-name>config</param-name>
      <param-value>/WEB-INF/struts-config.xml</param-value>
    </init-param>
    <init-param>
      <param-name>debug</param-name>
      <param-value>2</param-value>
    </init-param>
    <init-param>
      <param-name>detail</param-name>
      <param-value>2</param-value>
    </init-param>
    <init-param>
      <param-name>validate</param-name>
      <param-value>true</param-value>
    </init-param>
    <load-on-startup>2</load-on-startup>
  </servlet>

  <servlet>
    <servlet-name>redirectHomeServlet</servlet-name>
    <servlet-class>com.xpn.xwiki.web.HomePageRedirectServlet</servlet-class>
    <!-- Uncomment and edit this if you want to redirect to a different home page, or if you have different mappings.
         Note: the URL should not start with /, because it allows the context name to be changed. If it starts with /,
         then it should be an absolute URL, including the application context path.
    <init-param>
      <description>The address to redirect to when the client hits the root of the application.</description>
      <param-name>homePage</param-name>
      <param-value>bin/Main/</param-value>
    </init-param>
    -->
  </servlet>

  <!-- RESTful API Restlet servlet -->
  <servlet>
    <servlet-name>RestletServlet</servlet-name>
    <servlet-class>
      org.xwiki.rest.internal.XWikiRestletServlet
    </servlet-class>
  </servlet>

  <!-- RESTful API mapping -->
  <servlet-mapping>
    <servlet-name>RestletServlet</servlet-name>
    <url-pattern>/rest/*</url-pattern>
  </servlet-mapping>

  <servlet-mapping>
    <servlet-name>action</servlet-name>
    <url-pattern>/bin/*</url-pattern>
  </servlet-mapping>

  <servlet-mapping>
    <servlet-name>action</servlet-name>
    <url-pattern>/wiki/*</url-pattern>
  </servlet-mapping>

  <servlet-mapping>
    <servlet-name>action</servlet-name>
    <url-pattern>/testbin/*</url-pattern>
  </servlet-mapping>

  <servlet-mapping>
    <servlet-name>action</servlet-name>
    <url-pattern>/xwiki/*</url-pattern>
  </servlet-mapping>

  <servlet-mapping>
    <servlet-name>redirectHomeServlet</servlet-name>
    <url-pattern>/redirect</url-pattern>
  </servlet-mapping>

  <!-- We override the mime type definition for javascript and css files, as some containers don't
       provide it, causing problems for javascript files containg velocity code, like
       fullscreen.js -->
  <mime-mapping>
    <extension>js</extension>
    <mime-type>text/javascript</mime-type>
  </mime-mapping>
  <mime-mapping>
    <extension>css</extension>
    <mime-type>text/css</mime-type>
  </mime-mapping>

  <!-- In order to properly work, HTML Components MUST have the proper MIME type starting with XP SP2 -->
  <mime-mapping>
    <extension>htc</extension>
    <mime-type>text/x-component</mime-type>
  </mime-mapping>

  <mime-mapping>
    <extension>bmp</extension>
    <mime-type>image/bmp</mime-type>
  </mime-mapping>

  <!-- MS Office mime mappings. We add these to provide out-of-the-box support for downloading Office files as
       attachments. This is for convenience as this is normally a Servlet Container set up but some containers
       do not have these defined by default. For docx/ppt/xlsx this means they will be recognized by IE as zip
       files. See http://littletechthoughts.blogspot.com/2009/01/ie-changes-docx-xlsx-pptx-to-zip-while.html
       for more details. -->
  <mime-mapping>
    <extension>doc</extension>
    <mime-type>application/msword</mime-type>
  </mime-mapping>
  <mime-mapping>
    <extension>xls</extension>
    <mime-type>application/vnd.ms-excel</mime-type>
  </mime-mapping>
  <mime-mapping>
    <extension>ppt</extension>
    <mime-type>application/vnd.ms-powerpoint</mime-type>
  </mime-mapping>
  <mime-mapping>
    <extension>docx</extension>
    <mime-type>application/vnd.openxmlformats-officedocument.wordprocessingml.document</mime-type>
  </mime-mapping>
  <mime-mapping>
    <extension>xlsx</extension>
    <mime-type>application/vnd.openxmlformats-officedocument.spreadsheetml.sheet</mime-type>
  </mime-mapping>
  <mime-mapping>
    <extension>pptx</extension>
    <mime-type>application/vnd.openxmlformats-officedocument.presentationml.presentation</mime-type>
  </mime-mapping>

  <!-- Redirects to the Main.WebHome page if the user calls the root of the webapp, i.e.
       http://server:port/xwiki/
       Note 1: for this to work fine the redirect file needs to exist in the WAR
       Note 2: with Servlet 2.4 it's possible to have a Servlet directly specified in the welcome
               file list but right now we'd like XWiki to work out of the box with Servlet 2.3
  -->
  <welcome-file-list>
    <welcome-file>redirect</welcome-file>
  </welcome-file-list>

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

  <!-- Uncomment if you wish to use a DataSource to define the Database connection
  <resource-ref>
    <description>DB Connection</description>
    <res-ref-name>jdbc/XWikiDS</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
  </resource-ref>
  -->

  <!-- Uncomment if you wish to overwrite the default xwiki.cfg location or bypass the /etc/xwiki/xwiki.cfg step
  <env-entry>
    <env-entry-name>XWikiConfig</env-entry-name>
    <env-entry-type>java.lang.String</env-entry-type>
    <env-entry-value>/WEB-INF/xwiki.cfg</env-entry-value>
  </env-entry>
   -->
</web-app>
cat /usr/local/tomcat/webapps/ROOT/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 that must not be served by the Struts Servlet are not modified.
    </note>
    <from>^/((bin|resources|skins|asyncrenderer|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>