I am working with a vendor's API. In the documentation they state:
"... will generate up to 2 response messages for each command. The first response will be an
acknowledgement message that indicates the message was received and parsed...
The second response will indicate the result of the command. Some commands may take a while to complete, so the manager should not expect an immediate response to commands. If an error occurred during the execution of the command, the response will contain an error message."
Is there a way to make cURL wait for a second response?
$ch = curl_init('http://myserver.com');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, "XML=".$data_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: plain/xml'));
$result = curl_exec($ch);
It seems like this was an error in what I was sending the API, not the response. I have fixed the XML structure and received an appropriate response. However, I still think the documentation is written poorly.
It sounds like you will need to wait and check the same URL over and over until you get the data and not a status message. Not very optimal. Ideally they would let you pass a URL for them to POST back to when the result is ready.
Related
I currently have a Laravel application, which is doing a CURL request from one route to another route within the same route. My CURL looks like this:
//LOGGING THAT A CURL CALL IS ABOUT TO BE MADE
$url = env('APP_URL') . '/tests/add/results';
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //return server error
curl_setopt($ch, CURLOPT_HEADER, FALSE);
curl_setopt($ch, CURLINFO_HEADER_OUT, FALSE);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $test_post_data);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
$response = curl_exec($ch);
In the route, that the POST is being sent to, the first thing i log, is the request data:
//LOGING THAT I RECEIVED THE CURL CALL in receiving function
I'm noticing, that the logs for the request data get logged exactly the same amount of time as the timeout, meaning the request is actually being sent 10 seconds after the initial call.
In my logs i'll see something like:
10:10:10 - LOGGING CURL CALL
10:10:20 - Recieving CURL call
If i change the timeout to 30, then the log shows 30 seconds later that i received the CURL call.
Does anyone have any idea why this may be happening?
The response from the CURL just comes back as false always.
I did the following to make a post request work:
Instead of calling the route via CURL i did a post directly to the route function
$testController = new TestsController;
$test_data_request = new \Illuminate\Http\Request();
$test_data_request->setMethod('POST');
$test_data_request->request->add( $test_post_data );
$testId = $testController->addTestResults($test_data_request);
You've not provided enough information, but i think, the problem will be one or more of the following:
The WebServer http://127.0.0.1:8000 is not running
The script located on http://127.0.0.1:8000/tests/add/results is running too long and the request timeouts before it is completed
The requested path is returning redirect headers and creates an infinite loop
The response is too big to finish the data transfer in thirty seconds (very wierd if on localhost)
Try some more debugging and provide more information on this, so we may help you.
PS: Firstly i would try to catch the headers (curl_setopt($ch, CURLINFO_HEADER_OUT, true);) and print out the response (var_dump($response);) - or save it to some file :)
I've been going round in circles trying to get this bit of code working. The problem I am facing is that there could be any number of places where something is wrong and I'm not experienced enough with cURL and API requests to know if I've just done something simple and silly somewhere. The code below is supposed to fetch a JSON response. What I am currently getting is "false". The API developer keeps giving me a CLI sample and I don't know how to "translate" that into something I can use in PHP.
I have to hide the domain, service name and authentication details in my examples.
The string I was given:
'https://[domain]/agw/latest/services/[service]-api/latest/api/v2/[service]-actual-prizes -vk -H "Proxy-Authorization: Basic [authstr]"'
([authstr] is the username and password, separated by a colon and BASE64 encoded - the API dev has confirmed that my authorisation string is correct)
What I have been trying:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://[domain]/agw/latest/services/lottery-api/latest/api/v2/sportka-actual-prizes');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Proxy-Authorization: Basic '.$authstr.'"
,"Content-type: application/json"
));
$response = curl_exec($ch);
curl_close($ch);
var_dump($response);
If I understand this correctly (and I'm not sure that I do), then I'm passing the URL (without flags), saying that I don't want a header in the response (I've tried TRUE as well without any success) and then passing headers with my request that includes the authorisation.
I've tried file_get_contents with a stream_context_create header but that fails too.
Am I missing a header option or flag or something in my cURL code?
In my application I have to make a POST call to a webservice. They send me an XML response, basically saying "Accepted" or "Refused".
Last week I had an issue with one of these calls: I received a "Refused" response while their backend was telling me this request had been accepted.
I asked them what happened and they told me they received 2 requests (with the same ID - a parameter I send to them). First one was "Refused", second one was "Accepted".
I investigated: in my code, if I receive a "Refused" response, I log it, I update my database, and that's it. I do not try again.
The only thing would be PHP curl functions.
The day the problem occured, the webservice took unusual long time to response (20 seconds).
Could curl have made several calls? There is no retry option in the PHP function (or I didn't find it), but I'd rather ask here to be sure.
Here is my curl code.
$ch = curl_init();
$myArrayWithDatas = array( '...' );
$httpQueryFields = http_build_query($myArrayWithDatas);
$url = "https://www.webservice.com/api";
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $httpQueryFields);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
if (empty($response)) {
// I log an error
// (no trace of that in my logs)
} else {
// I log the XML response
// (one "Refused" response logged)
}
curl_close($ch);
Is there any case where this code could send 2 or more requests to the $url?
curl_exec will only do 1 call.
Are you running your code via a cron job or scheduled task ? If that's the case, maybe your code has been launched twice and that would explain why there were two calls done.
I am uploading an xml file to a supplier url. Not the content as a post, but the file itself. Regarding the response from the server, the instructions read as follows.
"For each OrderRequest from a client, the server will reply with a single OrderRequestResponse."
And:
"Once a successful order request is received, it will be placed in the queue to be run. The client shall not wait for this report to be generated – the communication over the HTTP socket will only consist of two messages – an OrderRequest, and an OrderRequestResponse."
It then goes on to say that the response may happen anywhere between 1 and 5 minutes later.
So the question is this - I would like to see the respose and make sure that the order has been accepted correctly, but how do i code for this given that i can't leave my cURL routine open for 5 minutes waiting. Can i tell the cURL request where to send the response within the parameters and then close the curl session and have my location process the response to email me or act on the content of the response.
Here is my upload code so far:
$xml = curl_file_create($thefile);
$data = array('test_file' => $xml);
$url = "www.supplierlocation.co.uk/etc";
$curlSession = curl_init();
curl_setopt ($curlSession, CURLOPT_URL, $url);
curl_setopt ($curlSession, CURLOPT_POST, 1);
curl_setopt ($curlSession, CURLOPT_POSTFIELDS, $data);
$ch_result = curl_exec($curlSession);
curl_close($curlSession);
What, if anything can i add so that the respose ends up somewhere that i can deal with it even after the session is closed.
[Does anybody know where i can find example of php code to respond to the response post my side. It would be an XML file that is received.]
Thanks,
I am attempting to send a PUT request using PHP and curl and my query parameters do not seem to be making it to the API. The logs verify that the request is coming in as a PUT but the parameters are not making it. I've followed every example I could find on the internet that describes how to build the query parameters building it manually and using the http_build_query function. I then add the parameters using the CURLOPT_POSTFIELDS value. Am I missing something needed for query params with a PUT request?
Unlike the POST request, the PUT request requires to specify the Content-Length that you are going to send to the server. Here is an example:
// data to be sent
$post_data = "...soem data";
// so that you get response
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// this is must for doing PUT
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Length: ' . strlen($post_data)));
// Doing PUT
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data );
If you still have problem after this, run the curl by enabling the verbose mode and it will show you the debug msg on curl's operation:
curl_setopt($ch, CURLOPT_VERBOSE, true);