How To Reject Requests With Too Long Urls In NGINX (HTTP 414)

by Oliver 26. November 2015 12:28

There are lots of posts out there on the topic of fixing the Request-URI Too Large error in NGINX, but this post is about how to generate such a response in order to avoid proxying requests with too long urls to a backend server.

The Problem

We recently had some really long request URLs coming through NGINX, with over 2000 characters! Those requests triggered an error response on our IIS hosted ASP.NET application – at first, on one backend server, then on the second one. This lead NGINX to believe that currently no backend servers are available for processing request which resulted in requests being dropped. Ouch!

Hence, our motivation to avoid passing requests with too long urls down to our backend/upstream servers.

Some Background

Since we don't have any URLs in our application whose path segment exceed the default limit of 260 characters, there is no need to change the respective maxUrlLength attribute on the <httpRuntime> element. There's also a default value of 2048 characters for the length of the query string, defined in the maxQueryStringLength attribute, that might be of interest.

So I set out to tell NGINX to drop requests with path segments longer than 260 chars or query strings longer than 2048 chars.

The Solution

We'll be looking at the $request_filename and $query_string variables and verify their length is less than or equal to the limits implemented in our application server.

At first, I tried to find a way to return the length of these variables' values but I couldn't find any way to that inside the NGINX configuration file.

So I was left with testing those variables against some value or… a regular expression.

That's right, a regular expression will tell us if our variables exceed our length limits:

if ( $request_filename ~* "^.{261,}$" ) {
    return 414;
}

if ( $query_string ~* "^.{2049,}$" ) {
    return 414;
}

We use the regex quantifier {n,} to match n or more occurrences of the previous expression, which in our case is a . (dot) meaning any character.

Roundup

We've put these two if directives at the server level of our configuration. We now successfully avoid to pass requests with too long urls to our application servers.

enjoyed the post?

Tags:

NGINX

Comments are closed

About Oliver

shades-of-orange.com code blog logo I build web applications using ASP.NET and have a passion for javascript. Enjoy MVC 4 and Orchard CMS, and I do TDD whenever I can. I like clean code. Love to spend time with my wife and our children. My profile on Stack Exchange, a network of free, community-driven Q&A sites

About Anton

shades-of-orange.com code blog logo I'm a software developer at teamaton. I code in C# and work with MVC, Orchard, SpecFlow, Coypu and NHibernate. I enjoy beach volleyball, board games and Coke.