nginx post method does not work - nginx

I have a problem with nginx to download an excel file using the Http POST method. In fact I am getting a Status Code: 405 Not Allowed.
here is my configuration
upstream backend{
server localhost:9090;
server localhost:9091;
server localhost:9092;
server localhost:9093;
}
server {
listen 8887;
server_name localhost;
location / {
proxy_pass http://backend;
proxy_next_upstream error timeout http_404;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
}
}
how can I solve this problem.
Thank you in advance.

Nginx responds with an HTTP 405 for POST requests that try to access a static asset.
From the Nginx release docs from a few years back:
*) Feature: now Nginx returns the 405 status code for POST method
requesting a static file only if the file exists.
A way to go around it would be to add this line, which changes the response code and sends you to the requested URI:
error_page 405 =200 $uri;
You can find other solutions here:
http://invalidlogic.com/2011/04/12/serving-static-content-via-post-from-nginx/
I hope this helps.

Related

Nginx: How to custom error page depends on presence of custom http header

we are using nginx as reverse http proxy before tomcat. Our app can return different HTTP status codes (400, 401, 404, 403) depends on requests. Every response from our app return custom HTTP header, let's say X-Custom which is used to determine if app is working and serving the request.
Our goal on nginx side is to serve custom error pages generated by our app to the client in case when custom HTTP header X-Custom is present and otherwise (if X-Custom is not present) serve our custom static page from nginx.
The problem is, I am not able to find out working solution even I tried almost everything. I am sure that I am missing something obvious.
Nginx configuration looks like:
location / {
proxy_set_header X-Forwarded-Port 80;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_intercept_errors on;
proxy_pass http://172.16.0.32:8080;
if ($is_x_custom_not_ok = "No") {
error_page 400 401 404 403 500 502 503 /503.html;
}
}
map $upstream_http_x_custom $is_x_custom_not_ok {
default "No";
~. "Yes";
}
location /503.html {
root /var/www/;
internal;
}
This is causing that even if header X-Custom is present and app return HTTP 400, static 503.html is shown. 503.html should be loaded only in case when X-Custom is not present in response.
Thanks
So, after endless hours I figured out that this is not going to work. The reason is, that the map and if blocks are executed before passing the upstream (proxy), so map and neither if does not have the x-custom content when they are executed.
So, my solution is to use Nginx OpenResty Lua to examine my custom header and make a decision on what error page to display.

Nginx ProxyPassReverse setup

I have a task to connect a jitsi server with my existing domain. The jitsi server should be running in a subpath like https://dev.example.com/video.
I have installed jitsi in aws with hostname https://dev.example.com.
For this to work I have to set up an nginx block that will remove /video while sending a request to the jitsi server and add /video on the responses.
The plan was to add an upstream in my nginx as follows.
upstream jitsi {
server 10.10.10.20:443;
}
location /video/ {
rewrite ^/video/(.*) /$1 break;
proxy_pass https://jitsi/$uri$is_args$args;
proxy_set_header X-Forwarded-Host $host:$server_port;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_redirect https://dev.example.com/ https://dev.example.com/video/;
}
The rewrite will strip away the /video and the rest is supposed to add it on the response. But when loading the page, browser is showing 404 for some of the internal links.
eg:
https://dev.example.com/libs/do_external_connect.min.js?v=1
[HTTP/1.1 404 Not Found 124ms]
https://dev.example.com/libs/lib-jitsi-meet.min.js?v=4466
[HTTP/1.1 404 Not Found 123ms]
https://dev.example.com/libs/app.bundle.min.js?v=4466
[HTTP/1.1 404 Not Found 123ms]
https://dev.example.com/static/pwa/registrator.js
I could clearly see that the last part which is supposed to add /video into the URL is not working correctly.
What am I doing wrong here?
Thanks in advance

Nginx Bad Gateway 502 when accessing istio-envoy deployed on kubernetes

My web application is running on One Server and two worker nodes
my nginx config file is
server {
listen ip-address:80 ;
server_name subdomain.domain.com;
server_name www.subdomain.domain.com;
server_name ipv4.subdomain.domain.com;
location / {
proxy_pass http://ip-address:32038/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
fastcgi_read_timeout 3000;
}
}
server {
listen ip-address:443 ssl http2;
server_name subdomain.domain.com;
server_name www.subdomain.domain.com;
server_name ipv4.subdomain.domain.com;
ssl_certificate /opt/psa/var/certificates/scf83NyxP;
ssl_certificate_key /opt/psa/var/certificates/scf83NyxP;
ssl_client_certificate /opt/psa/var/certificates/scfrr8L8y;
proxy_read_timeout 60;
location / {
proxy_pass https://ip-address:30588/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
my website on http://subdomain.mydomain.com is running fine . but when i use https://subdomain.mydomain.com it displays bad gateway error page server by nginx
through ssh when i run following command everything works fine
For http
curl -v -HHost:subdomain.mydomain.com http://ip-address:32038
curl -v subdomain.mydomain.com
For https
curl -v -HHost:subdomain.mydomain.com https://subdomain.mydomain.com:30588
From server node SSH
curl -v -HHost:subdomain.mydomain.com --resolve subdomain.mydomain.com:30588:ip-address --cacert /opt/psa/var/certificates/scf83NyxP https://subdomain.mydomain.com:30588
Any help will be really appreciated.
Thanks
Without knowing anything about the backend service, I would guess that perhaps it is not equiped for HTTPS. You may simply need to change this line...
proxy_pass https://ip-address:30588/;
to...
proxy_pass http://ip-address:30588/;
If the backend service does in-fact need to be called by https (unusual), then we would need to see how that service in configured, as the nginx error suggests that it is not correctly processing the SSL connection.
502 Bad Gateway in Nginx commonly occurs when Nginx runs as a reverse proxy, and is unable to connect to backend services. This can be due to service crashes, network errors, configuration issues, and more. How do we pinpoint the issue? We need to look at what is returning an invalid response to nginx.
Assuming nginx errored because of configuration issues ---
I have run into a 502 Bad Gateway - nginx simply because I had inconsistencies with white space on my config file.
Probably the result of copy/pasting your config file code here, but there are spacing inconsistencies that could trigger a parsing fail for the file.
i.e. My 502 bad gateway - nginx error was solved by deleting a space that I had accidentally added in front of a line in the config file.

Getting 505 HTTP Version Not Supported on HTTPS but not on HTTP

I am trying to call a GET api with a parameter which has space in it:
https://abc.xyz/search/web/buildings/search/v2/city/new%20york
The endpoint hits load balancer (nginx) which redirects the request to a suitable machine.
In the response, I get 505 HTTP Version Not Supported error. But when I make the same request to the load balancer using HTTP (using internal IP), it returns the response successfully.
Here are the relevant access logs of both cases:
access log of nginx when called via http
"GET /search/web/buildings/search/v2/city/r%20c HTTP/1.1" S=200 487 T=0.005 R=- 10.140.15.199
access log of the machine when called via http
"GET /search/search/web/buildings/search/v2/city/r%20c HTTP/1.0" 200 36
The above request works fine. but when we request through https, the request in machine comes differently (it should have been d%20a instead of d a)
access log of nginx when called via https
"GET /search/web/buildings/search/v2/city/d%20a HTTP/1.1" S=505 168 T=0.001 R=- 35.200.191.89
access log of the machine when called via https
"GET /search/search/web/buildings/search/v2/city/d a HTTP/1.0" 505 -
Here is the relevant nginx configuration:
upstream searchtomcat {
least_conn;
server search-1:8080;
server search-2:8080;
}
server {
#listen 443 ssl http2;
listen 443;
client_max_body_size 100M;
...
location ~* ^/search/(.*)$ {
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://searchtomcat/search/search/$1;
proxy_read_timeout 900;
}
}
There is nothing in error.log.
What could be the possible reason because of which the machine is getting request in a different manner?
The whole issue.is happening because of the space that is coming in your URL that is being sent over to tomcat. Because of it, a is being interpreted as the HTTP version code and not HTTP/1.0. Solving the extra space issue will solve the problem.
Using rewrite in location{} block should solve the problem.
location /search/ {
rewrite ^/search(/.*) /search/search$1 break;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://searchtomcat;
proxy_read_timeout 900;
}
Also, you have different configurations for http and https servers, have a look at the http one. That one seems to be correct.
I was getting 505s when trying to set up port forwarding on nginx.
For me the solution was to add this line to my location block containing the the proxy_pass directive:
proxy_http_version 1.1;
Closest to the doco I can find on the topic is here

nginx http auth request module will only return default error pages

I am using nginx as a single point of entry to my entire solution.
my goal is to send some url to be authenticated before continuing.
I have found a module named: ngx_http_auth_request_module which suits right in place to solve my problem.
http://nginx.org/en/docs/http/ngx_http_auth_request_module.html
i am compiling my nginx like this: ./configure --with-http_auth_request_module
my code looks like this:
http {
server {
listen 8080 default_server;
server_name _;
location /api {
auth_request /auth;
proxy_pass http://localhost:8000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
location = /auth {
proxy_pass http://localhost:8000/auth/user;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-Original-URI $request_uri;
}
}
}
my problem is that if my server returns and error, like 401, then a default page gets shown. what i want is to be able to return the json that was returned from my authentication service. this is useless without this. what is the point of showing just a generic 401 page? i want to return my proxied json response.
please help.
auth_request is just for authentication. This little hack should work for you
error_page 401 /auth;
After auth error it'll go to /auth location again, this time as ordinary request.

Resources