tags:

views:

625

answers:

4

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?

+2  A: 

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

mercutio
A: 

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 agains the ===== with no white space.

dragonmantank
+1  A: 

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));
dragonmantank
A: 

Check out this answer to another question -- I had a similar question to you, and found this helped me out.

davr