0
I’m trying to send the data both in the URL and in the body using PUT the idea was to make it work exactly like the POST method, but being the PUT method.
This is because I see many requests where the url would be for example /book/ and in the body would have a JSON (with the data used to update the element of that id).
I’m trying to do this using libcurl in C++, but despite the REQUEST_METHOD come PUT i do not receive the data. The implementation of POST, GET and DELETE send the data. I am having problems exclusively with PUT at first.
// Code in C++
I9CorpResponse * I9CorpRequest::request(int method, const char *url, const char *body, I9CorpRequestOptions * options) {
I9CorpResponse * response = nullptr;
long statusCode;
CURLcode res;
CURL *curl;
char mBufferHeader[I9CORP_BUFFER_MESSAGE];
char mTmp[I9CORP_BUFFER_MESSAGE];
std::map<std::string, char *> mHeaders;
struct curl_slist *chunk = nullptr;
char *mBufferParam = nullptr;
std::string content;
curl = curl_easy_init();
if (curl == NULL) {
return nullptr;
}
curl_easy_setopt(curl, CURLOPT_URL, url);
/* example.com is redirected, so we tell libcurl to follow redirection */
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
if (options != nullptr) {
std::map<std::string, char *>::iterator it;
mHeaders = options->getHeaders();
it = mHeaders.begin();
for (it = mHeaders.begin(); it != mHeaders.end(); ++it) {
snprintf(mBufferHeader, I9CORP_BUFFER_MESSAGE, "%s: %s\0"
, it->first.c_str()
, it->second);
chunk = curl_slist_append(chunk, mBufferHeader);
}
if (chunk != nullptr) {
res = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
}
if (body == nullptr) {
mBufferParam = options->createQueryParams();
}
}
switch (method) {
case METHOD_GET:
snprintf(mTmp, I9CORP_BUFFER_MESSAGE, "%s?%s\0", url, mBufferParam);
curl_easy_setopt(curl, CURLOPT_URL, mTmp);
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L);
break;
case METHOD_POST:
curl_easy_setopt(curl, CURLOPT_POST, 1L);
if (body != nullptr) {
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body);
} else if (mBufferParam != nullptr) {
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, mBufferParam);
}
break;
case METHOD_PUT:
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT");
if (body != nullptr) {
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body);
} else if (mBufferParam != nullptr) {
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, mBufferParam);
}
break;
case METHOD_DELETE:
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE");
snprintf(mTmp, I9CORP_BUFFER_MESSAGE, "%s?%s\0", url, mBufferParam);
curl_easy_setopt(curl, CURLOPT_URL, mTmp);
break;
}
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, I9CorpRequest::callbackDataWrite);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &content);
/* Perform the request, res will get the return code */
res = curl_easy_perform(curl);
if (mBufferParam != nullptr) {
free(mBufferParam);
}
/* Check for errors */
if (res == CURLE_HTTP_RETURNED_ERROR) {
response = new I9CorpResponse();
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &statusCode);
response->setStatusCode(statusCode);
} else if (res != CURLE_OK) {
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
} else {
response = new I9CorpResponse();
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &statusCode);
response->setStatusCode(statusCode);
response->setContent(content.c_str());
}
/* free the custom headers */
if (chunk != nullptr) {
curl_slist_free_all(chunk);
}
/* always cleanup */
curl_easy_cleanup(curl);
return response;
}
In the examples I’m doing the body is nullptr and mBufferParam has content
"lastname=Brito&name=Sileno&username=test"
To test I wrote the following code in PHP, but I can’t read the values, as they don’t arrive in php.
<?php
var_export(
array(
'server'=> $_SERVER,
'get'=> $_GET,
'post'=> $_POST,
'request'=> $_REQUEST
)
);