cURL adding whitespace to post content?
Question
I am attempting to POST against a vendor's server using PHP 5.2 with cURL. I'm reading in an XML document to post against their server and then reading in a response:
$request = trim(file_get_contents('test.xml'));
$curlHandle = curl_init($servletURL);
curl_setopt($curlHandle, CURLOPT_POST, TRUE);
curl_setopt($curlHandle, CURLOPT_POSTFIELDS, array('XML'=>$request));
curl_setopt($curlHandle, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($curlHandle, CURLOPT_HEADER, FALSE); # Have also tried leaving this out
$response = curl_exec($curlHandle);
That code, in an of itself, works OK, but the other server returns a response from it's XML parser stating:
Content not allowed in prolog
I looked that error up and this is normally caused by whitespace before the XML, but I made sure that the XML file itself has no whitespace and the trim() should clear that up anyway. I did a TCPDump on the connection while I ran the code and this is what is sent out:
POST {serverURL} HTTP/1.1
Host: {ip of server}:8080
Accept: */*
Content-Length: 921
Expect: 100-continue
Content-Type: multipart/form-data; boundry:---------------------------01e7cda3896f
---------------------------01e7cda3896f
Content-Disposition: form-data; name="XML"
[SNIP - the XML was displayed]
---------------------------01e7cda3896f--
Before and after the [SNIP] line there is visible whitespace when I replay the session in Ethereal. Is this what is causing the problem and, if so, how can I remove it, or am I looking too far and this may be an issue with the server I'm posting against?
Solution 2
It turns out it's an encoding issue. The app apparently needs the XML in www-form-urlencoded instead of form-data so I had to change:
# This sets the encoding to multipart/form-data
curl_setopt($curlHandle, CURLOPT_POSTFIELDS, array('XML'=>$request));
to
# This sets it to application/x-www-form-urlencoded
curl_setopt($curlHandle, CURLOPT_POSTFIELDS, 'XML=' . urlencode($request));
OTHER TIPS
Not an answer, but I find the whole fopen/fread/fclose thing very dull to peruse when looking at code.
You can replace:
$file = 'test.xml';
$fileHandle = fopen($file, 'r');
$request = fread($fileHandle, filesize($file));
fclose($fileHandle);
$request = trim($request);
With:
$request = trim(file_get_contents('test.xml'));
But anyway - to your question; if those are the headers that are being sent, then it shouldn't be a problem with the remote server. Try changing the contents of your xml file and using var_dump() to check the exact output (including the string length, so you can look for missing things)
Hope that helps
I did a wc -m test.xml
and came back with 743 characters in the XML file and the var_dump
on $request
comes back with 742 characters so something is getting stripped with trim()
(I assume).
I did a:
print "=====" . $request . "=====";
and the start and end of the XML butts right up against the ===== with no white space.