Skip to content

multipart data parser issues #350

@George2029

Description

@George2029

POST HTTP request results in connection drop (HTTP client gets as response something like: curl: (52) Empty reply from server, err_empty_response, socket hang up), if the request handler contains multidata parsing via req.multipart and it takes a long time to process.

The example server handles 3 requests:

/regular-long -- takes 15s to process, test request is successful.
/multipart-fast -- uses hyper-express multipart parser, takes 5s to process, test request is successful.
/multipart-long -- uses hyper-express multipart parser, takes 15s to process, test request is unsuccessful.

import { Server } from 'hyper-express';

const app = new Server({
  max_body_length: 4 * 1024 * 1024,
});
const PORT = 3000;
app.get('/regular-long', async (_, res) => {
  await new Promise((resolve) => setTimeout(resolve, 15000));
  res.send('OK');
});
app.post('/multipart-long', async (req, res) => {
  const formData = {};

  try {
    await req.multipart(async (field) => {
      if (field.file) {
        const chunks = [];
        for await (const chunk of field.file.stream) {
          chunks.push(chunk);
        }
      } else {
        formData[field.name] = field.value;
      }
    });

    await new Promise((resolve) => setTimeout(resolve, 15000));
    res.send(JSON.stringify({ success: true, formData }));
  } catch (err) {
    console.error('Error:', err);
    res.status(500).send(JSON.stringify({ error: err.message }));
  }
});

app.post('/multipart-fast', async (req, res) => {
  const formData = {};
  try {
    await req.multipart(async (field) => {
      if (field.file) {
        const chunks = [];
        for await (const chunk of field.file.stream) {
          chunks.push(chunk);
        }
        console.log(`File size: ${Buffer.concat(chunks).length} bytes`);
      } else {
        formData[field.name] = field.value;
        console.log(`Field ${field.name}: ${field.value?.substring(0, 50)}...`);
      }
    });

    await new Promise((resolve) => setTimeout(resolve, 5000));

    res.send(JSON.stringify({ success: true, formData }));
  } catch (err) {
    console.error('Error:', err);
    res.status(500).send(JSON.stringify({ error: err.message }));
  }
});

app
  .listen(PORT)
  .then(() => {
    console.log(`Server running on http://localhost:${PORT}`);
  })
  .catch((err) => console.error('Server error:', err));

Another parsers or HTTP libraries do not have this issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions