php-mod/curl

PUT does not send data as content body

Closed this issue · 5 comments

I am using this class to integrate my REST API, now I get to the problem, that my application expects the data, which gets sent through PUT, to update an ressource in the content-body of the Request. (Using Symfony2 HTTP Components to parse Request)

As the RFC (http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html) indicates that the "enclosed entity" should be saved at the given URI, I would guess it should be within the Request body. It also states, that the "fundamental difference between the POST and PUT" methods are, that POST creates a new entity stored at the given endpoint and PUT updates the entity the URI points at.

Last-but-not-least I will reference to http://www.restapitutorial.com/lessons/httpmethods.html which also states, that the entity should be within the request body.

Am I wrong somewhere and Curl already does this in the background and the "fail" is on my side? As in the current implementation you append the data to the URI with http_build_query.

Hi,

Can you give me an example of your Code, I need to see how you are using this class to help me reproduce the bug and write a test for it.

Also give me an example of the data you expected.

Thank you.

I currently do something like this:

            $this->curl->reset(); 

            switch(strtoupper($method))
            {
                case self::MODE_GET:
                    $this->curl->get($url, $data);
                    break;
                case self::MODE_POST:
                    $this->curl->post($url, $data);
                    break;
                case self::MODE_PUT:
                    // $this->curl->put($url, $data);
                    $this->curl->setopt(CURLOPT_URL, $url);
                    $this->curl->setopt(CURLOPT_CUSTOMREQUEST, 'PUT');
                    $this->curl->setopt(CURLOPT_POSTFIELDS, http_build_query($data));
                    $this->curl->_exec();
                    break;
                case self::MODE_DELETE:
                    $this->curl->delete($url, $data);
                    break;
                case self::MODE_PATCH:
                    $this->curl->patch($url, $data);
                    break;
            }

            $response = new ApiResponse(
                $this->curl->http_status_code,
                json_decode($this->curl->response, true)
            );

I replaced the put() method of yours with the corrected version. This will send the data through the POSTFILEDS and thus in the request body to the endpoint I am talking with. Because this endpoint does only use the request body, not the query params to proccess the data I want to store under the resource I put them to.

Do you need an fully working example, with proccessing code on the endpoint side or is this sufficient to describe the problem on your side?

The biggest problem that I see is, that currently it would push the data through the query-part to the endpoint and not the request-body, therefore it would limit the usefulness of the PUT method and its something one would not expect after reading the RFC or working with other endpoint APIs where a PUT action wants the data within the request-body.

As I can see, You find out a working solution for you I think it is better for me to continue working in the 2.0 release for this librarie. You can see the alpha release here: https://github.com/php-mod/curl/releases

I hope you will like it.

Yea I already looked at it, like 45 minutes after the push of your 2.x branch.
I already think this will be much superior than your first version and I really look forward to integrate it in my application, as soon as it's at least beta or so.

I also got an idea how to use it for my PUT purpose. I just set the customRequest to PUT and then use the setPostFields() method to set the POSTFIELDS, which will be just like what I do now, but just with a bit more descriptive OOP involved.

$this->curl->setUrl('url/to/api/endpoint')
$this->curl->setCustomRequest('PUT');
$this->curl->setPostFields($data);
$response = $this->curl->execute();

Just to ask, will there be a function like the current reset() so I can reuse the Curl object without bothering resetting all my set fields (like the CustomRequest) of previous requests?

nadar commented

I am going to close this issue because:

  • Missing information's
  • No more activity
  • No one picked up the task (no Pull Request received)

If you think this is still important or there are more/new informations. Please reopen the issue and let us know.