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

Problem using Multer and withRemult #328

Open
SpeedoPasanen opened this issue Jan 23, 2024 · 3 comments
Open

Problem using Multer and withRemult #328

SpeedoPasanen opened this issue Jan 23, 2024 · 3 comments

Comments

@SpeedoPasanen
Copy link

Hi, I wonder if you can spot easily if I'm missing something or if there's a bug? I tried looking at withRemult SRC but couldn't see what could cause this.

So if I call api.withRemult before registering my route which uses Multer, my handler's callback never gets called if the file is larger than 10 KB. Seems like smaller than 10 KB files work. No error, the request just hangs indefinately before reaching my route.

If I remove withRemult or add my own handler before it, this works with large files, but obviously then I don't have remult context.

app.use(express.json({ limit: '500mb' }));
app.use(express.urlencoded({ limit: '150mb', extended: false }));
app.use(api, api.withRemult);
sceneFilesRoutes(app);
export function sceneFilesRoutes(app: Express) {
  const fileSize = 1024 * 1024 * 500;
  const storage = multer.memoryStorage();
  const upload = multer({
    storage,
    limits: { fileSize, fieldSize: fileSize }
  }).single('file');

  app.post('/apix/scene-files', upload, async (req, res) => {
    const s3 = S3Service.get();
    const repo = remult.repo(SceneFile);
    // We never get here if we use `withRemult` and the file is > 10 KB
    console.log('Handler Called');
@SpeedoPasanen
Copy link
Author

SpeedoPasanen commented Jan 23, 2024

By the way I did try disabling bodyParser in the options because I added it myself:

export const createApi = (initApi?: (remult: Remult) => void) =>
  remultExpress({
    getUser: (req) => (req as any).auth,
    entities,
    controllers: [],
    dataProvider,
    initApi,
    bodyParser: false
  });

@SpeedoPasanen
Copy link
Author

Seems I just found a fix, kind of. Use Multer before anything else, so it's used on all routes. Some extra overhead because I need it on just one route, but works...

const app = express();
const fileSize = 1024 * 1024 * 500;
const storage = multer.memoryStorage();
const upload = multer({
  storage,
  limits: { fileSize, fieldSize: fileSize }
}).single('file');
app.use(upload);
// Add remult, etc.

@noam-honig
Copy link
Collaborator

I've used multer with remult without a problem, here's a code sample from one of my projects:

const upload = multer({ storage: multer.memoryStorage() })
app.post(
  "/upload",
  upload.single("image"),
  api.withRemult,
  async (req, res) => {
    function forbidden() {
      res.status(403).send("forbidden")
    }
    if (!remult.authenticated()) return forbidden()
    if (!(await remult.repo(PatientImage).findId(req.body.id)))
      return forbidden()
    const image = imagesPath + createId()
    await remult.repo(PatientImage).update(req.body.id, {
      base64Image:
        "data:image/png;base64," + req.file?.buffer?.toString("base64"),
      image,
    })

    res.status(200).send(image)
  }
)

You don't need to set the JSON and URL-encoded prior to result as we don't need it - you can set them after.

If you need me to dive deeper into it, please reproduce it in a code sandbox and I'll be happy to have a look.

Here's a code sandbox you can use as a starting point:
https://githubbox.com/remult/react-vite-express-starter

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

2 participants