Content Is Not Allowed In Prolog – Google API

Recently I’ve been having to work with the Google Provisioning and Email Settings API, which¬† I thought would be no big deal.¬† But soon, like a child who’s ice cream has just fallen on the ground, I was in tears and frustrated.

The issue wasn’t necessarily the API, or the PHP code that I was using to generate the calls to the API, but it was the error message that I kept getting back when I tried to send my PUT requests.


Content Is Not Allowed In Prolog.

Generally, this error indicates that there is content before the XML declaration, for example a space, or pehaps a gremlin. But in my case, there was nothing in before the <?xml version="1.0" encoding="utf-8"?>, and I checked and checked, then checked some more. And after that I checked some more, before checking even more.

So, after weeks of trying everything from different XML classes, writing the XML to a file, and creating a wig from the hair I’d ripped out of my head to cover my new found baldness, I finally figure it out!

With the Google API, like most API’s, it requires authentication. For the purposes of the app I’m working on we are ClientLogin authentication method which requires you to send an authentication token as part of your request headers.

$headers = array('Content-Type: application/atom+xml; charset=utf-8',
'Content-Length: '. strlen($xml),
'Authorization: GoogleLogin '. $authToken,
'Connection: close');

Those were the headers I was sending to those who do no evil (of course that depends on what you’re definition of evil is).
After dumping the headers to the browser I noticed something unusual…. after the last character of the auth token.. there was a SPACE.
So I changed

'Authorization: GoogleLogin '. $authToken,

to

'Authorization: GoogleLogin '. trim($authToken),

and voila, no more Content is not allowed in prolog error.

Hopefully, this will help some other poor sod out there who has been pulling their hair out. On the plus side, I now have a very cool wig.

Oh, and because I had so much trouble finding information on sending a put request to Google, here is some sample code:
Note: This code assumes you already have the auth token from Google.

$headers = array('Content-Type: application/atom+xml; charset=utf-8',
'Content-Length: '. strlen($xml),
'Authorization: GoogleLogin '. trim($authToken)),
'Connection: close');
 
// Initiate Curl
$ch = curl_init();
 
// Tell curl what URL we are putting the information too
curl_setopt($ch, CURLOPT_URL, $PUTUrl);
 
// Open the file we are going to put to the URL
$fp = fopen('test.xml','r');
 
// Tell curl we are using the PUT request
curl_setopt($ch, CURLOPT_PUT, true);
 
// Give curl the handle of the file we just opened
curl_setopt($ch, CURLOPT_INFILE, $fp);
 
/* We need to know the size of the file 
   (I had previously created the xml earlier in the 
   script and saved it to a file, hence the reason 
   I'm using a variable called $xml */
 
curl_setopt($ch, CURLOPT_INFILESIZE, strlen($xml));
 
// Set the user agent
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.0.3705; .NET CLR 1.1.4322; Media Center PC 4.0)');
 
// Set the timeout.  If the request has not completed in 30 seconds, terminate the call and show results
curl_setopt($ch, CURLOPT_TIMEOUT,30);
 
// Add our headers
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
 
// Close the file
fclose($fp);
 
// Do the curl request
$output = curl_exec($ch);
 
if(!$output){
    echo 'An error occurred with the request'. curl_error($ch);
}else{
    echo $output;
}
You can leave a response, or trackback from your own site.

Leave a Reply