Tengo una configuración de puerta de enlace nginx api similar a la que se veaquí. La aplicación se ofrece en "www.foo.com/bar/app/", pero también nos gustaría que los usuarios pudieran visitar el sitio web sin incluir la barra diagonal.
Actualmente, cuando visito la URL sin la barra diagonal, el servidor arroja un error 500. Profundizar en los registros muestra lo siguiente:
2021/01/05 22:43:39 [notice] 22#22: *4 rewritten data: "/", args: "", client: 172.29.0.1, server: , request: "GET /bar/app HTTP/1.1", host: "localhost:8080"
2021/01/05 22:43:39 [error] 22#22: *4 open() "/etc/nginx/html/nap/js/compiled/app.js" failed (2: No such file or directory), client: 172.29.0.1, server: , request: "GET /bar/js/compiled/app.js HTTP/1.1", host: "localhost:8080", referrer: "http://localhost:8080/bar/app"
Mientras que el registro muestra la siguiente secuencia cuando la URL tiene una barra diagonal:
2021/01/05 22:33:55 [notice] 22#22: *1 rewritten data: "//", args: "", client: 172.29.0.1, server: , request: "GET /bar/app/ HTTP/1.1", host: "localhost:8080"
2021/01/05 22:33:55 [notice] 22#22: *1 "^/bar/app(.*)$" matches "/bar/app/js/compiled/app.js", client: 172.29.0.1, server: , request: "GET /bar/app/js/compiled/app.js HTTP/1.1", host: "localhost:8080", referrer: "http://localhost:8080/bar/app/"
La definición de API + política actualmente:
location /bar/app {
set $upstream bar_frontend_app_main;
rewrite ^/bar/app(.*)$ /_bar_frontend_app_service$1 last;
}
location /_bar_frontend_app_service {
internal;
set $api_name "Frontend API";
rewrite ^/_bar_frontend_app_service(.*)$ /$1 break;
proxy_pass http://$upstream; # Proxy the rewritten URI
}
y aquí está la configuración completa:
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
# Added to troubleshoot trailing slash frontend issue
log_format upstream_logging '[$time_local] $remote_addr - $remote_user - $server_name to: '
'$upstream: $request upstream_response_time $upstream_response_time '
'msec $msec request_time $request_time';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
include /etc/nginx/api_gateway.conf; # All API gateway configuration
include /etc/nginx/conf.d/*.conf; # Regular web traffic
}
# configuration file /etc/nginx/mime.types:
types {
...
}
# configuration file /etc/nginx/api_gateway.conf:
log_format api_main '$remote_addr - $remote_user [$time_local] "$request"'
'$status $body_bytes_sent "$http_referer" "$http_user_agent"'
'"$http_x_forwarded_for" "$api_name"';
include api_backends.conf;
server {
set $api_name -; # Start with an undefined API name, each API will update this value
access_log /var/log/nginx/api_access.log api_main; # Each API may also log to a separate file
listen 80;
# API definitions, one per file
include api_conf.d/*.conf;
# Error responses
error_page 404 = @400; # Invalid paths are treated as bad requests
proxy_intercept_errors on; # Do not send backend errors to the client
include api_json_errors.conf; # API client friendly JSON error responses
default_type application/json; # If no content-type then assume JSON
proxy_http_version 1.1;
proxy_set_header Connection "";
rewrite_log on;
}
# configuration file /etc/nginx/api_backends.conf:
upstream foo_api_main {
keepalive 32;
zone foo_service 64k;
server foo-server:5000;
}
upstream foobar_api_main {
keepalive 32;
zone foobar_service 64k;
server foobar:5000;
}
upstream bar_frontend_app_main {
keepalive 32;
zone bar_frontend_app_service 64k;
server bar-frontend:80;
}
# configuration file /etc/nginx/api_conf.d/foo_api.conf:
# API definition
#
location /api/hello/foo {
set $upstream foo_api_main;
rewrite ^/api/hello/foo/(.*)$ /_foo_service$1 last;
}
# This is used when app is running through MAF
location /hello/foo {
set $upstream foo_api_main;
rewrite ^/hello/foo/(.*)$ /_foo_service$1 last;
}
# Policy section
#
location /_foo_service {
internal;
set $api_name "foo backend API";
rewrite ^/_foo_service(.*)$ /api/$1 break; # Remove /_foo_service prefix
proxy_pass http://$upstream; # Proxy the rewritten URI
}
# configuration file /etc/nginx/api_conf.d/bar_frontend.conf:
location /bar/app {
set $upstream bar_frontend_app_main;
rewrite ^/bar/app(.*)$ /_bar_frontend_app_service$1 last;
}
# Policy section
#
location /_bar_frontend_app_service {
internal;
set $api_name "Frontend API";
rewrite ^/_bar_frontend_app_service(.*)$ /$1 break;
proxy_pass http://$upstream; # Proxy the rewritten URI
}
# configuration file /etc/nginx/api_conf.d/foobar_api.conf:
# API definition
#
location /api/hello/foobar {
set $upstream foobar_api_main;
rewrite ^/api/hello/foobar/(.*)$ /_foobar_service$1 last;
}
# This is used when app is running through MAF
location /hello/foobar {
set $upstream foobar_api_main;
rewrite ^/hello/foobar/(.*)$ /_foobar_service$1 last;
}
# Policy section
location /_foobar_service {
internal;
set $api_name "foobar backend API";
rewrite ^/_foobar_service(.*)$ /$1 break; # Remove /_foobar_service prefix
proxy_pass http://$upstream; # Proxy the rewritten URI
}
# configuration file /etc/nginx/api_json_errors.conf:
error_page 400 = @400;
location @400 { return 400 '{"status":400,"message":"Bad request"}\n'; }
error_page 401 = @401;
location @401 { return 401 '{"status":401,"message":"Unauthorized"}\n'; }
error_page 403 = @403;
location @403 { return 403 '{"status":403,"message":"Forbidden"}\n'; }
error_page 404 = @404;
location @404 { return 404 '{"status":404,"message":"Resource not found"}\n'; }
error_page 405 = @405;
location @405 { return 405 '{"status":405,"message":"Method not allowed"}\n'; }
error_page 408 = @408;
location @408 { return 408 '{"status":408,"message":"Request timeout"}\n'; }
error_page 413 = @413;
location @413 { return 413 '{"status":413,"message":"Payload too large"}\n'; }
error_page 414 = @414;
location @414 { return 414 '{"status":414,"message":"Request URI too large"}\n'; }
error_page 415 = @415;
location @415 { return 415 '{"status":415,"message":"Unsupported media type"}\n'; }
error_page 426 = @426;
location @426 { return 426 '{"status":426,"message":"HTTP request was sent to HTTPS port"}\n'; }
error_page 429 = @429;
location @429 { return 429 '{"status":429,"message":"API rate limit exceeded"}\n'; }
error_page 495 = @495;
location @495 { return 495 '{"status":495,"message":"Client certificate authentication error"}\n'; }
error_page 496 = @496;
location @496 { return 496 '{"status":496,"message":"Client certificate not presented"}\n'; }
error_page 497 = @497;
location @497 { return 497 '{"status":497,"message":"HTTP request was sent to mutual TLS port"}\n'; }
error_page 500 = @500;
location @500 { return 500 '{"status":500,"message":"Server error"}\n'; }
error_page 501 = @501;
location @501 { return 501 '{"status":501,"message":"Not implemented"}\n'; }
error_page 502 = @502;
location @502 { return 502 '{"status":502,"message":"Bad gateway"}\n'; }