ibmi-brunch-learn

Announcement

Collapse
No announcement yet.

HTTPAPI http_urlEncode() issue

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • HTTPAPI http_urlEncode() issue

    I want to build a URL that can be opened on the user's PC via STRPCCMD. It will contain a query parameter containing special characters, so I need to URL encode the value of that parameter when building the URL e.g. "&% to %22%26%3F

    We are still on it i7.2 so we don'thave systools urlEncode(), so I tried HTTPAPI's http_urlEncode()
    Which worked apart from one thing. It encodes £ as %A3 instead of %C2%A3. Which doesn't work with the modern JavaScript methods of parsing URL query params e.g. decodeURIComponent() or URLSearchParams()

    Am I doing something wrong?

  • #2
    What character set is the string you're encoding? What character set are you expecting the hex values encoded into?

    In most languages/environments URL encoding simply puts a % followed by the hex value of the data. So if the hex value of the £ character is A3, it puts %A3 in the URL. If the hex value is C2A3, it puts %C2%A3 in the URL. It's very simple in those environments. RPG is different because the data is in EBCDIC, and you don't generally want the EBCDIC hex values in your URL. Instead, you want it converted to the character set of the network connection first, and then get the hex value of that.... then convert that back to EBCDIC so you can use it in further string manipulations.

    The problem you're having is that its converting the £ symbol to ASCII, and getting its hex value, x'A3'. From your example, it sounds like what you wanted was the hex value in UTF-8 rather than ASCII.

    To do that, tell HTTPAPI that you want your data to be sent in UTF-8 format by calling the http_setCCSIDs() routine. Then, when you encode it, you'll get the UTF-8 hex value.

    Code:
    dcl-s pound varchar(1) inz('£');
    dcl-s encoded varchar(10);
    
    http_setCCSIDs(1208: 0);
    encoded = http_urlencode(pound);
    It is only necessary to call http_setCCSIDs once (perhaps at the start of your program.) Once you've set the CCSIDs, it'll use those until you tell it to use different ones. So if you're calling http_urlEncode multiple times, it will keep the previous settings. No need to call http_setCCSIDs again.

    Comment


    • #3
      Thank you Scott, top notch advice as always. I figured I was missing something. It did not occur to me to check for a procedure to set the CCSID's within HTTPAPI, but it should have (I have used http_setCCSIDs() twice before when writing programs to consume SOAP/REST services using HTTPAPI).

      (I was not certain what I wanted to convert it to, but based on your explanation I'm sure now that it's UTF-8 I want, so CCSID 1208)

      I do have two questions about http_setCCSIDs().
      What is the default setting, if I never call it? Job CCSID to ASCII 819? 37 to 819?
      And what is it's scope? If I change it, will what I set be the new default for the lifetime of the current job, unless a later program calls it?

      Comment


      • #4
        Originally posted by Vectorspace View Post
        What is the default setting, if I never call it? Job CCSID to ASCII 819? 37 to 819?
        The default is set via the constant HTTP_ASCII in the CONFIG_H member. The idea is that if you don't like this default, you can change it before compiling HTTPAPI, and then the default will be whatever you've set.

        As shipped, it looks like this:
        Code:
        ***                                                            
        ***  These are the default CCSIDs used when translating between
        ***  ASCII/EBCDIC.  You can override these at runtime by       
        ***  calling HTTP_setCCSIDs()                                  
        ***                                                            
        D HTTP_EBCDIC     C                   CONST(0)                 
        D HTTP_ASCII      C                   CONST(819)
        So as shipped from ScottKlement.com, it will use 0 (special value for your job ccsid, or default ccsid if the job is 65535) for your program (EBCDIC), and 819 (which is iso-8859-1) for the network (ASCII). But you can change that.

        Originally posted by Vectorspace View Post
        And what is it's scope? If I change it, will what I set be the new default for the lifetime of the current job, unless a later program calls it?
        Its scoped to the activation group.

        Comment


        • #5
          Thanks Scott, it all worked fine

          Comment

          Working...
          X