Pregunta

The goal

I want to show meaningful message to my client when the file they try to upload is too big.

The problem

Right now my mod_fcgid throws 500 Internal Server Error when I try to send too big request. I don't know how can I tell this error from following:

  • PHP error when display_errors was set to 0
  • request uri too long
  • bad rewrite rules
  • other bad configuration
  • something completely different

If I am to tell my client "hey you, you tried to upload too big file" in a 500 ISE handler, it will also trigger for all of above, which makes no sense.

Things I've tried

The only thing I can currently do is to redirect all errors using ErrorDocument 500 /generic-500.php. Dumping $_SERVER and $_REQUEST doesn't show anything useful.

I could bypass the problem in an ugly way by:

  1. creating AJAX wrapper on the form
  2. making it append custom header for this form alone
  3. check for this header when I'm redirected to 500 ISE

But it's rather stupid and I'd have to remember doing this for every upload form.

The question

How can I either detect reason for 500 ISE in PHP or reconfigure my server so that I can detect too big uploads in PHP upon receiving POST request?

¿Fue útil?

Solución

Dumping $_SERVER and $_REQUEST [inside 500 error handling script] doesn't show anything useful.

What about $_SERVER['CONTENT_LENGTH'], have you checked that? If that value was still “intact” inside the error handling script and has the value the client initially send, that could be something to go on.

Apart from that, it seems quite hard to react to such an error with PHP – that would have to be handled at mod_fcgid level first of all, so that it still calls the script (or any script, for that matter) with the relevant information; but from the docs I can’t see any way to do that.

As a workaround, you could try and set up a different ErrorDocument script specifically for the scripts that are the endpoints that handle your file uploads – f.e. by using that directive inside of a FILES directive, that encompasses only your upload handling scripts.
That way, if your “special” 500 error script gets called, there would be quite a high chance that the reason might have been that too large a file was uploaded – and you could tell the user that, that the most likely reason for them seeing this error page was that.
Of course you would have to try everything you can to make sure that there are no other reasons why a 500 may occur for these scripts specifically – as you already said, that’s a bit of a p.i.t.a. too, and may not even be possible in a totally reliable way … but maybe it’s a start.

And on top of that, it might be a good idea to try and prevent this from happening before the upload even starts, client-side – adding a maxlength attribute to the file upload field might not stop each and every existing browser out there, but for those that do respect it, it might help mitigate the problem before it even occurs. (HTML5 has specified that attribute; though I haven’t checked yet in what way it can be used in combination with HTML5 form validation to alert the user to the specific error reason in that case.)


As a side note: From an HTTP point of view, answering with a status code 500 in such a case seems not really appropriate – 413 Request Entity Too Large exists, and should IMHO be considered the proper response in situations like this. Too bad mod_fcgid doesn’t do it that way automatically, because that would basically resolve the problem without further effort.

Otros consejos

This is weird but you can't know the request's length since request doesn't completed because of interrupted by your server.

The best thing you can do is increasing limit for the size of the request body using FcgidMaxRequestLen directive pretty high. After request handled by your server without producing any 500 Server Error and reached to the application, you can validate the content in your application and return a meaningful message to user.

What about set_file_buffer($f, $b)? You can set the buffer size there - if you can't make that work, I would use the output buffer methods to control it...

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top