Layton Everson Layton Everson - 8 months ago 50
PHP Question

Simultaneous file uploads return 403 forbidden with nginx, and php-fpm

I have an application that allows simultaneous file uploads via drag and drop. This application currently:

  • Has 3 versions of it's instance local, staging, production.

  • Runs
    php 5.6

  • Built on the CakePhp2.

Here is the problem I'm having:

  1. I upload 1 image, 1 succeeds, everything works.

  2. I upload 2 images, 1 succeeds, 403 is returned for second upload request.

  3. I upload 3+ images, 1 succeeds, 403 is returned for all other requests, user is logged out of application (session expires)

This happens anytime there are multiple concurrent posts. They do not have to be file uploads.

This feature works on all servers except the staging server. Local dev machines and the production box do not have this issue.

Files are uploaded by drag and drop onto the page. Each file is uploaded via ajax in a separate request.

Size doesn't matter small images fail as well as larger images.

I'm looking for mis-matching config parameters between environments but the difference is not obvious yet. Any ideas what I should check?

My nginx site config:

server {
listen *:443 ssl;

server_name ;

ssl on;
ssl_certificate /site.crt;
ssl_certificate_key /site.key;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
client_max_body_size 256m;
index index.html index.htm index.php;

access_log /var/log/nginx/site.access.log;
error_log /var/log/nginx/site.error.log;

root /var/www/site/webroot;

location / {
root /site/webroot;
try_files $uri $uri/ /index.php$is_args$args;
autoindex off;
index index.html index.htm index.php;

location ~ \.php$ {
set $path_info $fastcgi_path_info;
fastcgi_index index.php;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
try_files $uri $uri/ /index.php$is_args$args;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;

sendfile off;


I discovered the answer to my question. The problem lived within CakePhp2's session configuration. The auto-regenerate option was set to true cause the application to generate a new session id for each request. After the second request came in, it didn't know the new session id. By the time the third request came in the session ID was lost all together.

Resources that led to discover of solution are here:

How to resolve "ajax 403 error forbidden in CAKEPHP 2.x"

CakePHP 403 on AJAX request

I hope this question helps the next guy that comes across something like this.