I recently encountered a tough problem to understand. I have a project PHP project based on Laravel. One particular route was a generating a report, storing it to XLS, and downloading it for the user. Its a long report, and may take several minutes to process. (Before you mention we should be using queues, I know). Unexpected behavior was this:
- submit a POST to a route.
- system pulls data from database and from external APIs like Stripe and Easypost.
- system generates Excel spreadsheet for download.
- approximately 100 seconds into the process, the browser would redirect to the same route, but using a GET request.
If I chose shorter date ranges, it ran wonderfully. I knew it was a timeout behavior. Here are the steps I took to find the problem.
- PHP set_time_limit: PHP has a time limit set in its ini file. If you’re running 5.4 or newer, there is no safe_mode so you can use this to modify the time_limit. I set it to 0 as this report was behind an admin panel. If they want a long report, its up to them.
- File Generation: I used PHPExcel to generate the binary data. Originally, I was pushing it out php://output and setting headers directly. I changed it to store the file locally in a tmp directory (possible security issue, but there wasn’t anything sensitive in the file). Then I used Laravel’s Response::download() facade to push it down to the user.
- Apache’s TimeOut – Apache has a builtin timeout behavior as well. When the Apache process times out, it sends a 500 error code. Apparently, browsers when a 500 error code response is sent to a POST, the browser will respond with a GET request to the same URL. That’s why my page looked as if I was getting a redirect. The server wasn’t redirecting it, the browser was. Both Firefox and Chrome seemed to have the same bahavior. After bumping the Apache TimeOut length, I no longer suffered any issues.
This is the first time I’ve experienced getting a 500 code for a POST request and having the browser turn around and do a GET request for it. I hope this helps some poor soul suffering a similar issue.