Fernando André
Fernando André

Reputation: 1213

How to Allow PUT DELETE on nginx for form submission

I have a normal PHP script listening for $_SERVER["REQUEST_METHOD"] and I do the form submission using the PUT method, but I get error 405 on the nginx server.

Just want to submit a simple form using request methods.

  1 server {                                                                        
  2                                                                                 
  3  listen   80; # port 80 default                                                 
  4                                                                                 
  5  root /home/user/workspace/l; # default directory where the files will be stored and served from
  6                                                                                 
  7  index index.php index.html index.htm; # index defined to be served under directory
  8                                                                                 
  9  server_name l; #name of the virtual host or domain                  
 10                                                                                 
 11 error_log /var/log/nginx/l.error.log;                                       
 12 access_log /var/log/nginx/l.access.log;                                     
 13                                                                                 
 14                                                                                 
 15  location / {                                                                   
 16    try_files $uri $uri/ /index.html;                                            
 17  }                                                                              
 18                                                                                 
 19 # Serve PHP scripts to FastCGI server our php-fpm server listening on 127.0.0.1:9000
 20                                                                                 
 21  location ~ \.php$ {                                                            
 22   fastcgi_pass 127.0.0.1:9000;                                                  
 23   # With php5-fpm:                                                              
 24   #fastcgi_pass unix:/var/run/php5-fpm.sock;                                    
 25   fastcgi_index index.php;                                                      
 26   fastcgi_split_path_info ^(.+\.php)(/.*)$;                                     
 27   include fastcgi_params;                                                       
 28   fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;            
 29   }                                                                             
 30 }   

The request call is /index.php?groups

The initial call was:

function updateGroup(group_name, group_id) {
    values = {};
    values.name = group_name;
    values.id = group_id;
    $.ajax({
        url: '?groups',
        type: 'PUT',
        data: values,
        success: success,
        dataType: 'json'
    });
}

Upvotes: 1

Views: 4254

Answers (3)

OffTheBricks
OffTheBricks

Reputation: 444

As the other answers point out, nginx does not permit methods other than GET or POST to static resources. You therefore need to ensure that the request goes directly to your php handling.

Most configurations I came across work fine if you're making a call directly to index.php, or any specific php file. The problem arises when you want calls to / to be handled by index.php but you still want to support static resource serving.

After working through this for a while I discovered that you're able to nest location directives in the nginx configuration. This allows you to control your file extension regex configuration without making things too complicated. Here's what I'm using. Note that your php cgi config is in a separate file.

location ~ .+(?<!\.php)$ {
  location ~ ^[^.]*\.[^.]+$ {

  }
  location ~ / {
    include snippets/fastcgi-php.conf;
  }
}

location ~ \.php$ {
  include snippets/fastcgi-php.conf;
}

Upvotes: 0

Alex Howansky
Alex Howansky

Reputation: 53656

nginx will only allow GET for static files. In order to allow POST/PUT, nginx has to be configured to send the request through to PHP. So, the fact that you're getting a 405 on a PUT would seem to indicate that you're requesting a static file, which would mean that your nginx configuration is not invoking PHP where you think it is. This can be tested pretty easily by requesting the same URL with GET -- if it's configured correctly, you'll get PHP output. if it's configured incorrectly, you'll get PHP source code.

Upvotes: 2

Erik Johansson
Erik Johansson

Reputation: 1656

This is not supported in the HTML specification, so browsers will instead send a GET request if the form method isn't either GET or POST. So it's already too late once the request reaches your server.

This issue is commonly addressed in frameworks via "method spoofing". Set up your form like this:

<form method="post" ...>
    <input type="hidden" name="_method" value="put" />
    ...
</form>

Then use this information in PHP to evaluate how to route the request.

It might also be possible to accomplish this on the Nginx layer already, but I'm afraid I can't advise on that.

Upvotes: 0

Related Questions