6

I am currently using the following code:

<?php
/* Pre-requisite: Download the required PHP OAuth class from http://oauth.googlecode.com/svn/code/php/OAuth.php. This is used below */
require("OAuth.php");
$url = "https://yboss.yahooapis.com/geo/placespotter";
$cc_key = "MY_KEY";
$cc_secret = "MY_SECRET";
$text = "EYES ON LONDON Electric night in 100-meter dash";

$args = array();
$args["documentType"] = urlencode("text/plain");
$args["documentContent"] = urlencode($text);

$consumer = new OAuthConsumer($cc_key, $cc_secret);
$request = OAuthRequest::from_consumer_and_token($consumer, NULL,"POST", $url,$args);
$request->sign_request(new OAuthSignatureMethod_HMAC_SHA1(), $consumer, NULL);
$url = sprintf("%s?%s", $url, OAuthUtil::build_http_query($args));
$ch = curl_init();
$headers = array($request->to_header());//.',Content-Length: '.strlen($text));

//print_r($headers.',Content-Length: '.strlen($text));

curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
// somehow this line is not solving the issue
// curl_setopt($ch,CURLOPT_HTTPHEADER,array('Content-Length:'.strlen($text)));
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$rsp = curl_exec($ch);
print_r($rsp);
//echo "======= ENDING";
?>

With my own access keys and all, with the OAuth.php library.

Somehow I kept getting a Content-Length undefined error.

If I were to attempt to define Content-Length like this ( based on some answers seen here on StackOverFlow:

curl_setopt($ch,CURLOPT_HTTPHEADER,array('Content-Length:'.strlen($text)));

I do not get any response.

May I know how can this issue be solved?

Thanks!

PS: the php example comes from the official example: https://gist.github.com/ydn/bcf8b301125c8ffa986f#file-placespotter-php


LATEST EDIT

I've updated my code based on @alexblex's comment

    <?php
/* Pre-requisite: Download the required PHP OAuth class from http://oauth.googlecode.com/svn/code/php/OAuth.php. This is used below */
require("OAuth.php");
$url = "https://yboss.yahooapis.com/geo/placespotter";
$cc_key = "MY_KEY";
$cc_secret = "MY_SECRET";
$text = "EYES ON LONDON Electric from Singapore Raffles Place";
$args = array();
$args["documentType"] = urlencode("text/plain");
$args["documentContent"] = urlencode($text);
$args["outputType"] = "json";
$consumer = new OAuthConsumer($cc_key, $cc_secret);
$request = OAuthRequest::from_consumer_and_token($consumer, NULL,"PUT", $url, $args);
$request->sign_request(new OAuthSignatureMethod_HMAC_SHA1(), $consumer, NULL);
$url = sprintf("%s?%s", $url, OAuthUtil::build_http_query($args));
$ch = curl_init();
$headers = array($request->to_header());//.',Content-Length: '.strlen($text));
//$headers = array($request->to_header().',Content-Length="'.strlen($text).'"');
//$headers = array($request->to_header().',Content-Length: 277');
print_r($headers);
//print_r($headers.',Content-Length: '.strlen($text));
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POSTFIELDS, $request->to_postdata());
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$rsp = curl_exec($ch);
echo "\n\n\n\n";
var_dump($rsp);
//print_r($rsp);
?>

Currently, this new code returns a

{"bossresponse":{"responsecode":"500","reason":"non 200 status code from backend: 415"}

error.

Calimero
  • 4,238
  • 1
  • 23
  • 34
DjangoRocks
  • 13,598
  • 7
  • 37
  • 52
  • Can you be more specific on the error message ? please copy-paste here the error message you get. – Bar-code Nov 18 '15 at 14:38
  • Hi good day, the error message is: No Content Length Description: Could not process this request because there was no Content-Length specified. – DjangoRocks Nov 19 '15 at 10:10
  • is the information enough ? – DjangoRocks Nov 20 '15 at 14:05
  • If you're getting headers from $request->to_header() then maybe you just need to save it, append the content length header to it and use it with CURLOPT_HTTPHEADER. – Tim Sheehan Nov 21 '15 at 03:45
  • @DjangoRocks Since you're making a GET request, the length of its body is 0. So the content length in your case should not be the length of the `$text`, but exactly 0. And also you should combine headers from OAuth and this particular `Content-Length` header together. So just edit your `$headers` definition as the following: `$headers = array($request->to_header(), 'Content-Length: 0');`. I don't have auth tokens for Yahoo, but if i send your request without my modification - i get the same error, but if with it - just `Please provide valid credentials`. so i expect it should work properly. – user2655603 Nov 21 '15 at 08:13
  • @Dontfeedthecode apologies i'm not a php CURL expert. How would the code look like ? – DjangoRocks Nov 21 '15 at 11:33
  • @user2655603 i'm making a POST request, not a GET request for your information. – DjangoRocks Nov 21 '15 at 11:34
  • @user2655603 i've tested out with your code sample, but I also got a `Please provide valid credentials` error despite using the correct credentials. – DjangoRocks Nov 21 '15 at 11:44
  • @DjangoRocks Sorry, my fault. I'll recheck the length with POST. – user2655603 Nov 21 '15 at 11:49

2 Answers2

3

You send no POST data, hence no Content-Length being sent. To make a correct curl request you need to specify which data you like to send. In your case it is likely to be:

curl_setopt($ch, CURLOPT_POSTFIELDS, $request->to_postdata());

IF it should be a POST request. The PlaceSpotter docs reads:

The PlaceSpotter Web service supports only the HTTP PUT method. Other HTTP methods are not supported.

So I assume it should be PUT method instead:

$request = OAuthRequest::from_consumer_and_token($consumer, NULL,"PUT", $url,$args);
....
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');

EDIT for 415 response code

It may be an issue with double urlencodeing.

Try to set arguments as unencoded text:

$args["documentType"] = "text/plain";
$args["documentContent"] = $text;
Alex Blex
  • 34,704
  • 7
  • 48
  • 75
  • Hi good day, I've tried to use PUT as per your code sample, but I still receive the `No Content Length Description: Could not process this request because there was no Content-Length specified.` error. – DjangoRocks Nov 23 '15 at 14:13
  • @DjangoRocks, `PUT` request still requires some data to send. `CURLOPT_POSTFIELDS` still apply for `PUT` method. – Alex Blex Nov 23 '15 at 14:36
  • Hi there, I've updated my code. But i'm now receiving `{"bossresponse":{"responsecode":"500","reason":"non 200 status code from backend: 415"}` error. is my code wrong ? Cheers. – DjangoRocks Nov 24 '15 at 05:15
  • Apparently their backend do not support requested media type. The Content-Length issue has been resolved from your side. The "415" error is the PlaceSpotter problem, which means your request was accepted by frontend API and successfully passed through. – Alex Blex Nov 24 '15 at 10:24
  • wow geez. ok now this is weird. i assume the next step will be to contact Yahoo for support ? – DjangoRocks Nov 25 '15 at 02:56
  • @DjangoRocks, I have updated the answer regarding '415' response. First thing to do is to confirm you face the same problem with unencoded values for `documentType` and `documentContent`. If it is still the case, than yes, it makes sense to contact BOSS support team. – Alex Blex Nov 25 '15 at 09:05
  • hi there, i think u nailed it! – DjangoRocks Nov 27 '15 at 14:50
2

As per RFC-2616 Content-Type header indicates the size of the entity-body without headers. So if you would like to make POST requests without entity-body you should specify Content-Length: 0. Give this a try.

max
  • 2,757
  • 22
  • 19