JIRA Update custom fields using REST, PHP and cURL - php

I am trying to update some custom fields using the REST API and PHP/cURL.
I'm wondering if I might have edited something without realizing it, while what I have below "worked" yesterday (I think), it does not work now.
I get varying responses using the different "methods", from:
I get this one using the POST method, as it is uncommented below.
HTTP 405 - The specified HTTP method is not allowed for the requested
resource ().
I get this one if I use the commented-out PUT method, with POST commented out.
{"status-code":500,"message":"Read timed out"}
And this one mixing and matching PUT and POST.
{"errorMessages":["No content to map to Object due to end of input"]}
What am I missing/doing wrong? I am using the following code:
<?php
$username = 'username';
$password = 'password';
$url = "https://example.com/rest/api/2/issue/PROJ-827";
$ch = curl_init();
$headers = array(
'Accept: application/json',
'Content-Type: application/json'
);
$test = "This is the content of the custom field.";
$data = <<<JSON
{
"fields": {
"customfield_11334" : ["$test"]
}
}
JSON;
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
// Also tried, with the above two lines commented out...
// curl_setopt($ch, CURLOPT_PUT, 1);
// curl_setopt($ch, CURLOPT_INFILE, $data);
// curl_setopt($ch, CURLOPT_INFILESIZE, strlen($data));
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
$result = curl_exec($ch);
$ch_error = curl_error($ch);
if ($ch_error) {
echo "cURL Error: $ch_error";
} else {
echo $result;
}
curl_close($ch);
?>

The problem here is that PHP's cURL API is not particularly intuitive.
You might think that because a POST request body is sent using the following option
that a PUT request would be done the same way:
// works for sending a POST request
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
// DOES NOT work to send a PUT request
curl_setopt($ch, CURLOPT_PUT, 1);
curl_setopt($ch, CURLOPT_PUTFIELDS, $data);
Instead, to send a PUT request (with associated body data), you need the following:
// The correct way to send a PUT request
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
Note that even though you're sending a PUT request, you still have to use the CURLOPT_POSTFIELDS
option to send your PUT request body. It's a confusing and inconsistent process, but it's what you've
got if you want to use the PHP cURL bindings.
According to the relevant manual entrydocs, the CURLOPT_PUT option seems to only work for PUTting a file directly:
TRUE to HTTP PUT a file. The file to PUT must be set with CURLOPT_INFILE and CURLOPT_INFILESIZE.
A better option IMHO is to use a custom stream wrapper for HTTP client operations. This carries the
added benefit of not making your application reliant on the underlying libcurl library. Such an
implementation is beyond the scope of this question, though. Google is your friend if you're interested
in developing a stream wrapper solution.

Related

Why is PHP cURL PUT request not working despite getting status code 200 in return?

I've been stuck with this problem for a little while now. I am trying to use a REST API to change certain settings of a user like clear a user and set their device to inactive.
The REST calls are made in php which I am pretty new to. Most calls (get and post) are working just fine so I think I understood the basic concept of php and curl but I just can't get put requests working. The problem is that when making the REST call I get a status code 200 in return indicating that everything went fine but when I check the database nothing changed and the device is still active.
I've spent several hours researching this problem here on stackexchange (cURL PUT Request Not Working with PHP, Php Curl return 200 but not posting, PHP CURL PUT function not working) and additionally reading various tutorials.
To me my code looks fine and makes perfect sense because it is similar to many examples I found online. So please help me find my mistake.
$sn = "123456789";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://example.com/api/sn/".$sn);
$data = array("cmd" => "clearUser");
$headers = array(
'Accept: application/json',
'Content-Type: application/json'
);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$username = 'XXX';
$password = 'XXX';
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($ch, CURLOPT_POSTFIELDS,http_build_query($data));
$output = curl_exec($ch);
curl_close($ch);
So far as I can see, you have two problems in your code.
Content-Type: application/json is incorrect, I would remove it entirely.
You don't have a Content-Length header.
I suggest trying
$sn = "123456789";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://example.com/api/sn/".$sn);
$data = array("cmd" => "clearUser");
$httpQuery = http_build_query($data);
$headers = array(
'Accept: application/json',
'Content-Length: ' . strlen($httpQuery)
);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$username = 'XXX';
$password = 'XXX';
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($ch, CURLOPT_POSTFIELDS,$httpQuery);
$output = curl_exec($ch);
curl_close($ch);
You define in the Header 'Content-Type: application/json'. Try to encode your $data to json and then transfer the jsonEncodeteData:
$dataJson = json_encode($data);
curl_setopt($ch, CURLOPT_POSTFIELDS, $dataJson);
perhaps this helps already.
status 200 may not be a success in the case of a PUT request. In a correct semantics (correct implementation of the server) successful PUT returns "201 Created" and, if the client sends empty or somehow wrong content, the server returns "204 No Content".
Lazy programmers may just return "200 Ok" instead of 204 with the meaning "your request is fine, but there is nothing to do with the data".
Try to verify your data and make sure that you send something that is not empty and is conformal to the API specs.

XML in curl PHP

I am calling an API using CURL.
When I run it directly in browser or via ajax request it runs well and gives xml output.The Api am calling stores the xml in a database table and would only then work well.
However when I call it via PHP curl their table is not getting updated.
The code am doing it with PHP curl is
curl_setopt($ch, CURLOPT_URL, $api);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
$headers = array();
$headers[] = "Accept: application/json";
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
Sample URL : http://example.com/code=x05a&businessKeyValue=8519ada0-9e2f-e265-8698-5b6145af9704&entity=funded_program_concession&parameters=fpc_funded_program_concession_id%7C8519ada0-9e2f-e265-8698-5b6145af9704&parameters=fps_funded_program_subsidy_id%7Cf320f2d9-7c6a-0b56-2940-5b61147a0f3d
If I open this link which opens it in browser, it works good, but if I run it via curl the API is not receiving xml content.
How can I resolve this issue?
$api='http://example.com/code=x05a&businessKeyValue=8519ada0-9e2f-e265-8698-5b6145af9704&entity=funded_program_concession&parameters=fpc_funded_program_concession_id%7C8519ada0-9e2f-e265-8698-5b6145af9704&parameters=fps_funded_program_subsidy_id%7Cf320f2d9-7c6a-0b56-2940-5b61147a0f3d';
$ch = curl_init();
$headers = array();//put your headers only if you need them
curl_setopt($ch, CURLOPT_URL, $api);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result= curl_exec($ch);
return $result;
This should work for you. Inside your headers array make sure you put the headers you need and not extra. This is a simple curl, get call so i guess the above code will work without any trouble.
If you want to accept xml then you can got for Accept:application/xml or Accept:application/xhtml+xml
If the above methods don't work provide us with your error.
echo 'Curl error: ' . curl_error($ch);
Add the above line as a breaking point in your code and see what's the error.

How do I post to a Google script with cURL in PHP and return text?

I'm trying to do the bare minimum, just to get it working.
Here is my Google Script:
function doPost(e) {
return ContentService.createTextOutput(JSON.stringify(e.parameter));
}
Here is my PHP code:
$url = 'https://script.google.com/a/somedomain.com/macros/s/### script id ###/exec';
$data['name'] = "Joe";
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-type: multipart/form-data"));
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
// curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$result = curl_exec($ch);
$error = curl_error($ch);
Executing this, $result is true.
If I uncomment the CURLOPT_RETURNTRANSFER line, $result =
<HTML>
<HEAD>
<TITLE>Bad Request</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000">
<H1>Bad Request</H1>
<H2>Error 400</H2>
</BODY>
</HTML>
$error is always empty.
I would use doGet() but I need to send some rather large POSTs that will exceed what GET can handle.
How can I post to a Google script and return data?
------ UPDATE ------
I've just learned my lead developer tried this some time ago and concluded doPost() errors when returning so apparently it's not just me. My take is that Google is simply not reliable enough to use. I would love for someone to prove me wrong.
------ UPDATE 2 - THE FIX ---------
Apparently this was the problem:
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
needs to be:
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
No idea why http_build_query() caused it to error.
Try reading the documentation for CURLOPT_POSTFIELDS and you'll see that is says To post a file, prepend a filename with # and use the full path. That looks what you are trying to do. Note that in php 5.5, the CURLFile class was introduced to let you post files.
If you are using php 5.5 or later, you might try this:
$url = 'https://script.google.com/a/somedomain.com/macros/s/### script id ###/exec';
// create a CURLFile object:
$cfile = new CURLFile('file.pdf','application/pdf'); // you can also optionally use a third parameter
// your POST data...you may need to add other data here like api keys and stuff
$data = array("fileName" => $cfile);
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-type: multipart/form-data"));
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
// FROM THE DOCS:
// If value is an array, the Content-Type header will be set to multipart/form-data (so you might skip the line above)
// As of PHP 5.2.0, value must be an array if files are passed to this option with the # prefix
// As of PHP 5.5.0, the # prefix is deprecated and files can be sent using CURLFile
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
// set this to TRUE if you want curl_exec to retrieve the result
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$result = curl_exec($ch);
if ($result === FALSE) {
echo "The result is FALSE. There was a problem\n";
$error = curl_error($ch);
var_dump($error);
die();
} else {
echo "success!\n";
var_dump($result);
}
// this can give you more information about your request
$info = curl_getinfo($ch);
if ($info === FALSE) {
echo "curlinfo is FALSE! Something weird happened";
}
var_dump($info); // examine this output for clues
EDIT: If you are not getting any error, and $result comes back with something like "Bad Request" then you will need to inspect the result more closely to find out what the problem is. A well-behaved API should have informative information to help you fix the problem. If the API doesn't tell you what you did wrong, you can examine the curlinfo you get from these commands:
$info = curl_getinfo($ch);
var_dump($info); // examine this output for clues
if $result and $info don't tell you what you've done wrong, try reading the API documentation more closely. You might find a clue in there somewhere.
If you can't figure out what the problem is using these tactics, there's not much else you can do with your code. You'll need more information from the maintainers of the API.
You need to look at your HTTP Request header to see what is actually being posted.
When trouble shooting I add these options:
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_TIMEOUT,10);
curl_setopt($ch, CURLOPT_FAILONERROR,true);
curl_setopt($ch, CURLOPT_ENCODING,"");
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
CURLINFO_HEADER_OUT will add "request_header" to curl_getinfo()
You also want to look at these curl_getinfo() elements.
request_size
size_upload
upload_content_length
request_header

PHP - How to fire HTTP get request on a secured URL (HTTPS)?

I am trying to fire a HTTP GET request on a secured URL which asks for username and password. This is fine when I am using that from browser but I am not sure how to do that using PHP.
I have tried using the two methods:
1) Using Curl as suggested in here: Make a HTTPS request through PHP and get response
2) Using the file_get_contents as suggested in here: How to send a GET request from PHP?
But the first one didn't give me any response back. And the second one gave me the following error:
failed to open stream: HTTP request failed
And this is my code for the curl:
$url="https://xxxxx.com";
$ch=curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
and for the file_get_contents:
$url="https://xxxx.com";
$response=file_get_contents($url);
echo $response;
The URL will return a XML response for a API I am testing. Can someone point me to the right direction?
Thanks!
If we focus on the requirement to send a username and password because I suspect that's your main problem, try this
$ch = curl_init();
$url="https://xxxxx.com";
// OR - check with your server's operator
$url="http://xxxxx.com";
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
// or maybe
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
// - see http://stackoverflow.com/questions/4753648/problems-with-username-or-pass-with-colon-when-setting-curlopt-userpwd
// check the cURL documentation
$output = curl_exec($ch);
$info = curl_getinfo($ch);
// don't forget to check the content of $info, even a print_r($info) is better
// than nothing during debug
curl_close($ch);

getting results from a site using curl

I have been trying to post some variables to a site using POST method, using curl to get some results. I am posting to this link.
http://www.rasta.pk/Lhr/Lhr_Traffic.aspx
At this page you will see a drop down menu .. onchange some values are returned in "Yellow" colored table.
I have monitored this site and trying to get those results by making a post request to that link. But, I am getting "Bad Header" error. I have tried changing things but ubable to find a solution.
Here is my code:
"Canal Bank Rd",
"ScriptManager1 " => "UpdatePanelDDLRoads|DropDownRoads",
"__EVENTARGUMENT" => "",
"__EVENTTARGET" => "DropDownRoads"
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headerz);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
curl_setopt($ch, CURLOPT_REFERER, "http://www.rasta.pk/Lhr/Lhr_Traffic.aspx");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
curl_close($ch);
echo $output;
?>
There's too little details presented for us to know for sure.
A guess is that you're doing the wrong kind of post, since when you pass in a hash array to CURLOPT_POSTFIELDS it will do a multipart formpost which might not be what the server expects. Pass in a string instead to make a "normal" POST.
If that is not enough, use LiveHTTPHeaders or similar in a browser to figure out exactly what is sent in a "manual" session and then you make sure that your curl program mimics that operation as closely as possible.

Categories