Hello,
I’m puzzled by a problem we’ve been getting with URLs like this:
/webserviceakqa-geraldoflanagan_ais_JEzKjKps%2B0%2FAynL0G17OWg?line=cMyYNDWTMJCOFAMGPMHE
nginx (version 0.6.35) is returning a Bad Request error, response code
400. The problem seems to be in the URL encoding of the string after the
‘ais’ part - when there are no escaped characters (such as %2B), no
error is returned. If it is a deliberate feature, is there some way I
can bypass it?
JM
On Tue, Nov 03, 2009 at 08:07:25PM +0000, John M. wrote:
error is returned. If it is a deliberate feature, is there some way I
can bypass it?
In my tests 0.5.36, 0.6.39, 0.7.63, 0.8.22 try to open
“/path/to/webserviceakqa-geraldoflanagan_ais_JEzKjKps+0/AynL0G17OWg”
and return 404. You may try to set error_log to info level to see 400
error
reason.
Igor S. wrote:
nginx (version 0.6.35) is returning a Bad Request error, response code
Thanks, Igor. It may just be to do with copying and pasting to the
mailing list, but your URL is actually different - the problem section
is not URL encoded (‘JEzKjKps+0/AynL0G17OWg’ instead of
‘JEzKjKps%2B0%2FAynL0G17OWg’). It appears to be the URL encoding which
is actually causing the problem.
I’ll try setting the log as you suggest.
JM
On Tue, Nov 03, 2009 at 09:44:17PM +0000, John M. wrote:
reason.
Thanks, Igor. It may just be to do with copying and pasting to the
mailing list, but your URL is actually different - the problem section
is not URL encoded (‘JEzKjKps+0/AynL0G17OWg’ instead of
‘JEzKjKps%2B0%2FAynL0G17OWg’). It appears to be the URL encoding which
is actually causing the problem.
I tested escaped URL “…s%2B0%2FA…”, nginx unescaped it and tried to
open the file.
On Tue, Nov 03, 2009 at 09:57:16PM +0000, John M. wrote:
Igor S. wrote:
You may try to set error_log to info level to see 400 error
reason.
Having tried this, nothing gets written to the error log when the 400
error is returned.
Is this URL is proxied ? What signature do you see in 400 message ?
Igor S. wrote:
You may try to set error_log to info level to see 400 error
reason.
Having tried this, nothing gets written to the error log when the 400
error is returned.
JM
Igor S. wrote:
Having tried this, nothing gets written to the error log when the 400
error is returned.
Is this URL is proxied ? What signature do you see in 400 message ?
Igor, really sorry to have wasted your time. The problem turns out not
to be in nginx at all. Yes, nginx is acting as a reverse proxy, in front
of Tomcat, and it is evidently Tomcat which is returning the 400 error.
The reason I didn’t spot this is that there is no sign of this request
at all in the Tomcat logs, it’s as if the request never got there. The
only way I could tell was by the fact that there was a specific response
header which could only have come from Tomcat.
So, that brings me on to another question. Can I use nginx to correct
the URL, so that Tomcat doesn’t choke on it? That is, can I use some
rewrite trickery to URL decode part of the URL, so that
_ais_JEzKjKps%2B0%2FAynL0G17OWg?
becomes
_ais_JEzKjKps+0/AynL0G17OWg?
JM
On Wed, Nov 04, 2009 at 09:43:14AM +0000, John M. wrote:
of Tomcat, and it is evidently Tomcat which is returning the 400 error.
becomes
_ais_JEzKjKps+0/AynL0G17OWg?
If you set
location / {
proxy_pass http://tomcat;
}
then nginx passes a unchanged original client request, however, if you
set
location / {
proxy_pass http://tomcat/;
}
then nginx passes unescaped and then escaped again request,
So “+” and “/” will be unescaped in this case.
Igor S. wrote:
proxy_pass http://tomcat/;
}
then nginx passes unescaped and then escaped again request,
So “+” and “/” will be unescaped in this case.
Thanks. I’m using the upstream module, so what I had was this:
proxy_pass http://backend;
I changed it to
proxy_pass http://backend/;
The result was this:
Starting nginx: 2009/11/04 11:12:12 [emerg] 2272#0: “proxy_pass” may not
have URI part in location given by regular expression, or inside named
location, or inside the “if” statement, or inside the “limit_except”
block in /etc/nginx/proxy.conf:1
What have I done wrong?
On Wed, Nov 04, 2009 at 10:16:14AM +0000, John M. wrote:
location / {
proxy_pass http://backend;
block in /etc/nginx/proxy.conf:1
What have I done wrong?
Probably, you set proxy_pass inside “if” block. Could you should this
configuration part ? I think it can be rewritten without “if”.
Igor S. wrote:
Probably, you set proxy_pass inside “if” block. Could you should this
configuration part ? I think it can be rewritten without “if”.
No, it’s not inside an if block. Basically this is how it’s configured:
In nginx.conf:
location / {
include /etc/nginx/proxy.conf;
}
proxy.conf:
proxy_pass http://backend;
proxy_pass_header Server;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header Original-Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Original-Scheme $scheme;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
This works fine. When I append the / to http://backend, I get the error
on starting.
Igor S. wrote:
Is this file included only once ?
I have two server blocks in my nginx.conf, one for HTTP and one for
HTTPS, and it’s included in the location /{} block in each.
JM
On Wed, Nov 04, 2009 at 10:45:24AM +0000, John M. wrote:
proxy_set_header Host $host;
proxy_read_timeout 90;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
This works fine. When I append the / to http://backend, I get the error
on starting.
Is this file included only once ?
On Wed, Nov 04, 2009 at 11:43:55AM +0000, John M. wrote:
Igor S. wrote:
Is this file included only once ?
I have two server blocks in my nginx.conf, one for HTTP and one for
HTTPS, and it’s included in the location /{} block in each.
I will look.
As quick workaround try to move proxy_pass to the locations from the
file.
This allows to look whether “proxy_pass …/” fixes issue with Tomcat.
Igor S. wrote:
I will look.
As quick workaround try to move proxy_pass to the locations from the file.
This allows to look whether “proxy_pass …/” fixes issue with Tomcat.
Do you mean not to use the include, but to use the text itself?
JM
Igor S. wrote:
As quick workaround try to move proxy_pass to the locations from the file.
This allows to look whether “proxy_pass …/” fixes issue with Tomcat.
Yes, moving the whole proxy section into the location block instead of
including the separate file seems to have solved the problem. Thanks so
much for this!
JM
On Wed, Nov 04, 2009 at 12:25:21PM +0000, John M. wrote:
Igor S. wrote:
As quick workaround try to move proxy_pass to the locations from the file.
This allows to look whether “proxy_pass …/” fixes issue with Tomcat.
Yes, moving the whole proxy section into the location block instead of
including the separate file seems to have solved the problem. Thanks so
much for this!
Have this resolved Tomcat issue ? It’s really strange that Tomcat does
not
support the encoded URL.
Igor S. wrote:
Have this resolved Tomcat issue ? It’s really strange that Tomcat does not
support the encoded URL.
It seems to have done, yes. It’s had a slight side-effect, though, in
that I’m now getting a 404 error from nginx on a particular page, which
it should be proxying. How would the addition of the forward slash to
http://backend cause this, and what do I need to do to compensate?
JM
On Wed, Nov 04, 2009 at 01:08:44PM +0000, John M. wrote:
http://backend cause this, and what do I need to do to compensate?
It should not. Do you see nginx signature on the 404 error page ?
On Wed, Nov 04, 2009 at 12:14:48PM +0000, John M. wrote:
HTTPS, and it’s included in the location /{} block in each.
I will look.
As quick workaround try to move proxy_pass to the locations from the file.
This allows to look whether “proxy_pass …/” fixes issue with Tomcat.
Do you mean not to use the include, but to use the text itself?
Yes, however, only single line of proxy_pass is enough.