Question HTTP POST response not getting fully read

Potish

Member
I am submitting a HTTP SOAP request to a host and when the response is sent back I am running into two problems

1. The progress program looks to stop getting/reading the response which is chunked and I end up with a partial XML file.
2. The socket stays connected even after the program has stopped getting any response back and so the program gets caught in a repetitive loop waiting for the socket disconnect to take place

The code looks as follows

Code:
DEFINE INPUT PARAMETER pmop-file       AS MEMPTR    NO-UNDO.
DEFINE INPUT PARAMETER pcsavedirectory AS CHARACTER NO-UNDO.
DEFINE INPUT PARAMETER pcfilename_RP   AS CHARACTER NO-UNDO.
DEFINE INPUT PARAMETER pcfilename_DT   AS CHARACTER NO-UNDO.
DEFINE INPUT PARAMETER pcfilename_ER   AS CHARACTER NO-UNDO.

DEFINE VARIABLE vcposturl      AS CHARACTER NO-UNDO.
DEFINE VARIABLE vcfilepath_RP  AS CHARACTER NO-UNDO.
DEFINE VARIABLE vcfilepath_ER  AS CHARACTER NO-UNDO.
DEFINE VARIABLE vlDataReceived AS LOGICAL   NO-UNDO.
DEFINE VARIABLE vcFinalResp    AS LONGCHAR  NO-UNDO.

DEFINE VARIABLE vcHost         AS CHARACTER NO-UNDO.
DEFINE VARIABLE vcPort         AS CHARACTER NO-UNDO.
DEFINE VARIABLE vcsoapaction   AS CHARACTER NO-UNDO.
DEFINE VARIABLE vhSocket       AS HANDLE    NO-UNDO.

ASSIGN
    vcHost              = "api.somehost.com"    
    vcPort               = "80"
    vcsoapaction  = ""
    vcposturl          =  "[URL]http://api.somehost.com/ws/v3[/URL]" /
    vcfilepath_RP = TRIM(pcfilename_RP)
    vcfilepath_ER = TRIM(pcfilename_ER)
    vcFinalResp   = "".
    
CREATE SOCKET vhSocket.

vhSocket:SET-READ-RESPONSE-PROCEDURE('getResponse').

vhSocket:CONNECT('-H ' + vcHost + ' -S ' + vcPort) NO-ERROR.
  
IF vhSocket:CONNECTED() = FALSE THEN
DO:
        MESSAGE "Host Connection failure" VIEW-AS ALERT-BOX.     
        RETURN.
END.
ELSE 
        MESSAGE "Host Connection successful" VIEW-AS ALERT-BOX.

RUN PostRequest (INPUT vcposturl).

REPEAT:
    IF vhSocket:CONNECTED() = TRUE THEN
        WAIT-FOR READ-RESPONSE OF vhSocket PAUSE 1. 
    ELSE
        LEAVE.
END.

/* Save response data to .dat file */
COPY-LOB FROM OBJECT vcFinalResp TO FILE pcfilename_DT.

vhSocket:DISCONNECT() NO-ERROR.

DELETE OBJECT vhSocket.

/* Save response data to .xml file */
RUN postProcessDataFile.
  
RETURN.

PROCEDURE getResponse:

    DEFINE VARIABLE vcWebResp    AS LONGCHAR NO-UNDO.
    DEFINE VARIABLE viBytesAvail AS INTEGER  NO-UNDO.
    DEFINE VARIABLE mResponse    AS MEMPTR   NO-UNDO.

    ASSIGN viBytesAvail = vhSocket:GET-BYTES-AVAILABLE().

    /* if no bytes to read, exit from procedure */
    IF viBytesAvail = 0 THEN RETURN.

    SET-SIZE(mResponse) = 0.
    SET-SIZE(mResponse) = viBytesAvail.
    vhSocket:READ(mResponse,1,viBytesAvail,READ-EXACT-NUM).

    COPY-LOB FROM OBJECT mResponse TO vcWebResp.

    ASSIGN vcFinalResp = vcFinalResp + vcWebResp.
    SET-SIZE(mResponse) = 0.

END PROCEDURE.

PROCEDURE PostRequest:
    DEFINE INPUT PARAMETER postUrl AS CHAR. 

    DEFINE VARIABLE vcRequest AS CHARACTER.

    vcRequest =
        'POST ' + postUrl + ' HTTP/1.1~r~n' +
        'Content-Type: text/xml;charset=UTF-8~r~n' +
        'SOAPAction: ' + trim(vcsoapaction) + '~r~n' +           
        'Content-Length: ' + STRING(LENGTH(STRING(pmop-file))) + '~r~n'  +       
        'Host: ' + trim(vcHost) + '~r~n' +
        'Connection: keep-alive~r~n' +         
        'User-Agent: Apache-HttpClient/4.1.1 (java 1.5)~r~n' +                         
        '~r~n' +
        STRING(pmop-file) + '~r~n'.

    SET-SIZE(pmop-file)            = 0.
    SET-SIZE(pmop-file)            = LENGTH(vcRequest) + 1.
    SET-BYTE-ORDER(pmop-file)      = BIG-ENDIAN.
    PUT-STRING(pmop-file,1)        = vcRequest .

    vhSocket:WRITE(pmop-file, 1, GET-SIZE(pmop-file)).
  
END PROCEDURE.

PROCEDURE postProcessDataFile:
    /* Memory Pointers */
    DEFINE VARIABLE mSourceData  AS MEMPTR NO-UNDO.
    DEFINE VARIABLE mSourceData2 AS MEMPTR NO-UNDO.
    DEFINE VARIABLE mSourceData3 AS MEMPTR NO-UNDO.
    DEFINE VARIABLE vcWebResp    AS LONGCHAR NO-UNDO.
  
    /* Processing Variables */
    DEFINE VARIABLE inBlobLength AS INTEGER NO-UNDO.
    DEFINE VARIABLE inPos        AS INTEGER NO-UNDO.
  
    /* -- REMOVE HTTP HEADERS -- */
    SET-SIZE(mSourceData) = 0.
    COPY-LOB FROM FILE pcfilename_DT TO OBJECT mSourceData.

    inBlobLength = GET-SIZE(mSourceData).
    HTTP-HEADER-BLOCK:
    DO inPos = 1 TO inBlobLength:
        IF GET-STRING(mSourceData, inPos, 4) = "~r~n~r~n" THEN
            LEAVE HTTP-HEADER-BLOCK.
    END.

    /* --REMOVE HTML FOOTER -- */
    SET-SIZE(mSourceData2) = 0.
    COPY-LOB FROM OBJECT mSourceData STARTING AT (inPos + 4) TO OBJECT mSourceData2.
  
    inBlobLength = GET-SIZE(mSourceData2).
    /* -- SAVE XML FILE -- */
    SET-SIZE(mSourceData3) = 0.
    COPY-LOB FROM OBJECT mSourceData2 STARTING AT 1 FOR inBlobLength TO OBJECT mSourceData3.
  
    DEFINE VARIABLE hDoc AS HANDLE NO-UNDO.
    CREATE X-DOCUMENT hDoc.
    hDoc:LOAD("MEMPTR", mSourceData3, FALSE). 
    hDoc:SAVE("FILE", pcfilename_RP).
    DELETE OBJECT hDoc.
  
    RETURN.
END PROCEDURE.
 
Last edited by a moderator:
Top