Attached below is the MIT-licenced source code for using sockets and classes in the ABL.
Written for 10.2B, there are examples of using the socket classes for grabbing a web page and for a client / server demo of messaging. These classes should work with appserver and webspeed clients as well.
All comments welcome.
I would like to thank Greg Higgins for doing some debugging on the amazing disappearing read-response procedure. You can reward our efforts by subscribing to the PEG (http://www.peg.com/jointoday.html).
Thanks for the socket classes.
I have had some trouble using the HttpSocket for getting binary data, like downloading a PDF file from a webserver, and found some bugs in the handling of chunks.
So I have made modifications to your sourcecode and attached the mods to this reply.
Also added two example .p files: one that uses the modified httpsocket to fetch an HTML document and one that uses the class to download a ZIP file.
I have trouble using the HttpSocket class on an appserver.
Appserver does not have a wait-for, so my problem is: how do you wait until the socket is ready downloading the requested file?
For this purpose I have added a method WaitForResponse that you can use on the appserver, but this is basically a loop and performs really bad.
No matter what I have tried, the performance of the wait loop is just bad.
I understand why the loop is slow, but have no idea how to make it fast and efficient. Please help? The loop goes like this:
PUBLIC VOID WaitForResponse(INPUT timeout_seconds AS INTEGER):
DEFINE VARIABLE starttime AS DATETIME-tz NO-UNDO.
DEFINE VARIABLE loopnumber AS INTEGER NO-UNDO.
ASSIGN ResponseComplete = FALSE
DO WHILE (NOT ResponseComplete) :
loopnumber = loopnumber +
IF NOT socket1:CONNECTED() THEN
if socket1:get-bytes-available() > 0 then
IF timeout_seconds > 0 THEN
IF (now - starttime) > (timeout_seconds * 1000) THEN DO:
/* publish a time-out event */
Solved! The WaitForResponse method is now looping around the socket:READ statement, which is much better.
Improved code is attached.
Hi Jurjen !
Thanks for the updates - however, I am curious to know why this failed in the first place because I was pretty sure I tested pdf files.
Can you give me an example of a URL that failed for you so I can go back and track this down for my own sake ?
Sorry, I cannot give you an URL to the server from where I needed to download a pdf. It is an Apache Tomcat servlet container with a custom-built servlet which calls the JasperReport engine to generate a pdf. It is not facing the internet, so I can't give an URL that you can reach. Tomcat returned the PDF as a binary stream, chunked. Since it was binary, the messagefragment = GET-STRING(p_Data, 1) statement stopped at the first CHR(0) in the data instead of reading to the end of the data. After fixing that the class missed the last chunk, because in our case the chunksize was a lot smaller than the packetsize, so I had to loop in the packet to find all chunks.
Perhaps a different server may return PDF's in some base64 encoded format so it is all ascii?
Don't you also have the problem when you use the class to download the zip file that is attached to this page?
I was just thinking, perhaps a PDF is not "binary" enough until it contains embedded fonts and pictures? Perhaps a "for each customer: display customer" output to PDF is all text?
Is it possible to attach a file (PDF file) to the HTML request using HttpSocket ?
I would like to attach a file using Mime and Multipart...