Nginx audio files (wav/ogg/mp3) not working - javascript

Audios on prod are not working while working fine on dev environment (Angular 7).
Prod config (VPS):
Ubuntu 18
Nginx
Let's encrypt
AudioService:
export class AudioService {
audio = new Audio();
constructor() { }
isPlaying() {
return this.audio.currentTime > 0 && !this.audio.paused && !this.audio.ended && this.audio.readyState > 2;
}
play(name: string): void {
this.audio.src = `assets/audio/${name}`;
this.audio.crossOrigin = 'anonymous';
this.audio.load();
if (!this.isPlaying()) {
this.audio.play();
}
}
pause(): void {
if (this.isPlaying()) {
this.audio.pause();
}
}
}
CORS are enabled on Nodejs side (using Nestjs). main.ts:
app.enableCors();
Chrome log:
Uncaught (in promise) DOMException: Failed to load because no
supported source was found.
Firefox log:
NotSupportedError: The media resource indicated by the src attribute
or assigned media provider object was not suitable.
Looking at Network console we can see myaudio.wav with:
Status Code: 206 Partial Content
Note: Loading images works fine !
EDIT:
Nginx config /etc/nginx/sites-available/mywebsite:
# Redirection
server {
# if ($host = mywebsite.com) {
# return 301 https://$host$request_uri;
# } # managed by Certbot
listen 80;
listen [::]:80;
server_name mywebsite.com www.mywebsite.com;
return 301 https://$host$request_uri;
#return 404; # managed by Certbot
}
# Config
server {
server_name mywebsite.com www.mywebsite.com;
root /home/foo/mywebsite/gui;
index index.html index.htm;
location / {
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;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://my.ip:3000/;
# Websocket
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
if ($host = 'www.mywebsite.com') {
return 301 https://mywebsite.com$request_uri;
}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/mywebsite.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/mywebsite.com/privkey.pem; # managed by Certbot
}
On dev environment localhost:4200/assets/audio/myaudio.wav → works fine
On prod environment https://mywebsite.com/assets/audio/myaudio.wav → returns home page
While https://mywebsite.com/assets/image.jpg → works fine
Only audios don't work.

Set max_ranges to 0.
For your case, this would look like something like this:
location ~ \.wav$ {
max_ranges 0;
}
Meaning the rule applies to every wav file regardless of their location.

Related

NextJS FetchError ETIMEDOUT

I deployed my project on centos 7 that port forwarded to 8080 which means, we use the site using ip then :8080. And here is the NGINX config I used for my front-end and backend reverse proxy
Site nginx config
server {
listen 80;
listen [::]:80;
server_name myapp.com etc.com;
#my api
location / {
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_set_header X-Auth-Request-Redirect "http://api.myapp.com";
proxy_cache_bypass $http_upgrade;
proxy_pass http://127.0.0.1:3333;
proxy_http_version 1.1;
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
proxy_redirect off;
#proxy_cookie_path / "/; SameSite=lax; HTTPOnly; Secure";
}
#my app
location /myapp {
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_set_header X-Auth-Request-Redirect "http://ipaddress:8080/adminpage";
proxy_cache_bypass $http_upgrade;
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
#proxy_cookie_path / "/; SameSite=lax; HTTPOnly; Secure";
}
}
I got this error
FetchError: request to http://ipaddress:8080/auth/checkauth failed, reason: connect ETIMEDOUT ipaddress:8080
at ClientRequest.<anonymous> (/root/web/myapp/node_modules/next/dist/compiled/node-fetch/index.js:1:64142)
at ClientRequest.emit (node:events:527:28)
at Socket.socketErrorListener (node:_http_client:454:9)
at Socket.emit (node:events:527:28)
at emitErrorNT (node:internal/streams/destroy:157:8)
at emitErrorCloseNT (node:internal/streams/destroy:122:3)
at processTicksAndRejections (node:internal/process/task_queues:83:21) {
type: 'system',
errno: 'ETIMEDOUT',
code: 'ETIMEDOUT'
}
_middleware.ts
import type { NextRequest } from 'next/server';
import { NextResponse } from 'next/server';
export async function middleware(req: NextRequest) {
const token = req.cookies;
const urlClone = req.nextUrl.clone();
urlClone.pathname = `/404`;
const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/auth/checkauth`, {
method: 'GET',
headers: {
Authorization: `Bearer ${token.app_token}`,
},
});
if (res.status === 200) {
return NextResponse.next();
}
return NextResponse.rewrite(urlClone);
}
The app works fine in production, also with my Axios api. I can login thru my app using axios request but my middleware that have fetch api and getServerSideProps that also have fetch api having connect ETIMEDOUT error.
What I tried so far
proxy agent
change fetch api to axios with adapter
tried playing with url
set cors on my API to all and true
I can also call my api endpoint using curl inside the server and postman on my local machine
My other NextJS app that being deployed in linux server same procedure also, it does have fetch api in middleware and getServerSideProps works fine but that server is not port forwarded to any port. I'm wondering if that could be the issue
I used NextJS v12.1.6
I solved this by replacing my await fetch base url to localhost http://127.0.0.1:3333 (api host) on the server. Works perfect on my case.
const res = await fetch(`http://127.0.0.1:3333/auth/checkauth`, {
method: 'GET',
headers: {
Authorization: `Bearer ${token.app_token}`,
},
});

nginx reverse proxy Angular Node app mixed content http requests

I'm dealing with nginx and node express server, the app used to works fine with reverse proxy over port 80 but the issue started when i installed a SSL with certbot over nginx, i've been trying also with https node module but i'm still getting mixed content error when i make requests from my angular front to my node backend. I think it's a bad traffic configuration over nginx, maybe i need to set traffic from nginx to node server (port 3000) with http but i'm not sure how to achieve that. Thanks in advance.
Console error when requests:
polyfills-es2015.aa82454585d558e1759e.js:1 Mixed Content: The page at 'https://www.example.com/signup' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://myVpsIpNumber:3000/api/register'. This request has been blocked; the content must be served over HTTPS.
This is my nginx set:
server {
server_name example.com www.example.com;
location / {
proxy_pass http://localhost:3000;
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;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = www.example.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
if ($host = example.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
server_name example.com www.example.com;
return 404; # managed by Certbot
}
my express server:
const express = require('express');
const cors = require('cors');
let app = express();
//routes
const user_routes = require('./routes/user.router');
// middlewares
app.use(cors());
app.use(('/'), express.static('client', {redirect: false}));
app.use('/api', user_routes);
app.get('*', function(req, res, next){
res.sendFile(path.resolve('client/index.html'));
})
// start server
app.listen(3000, () => console.log('Server started at port : 3000'));
Angular service:
import { HttpClient, HttpHeaders } from '#angular/common/http';
noAuthHeader = { headers: new HttpHeaders({ 'NoAuth': 'True' }) };
constructor(private http: HttpClient) {}
postUser(user: User){
return this.http.post('http://localhost:3000/api' + '/register', user, this.noAuthHeader);
}
node backend:
register: (req, res, next) => {
let user = new User();
user.email = req.body.email;
user.password = req.body.password;
user.save((err, doc) => {
if (!err)
res.send(doc);
else {
if (err.code == 11000)
res.status(422).send(['Email ya registrado']);
else
return next(err);
}
});
}
I had the same issue although not with Angular but Vuejs. With http everything worked fine but after installing SSL certificate with certbot I got the "mixed content" error. I'm a beginner and couldn't figure out how to have my frontend talk to backend. It took me quite a while to solve this, so I hope this helps:
Copy your "dist" folder in which you store your production build in this directory /var/www/html like so
$ cp -r /usr/src/app/dist/* /var/www/html
Nginx default file at /etc/nginx/sites-available/default should look like this:
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
server_name _;
location / {
try_files $uri $uri/ =404;
}
}
server {
root /var/www/html;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
server_name www.example.com example.com; # managed by Certbot
location / {
try_files $uri $uri/ =404;
}
location /api {
proxy_pass http://localhost:3000;
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;
}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = www.example.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
if ($host = example.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80 ;
listen [::]:80 ;
server_name www.example.com example.com;
return 404; # managed by Certbot
}
In frontend use https://example.com/api instead of http://localhost:3000/api like so (not sure if this is working in Angular exactly like this, but you get the point):
postUser(user: User){
return this.http.post('https://example.com/api' + '/register', user, this.noAuthHeader);
}
app.js file looks ok. So no changes should be necessary.
The problem was in API calls from frontend, the solution is replacing the URL with the SSL domain (using https://).
Development:
'http://localhost:3000'
Production:
'https://www.example.com'
import { HttpClient, HttpHeaders } from '#angular/common/http';
noAuthHeader = { headers: new HttpHeaders({ 'NoAuth': 'True' }) };
constructor(private http: HttpClient) {}
postUser(user: User){
return this.http.post('https://www.example.com/api' + '/register', user, this.noAuthHeader);
}

config ssl nginx server for prerender angular js app

Can you tell me how to config nginx to prerend my app.
The tutorial doesn't work, when I crawl the website with crawler googlebot, I see brackets from angular.
I'm lost.
many thanks in advance
my nginx config:
server {
listen 80;
listen [::]:80 default_server ipv6only=on;
return 301 https://$host$request_uri;
}
server {
listen 443;
server_name www.thedomain.com;
ssl on;
# Use certificate and key provided by Let's Encrypt:
ssl_certificate /etc/letsencrypt/live/www.thedomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.thedomain.com/privkey.pem;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
location / {
# Proxy_pass configuration
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_max_temp_file_size 0;
proxy_pass http://0.0.0.0:3000;
proxy_redirect off;
proxy_read_timeout 240s;
}
}
}
This should work:
server {
listen 80;
listen [::]:80 default_server ipv6only=on;
return 301 https://$host$request_uri;
}
server {
listen 443;
server_name www.thedomain.com;
ssl on;
# Use certificate and key provided by Let's Encrypt:
ssl_certificate /etc/letsencrypt/live/www.thedomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.thedomain.com/privkey.pem;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
location / {
#proxy_set_header X-Prerender-Token YOUR_TOKEN;
set $prerender 0;
if ($http_user_agent ~* "baiduspider|twitterbot|facebookexternalhit|rogerbot|linkedinbot|embedly|quora link preview|showyoubot|outbrain|pinterest|slackbot|vkShare|W3C_Validator") {
set $prerender 1;
}
if ($args ~ "_escaped_fragment_") {
set $prerender 1;
}
if ($http_user_agent ~ "Prerender") {
set $prerender 0;
}
if ($uri ~* "\.(js|css|xml|less|png|jpg|jpeg|gif|pdf|doc|txt|ico|rss|zip|mp3|rar|exe|wmv|doc|avi|ppt|mpg|mpeg|tif|wav|mov|psd|ai|xls|mp4|m4a|swf|dat|dmg|iso|flv|m4v|torrent|ttf|woff|svg|eot)") {
set $prerender 0;
}
#resolve using Google's DNS server to force DNS resolution and prevent caching of IPs
resolver 8.8.8.8;
if ($prerender = 1) {
#setting prerender as a variable forces DNS resolution since nginx caches IPs and doesnt play well with load balancing
set $prerender "service.prerender.io";
rewrite .* /$scheme://$host$request_uri? break;
proxy_pass http://$prerender;
}
# Proxy_pass configuration
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_max_temp_file_size 0;
proxy_pass http://0.0.0.0:3000;
proxy_redirect off;
proxy_read_timeout 240s;
}
}
}
Don't forget to remove the # from the proxy_set_header for X-Prerender-Token once you replace YOUR_TOKEN.
You will then want to test your URL be appending the ?_escaped_fragment_= query parameter. If your URLs look like:
https://www.example.com/
You'll test them like:
https://www.example.com/?_escaped_fragment_=
That will force a prerendered page so you can View Source there and make sure you're seeing a static HTML page instead of just the tags.

Nginx redirect to PhantomJS

I am attempting to redirect to a phantomJS instance running on port 8888. However it is failing. The regular page loads, but when I change the #! for the ?_escaped_fragment_= it just gives me the regular page still...
Excerpt from the nginx file
user www-data;
worker_processes 4;
pid /var/run/nginx.pid;
events {
worker_connections 768;
# multi_accept on;
}
http {
if ($args ~ _escaped_fragment_) {
proxy_pass http://localhost:8000/?_escaped_fragment_=/;
}
#mi angular app
server {
location / {
root /var/www/html/miwebapp/client/app;
}
}
##
# Basic Settings
##
sendfile on;
tcp_nopush on;
The solution found at the bottom of this "crawlable application" post on senior-java-developer.com shows how to address the issue by rewriting to another location that handles the proxy_pass as follows:
if ($args ~ "_escaped_fragment_=(.*)") {
rewrite ^ /snapshot${uri};
}
location /snapshot {
proxy_pass http://api;
proxy_connect_timeout 60s;
}
My working configuration:
if ($args ~ _escaped_fragment_) {
rewrite ^ /snapshot$uri;
}
location ~ ^/snapshot(.*) {
rewrite ^/snapshot(.*)$ $1 break;
proxy_pass http://localhost:8888;
proxy_set_header Host $host;
proxy_connect_timeout 60s;
}
More info here: https://github.com/liuwenchao/ajax-seo

config nginx for multiple nodejs apps

hello i have to config multiple apps of nodejs using nginx...
this is my actual configuration
upstream domain.com.ar {
server 127.0.0.1:9000;
}
server {
listen 80;
server_name www.domain.com.ar;
rewrite ^/(.*) http://domain.com.ar/$1 permanent;
}
server {
listen 80;
listen [::]:80 ipv6only=on;
server_name domain.com.ar;
#access_log /var/log/nginx/domain.com/access.log;
location / {
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;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://domain.com.ar;
proxy_redirect off;
}
}
when i use the ip 190.213.125.17:9000 (its just an example of my ip) the app works fine
but when i try to use the domain.com.ar nginx redirect to this page
http://domain.com.ar/cgi-sys/defaultwebpage.cgi
so the app respond with a 404 error configured by me in my app.js like a middleware
app.use(function(req, res, next){
res.render('404.jade',
{
title: "404 - Page Not Found",
showFullNav: false,
status: 404,
url: req.url
});
});
there is something wrong in the nginx config???

Categories

Resources