Luracast / Restler

Simple and effective multi-format Web API Server to host your PHP API as Pragmatic REST and/or RESTful API
http://luracast.com/products/restler/
GNU Lesser General Public License v2.1
1.36k stars 315 forks source link

PUT without body fails #622

Closed RolandRosenfeld closed 3 years ago

RolandRosenfeld commented 5 years ago

I defined a function like this:

   /**
    * Unlock user
    *
    *  comment
    *
    * @url PUT {username}/unlock
    * @param string $username {@from path} Username
    */
   public function unlock($username)
   {
      ...
   }

Which takes exactly one parameter, that is transported in the URL.

On an old server (with an ancient PHP version) this was usable by

curl  -X PUT 'https://soap/usermanage/myusername/unlock'

After an upgrade to a newer server with PHP 7 this fails with 400 Bad Request: Error parsing JSON, malformed JSON and I have to send a body with this call like

curl  -X PUT 'https://soap/usermanage/myusername/unlock' -d ''

or

curl  -X PUT 'https://soap/usermanage/myusername/unlock' -H "Content-Type: application/json" -d '{}'

Also explorer/swagger fails on this PUT function with only one parameter in the path, because it doesn't allow me to enter a body but runs into the 400 Bad Request: Error parsing JSON, malformed JSON error.

A different PUT function with a second parameter, that is sent via POST works without problems:

   /*
    * @url PUT pw/{username}
    * @param string $username Username
    * @param string $newpw {@from body} new password, which should be set

since it always uses a non empty POST body.

Any idea how to work around this on the restler side? Currently we have to modify all our clients to send an empty {} JSON body on the unlock requests.

nicodeboer76 commented 4 years ago

I have fixed this by changing the following code in Restler.php (approx. line 562):

        if ($this->requestFormat instanceof iDecodeStream) {
            $r = $this->requestFormat->decodeStream($stream);
        } else {
            $contents = stream_get_contents($stream);
            if ($contents === '') {
                return array();
            }
            $r = $this->requestFormat->decode($contents);
        }

PHP 7.x has changed the behaviour of json_decode. See: https://bugs.php.net/bug.php?id=71718

Arul- commented 3 years ago

This is now working fine with the latest changes to restler 5!