2

Background

I am using Spring Boot 1.4 in a simple Java application. As an experiment, I have decided to write my own servletContainer() bean to inject Tomcat's RewriteValve into the container. This valve is added as global context valve, and should apply to all requests.

I am using Tomcat 8.5.x.

Because the valve expects the configuration to be available inside a WEB-INF folder, I managed to override the startInternal() method of it to let it read the rewrite.config file under a classpath location that is containers/tomcat/rewrite.config.

The valve reads the configuration fine. The rewrite.config file simply states the following rule:

^/app2.+ /app

Meaning, rewrite the url to be /app when the request url begins with /app2.

It's important to note that the app itself is deployed under /app, and not under ROOT. This is handled via the server.context-path property.

What does not work

Since the app is deployed under /app, the valve is never really invoked when /app2 requests are submitted. For instance:

  1. http://localhost:8080/app2 never activates the valve
  2. http://localhost:8080/app/app2 activates the valve

If I remove the context-path and deploy /app under root, this is what I can observe:

  1. http://localhost:8080/app2 activates the valve

What works

Using an external tomcat container, if I manually configure the valve with the same rules, and deploy the app under /app, I can observe:

  1. http://localhost:8080/app2 activates the valve correctly. The url is rewritten to be http://localhost:8080/app

what might I be doing wrong?

Misagh Moayyed
  • 4,154
  • 2
  • 15
  • 25
  • i think snapshots of output will be more appropriate as your localhost is not visible to other machine – bananas Aug 22 '16 at 06:50
  • There is a world of difference using an embedded tomcat and deploying to a standalone tomcat. The embedded tomcat listens *only* to the url on the context-path (so basically the root of the whole server is changed!) whereas a standalone tomcat (without modification) listens to `/` and dispatches to the correct application based on the url. Hence the result of what you describe here is basically more or less as I would expect it to be. You stated you also wrote your own `servletContainer` which basically renderes the default one pretty useless, add your code for more assistance. – M. Deinum Aug 22 '16 at 07:05
  • What you described makes sense. There is nothing in my servletContainer that is worthy to share really. All it does is, it creates a new valve instance, lets is read the config file and adds it the factory as a context valve. Nothing more. – Misagh Moayyed Aug 22 '16 at 07:18
  • You say that you've added it as a context valve, but I think it needs to be configured on the host (or engine) to work as you're expecting. – Andy Wilkinson Aug 22 '16 at 10:50
  • Tried that as well. Made no difference really – Misagh Moayyed Aug 22 '16 at 12:34
  • What I ended up doing was to remove the context path setting altogether and deploy the app at the root. Then I put together rewrite rules to take anything under /app and route it back to root. This is the only solution that has worked so far. – Misagh Moayyed Aug 22 '16 at 12:36

1 Answers1

0

You made an mistake in the regular expression used to describe the rewrite rule

^/app2.+ /app

the ".+" part means any character that occurres one or more times, but there need to be at least one character after the app2 string. I think that you should simply change it to ".*" which implies that there might be a character after the app2, but at the same time we don't expect it to be there:

^/app2.* /app