Content-Length undefined ? Weird error using Yahoo's PlaceSpotter sample php code
Asked Answered
B

2

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.

Blindworm answered 18/11, 2015 at 14:14 Comment(9)
Can you be more specific on the error message ? please copy-paste here the error message you get.Yongyoni
Hi good day, the error message is: No Content Length Description: Could not process this request because there was no Content-Length specified.Blindworm
is the information enough ?Blindworm
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.Butene
@Blindworm 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.Rizo
@Dontfeedthecode apologies i'm not a php CURL expert. How would the code look like ?Blindworm
@Rizo i'm making a POST request, not a GET request for your information.Blindworm
@Rizo i've tested out with your code sample, but I also got a Please provide valid credentials error despite using the correct credentials.Blindworm
@Blindworm Sorry, my fault. I'll recheck the length with POST.Rizo
D
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;
Dogcart answered 23/11, 2015 at 10:32 Comment(7)
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.Blindworm
@DjangoRocks, PUT request still requires some data to send. CURLOPT_POSTFIELDS still apply for PUT method.Dogcart
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.Blindworm
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.Dogcart
wow geez. ok now this is weird. i assume the next step will be to contact Yahoo for support ?Blindworm
@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.Dogcart
hi there, i think u nailed it!Blindworm
C
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.

Callery answered 26/11, 2015 at 16:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.