This is my setup:
I have a webpage which uses dash.js to view a live stream. The live stream is coming from my computer which is running OBS and NGINX. This works without a problem except when I call up the webpage within the first 30 seconds (or so) after the stream has started.
I tell dash to open up index.mpd on my computer, but only when it's available. In pseudo code:
START: If index.mpd is available
initialize stream and view it
Else
go to START
End
As soon as index.mpd is available, this means there's also a video/audio chunk available so it should be able to start playing. But it stalls instead (grey screen with rotating pin wheel). This probably has to do with the fact the settings ask for a 20 second buffer and a video/audio chunk is 8.3 seconds. (BTW, I have no idea why those chunks are 8.3 seconds - I could not find a setting anywhere in OBS or NGINX that reflects those 8.3 seconds)
The problem is, it never stops stalling (is it trying to buffer? I don't know). Even when all chunks are available and NGINX starts FIFO-ing the chunks. It never recovers from the stall.
Only when I open the page at a time when the entire buffer is available (which, again for some unknown reason, is about 30 seconds instead of the 20 I have set it to) will it start (dis)playing the stream.
Here is the complete NGINXG.conf:
worker_processes 1;
error_log logs/error.log;
events {
worker_connections 1024;
}
rtmp {
server {
listen 1935;
chunk_size 4096;
application live {
live on;
interleave on;
meta on;
session_relay on;
max_connections 1500;
record_path recordings;
record_suffix all-%d-%b-%y-%T.flv;
push rtmp://localhost/dash;
}
application dash {
live on;
dash on;
dash_nested on;
dash_cleanup on;
dash_fragment 5s;
dash_playlist_length 20s;
dash_path temp/tmp_dash;
}
}
}
http {
keepalive_timeout 60;
send_timeout 10;
keepalive_requests 10;
client_body_timeout 10;
sendfile on;
include 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"';
access_log logs/access.log main;
server {
listen 8050;
server_name localhost;
access_log logs/host.access.log main;
add_header Strict-Transport-Security "max-age=63072000;";
index index.php index-nginx.html index.html index.htm;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root site;
}
location / {
location ~* \.m3u8$ {
add_header Cache-Control no-cache;
}
try_files $uri $uri/ =404;
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Strict-Transport-Security' 'max-age=31536000';
add_header 'X-Content-Type-Options' "nosniff" 'always';
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Max-Age' 1728000;
# add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Expose-Headers' 'Content-Length';
}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
}
root site;
index index.php index.html index-nginx.html index.htm index.m3u8 index.mpd;
}
location /stat {
rtmp_stat all;
rtmp_stat_stylesheet stat.xsl;
}
location /stat.xsl {
root site;
}
location /tmp_dash {
alias temp/tmp_dash;
autoindex on;
autoindex_localtime on;
autoindex_exact_size off;
expires -1;
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Expose-Headers' 'Content-Length';
}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Expose-Headers' 'Content-Length';
}
types {
application/dash+xml mpd;
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
text/html html;
}
}
}
}
And here's the HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="http://cdn.dashjs.org/latest/dash.all.min.js"></script>
<script>
window.addEventListener( "load", init );
var XMLHttp;
var streamActive = false;
var url = "/tmp_dash/stream/index.mpd";
function init(){
XMLHttp = new XMLHttpRequest();
XMLHttp.onreadystatechange = function() {
if( XMLHttp.readyState == 4
if( XMLHttp.status == 200 ) {
// Index.mpd exists
if( ! streamActive ) {
player = dashjs.MediaPlayer().create();
player.initialize( document.querySelector( "#videoPlayer" ), url, true);
}
} else if( XMLHttp.status == 404 ) {
setTimeout( checkStreamReady, 5000 ); // Check again in 5 seconds
}
}
}
checkStreamReady();
}
function checkStreamReady() {
XMLHttp.open( "GET", url, true );
XMLHttp.send();
}
</script>
</head>
<body>
<div id="videocontainer">
<video id="videoPlayer" controls></video>
</div>
</body>
</html>
I am trying to use NGINX as an "API Gateway" into my gRPC services - all within a Kubernetes Cluster. A Typescript React App is just making calls via the grpc-web module to an Envoy proxy, then to the API NGINX Proxy. (I have tested that end of the stack - and I'm 100% sure that envoy works fine).
NOTE: I may be making a mistake NOT using TLS with the Envoy Proxy (Which is the 'client' to NGINX) - so please comment if that's the mistake I'm making
For this to work with my gRPC endpoints, I need to enable HTTP/2 proxying (this is required for gRPC to work - it must be over HTTP/2). And so, following the official NGINX Documentation which is here: https://www.nginx.com/blog/nginx-1-13-10-grpc/ , my nginx.conf file looks like:
worker_processes auto;
events {}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent"';
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 1449 ssl http2;
ssl_protocols TLSv1.2;
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
ssl_prefer_server_ciphers on;
ssl_certificate ./server.crt;
ssl_certificate_key ./server.key;
location /com.example.grpcService {
grpc_pass grpcs://api-grpc-server:9090;
proxy_buffer_size 512k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 512k;
grpc_set_header Upgrade $http_upgrade;
grpc_set_header Connection "Upgrade";
grpc_set_header Connection keep-alive;
grpc_set_header Host $host:$server_port;
grpc_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
grpc_set_header X-Forwarded-Proto $scheme;
}
}
}
I also heard from another forum that you MUST use TLS/SSL with HTTP/2 or it won't work, so I first tried it without - it didn't work. Then I tried it with the generated SSL certificates and it looks like I'm still getting a 400 error from the proxied service. The log looks like:
172.17.0.17 - - [05/Jan/2021:18:16:23 +0000] "PRI * HTTP/2.0" 400 157 "-" "-"
I have used OpenSSL for the certificates which resulted in .crt and .key files being generated - which I then used for BOTH my Spring Boot gRPC Server & NGINX Proxy. My OpenSSL version is OpenSSL 1.1.1c 28 May 2019.
I am using those same certificates on the actual gRPC Server itself, this looks like:
#Component
public class GrpcServerRunner implements CommandLineRunner, DisposableBean {
private final ConfigurableApplicationContext applicationContext;
private Server server;
public GrpcServerRunner(#Autowired ConfigurableApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
#Override
public void run(String... args) throws Exception {
File cert = new File("~/etc/ssl/server.crt");
File key = new File("~/etc/ssl/server.key");
BindableService service = applicationContext.getBean("grpcService", BindableService.class);
server = ServerBuilder.forPort(9090).useTransportSecurity(cert, key).addService(service).build();
runSever();
}
private void runSever() {
Thread thread = new Thread(() -> {
try {
server.awaitTermination();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
thread.setDaemon(false);
thread.start();
}
#Override
public void destroy() {
server.shutdown();
}
}
I'd really appreciate any help, questions, feedback or solutions to this problem - so thanks in advance.
It actually had nothing to do with the gRPC Server or the Java Project.
Here's the root NGINX config file:
worker_processes auto;
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr [$time_local] [$time_local] [$cookie_X-AUTH-TOKEN] '
'"$scheme $host $request" $status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'($request_time)'
'(($sent_http_set_cookie))';
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
# Upstream servers here
upstream api-server-address {
server api-server-address:9090;
keepalive 20;
}
# gRPC Client requirements set
client_max_body_size 0;
proxy_request_buffering off;
server {
listen 1449 http2;
include ./config/grpc-header-config.conf.conf;
# gRPC service proxied here
location /com.yourpackage {
auth_request_set $upstream_http_set_cookie;
auth_request_set $upstream_http_status;
grpc_pass grpc://api-service-address;
include config/grpc-header-config.conf;
}
default_type application/grpc;
}
}
The key file that made this work was this one (this is the one referenced by the root one in config/grpc-header-config.conf):
error_page 400 = #grpc_internal;
error_page 401 = #grpc_unauthenticated;
error_page 403 = #grpc_permission_denied;
error_page 404 = #grpc_unimplemented;
error_page 429 = #grpc_unavailable;
error_page 502 = #grpc_unavailable;
error_page 503 = #grpc_unavailable;
error_page 504 = #grpc_unavailable;
error_page 405 = #grpc_internal;
error_page 408 = #grpc_deadline_exceeded;
error_page 413 = #grpc_resource_exhausted;
error_page 414 = #grpc_resource_exhausted;
error_page 415 = #grpc_internal;
error_page 426 = #grpc_internal;
error_page 495 = #grpc_unauthenticated;
error_page 496 = #grpc_unauthenticated;
error_page 497 = #grpc_internal;
error_page 500 = #grpc_internal;
error_page 501 = #grpc_internal;
location #grpc_deadline_exceeded {
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Transfer-Encoding,Custom-Header-1,X-Accept-Content-Transfer-Encoding,X-Accept-Response-Streaming,X-User-Agent,X-Grpc-Web,Access-Control-Allow-Credentials';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Set-Cookie' $auth_cookie;
add_header 'Access-Control-Expose-Headers' 'Content-Transfer-Encoding,Grpc-Message,Grpc-Status';
add_header 'Access-Control-Allow-Origin' *';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'grpc-status' 4;
add_header 'grpc-message' 'deadline exceeded';
return 204;
}
location #grpc_permission_denied {
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Transfer-Encoding,Custom-Header-1,X-Accept-Content-Transfer-Encoding,X-Accept-Response-Streaming,X-User-Agent,X-Grpc-Web,Access-Control-Allow-Credentials';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Set-Cookie' $auth_cookie;
add_header 'Access-Control-Expose-Headers' 'Content-Transfer-Encoding,Grpc-Message,Grpc-Status';
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'grpc-status' 7;
add_header 'grpc-message' 'permission denied';
return 204;
}
location #grpc_resource_exhausted {
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Transfer-Encoding,Custom-Header-1,X-Accept-Content-Transfer-Encoding,X-Accept-Response-Streaming,X-User-Agent,X-Grpc-Web,Access-Control-Allow-Credentials';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Set-Cookie' $auth_cookie;
add_header 'Access-Control-Expose-Headers' 'Content-Transfer-Encoding,Grpc-Message,Grpc-Status';
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'grpc-status' 8;
add_header 'grpc-message' 'resource exhausted';
return 204;
}
location #grpc_unimplemented {
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Transfer-Encoding,Custom-Header-1,X-Accept-Content-Transfer-Encoding,X-Accept-Response-Streaming,X-User-Agent,X-Grpc-Web,Access-Control-Allow-Credentials';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Set-Cookie' $auth_cookie;
add_header 'Access-Control-Expose-Headers' 'Content-Transfer-Encoding,Grpc-Message,Grpc-Status';
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'grpc-status' 12;
add_header 'grpc-message' unimplemented;
return 204;
}
location #grpc_internal {
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Transfer-Encoding,Custom-Header-1,X-Accept-Content-Transfer-Encoding,X-Accept-Response-Streaming,X-User-Agent,X-Grpc-Web,Access-Control-Allow-Credentials';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Set-Cookie' $auth_cookie;
add_header 'Access-Control-Expose-Headers' 'Content-Transfer-Encoding,Grpc-Message,Grpc-Status';
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'grpc-status' 13;
add_header 'grpc-message' 'internal error';
return 204;
}
location #grpc_unavailable {
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Transfer-Encoding,Custom-Header-1,X-Accept-Content-Transfer-Encoding,X-Accept-Response-Streaming,X-User-Agent,X-Grpc-Web,Access-Control-Allow-Credentials';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Set-Cookie' $auth_cookie;
add_header 'Access-Control-Expose-Headers' 'Content-Transfer-Encoding,Grpc-Message,Grpc-Status';
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'grpc-status' 14;
add_header 'grpc-message' 'unavailable';
return 204;
}
location #grpc_unauthenticated {
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Transfer-Encoding,Custom-Header-1,X-Accept-Content-Transfer-Encoding,X-Accept-Response-Streaming,X-User-Agent,X-Grpc-Web,Access-Control-Allow-Credentials';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Set-Cookie' $auth_cookie;
add_header 'Access-Control-Expose-Headers' 'Content-Transfer-Encoding,Grpc-Message,Grpc-Status';
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'grpc-status' 16;
add_header 'grpc-message' '401. Unauthorized.';
return 200;
}
I realize this looks super sketchy/hacky, but that's the only way I could do it. Feel free to improve this answer!
Your essentially setting the default protocol to gRPC and HTTP/2, then on any error page you just reset the statuses to match the gRPC conventions + spec so that your client will be able to parse the binaries. If you are using SSL with this, you just need to put the certificates on each side as normal, then change the grpc_pass to grpcs://api-server-address instead of what I have.
Feel free to add any constructive feedback or any questions! Cheers, Ben
I'm following the instructions to install Nextcloud on an nginx server.
I copy the configuration from the offical documentation, i set my server name and my ssl certificate path, and when i try to reach nextcloud from my browser i get
"500 Internal server error".
When i check in the error.log i get
rewrite or internal redirection cycle while processing "/index.php"
This is my configuration file:
upstream php-handler {
#server 127.0.0.1:9000;
server unix:/var/run/php/php7.3-fpm.sock;
}
server {
listen 80;
listen [::]:80;
server_name mrbackslash.tk;
# enforce https
return 301 https://$server_name:443$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name mrbackslash.tk;
# Use Mozilla's guidelines for SSL/TLS settings
# https://mozilla.github.io/server-side-tls/ssl-config-generator/
# NOTE: some settings below might be redundant
ssl_certificate /etc/ssl/mrbackslash_tk_cert.crt;
ssl_certificate_key /etc/ssl/mrbackslash_tk_key.key;
# Add headers to serve security related headers
# Before enabling Strict-Transport-Security headers please read into this
# topic first.
#add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always;
#
# WARNING: Only add the preload option once you read about
# the consequences in https://hstspreload.org/. This option
# will add the domain to a hardcoded list that is shipped
# in all major browsers and getting removed from this list
# could take several months.
add_header Referrer-Policy "no-referrer" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Download-Options "noopen" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Permitted-Cross-Domain-Policies "none" always;
add_header X-Robots-Tag "none" always;
add_header X-XSS-Protection "1; mode=block" always;
# Remove X-Powered-By, which is an information leak
fastcgi_hide_header X-Powered-By;
# Path to the root of your installation
root /var/www/mrbackslash.tk/public-html/;
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
# The following 2 rules are only needed for the user_webfinger app.
# Uncomment it if you're planning to use this app.
#rewrite ^/.well-known/host-meta /public.php?service=host-meta last;
#rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last;
# The following rule is only needed for the Social app.
# Uncomment it if you're planning to use this app.
#rewrite ^/.well-known/webfinger /public.php?service=webfinger last;
location = /.well-known/carddav {
return 301 $scheme://$host:$server_port/remote.php/dav;
}
location = /.well-known/caldav {
return 301 $scheme://$host:$server_port/remote.php/dav;
}
# set max upload size
client_max_body_size 512M;
fastcgi_buffers 64 4K;
# Enable gzip but do not remove ETag headers
gzip on;
gzip_vary on;
gzip_comp_level 4;
gzip_min_length 256;
gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
# Uncomment if your server is build with the ngx_pagespeed module
# This module is currently not supported.
#pagespeed off;
location / {
rewrite ^ /index.php$request_uri;
}
location ~ ^\/(?:build|tests|config|lib|3rdparty|templates|data)\/ {
deny all;
}
location ~ ^\/(?:\.|autotest|occ|issue|indie|db_|console) {
deny all;
}
location ~ ^/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|ocs-provider/.+)\.php(?:$|/) {
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param HTTPS on;
#Avoid sending the security headers twice
fastcgi_param modHeadersAvailable true;
fastcgi_param front_controller_active true;
fastcgi_pass php-handler;
fastcgi_intercept_errors on;
fastcgi_request_buffering off;
}
location ~ ^\/(?:updater|oc[ms]-provider)(?:$|\/) {
try_files $uri/ =404;
index index.php;
}
# Adding the cache control header for js, css and map files
# Make sure it is BELOW the PHP block
location ~ \.(?:css|js|woff2?|svg|gif|map)$ {
try_files $uri /index.php$request_uri;
add_header Cache-Control "public, max-age=15778463";
# Add headers to serve security related headers (It is intended to
# have those duplicated to the ones above)
# Before enabling Strict-Transport-Security headers please read into
# this topic first.
#add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always;
#
# WARNING: Only add the preload option once you read about
# the consequences in https://hstspreload.org/. This option
# will add the domain to a hardcoded list that is shipped
# in all major browsers and getting removed from this list
# could take several months.
add_header Referrer-Policy "no-referrer" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Download-Options "noopen" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Permitted-Cross-Domain-Policies "none" always;
add_header X-Robots-Tag "none" always;
add_header X-XSS-Protection "1; mode=block" always;
# Optional: Don't log access to assets
access_log off;
}
location ~ \.(?:png|html|ttf|ico|jpg|jpeg|bcmap|mp4|webm)$ {
try_files $uri /index.php$request_uri;
# Optional: Don't log access to other assets
access_log off;
}
}
Help!
I solved the issue by re-uploading the configuration file via ftp, pasting it in nano on the ssh shell was a bad idea!
Here is part of my location config:
location /web {
proxy_pass http://192.168.1.141:8079/gateway/web;
add_header "TEST" 1;
proxy_pass_request_headers on;
if ($request_method ~* "(GET|POST)") {
add_header "Access-Control-Allow-Origin" *;
add_header "TEST" 1;
}
if ($request_method = OPTIONS ) {
add_header "Access-Control-Allow-Origin" *;
add_header "TEST" 1;
add_header "Access-Control-Allow-Methods" "GET, POST, OPTIONS, HEAD";
add_header "Access-Control-Allow-Headers" "Origin, X-Requested-With, Content-Type, Accept";
return 200;
}
I'm trying to configure to add TEST header to every request which will be done beyond /web, thus if link will contain "/web", add TEST header in all requests,i.e.
/web/mail/*
/web/auth/*
/web/people/*