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

Re: http_url_post_raw encoding Issue

I do not think that HTTP API provides a procedure to encode XML entities. I use the following procedure to do it (see also the attached zip file):

    R *  *** private ***
      *  Encodes XML entities.
     P XmlEntityEncoder_encode...
     P                 B
     D XmlEntityEncoder_encode...
     D                 PI         65535A          varying
     D  i_value                   65535A   value  varying
      *  Helper fields
     D x               S             10I 0 inz
     D y               S             10I 0 inz
     D hIconv          DS                  likeds(iconv_t   ) inz
     D dsFrom          DS                  likeds(QtqCode_t ) inz
     D dsTo            DS                  likeds(QtqCode_t ) inz
     D inSize          S             10U 0 inz
     D outSize         S             10U 0 inz
     D pInData         S               *   inz
     D pOutData        S               *   inz
     D rc              S             10U 0 inz
      *  Static fields
     D isInit          S               N   inz(cFalse)     static
     D esc_from        S             10A   Dim(5) varying  static
     D esc_to          S             10A   Dim(5) varying  static
      *  Constants
D cESC_FROM_1 C U'0026' & D cESC_FROM_2 C U'003E' > D cESC_FROM_3 C U'0022' " D cESC_FROM_4 C U'003C' < D cESC_FROM_5 C U'0027' '
D cESC_TO_1 C U'00260061006D0070003B' &amp; D cESC_TO_2 C U'002600670074003B' &gt; D cESC_TO_3 C U'002600710075006F0074003B' &quot; D cESC_TO_4 C U'0026006C0074003B' &lt; D cESC_TO_5 C U'002600610070006F0073003B' &apos;
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

 B01     if (not isInit);
            esc_from(1) = %char(cESC_FROM_1);
            esc_from(2) = %char(cESC_FROM_2);
            esc_from(3) = %char(cESC_FROM_3);
            esc_from(4) = %char(cESC_FROM_4);
            esc_from(5) = %char(cESC_FROM_5);
            esc_to(1)   = %char(cESC_TO_1);
            esc_to(2)   = %char(cESC_TO_2);
            esc_to(3)   = %char(cESC_TO_3);
            esc_to(4)   = %char(cESC_TO_4);
            esc_to(5)   = %char(cESC_TO_5);
            isInit = cTrue;
 E01     endif;

 B01     for x = 1 to %len(i_value);
 B02        for y = 1 to %elem(esc_from);
 B03           if (%subst(i_value: x: 1) = esc_from(y));
                  i_value = %replace(esc_to(y): i_value: x: 1);
                  x = x + %len(esc_to(y)) - 1;
 E03           endif;
 E02        endfor;
 E01     endfor;

         return i_value;

     P XmlEntityEncoder_encode...
     P                 E



Am 08.10.2010 23:17, schrieb Natarajan Palani:

    Hi Scott,

    Thanks for the prompt response. Is there a API that I can use to make
    an XML document into a valid (well-formed) XML document.

    Please let me know and Thanks for your help.


      * From: Scott Klement<[1]sk@xxxxxxxxxxxxxxxx>
      * To: HTTPAPI and FTPAPI Projects<[2]ftpapi@xxxxxxxxxxxxxxxxxxxxxx>
      * Subject: Re: http_url_post_raw encoding Issue
      * Date: Fri, 08 Oct 2010 15:02:19 -0500

Hi Raj,
There are two levels of encoding needed here:

1) You need to make your XML document into a valid (well-formed) XML
document by encoding characters that are special to XML.

2) In some circumstances (and I'm guessing yours is one) you have to
encode your data so that it's valid as an HTTP URL.  (Called "URL Encoding.)

You are doing the 2nd level, but are missing the first.

Let's see how that affects you.  You start out with this:


This is _not_ a valid XML document.  Then you URL encode it, and you end
up with this:


That's perfectly valid as HTML form data, and can be legitimately put
into a URL.  HTTPAPI's encoder has done it's job!  Hurray!  So it's sent
over the network to the computer on the opposite end.

That computer receives the URL encoded string, and decodes it (since XML
parsers have no concept of URL encoding.) and the result is this once again:


Now the XML parser tries to parse it... and fails because it's not a
well-formed (valid) XML document.  You can't have a lone&  in the middle
of chardata in XML.

That's what's happening... and HTTPAPI is doing exactly what it should,
it's encoding your data so it's valid for HTTP.  HTTPAPI doesn't even
know that your data is XML!  And even if it somehow was smart enough to
figure that out for you, how would it know whether&  was intended to be
the literal&  character, or whether it's intended to be an entity?  You
seem to think it can read your mind, but it cannot.

For the process to work, you need to start with a _valid_ XML document.
   In other words, you need to start with this:


After URL encoding, it will look like this:


Now it goes over HTTP protocol successfully... when it's received, the
receiving HTTP server decodes the URL encoding back to this:


And the XML parser will now parse it successfully.

    From: natarajanpalani@xxxxxxx
    To: ftpapi@xxxxxxxxxxxxxxxxxxxxxx
    Subject: http_url_post_raw encoding Issue
    Date: Fri, 8 Oct 2010 18:50:59 +0000
    Hi Scott,

    I am using http_url_post_raw. It works like a charm.

    The input to the server is in XML. During our testing we came across a
    scenario where the XML data had and "&" char for an element

    And we got the error response from the target Server as

    <ERROR DESCRIPTION>Unable to parse input XML entity reference names
    can  not start with character&apos;&apos; (position: START_TAG seen
    ...&lt;VALUE&gt;GENERAL&amp; ... @1:2497)</ERROR DESCRIPTION>

    I thought by using WEBFORM_setPtr&  WEBFORM_postData the data gets
    converted to URL encoded data. But it did not convert my "&" char to
    &amp;. Is there any reason behind this or am I doing something wrong
    here. Below is my code for Ur reference:

                form = WEBFORM_open();
                WEBFORM_setPtr(form: 'instring': %addr(@XML_Input) :
                               %len(%trimR(@XML_Input)) );
                WEBFORM_postData(form: postData: postDataSize );
                // Post data and get document
                rc = http_url_post_raw(%trim(@ServerName)
                          : postData
                          : postDataSize
                          : 1
                          : %paddr('RECEIVEDATA')
                          : @HTTPPostTimeout
                          : *OMIT
                          : %trim(@URLEncodApp) );
                if rc<>  1;
                  DS_HTTP_StatusData.HTTPErrDesc = 'HTTP Post Failed. ' +
                  DS_HTTP_StatusData.ReturnCd    = HTTPPostFailed;
                  callp Translate(retlen: retdata: 'QTCPEBC');
                  DS_HTTP_StatusData.XML_Response = %trim(retdata);

    Please let me know.

    Thanks for your help.



    1. mailto:sk@xxxxxxxxxxxxx
    2. mailto:ftpapi@xxxxxxxxxxxxx

This is the FTPAPI mailing list.  To unsubscribe, please go to:

Attachment: XmlEntityEncoder_encode.zip
Description: Zip archive

This is the FTPAPI mailing list.  To unsubscribe, please go to: