hapijs / hapi

The Simple, Secure Framework Developers Trust
https://hapi.dev
Other
14.6k stars 1.34k forks source link

No response when payload is large #4482

Open cariolet opened 6 months ago

cariolet commented 6 months ago

Runtime

node.js

Runtime version

16.18.1

Module version

21.3.3

Last module version without issue

No response

Used with

No response

Any other relevant information

No response

What are you trying to achieve or the steps to reproduce?

1) Define a strategy 2) Define a post route for uploading large files (e.g. an image) 3) Assign the previously defined strategy to the route 4) Define a form-data client call to load a large file (e.g. 3/4 MB)

Below is the hapi server code to reproduce the error

const Hapi = require('@hapi/hapi')
const {unauthorized} = require('@hapi/boom')
const server = Hapi.server({
  port: 3000,
  host: 'localhost',
})
server.auth.scheme('testScheme', () => {
  return {
    authenticate: async (request, h) => {
      const err = unauthorized('Unauthorized from testScheme')
      return h.unauthenticated(err)
    }
  }
})
async function init() {
  server.auth.strategy('testStrategy', 'testScheme')
  server.route({
    method: 'POST',
    path: '/upload',
    options: {
      auth: {
        strategy: 'testStrategy'
      },
      payload: {
        maxBytes: 10 * 1024 * 1024,
        output: 'stream',
        parse: true,
        allow: 'multipart/form-data',
      },
    },
    handler: async (request, h) => {
      const { payload } = request
      const file = payload.file
      const filename = file.hapi.filename
      const data = file._data
      return h.response({ message: 'File uploaded successfully' })
    },
  });
  await server.start()
  console.log('Server running on %s', server.info.uri)
}
process.on('unhandledRejection', (err) => {
  console.log(err)
  process.exit(1)
})
init()

What was the result you got?

If the defined strategy returns an unauthorized route error, a "no response" is returned to the client

What result did you expect?

I expect it to return error 401

damusix commented 6 months ago

@cariolet I tried this on Node 16 / Hapi 21.3.3:

import { Server } from '@hapi/hapi';
import Boom from '@hapi/boom';

const server = new Server({
    port: 3000,
    host: 'localhost',
});

server.auth.scheme('custom', () => ({

    authenticate: (request, h) => {

        return h.unauthenticated(
            Boom.unauthorized()
        )
    }
}));

server.auth.strategy('custom', 'custom');

server.route({
    method: 'POST',
    path: '/',
    handler: (request, h) => {
        return 'Hello World!';
    },
    options: {
        auth: 'custom',
        payload: {
            output: 'stream',
            parse: true,
            allow: 'application/json',
            maxBytes: 10 * 1024 * 1024
        }
    }
});

const init = async () => {
    await server.start();
    console.log(`Server running on ${server.info.uri}`);
};

init();

and I get the following response:

curl localhost:3000 -d '{ "hello": true }'
{"statusCode":401,"error":"Unauthorized","message":"Unauthorized"}     

And using allow: 'multipart/form-data', yields the same response

Could you give a more complete example?

cariolet commented 6 months ago

Hi, It also returns 401 Unauthorized to me if I send a payload with little data. If I send a large payload (e.g. 3/4MB) I get "no response" and not 401 Unauthorized Thanks