chimurai / http-proxy-middleware

:zap: The one-liner node.js http-proxy middleware for connect, express, next.js and more
MIT License
10.6k stars 828 forks source link

Setting followRedirects to true limits the form-data body size length to 10 MB #983

Open omarmhamza opened 2 months ago

omarmhamza commented 2 months ago

Checks

Describe the bug (be clear and concise)

Setting followRedirects option to true limits the form body size to 10 MB.

If you try to send a file through the form body that exceeds ~10 MB an error will be emitted.

Attaching the step-by-step reproduction instructions below.

Step-by-step reproduction instructions

  1. Create a proxy middleware on route /proxy. I am using a basic express.js REST API running on 8080.
    
    const proxy = createProxyMiddleware({
    router: {
      '/api': 'http://localhost:9080'
    },
    followRedirects:true,
    secure: false,
    on: {
      error: (err, req, res) => {
        console.log(err.message)
        res.end(err.message)
        return err
      }
    }
    });

app.use('/proxy',proxy)


2. Used a dummy server to simulate a server handling the proxied requests. I have attached the python code to create this dummy server. I am using Python 3.12.2, the script uses the built-in http server library. The script just handles post requests and reads the file from the form data (called filename)
The server is run on port 9080.

```python
from http.server import BaseHTTPRequestHandler, HTTPServer
import cgi
import time

class MyHandler(BaseHTTPRequestHandler):
    def do_POST(self):
        content_type, _ = cgi.parse_header(self.headers.get('content-type'))
        if content_type == 'multipart/form-data':
            form_data = cgi.FieldStorage(
                fp=self.rfile,
                headers=self.headers,
                environ={'REQUEST_METHOD': 'POST',
                         'CONTENT_TYPE': self.headers['Content-Type'], }
            )

            field_value = form_data['filename'].value
            file_field = form_data['filename']
            file_content = file_field.file.read()
            # time.sleep(6)   
            self.send_response(200)
            self.send_header('Content-type', 'text/html')
            self.end_headers()
            try:
                self.wfile.write(b"Form data received successfully.")
            except BrokenPipeError:
                pass  # Ignore broken pipe errors

        else:
            self.send_response(400)
            self.send_header('Content-type', 'text/html')
            self.end_headers()
            self.wfile.write(b"Unsupported content type.")

def run(server_class=HTTPServer, handler_class=MyHandler, port=9080):
    server_address = ('', port)
    httpd = server_class(server_address, handler_class)
    print(f"Starting server on port {port}...")
    httpd.serve_forever()

if __name__ == "__main__":
    run()
  1. Send a request to the proxy with the file called filename using a dummy large file exceeding 12MB
    curl -X POST -F "filename=@large_file.tar" http://127.0.0.1:8080/proxy/api
  2. Error will be emitted and logged: Request body larger than maxBodyLength limit

Expected behavior (be clear and concise)

The expected behavior is for the request to go through or have the max body length configurable when followRedirects is true.

How is http-proxy-middleware used in your project?

http-proxy-middleware@3.0.0

What http-proxy-middleware configuration are you using?

{
    router: {
      '/api': 'http://localhost:9080'
    },
    followRedirects:false,
    secure: false,
    on: {
      error: (err, req, res) => {
        console.log(err.message)
        res.end(err.message)
        return err
      }
    }
  }

What OS/version and node/version are you seeing the problem?

Windows 11 
Node v20.12.1

Additional context (optional)

No response