Overcoming the non availability of PUT and DELETE methods on commercial servers


#1

I developed an Apigility REST API with DBConnect and was working fine on my local XAMPP server with MySql. However uploding it to a commercial server the API stops responding to PUT, DELETE, and OPTION http methods. First I suspected that it was related to protocol being HTTPS, but soon it proved I was wrong and my research indicated most commercial servers does not by default allow PUT and DELETE.

I research on apache to see what can be done about it. Most solutions given with “.htaccess” file filter and redirect commands did not work. The only working solution required me to edit the apache config files to which I did not have access to.

However there was one alternate solution provided on a ASP.net platform using “X-HTTP-Method-Override” header. I first tried to figureout how I could get this working on Apigility. Failing on this I asked help from Matthew Weier O’Phinney who instructed me to post this on the forum and directed me here.

However while waiting for Mathew’s responce I figured it out my self nd implemented the following solution with success. However the method I followed needed tinkering an Apigility core code. I am sure there is a better way (As I once saw it being done elsewhere with HTTP) of using Method overriding.

Here is my solution. In order to get the PUT and DELETE functions to work with the new X-HTTP-Method-Override header is to intercept the Request headers and check if the request is passed with the “X-HHTP…” header and if so return the method as given in the x-http header.

In order to do the above I had to modify the “Request.php” file in “vendor/zendframework/zend-http/src/” folder. I had to change the “getMethod()” method in the script to check for presence of the extra header and respond accordingly.

 public function getMethod()
{
    // ------ WCD modification------
    $header = $this->getHeaders()->get('X-HTTP-METHOD-OVERRIDE');
    if ($this->method == 'POST' && false !== $header && $header->getFieldValue() === 'PUT')
    {
        return 'PUT';
    }elseif ($this->method == 'POST' && false !== $header && $header->getFieldValue() === 'DELETE') {
       return 'DELETE';
    }else{
        return $this->method;
    }
    // ------------------
    //return $this->method; //the original code from Zend
}

You may need to convert the case of PUT and DELETE in the comparison above, which I have not done here.

Once the above modification is done, all you need to do is to call POST insted of PUT or DELETE in your http call.

NOTE Remember to call the post method with an empty array for the payload in delete. Usualy the delete(id, options) should be as post(id,[],options). The PUT insted of put(id, data, options), post(id, data, options) where “id” is the resource ID, “data” is the body or payload and “options” are the extra headers and query strings which holds the “X-HTTP-Method-Override:PUT[DELETE]” header.

If you have Oauth enabled you need to specify and enable the “X-HTTP-Method-Override” header in the CORS config file.

Hope osome one can give a better more profesional solution than this.


#2

Take a look at this module to see if it suits your need:


#3

Thanks and it looks like a better solution. Let me try this out.