This section provides a tutorial example of SOAP 1.1 request to use the GetSpeech Web service provided at xmlme.com. Communication hangs if Content-Length is larger than the number of bytes in the request content, because the server will wait forever for more data.
In the previous tutorial, I was lazy and didn't want to count the number of bytes
in XML message in my SOAP 1.1 request.
To count the number of bytes in XML message, I save it in a separate file, soap_1_1_GetSpeech.xml.
The extra blank line at the end indicates that I have a new line (\n) after the soap:Envelope ending tag.
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetSpeech xmlns="http://xmlme.com/WebServices">
<Request>To be, or not to be</Request>
</GetSpeech>
</soap:Body>
</soap:Envelope>
I use Windows File Explorer to locate this file, right-mouse-click it, and select Properties from
the pop up menu. The Properties dialog box says "Size: 384 bytes (384 bytes)" as shown in this picture:
Let's put the 384 as Content-Length in soap_1_1_GetSpeech.req:
POST /WSShakespeare.asmx HTTP/1.1
Host: www.xmlme.com
Content-Type: text/xml; charset=utf-8
Content-Length: 384
SOAPAction: "http://xmlme.com/WebServices/GetSpeech"
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetSpeech xmlns="http://xmlme.com/WebServices">
<Request>To be, or not to be</Request>
</GetSpeech>
</soap:Body>
</soap:Envelope>
Now we are ready to try again:
\herong>SocketRequestResponse.pl www.xmlme.com 80
soap_1_1_GetSpeech.req soap_1_1.res
Terminating on signal SIGINT(2)
My SocketRequestResponse.pl hung for more than 5 minutes. I had to press Ctrl-C
to terminate it. Why?
After some thinking and testing, I have a good guess on what happened here:
My Windows system uses two bytes (\r\n, or 0x0D0A) to end a line.
My SocketRequestResponse.pl has a bug at 'open(IN, "< $in"); read(IN, $req, (-s $in));'.
The content of the request file is not read in binary mode!
The read() function convert \r\n to \n in non-binary mode remove 1 byte for each line.
The impact is that my HTTP request content only have 374 bytes when sending to the server,
because the XML message has 10 lines.
The server continues to wait for socket input after reading 374 bytes for the request content,
because "Content-Length" says 384 bytes in the content.
This is why my execution never returned by iteself.
Now I learned that HTTP servers really respect the "Content-Length" header line
in the request. I will fix my test program SocketRequestResponse.pl and try again
in the next tutorial.