node.js – Unable to reach POST destination – Express

I have been unable to reach a POST route on my express application when I serve the content on EC2. I am able to test locally, but I receive a 404 once hosted. I have googled a ton, and tried various suggestions from similar questions here, with no luck. Can someone please help me understand why I am unable to reach a post route. everything works good for the get “/” but the below post route retrieves a 404 direct to the instance and via nginx.

I have tried the following post with the same error:
http://:3000/forms/test
https://.com/forms/test

The supporting files are below:

When I try to make a post request directly to my EC2 instance with insomnia I get the following error:

* Preparing request to http://<EC2-IP>:3000/forms/test
* Current time is 2022-05-02T13:22:27.758Z
* Using default HTTP version
* Disable timeout
* Enable automatic URL encoding
* Enable SSL validation
* Enable cookie sending with jar of 0 cookies
* STATE: INIT => CONNECT handle 0x70006bb008; line 1789 (connection #-5000)
* Connection 103 seems to be dead!
* The cache now contains 0 members
* Closing connection 103
* Added connection 104. The cache now contains 1 members
* Hostname <EC2-IP> was found in DNS cache
* family0 == v4, family1 == v6
*   Trying <EC2-IP>:3000...
* STATE: CONNECT => CONNECTING handle 0x70006bb008; line 1850 (connection #104)
* Connected to <EC2-IP> (<EC2-IP>) port 3000 (#104)
* STATE: CONNECTING => PROTOCONNECT handle 0x70006bb008; line 1982 (connection #104)
* STATE: PROTOCONNECT => DO handle 0x70006bb008; line 2003 (connection #104)

> POST /forms/test HTTP/1.1
> Host: <EC2-IP>:3000
> User-Agent: insomnia/2022.2.0
> Accept: */*
> Content-Length: 0

* STATE: DO => DID handle 0x70006bb008; line 2077 (connection #104)
* STATE: DID => PERFORMING handle 0x70006bb008; line 2196 (connection #104)
* Mark bundle as not supporting multiuse
* HTTP 1.1 or later with persistent connection

< HTTP/1.1 404 Not Found
< X-Powered-By: Express
< Content-Security-Policy: default-src 'none'
< X-Content-Type-Options: nosniff
< Content-Type: text/html; charset=utf-8
< Content-Length: 150
< Date: Mon, 02 May 2022 13:22:27 GMT
< Connection: keep-alive
< Keep-Alive: timeout=5


* Received 150 B chunk
* STATE: PERFORMING => DONE handle 0x70006bb008; line 2395 (connection #104)
* multi_done
* Connection #104 to host <EC2-IP> left intact
* Expire cleared (transfer 0x70006bb008)

index.js

import "dotenv/config"; 

require("dotenv").config();
console.log(process.env);
const express = require("express");
const app = express();
const port = process.env.PORT || 3000;
// const router = express.Router();
const forms = require("./routes/forms");


// app.use(express.static("public"));
// app.use(router);
app.use("/forms", forms)
app.use("/", express.static("public"));


app.listen(port, () => console.log(`Server listening on port: ${port}`));

forms.js

"use strict";
const exp = require("express");
const router = exp.Router();
const sgMail = require("@sendgrid/mail");
const { body, validationResult } = require("express-validator");

sgMail.setApiKey(process.env.SENDGRID_API_KEY);
router.use(exp.json());
router.use(exp.urlencoded({ extended: true }));


router.post("/test", (req, res) => {
  res.status(200).send(" Oh Hai 👋🏽  ");
});

module.exports = router;

nginx.conf looks like this:


user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    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  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 4096;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;

    server {
    listen       80;
        listen       [::]:80;
        server_name  <myurl>.com;
        #add_header Content-Security-Policy "default-src * data: 'unsafe-eval' 'unsafe-inline'" always;
        return       301 https://$server_name$request_uri;

        location / {
                proxy_pass http://localhost:3000;
        }
    location ~ ^/forms/(contact|sub|test)? {
                proxy_pass http://localhost:3000;
        }

        # Load configuration files for the default server block.
        # include /etc/nginx/default.d/*.conf;



        #error_page 404 /404.html;
        #location = /404.html {
        #}

        #error_page 500 502 503 504 /50x.html;
        #location = /50x.html {
        #}
    }

    server {
    listen       443 ssl http2;
        listen       [::]:443 ssl http2;
        server_name <myurl>.com;

        if ($host="www.<myurl>.com" ){
        rewrite ^/(.*)$  https://<myurl>.com/$1  permanent;
        }
#       server_name  _;
       #root         /usr/share/nginx/html;
        location / {
                access_log /var/log/nginx/home-access.log combined;
                proxy_pass http://localhost:3000;
                add_header X-Frame-Options "SAMEORIGIN" always;
                add_header X-XSS-Protection "1; mode=block" always;
                add_header X-Content-Type-Options "nosniff" always;
                add_header Referrer-Policy "no-referrer-when-downgrade" always;
                #add_header Content-Security-Policy "default-src * data: 'unsafe-eval' 'unsafe-inline'" always;
                #add_header Content-Security-Policy "script-src 'self' 'unsafe-inline' 'unsafe-eval' *.google.com; object-src 'self'";
        }
    location ~ ^/forms/(contact|sub|test)? {
                access_log /var/log/nginx/form-access.log combined;
                proxy_pass http://localhost:3000;
                proxy_set_header content-type "application/json";
                proxy_set_header Connection $http_connection;
                proxy_set_header Upgrade $http_upgrade;
                #add_header Content-Security-Policy "default-src * data: 'unsafe-eval' 'unsafe-inline' always <myurl>.com";
                #add_header Content-Security-Policy "script-src 'self' 'unsafe-inline' 'unsafe-eval' *.google.com; object-src 'self'";
                proxy_set_header Host $host;
                proxy_cache_bypass $http_upgrade;
                proxy_set_header   X-Forwarded-Proto $scheme;
                proxy_redirect off;
                proxy_http_version 1.1;
                proxy_buffering off;
        }

        #ssl_certificate "/etc/pki/nginx/server.crt";
        #ssl_certificate_key "/etc/pki/nginx/private/server.key";
        ssl_certificate /etc/letsencrypt/live/<myurl>.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/<myurl>.com/privkey.pem;
        ssl_session_cache shared:SSL:1m;
        ssl_session_timeout  10m;
        #ssl_ciphers PROFILE=SYSTEM;
        server_tokens off;
        ssl_ecdh_curve secp384r1;
        ssl_session_tickets off;
        ssl_stapling on;
        ssl_stapling_verify on;
        resolver 8.8.8.8;

        ssl_prefer_server_ciphers on;
        ssl_protocols TLSv1.2;
        ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;
#
#        # Load configuration files for the default server block.
#        include /etc/nginx/default.d/*.conf;
#
#        error_page 404 /404.html;
#            location = /40x.html {
#        }
#
#        error_page 500 502 503 504 /50x.html;
#            location = /50x.html {
#        }
   }

Leave a Comment