Coyoterequest

admin

Read querystring on URL. Related Posts: Resolved Spring Dispatcher Servlet Cannot Be Regarding formal parameters and actual parameters, Can request be used in servlet to Get servletcontext?

2015-12-21

There some cases when you would like to map different URI encodings on different HTTP endpoints. And one of those cases is when your application handles GET requests containing percent-encoded non-ASCII data in different charsets. For example, one HTTP endpoint uses standard UTF-8 while the other uses Windows-1251.

Plain Tomcat way

According to How do I change how GET parameters are interpreted? the only way to specify GET request encoding is to use by-connector URIEncoding attribute. For example:

Legacy tool for word on a mac. Then you have map servlets to different connectors somehow.

Spring Boot multiple HTTP connectors way

Spring Boot can help you out in this matter. Although it uses the only one URI encoding which is specified in server.tomcat.uri-encoding parameter (“UTF-8” by default, see Appendix A. Common application properties), it can fire up multiple child applications residing on different ports.

Implementation is really simple as you can see from Spring Boot Connectors application.

Pros:

  • no hacks and workarounds, pure Spring Boot solution :)
  • controller unit tests are passed.

Cons:

  • some mess with controllers mappings;
  • integration tests (with full context initialization) are failed on non-ASCII requests; in fact, you have no option to point which connector are used in test;
  • say bye-bye to Spring Boot actuators, you’ll have to use some workarounds to plug them in.

Links:

Nginx+Lua way

Nginx being built with Lua module becomes a very fast non-blocking application server. They even have a framework! So the URI re-encode it’s a quite an easy task to solve.

It’s a more complicated way, but if you already use Nginx as a reverse proxy server / balancer / HTTPS terminator in front of or Java application — why not?

Coyote

Nginx build options, functions and configuration file example can be found in docker-nginx project. Function to convert encoding:

It converts only URI parameter values and leaves parameter names untouched. Converting is performed by iconv C library with help of Lua-iconv binding, so it’s very fast.

This Nginx config block configures Lua module, load convert function and initializes iconv:

In order to re-encode URIs before proxying to Java backend use the following sample:

Coyote Request Java

Pros:

  • no multiple connectors, listen on single port;
  • extremely fast, no performance drawback;
  • all tests are passed.

Cons:

  • extra devops work :)

Links:

Java hackish way

The idea is the same — url-decode GET-request values, convert to proper encoding and url-encode. At this time it’s achieved by using private API of org.apache.coyote.Request class to decode query string conditionally.

Implementation is quite simple as you can see from Spring Boot Filters application.

URIs are re-encoded in servlet filter:

Pros:

  • no multiple connectors, listen on single port;
  • no recompiled Nginx stuff - just Java;
  • controller unit tests are passed;
  • integration tests are passed.

Cons:

  • reflection and private API usage :)
  • query string could be handled twice.

Links:

The other way

Coyoterequest

Use the microservices, Luke! But for their simplicity and scalability you have pay with massive infrastructure changes. See the following articles for consideration:

Coyote Request

Tags: Please enable JavaScript to view the comments powered by Disqus.comments powered by Disqus
Hello,
I try to get the following to work (Apache Tomcat/5.5.9 as ServletContainer within JBoss 4.x):
I have a servlet inside a web application which is protected by Basic Authentication. The problem is that I have some clients which cannot do the challenge response basic authentication needs. They are identified via the hardware serial number of their device which is submitted in the request.
So I want to do a lookup in an own database table containing a mapping from the hardware serial number to the user's username and password and then add the basic authentication authorization header before tomcat/JBoss does the authorization.
I developed a simple valve to test:
public class PenFrameworkAuthenticationValve extends ValveBase {
public void invoke(Request request, Response response) throws IOException, ServletException {
Log log = container.getLogger();
log.info(this.getClass().getName() + ' called.');
request.addHeader('Authorization', 'Basic am9jaGVuYjpqb2NoZW5i');
this.getNext().invoke(request, response);
log.info(this.getClass().getName() + ' finished.');
}
}
But the problem is, that this valve is called after the basic authentication took place (exactly as it happens if I try to use a servlet filter).
Is there another possibility to achieve what I want using JBoss or Tomcat functionality?
Kind regards
Jochen
---------------------------------------------------------------------
To start a new topic, e-mail: [hidden email]
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]