question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Retrieve the raw request body

See original GitHub issue

Please avoid duplicates

Context

I use nock to test that my server correctly sends webhook notifications. The requests are signed using the header x-hub-signature, a header containing a sha256 hash of the binary body data.

Ideally I would like to retrieve the raw body data in order to check that the header is consistent with this data.

Alternatives

As an alternative I can:

  • retrieve the body object value
  • retrieve the header value
  • use JSON.stringify() and Buffer.from() to recreate the (hopefully) same binary data
let notificationBody;
let signatureHeader;
nock("https://www.example.com", {
  reqheaders: {
    "x-hub-signature": value => {
      signatureHeader = value;
      return true;
    }
  }
})
  .post("/callback", body => {
    notificationBody = body;
    return true;
  })
  .reply(200);
// and once I sent the request:
const expectedSignature = `sha256=${createHmac("sha256", secret)
  .update(Buffer.from(JSON.stringify(notificationBody)))
  .digest("hex")}`;
expect(signatureHeader).toEqual(expectedSignature);

But with this approach, I am abusing the reqheaders property and the body function to extract the info, then a lot can go wrong (for example if the JSON isnt formatted the same way in my tested code or if the encoding isnt the same).

I feel that there could be a better way to do that.

If the feature request is accepted, would you be willing to submit a PR?

  • yes

Issue Analytics

  • State:open
  • Created 2 years ago
  • Comments:6 (4 by maintainers)

github_iconTop GitHub Comments

2reactions
gr2mcommented, Nov 30, 2021

I am refactoring the intercept logic right now, you can follow my progress at https://github.com/nock/nock/discussions/2247, the current code is at https://github.com/nock/nock/tree/code-review/modules/intercept-node-http. I had to expose an extra method which does not exist on Node’s native http.ClientRequest called nockGetRequestBodyAsBuffer in order to retrieve the request body for matching purposes.

I’m not a big fan of defining a dedicated method but I actually couldn’t figure out how to read the request body for a native http.ClientRequest object. My guess is the current workaround in nock is there because of the same reason?

The base issue IMO is one we’ve discussed a lot in the past in that there is no way to access requests after the fact for clean assertions, which means tests are forced to pull data out in the middle of matching.

Once I have the first version ready of the @nock/intercept-node-http module it would be good to discuss how to use this low level module for clean request body assertions. Then we can adopt that for a future nock version

0reactions
thomaslulecommented, Nov 30, 2021

Just curious: how come you don’t know the body? I’d expect a test to run in a fully controlled environment, where the same input always results in the same output?

The request body is generated by my tested code, I know most things about it except some details: it will contain a random uuid that I dont know beforehand (but I could probably make it predictable with a mock) + the formatting of the json is considered implementation detail. Technically I know how it’s formatted but I would prefer that my tests dont need to know that.

Off-topic question: can you elaborate on what you are trying to build? It seems that you are attempting to emulate webhook requests sent by GitHub? Are you trying to implement custom webhook requests for a GitHub App? If so, I think I’d rather implement custom routes

Of course! I work on a system that will emit webhook requests, it is unrelated to github but it mostly works the same way.

Off-hand, I think you access the req directly using this in the post callback.

Oh yes, apparently you can do that, but the object doesnt contain the body of the request.

The base issue IMO is one we’ve discussed a lot in the past in that there is no way to access requests after the fact for clean assertions, which means tests are forced to pull data out in the middle of matching.

Yeah I agree. I understand that the primary goal of this lib is to define predictable responses to http calls (and it does that very well 👏 ), but sometimes we also want to make assertions on the requests 😅

Read more comments on GitHub >

github_iconTop Results From Across the Web

Node.js - get raw request body using Express - Stack Overflow
The best way to get raw body in every API is to convert buffer into a string. enter image description here app.use( express.json({...
Read more >
Raw request body - HTTPie 3.2.1 (latest) docs
The universal method for passing request data is through redirected stdin (standard input)—piping. By default, stdin data is buffered and then with no...
Read more >
How do I get the raw request body from the ... - YouTube
How do I get the raw request body from the Request.Content object using .net 4 api endpoint and deserialise json string.
Read more >
Accepting Raw Request Body Content in ASP.NET Core API ...
If you want to send a RAW string or binary data and you want to pick that up as part of your request...
Read more >
Get raw request body in custom controller - Strapi Backend
const raw = ctx.request.body[Symbol.for("unparsedBody")];. Home · Categories ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found