Ritz
Ritz

Reputation: 1253

Read timed out. error while sending a POST request to a node.js API

I have a node.js API as below to which I send a POST request from python as below,the issue am facing is if I remove the headers={"Content-Type": "application/json"} the POST goes thorugh,if not i get a Read timed out. error, can anyone provide guidance on how to fix this timeout error ?

node.js endpoint

app.post("/api/bats_push",(req, res) => {
        //console.log("Calling bats_push...")
        const d = {
            method: req.method,
            headers: req.headers,
            query: req.query,
            body: ''
        }

        req.on('data', (c) => {
            //console.log(c)
            d.body = d.body + c
        });

        req.on('end', () => {
            DATA.push(d);
            res.end('Saved BATS job details');
            //res.status(200).json({
              //message: "Saved BATS job details",
              //posts: req.body
          //}); 
        });
});

Python POST

try:
json"},timeout=10.0)
    r = requests.post(webhook_url,data=json_data.encode("utf8"),verify=False,headers={"Content-Type": "application/json"})
    print "posted"
    print(r.status_code, r.reason)
    print r.url
    print r.text
except Exception as e:
    print (e)

Error:-

  InsecureRequestWarning)
HTTPSConnectionPool(host='company.com', port=443): Read timed out. (read timeout=10.0)

Upvotes: 6

Views: 2688

Answers (4)

Tomas
Tomas

Reputation: 1694

I seems that you are using express.js. I believe that your problem is, that body is actually already parsed. You can check it by reading req.body. The situation is caused because express.js already read whole body (due to the content type) and trying to read body again will cause timeout (event data and event end are not emitted). There are several ways how to fix it.

  1. disable express.js body parser - or reconfigure it to ignore json

  2. remove reading body code and use directly req.body

app.post("/api/bats_push",(req, res) => {
        //console.log("Calling bats_push...")
        const d = {
            method: req.method,
            headers: req.headers,
            query: req.query,
            body: req.body
        }

        DATA.push(d);
        res.end('Saved BATS job details');
});

Upvotes: 1

lanhao945
lanhao945

Reputation: 450

From your question,the key word is:

if I remove the headers={"Content-Type": "application/json"} the POST goes thorugh.

The reason may clear:it is a wrong way use about the header.

Simpler say: the node.js app check the header before into the logic code.

if do not send the header by ourself,the requests part use the default headers below:

{
  'User-Agent': 'python-requests/2.22.0', 
  'Accept-Encoding': 'gzip, deflate', 
  'Accept': '*/*', 
  'Connection': 'keep-alive', 
}

through the requests's code can print the default headers when post.

you just use the header

{"Content-Type": "application/json"}

may resulting in the node.js app think the reqeust not legitimate(the word I do not know how to explain in English).

If the node.js app is developed by yourself, you can try to find the frame's check after create a tcp connection and before the logic code,the way is to read the source code.

If the node.js app is not developed by yourself,try to change the header mixing the default header to find which header key checked by the node.js app.

But in my thought,It is import ,about the node.js app's interface description:

we just use by interface description engouth,just need to know the error from the api header's check, which the description should show but not show to us?

Hope to help you.

Upvotes: 0

Hobey823
Hobey823

Reputation: 272

Looks like it could be something related to your SSL. Check if you get the same error sending a request to your localhost with the server running.

Upvotes: 0

Narcisse Doudieu Siewe
Narcisse Doudieu Siewe

Reputation: 1104

according to requests why not use this:

#replace this 
r = requests.post(webhook_url,data=json_data.encode("utf8"),verify=False,headers={"Content-Type": "application/json"})

#by this...assuming that 'data' is a dict
r = requests.post(webhook, json=data, verify=False)

Upvotes: 0

Related Questions