2017-02-11 3 views
0

Ich ging zu ähnlichen Fragen, aber ohne Erfolg.nginx warum alle Routen funktioniert, aber man ist "301 Moved Permanently"?

Lassen Sie sagen, ich habe zwei node.js App auf einem Server drehen:

// App GoodMorning 
var express  = require('express'); 

app.post('/breakfast', function (req, res) { 
    console.log("Eating breakfast"); 
    res.sendStatus(200); 
}); 

app.get('/', function (req, res) { 
    res.send('GoodMorning'); 
}); 

app.listen(3000, function() { 
    console.log('GoodMorning app listening on port 3000!'); 
}); 

und

// App GoodEvening 
var express  = require('express'); 

app.post('/diner', function (req, res) { 
    console.log("Eating diner"); 
    res.sendStatus(200); 
}); 

app.get('/', function (req, res) { 
    res.send('GoodEvening'); 
}); 

app.listen(4000, function() { 
    console.log('GoodEvening app listening on port 4000!'); 
}); 

Und sagen wir mal Nginx als Reverse-Proxy-Server verwendet wird. Also muss es Anfragen an den richtigen Port senden, oder? So ist die „Magie“ Datei ist wie folgt aus:

# HTTP - redirect all requests to HTTPS: 
server { 
    listen 80; 
    listen [::]:80 default_server ipv6only=on; 
    return 301 https://$host$request_uri; 
} 


# HTTPS - proxy requests on to local Node.js app: 
server { 
    listen 443; 
    server_name iamhungry.com; 

    ssl on; 
    # Use certificate and key provided by Let's Encrypt: 
    ssl_certificate /etc/letsencrypt/live/iamhungry.com/fullchain.pem; 
    ssl_certificate_key /etc/letsencrypt/live/iamhungry.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'; 

    # Pass requests for/to localhost:3000: 
    location/{ 
      proxy_set_header X-Real-IP $remote_addr; 
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
      proxy_set_header X-NginX-Proxy true; 
      proxy_pass http://localhost:3000/; 
      proxy_ssl_session_reuse off; 
      proxy_set_header Host $http_host; 
      proxy_cache_bypass $http_upgrade; 
      proxy_redirect off; 
    } 

    # Pass requests for /homepageevening to localhost:4000: 
    location /homepageevening { 
      proxy_set_header X-Real-IP $remote_addr; 
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
      proxy_set_header X-NginX-Proxy true; 
      proxy_pass http://localhost:4000/; 
      proxy_ssl_session_reuse off; 
      proxy_set_header Host $http_host; 
      proxy_cache_bypass $http_upgrade; 
      proxy_redirect off; 
    } 

    # Pass requests for /diner to localhost/diner:4000: 
    location /diner { 
      proxy_set_header X-Real-IP $remote_addr; 
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
      proxy_set_header X-NginX-Proxy true; 
      proxy_pass http://localhost/diner:4000/; 
      proxy_ssl_session_reuse off; 
      proxy_set_header Host $http_host; 
      proxy_cache_bypass $http_upgrade; 
      proxy_redirect off; 
    } 

} 

Dann werden die folgenden Anfragen tun die folgenden Ergebnisse:

$ curl iamhungry.com 
$ GoodMorning // OK 

$ curl -X POST iamhungry.com/breakfast 
--> I see "Eating brakfast" in the log file of breakfast.js // OK 


$ curl iamhungry.com/homepageevening 
$ GoodEvening // OK 

$ curl -X POST iamhungry.com/diner -I 
HTTP/1.1 301 Moved Permanently // why ?! 
--> And I see nothing in the log file of evening.js // why ?! 

Ich bin nicht wohl mit diesen Proxy-Konzepte. Ich ging die Dokumentation von Nginx durch und fand keine Hilfe. Ich frage mich, ob meine Art zu verstehen, wie es funktioniert, richtig ist.

+0

Ist dies ein Tippfehler: 'proxy_pass http: // localhost/diner: 4000 /;'? Der Port sollte an den Domänennamen angehängt sein. –

+0

@RichardSmithc sollte ich 'proxy_pass http: // localhost: 4000/diner /;'? Ich habe gerade versucht, aber ich sehe immer noch nichts in den Logs, und es gibt irgendwie 400 zurück. Ich verstehe nicht, wie "curl -X POST iamhungry.com/breakfast" korrekt auf "http: // localhost: 3000/fruehstueck /;" umgeleitet wird. Es ist nicht einmal genau in der Nginx-Konfiguration. – NoonanRosenblum

+0

Beginnen Sie mit 'http: // localhost: 4000;', das '/ diner' an Ihre Anwendung unverändert weitergibt. 'proxy_pass' ist [hier dokumentiert] (http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass) –

Antwort

0

OK danke @RichardSmith. Ich hatte die Konfigurationsdatei zu beheben:

location /diner { 
     ... 
     proxy_pass http://localhost:4000/diner; 

Und tut meine Tests mit curl http://iamhungry.com -I -L statt curl http://iamhungry.com -I, um tatsächlich dem Rerouting zu folgen.

Hier ist, was mir fehlte:

  1. A 301 ist kein Fehler. Ich machte meinen Test im Terminal unter Verwendung curl http://iamhungry.com -I, aber mit der Option -L curl http://iamhungry.com -I -L erlaubte mir, die Umleitung zu folgen und dann das Ende der Linie zu bekommen! Also 301 ist eigentlich normal mit nginx, weil Redirect seine Rolle ist.

  2. Die Portnummer ist an den Domänennamen angehängt. Danke @RichardSmith.

  3. von @RichardSmith Link: [...] der Teil eines normalisierten Anforderungs-URI passende die Lage durch einen URI in der Richtlinie angegebenen ersetzt.