Introduction
My POST request works offline i.e. on localhost, but doesn't work when the website is deployed.
I am using nextjs, node, nodemailer, axios and nginx. I have also used fetch instead of axios and it gave me the same issue.
The situation
I have a handleSubmit function, that takes some inputs from a contact form and sends it to my Gmail account:
axios({
method: "POST",
url: "/api/submit",
data: body,
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
}).then((response) => {
if (response.data.status === 'success') {
alert("Email sent, awesome!");
} else {
alert("Oops, something went wrong. Try again")
}
})
The api/submit.js is as follows:
import nodemailer from "nodemailer"
var transport = {
service: 'gmail',
host: "smtp.gmail.com",
port: 587,
secure: false,
auth: {
user: process.env.USER,
pass: process.env.PASS
}
}
var transporter = nodemailer.createTransport(transport);
transporter.verify((error, success) => {
if (error) {
console.log("There was an error:" + error);
} else {
console.log("Server is ready to take messages")
}
})
export default async (req, res) => {
switch (req.method) {
case "POST":
var name = req.body.name;
var content = name " text "
var mail = {
from: name,
to: "myemail@gmail.com",
text: content
}
transporter.sendMail(mail, (err, data) => {
if (!err) {
res.json({
status: "success"
})
res.end();
}
})
break
case "GET":
res.status(200).json({name:"John Doe"})
break
default:
res.status(405).end()
break
}
}
The code works locally when I run npm run dev, or npm start it posts to http://localhost:3000/api/submit and I receive the email within seconds.
However, when I deploy the website on DigitalOcean and hit the submit button nothing happens for 60 seconds then I get a status code of 504 on my POST request. If I send a GET request to api/submit, it works and I see the JSON for that request, so it's an issue with the POST request specifically.
My Nginx logs it as the following:
2021/02/27 13:59:35 [error] 95396#95396: *3368 upstream timed out (110: Connection timed out) while reading response header from upstream, client: my.ip, server: website.com, request: "POST /api/submit HTTP/1.1", upstream: "http://127.0.0.1:3000/api/submit", host: "website.com", referrer: "https://website.com/contact"
I've been trying to debug it for days now, but I just can't figure it out. Anyone have any ideas?
EDIT 01.03.2021 The problem is resolved embarrassingly.
Turns out the ports were all open, telnet worked for all mail ports and smtp hosts.
When I hard coded the username/password e.g. for ephemeral mail user: "blah@emphemeral.email", pass: "fakepassword"; the email would send in production.
Turns out my process.env.USER and process.env.PASS were not being replaced with the values of process.env.USER/PASS in .env during npm run build, because I was cloning my GitHub repo, which didn't contain my .env file. After creating my .env file on the server and running npm run build the code worked fine.
Thank you for the replies, sorry for the hassle.
I suspect I'm not the first to do this but it's rather embarrassing.
First, I confirmed that the ports were all open, telnet worked for all mail ports and smtp hosts.
Then, when I hard coded the username/password e.g. for ephemeral mail user: "blah@emphemeral.email", pass: "fakepassword"; the email would send in production.
Then I realized that my process.env.USER and process.env.PASS variables were not being replaced with the true values of process.env.USER/PASS in .env during npm run build, because I was cloning my GitHub repo, which didn't contain my .env file. Meaning I was trying to login as username = "process.env.USER" and password = "process.env.PASS".
After creating my .env file on the server and running npm run build the code worked fine.
Thank you for the replies and sorry for the hassle.