[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Ftpapi] help using HTTPAPI to call SOAP service including PDF in request



Bob,

The way base64 works is that it takes chunks of 3 bytes and encodes it into 4 bytes.  (Decoding is the opposite, 4 bytes become 3.)

So you can read your document in pieces, assuming that you read in multiples of 3 bytes, it should encode properly.  For example, maybe you want to create a character string that's 60000 bytes long (since this is a multiple of 3) and read that much at a time.

Pseudo-code:

1. open() a file for reading (O_RDONLY) like you have now.

2. open() a second file for writing.

3. Write the initial XML stuff into the second file.

4. Read the input file, 60000 bytes per call.

5. Call base64_encode on the 60000 byte field.  Be sure to pass the actual length returned by read() to the encoder (when you reach the eof, the length will be less than 60000 -- this is what you want.)   Also be sure to store the length returned by the base64 encoder for the next step.

6. write the chunk of base64-encoded data to the output file.  Use the output data and length returned by the encoder.

7. Repeat step 4-6 until you've written the entire input file.  Since you're only working with 60k at a time, running out of memory is not a concern.

8. finish writing the remainder of the XML file.

9. Close both files

10. Send the output file with http_stmf.  The result will also be returned as a file...  just use a temporary filename.

11. Parse the XML in the file received from http_stmf() to get the result.  If you prefer httpapi's xml parser, you can use http_parse_xml_stmf() to parse it, but you can also choose to use other tools such as RPG's built-in XML-SAX or XML-INTO opcodes.  Either way works fine.

12. Clean up/delete any temporary IFS files you used.

The point is to use files to store the documents you send/receive so that you don't have to worry about the maximum size of RPG variables.

-SK


On 12/31/2019 8:35 AM, Bob Long wrote:

Yes, the service does require a base64 encoded string.

 

And yes, our size concern was in trying to build the xml to send to the service, we were running up against the maximum size for an alpha-numeric field 16773104. We also figured that using some kind of stream would likely be the solution, but were unsure how.

 

Attached is our program. It attempts to read an existing pdf from IFS, base64 encode it, and send it to the service. How would you recommend adjusting this program to be able to handle larger documents like 150mb?

 

     Hdatfmt(*usa) timfmt(*hms) BNDDIR('UTLIB/COMMON' : 'LIBHTTP/HTTPAPI'

     H                                 : 'BASE64/BASE64')

     H DFTACTGRP(*NO)

 

     D/COPY LIBHTTP/QRPGLESRC,IFSIO_H

     D/COPY LIBHTTP/QRPGLESRC,HTTPAPI_H

     D/COPY BASE64/SRC,BASE64_H

 

     D/COPY UTLIB/CPY,UTCMUSR_H

     D/COPY PLLIB/CPY,PLPSDS

 

     D fileDescriptor  S             10I 0

     D flags           S             10U 0

     D permissions     S             10U 0

     D pdfFile         S             50A   VARYING

     D pdfContents     S               A   LEN(10000000)

 

     D Msg             S             50A

     D Len             S             10I 0

     D encData         S               A   LEN(10000000)

 

     D url             S            200    VARYING

     D request         s               A   LEN(10000000)

     D responseCode    s             10I 0

 

     C/FREE

       flags = O_RDONLY;

       permissions = S_IRUSR;

       pdfFile = '/home/JUSTINB/Test.pdf';

 

       fileDescriptor = open(pdfFile

          : flags

          : permissions);

 

       if fileDescriptor < 0;

        Msg = 'Failed to open ' + pdfFile + ' for reading';

 

        dsply Msg;

 

        return;

       endif;

 

       len = read(fileDescriptor

        : %addr(pdfContents)

        : %size(pdfContents));

 

       BASE64_ENCODE(%ADDR(pdfContents)

        : len

        : %ADDR(encData)

        : %SIZE(encData));

 

       callp close(fileDescriptor);

 

       url = '';

 

       http_debug(*ON: GetDebugFileName());

       http_XmlStripCRLF(*ON);

 

        request =

          '<s:Envelope'

         +' xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">'

         + '<s:Header/>'

         + '<s:Body>'

         +  '<DepositDocument xmlns="http://tempuri.org/">'

         +   '<documentBytes>'

         +   %trim(encData)

         +   '</documentBytes>'

         +   '<comment>' + 'Test' + '</comment>'

         +  '</DepositDocument>'

         + '</s:Body>'

         +'</s:Envelope>';

 

        responseCode = http_url_post_xml(

            %TRIM(url)

          : %addr(request)

          : %len(%trim(request))

          : *NULL

          : *NULL

          : *NULL

          : 300

          : HTTP_USERAGENT

          : 'text/xml;charset=UTF-8'

          : 'http://tempuri.org/IService/DepositDocument'

        );

 

        if (responseCode <> 1);

          dsply 'Fail';

        else;

         dsply 'success';

        endif;

     C/FREE

     C                   EVAL      *INLR = *ON

 

 

 

Bob Long

Programmer Analyst IV

Direct: 877.309.9176 | Mobile: 207.227.1355 | Fax: 207.760.1002

 

From: ftpapi-bounces@xxxxxxxxxxxxxxxxxxxxxx [mailto:ftpapi-bounces@xxxxxxxxxxxxxxxxxxxxxx] On Behalf Of Scott Klement
Sent: Monday, December 30, 2019 12:39 PM
To: ftpapi@xxxxxxxxxxxxxxxxxxxxxx
Subject: Re: [Ftpapi] help using HTTPAPI to call SOAP service including PDF in request

 

Hi Bob,

Most likely, the binary data would need to be base64-encoded.  If you have a WSDL for the SOAP service, it should provide the details of what needs to be done.

I'm guessing that your document is larger than 16mb based on your concern about it being too large.  If that's the case, you can generate it into a stream file, and send the file.  That way it doesn't all need to be in memory at the same time.

-SK

On 12/30/2019 10:12 AM, Bob Long wrote:

We are currently using HTTPAPI to integrate with our REST APIs and SOAP services. 
We would like some assistance in calling one of our SOAP services which has a request
that includes a binary (of a pdf document) as one of its parameters. We would like
to call this service after generating a pdf file from a spool file and pass the binary
of the document into the request for the SOAP service.

 

We are mainly struggling with how to read and store (in memory most likely) the pdf file 
generated by the spool to pdf commend. Secondly, we were unsure the best way to send the
request to the SOAP service without building it in such a way that the xml is too long for
an RPG program.

 

We are also open to other options for getting a spool file into a request to this SOAP service
in a pdf format.

 

MMG Insurance 


MMG Insurance | mmgins.com | Facebook | Twitter | LinkedIn

This message is intended for the use of the addressee only and may contain information that is privileged and confidential. If you are not the intended recipient of this message, be advised that any dissemination or use of this message is strictly prohibited.  If you have received this message in error, please delete all copies of the message and its attachments and notify the sender immediately. Thank you. MMG Insurance


-- 
_______________________________________________
Ftpapi mailing list
Ftpapi@xxxxxxxxxxxxxxxxxxxxxx
http://scottklement.com/mailman/listinfo/ftpapi