Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

POST Request sending only the first 36 characters without Content-length header #1367

Closed
sam-huckaby opened this issue Jan 23, 2015 · 2 comments

Comments

@sam-huckaby
Copy link

I am seeing a strange issue where I try to send a JSON object via POST, and Request is only putting the first 36 characters into the body, unless I include a Content-length header. I can send the exact same request using the Postman REST client without the header and the entire data is submitted.

app.post(modulePath + '/password/request_reset', function(req, res){
            var email = req.body.email;
            var data = {};
            data.email = email;
            data.link = req.headers.origin + "/reset_password/";
            // At this point, data looks like this:
            // {"email":"sam.huckaby@website.com","link":"http://website:3333/reset_password/"}
            // This is required, otherwise I will only get the first 36 characters
            req.headers['Content-length'] = JSON.stringify(data).length;
            request({
                url: apiPath+routes.FORGOT.password,
                method: "POST",
                headers: req.headers,
                timeout: 10000,
                followRedirect: true,
                json: true,
                body: data
            }, function (response, body) {
                // success
                res.status(response.statusCode).send(body);
            }, function (response, error) {
                // error
                res.status(response.statusCode).send({message: error});
                return false;
            });
        });

Has anyone else seen this issue? Or is there something wildly wrong with my code?

@nylen
Copy link
Member

nylen commented Jan 23, 2015

There are several issues with your code. Your incoming request has a Content-length header, and I bet it's 36. Unless you override it, this gets sent on to request, which you don't want to do.

Passing headers from the client on to an API server is a really bad idea in general, you'll want to whitelist the allowed headers. I'd also suggest using caseless to handle casing for you, something like this:

var caseless = require('caseless');

var reqHeaders = caseless(req.headers),
    whitelist  = ['header1', 'header2'],
    apiHeaders = {};

whitelist.forEach(function(name) {
    if (reqHeaders.has(name)) {
        apiHeaders[name] = reqHeaders.get(name);
    }
});

request({
    url : ...,
    headers : ...
}, function(err, response, body) {
    if (err) {
        res.status(400).send({ message : err.message });
    } else {
        res.status(response.statusCode).send(body);
    }
});

Note I didn't whitelist the allowed values for each header, you'll probably want to do that too. In fact it's probably better to not even allow the client to pass header values to the API server.

Finally, I also changed your callback code - as written, your second callback would never be called, and your first one had incorrect parameters. We only accept one callback with signature err, response, body, and if there is an error then response and body will not be set.

@ihsan-driveyello
Copy link

@nylen I made the mistake of forwarding the headers from a request in to a request out and my content-length was limited. We were getting the strangest issues. After 3 days of bug fixing your advice worked.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants