5

The npm-request library allows me to construct HTTP requests using a nice JSON-style syntax, like this.

request.post(
    {
        url: 'https://my.own.service/api/route',
        formData: {
            firstName: 'John',
            lastName: 'Smith'
        }
    },
    (err, response, body) => {
        console.log(body)
    }
);

But for troubleshooting, I really need to see the HTTP message body of the request as it would appear on the wire. Ideally I'm looking for a raw bytes representation with a Node.js Buffer object. It seems easy to get this for the response, but not the request. I'm particularly interested in multipart/form-data.

I've looked through the documentation and GitHub issues and can't figure it out.

Nic
  • 4,319
  • 5
  • 29
  • 36
  • 1
    Use a network sniffer and see what's actually being sent over the socket, independent of your node.js code. – jfriend00 Aug 02 '19 at 23:51
  • I don't particularly want to set up a network sniffer and deal with the hassle of intercepting TLS connections. I want to do this in code. – Nic Aug 03 '19 at 00:05
  • If it's your own target server, you can temporarily allow http just for debugging or just from your endpoint or just in your local test network to avoid TLS for the sniffer. Sometimes you need to create conditions favorable for debugging. – jfriend00 Aug 03 '19 at 00:19
  • @jfriend00 It's not my own server. – Nic Aug 03 '19 at 00:20
  • Well `http://my.own.service` in your question made it look like it was. Anyway, you have plenty of other options. – jfriend00 Aug 03 '19 at 00:21
  • 1
    I don't know if this is an acceptable answer so I leave it as a comment for now but you can modify the file `node_modules/request.js` and add `console.log(arguments)` after this line: https://github.com/request/request/blob/master/request.js#L1493 – slebetman Aug 03 '19 at 02:48
  • Just so you know, ```request``` is deprecated. – little_monkey May 26 '20 at 13:22

5 Answers5

5

Simplest way to do this is to start a netcat server on any port:

$ nc -l -p 8080

and change the URL to localhost in your code:

https://localhost:8080/v1beta1/text:synthesize?key=API_KEY

Now, any requests made will print the entire, raw HTTP message sent to the localhost server.

Obviously, you won't be able to see the response, but the entire raw request data will be available for you to inspect in the terminal you have netcat running

Swayam
  • 580
  • 6
  • 11
4

I figured out how to dump the HTTP message body with Request. In both cases, I'm just copying the same approach that request uses internally.

Multipart Form Uploads

req._form.pipe(process.stdout);

URL-encoded Forms

console.log(req.body);
Nic
  • 4,319
  • 5
  • 29
  • 36
0

You could try @jfriend00 suggestion an use a network sniffer like wireshark but as you're fetching an https URL this might not be the easiest route as it requires some setup to intercept TLS connections.

So maybe it would be enough turning on debug mode for the request module itself, you can do that by simply setting require('request').debug = true. As a third option you could go with the dedicated debug module for request here which allows you to view request and response headers and bodies.

exside
  • 3,736
  • 1
  • 12
  • 19
  • The debug mode for `request` still doesn't print the HTTP message body, it just echoes the JSON object back to me in the same format I provided. – Nic Aug 03 '19 at 00:08
  • The `request-debug` module in its default configuration only shows the headers, not the message body. – Nic Aug 03 '19 at 00:11
0

I can think of a number of ways to see the bytes of the request:

  1. Turn on debugging in the request module. There are multiple ways to do that documented here including setting NODE_DEBUG=request or require('request').debug = true or using the request-debug module.

  2. Use a network sniffer to see what's actually being sent over the socket, independent of your node.js code.

  3. Create your own dummy http server that does nothing but log the exact incoming request and send your same request to that dummy server so it can log it for you.

  4. Create or use a proxy (like nginx) that can dump the exact incoming request before forwarding it on to its final destination and send the request to the proxy.

  5. Step through the sending of the request in the debugger to see exactly what it is writing to the socket (this may be time consuming, particularly with async callbacks, but will eventually work).

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • 1
    #4) You can use an existing proxy. It seems reasonable to insert nginx in front of the server to dump info like this: https://stackoverflow.com/questions/4939382/logging-post-data-from-request-body – Wyck Aug 03 '19 at 00:16
0

you could use a nodejs server capable of logging the raw request/response string , then direct your request to that server

i gave an example using both http and https server - no dependencies

nodejs getting raw https request and response