Here is my problem. I'm running a service on a remote machine working perfectly. The way to get the results from the machine is via api.
curl -X GET http://ip:777/api \
-d "r=request"
It works perfectly on the terminal. Moreover, it works perfectly, if the request query is short. But, it turns into a huge problem once, it passes some length(1800-2000 characters and I need 7k-8k chars).
However, I can't "transliterate" the curl code into PHP. If there is anyone with any idea how to do it please show me the way. As much as, I'm aware, this is a curl GET method with REQUEST BODY.
$long_query = "r=" . $request;
// set the api
curl_setopt($ch, CURLOPT_URL, 'http://ip:777/api');
// i want to get the return
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// 2min+ timeout as to make sure that I get a result
curl_setopt($ch, CURLOPT_TIMEOUT, 140);
// Set request method to GET by 0'ing the POST method
curl_setopt($ch, CURLOPT_POST, 0);
// Set query data here with CURLOPT_POSTFIELDS
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($long_query));
$content = curl_exec($ch);
curl_close($ch);
echo $content;
What am I doing wrong in here? If someone knows, please explain as if you are teaching a year old. Thanks in advance!
I think the following doc would help you understand how GET method works. This is from RFC 7231
A payload within a GET request message has no defined semantics; sending a payload body on a GET request might cause some existing implementations to reject the request.
For more details, please refer to this answer.
Alright, here we go with the proper answer.
on terminal,
curl -X GET http://ip:777/api \
-d "r=request"
works perfectly. However, the problem with converting that to php curl is quite troublesome while very easy at the same time.
I've read through every stack problem regarding this and no-one has provided a clear answer to the problem. I'm not sure the reason behind it but as a generous person I'll give out the code so that anyone in the future facing this rare problem will solve it out easily.
Long story short,
curl -X GET -d is the same as curl -X POST -H "X-HTTP-Method-Override: GET".
The actual request is POST but THE SERVER will consider it as a GET. This way you won't face the LONG URI problem.
$long_query = "r=" . $request;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,"ip:777/api");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $long_query); //Post Fields
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$headers = [
'X-HTTP-Method-Override: GET',
];
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$server_output = curl_exec ($ch);
curl_setopt($ch, CURLOPT_TIMEOUT, 140);
curl_close ($ch);
var_dump($server_output);
I've set the timeout to 140 as the query is long and it takes a bit of time for the server to go through it and respond (in my case its a json). Nevertheless, I've added var_dump so that anyone who uses it in the future might see if its a serialized array or whatever.
Good luck!
Related
I am trying to make a call from my Laravel application to the Bullhorn API to convert a document to HTML, but it looks like the file isn't being attached to the call. Below is my code:
$data = curl_file_create("full/path/to/file.docx", 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'testcv');
$ch = curl_init();
curl_setopt($ch, CURLINFO_HEADER_OUT, 1);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
$response = curl_exec($ch);
However I receive the following 500 error:
Bad File Uploaded: the request doesn't contain a multipart/form-data or multipart/mixed stream, content type header is application/x-www-form-urlencoded
When I try to set the Content-Type explicitly:
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: multipart/form-data'
));
I still receive a 500 error, just slightly different:
Bad File Uploaded: the request was rejected because no multipart boundary was found
I don't believe it's an issue with the Bullhorn API because executing the following call through the command line works fine:
curl -X POST "https://restXXX.bullhornstaffing.com/rest-services/{corptoken}/resume/convertToHtml?format=docx&BhRestToken={bhRestToken}" -F "file=#full\path\to\file.docx"
I assume that for some reason the file isn't being attached in my PHP call but I cannot figure out why.
Any help would be greatly appreciated.
The content-type: multipart/form-data uses boundary parameter for encapsulation, you can pass the boundary value as a string
'Content-Type: multipart/form-data; boundary=---------------------------7da24f2e50046'
Boundary is a string of "--" followed by a random string.
https://www.w3.org/Protocols/rfc1341/7_2_Multipart.html
If I ever have any weird problems with requests, I always put the request into postman and test it there since it compiles most of the headers and options for you, then just hit the code button on the top right to generate code in whatever language you want.
For your case you could datadump (dd) out your $data variable and copy it into one of the postman fields then set the url as well as the request type then run it and see what you get back.
Just a suggestion on how to debug a problem like this, hope it helps! good luck!
I have tried the following code and receive a message saying my particular request is not supported, I cannot find any solutions that are not python for the v20 api. any help would be appreciated on what to use or where im going wrong
My error message is:
{"errorMessage":"Requested HTTP method is not supported for supplied
endpoint."}
<?php
$ch = curl_init();
$vars = "price=B&granularity=M5&count=20";
curl_setopt($ch, CURLOPT_URL,"https://api-fxpractice.oanda.com/v3/instruments/EUR_USD/candles");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS,$vars); //Post Fields
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$headers = [
'Content-Type: application/json',
'Authorization: Bearer access-token',
];
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$server_output = curl_exec ($ch);
curl_close ($ch);
print $server_output ;
?>
My goal here is to successfully connect and get the response from the endpoint containing data. I have no python experience which is why im trying curl or even a javascript solution would work. Am i just not understanding this API at all?
Two things that stand out in the code are:
that there is no actual authorisation code. I don’t know if you have removed it for security while posting, or if you don’t realise you need to create a practice account and get an authorisation code for it? Both are free.
Your code curl_setopt($ch, CURLOPT_POST, 1); suggests you are trying a POST, whereas a GET is required for the \instruments endpoint.
But the simplest thing I can suggest that might help is to look at the following Github bash script that has taken OANDA's V1 API bash cURL example, and updated it for the v2 rest API.
https://github.com/p-burke/oanda-REST-v2-API-bash-script
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?
Here's the situation. On one side, we have a server, with a RESTful service. One possible query to it is a POST query to create an object. When that is done, the server returns a 'Location' header, to indicate where information on the newly created object can be found.
However, said server is anal about having the correct Content-Type for each request. For instance, POST requires 'application/json', and GET requires this to be unset (make sense, since GET doesn't have a body).
To sum up, we have:
www.example.com/articles/ ; one can send a POST request with 'Content-Type: application/json', and server will return 'Location: www.example.com/articles/123' if 123 is the id of the new object ;
www.example.com/articles/123 ; one can send a GET request with no 'Content-Type' and server will return a description of the new article object.
On client side, we use PHP with cURL. We use the CURLOPT_FOLLOWLOCATIONsetting so we can read the description of the newly created object. Obviously, we also set 'Content-Type: application/json' for our POST request:
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_POSTFIELDS, '{"name": "test"}');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_URL, "https://www.example.com/Articles/");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
$result=curl_exec($ch);
var_dump($result);
curl_close ($ch);
?>
This is what we get:
string(101) "{ "errorNo": 415, "error": "Unsupported Media Type Content-Type should not be set in a GET request" }"
I looked at the log of the server, and indeed, 'Content-Type: application/json' is sent to GET www.example.com/articles/123.
Is this an expected behaviour?
If yes, what is then best approach:
remove the 'Content-Type' check on GET requests, server-side?
(sounds silly)
forget about CURLOPT_FOLLOWLOCATION, and make 2 clearly separated curl requests, so I have control over the headers? (but then what's the point of CURLOPT_FOLLOWLOCATION?)
something else?
For control and testing, I also use Postman, and I have no problem with it, it follows the location, doesn't send the 'Content-Type' on the GET part (apparently) after the redirection and so I don't have an error.
EDIT:
There seems to be nothing useful in the PHP doc. But I found something interesting in the command line man page:
https://curl.haxx.se/docs/manpage.html
It says:
"WARNING: headers set with this option will be set in all requests - even after redirects are followed, like when told with -L, --location."
So I guess it probably is the expected behaviour for PHP too. May someone suggest best practices then?
Have you tried using
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
to set the post type
Thanks for stopping in :)
I break things, fiddle around, and then try to put them back together.
It is how I seem to learn best.
(One of) My recent obsession(s) has been with crypto-currency.
Since I have a little bit of knowledge working with API's through PHP and cUrl, I decided to use PHP for my fiddling.
So, I tell myself, "Why not register with a popular pool and see if I can't examine what a piece of 'work' looks like. Simple!"
I'm well aware that PHP, Json-RPC and CPU Bitcoin mining are extremely inefficient. I am not attempting to really create anything that will see the light of day; simply fiddling for fiddling's sake.
Evidently, I am just a bit ignorant on how Json-RPC and Stratum servers operate. I had thought to post this to the Bitcoin specific exchange, however I have the feeling my mistake is much more elementary than that.
The Goal: Get some work and print it to the page so I can inspect it and hopefully learn something.
My Attempt:
<?php
error_reporting(E_ALL);
ini_set('display_errors', '1');
function tickleElmo () {
$feed = 'http://stratum.btcguild.com';
$post_string = '{"method": "getblocktemplate", "params": [], "id": "0"}';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $feed);
curl_setopt($ch, CURLOPT_PORT, 3333);
curl_setopt($ch, CURLOPT_USERPWD, "elmoworker_1:123");
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_string);
//curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type: application/stratum', 'Content-length: '.strlen($post_string)));
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type: application/json', 'Content-length: '.strlen($post_string)));
$output = curl_exec($ch);
curl_close($ch);
return $output;
}
$data = tickleElmo();
var_dump($data);
?>
So, I had assumed (obviously incorrectly) that simply making a POST to the end-point would yield at least some response. I can ping the server stratum.btcguild.com just fine. Yet, via cUrl I don't get anything at all... the script simply times out and returns false.
I have tried a few different Content-type's, adding a newline character to the end of the post, the getwork and getblocktemplate methods inside the $post_string, and about 2 dozen other hack and slash alterations :(
I believe that the problem lies in my understanding of Json-RPC, as I have only previously worked with simple get API end-points in the past, but I have done my personal best to read up and find a simple explanation and have hit a road-block. I just don't have the tools to understand... :(
Any thoughts or additional sources of research/information from the intelligent folks here #stackoverflow would be greatly appreciated,
Samantha.