      * PUT example -- this program updates the name/address of a customer
      *
      * URL is expected in this format (where XXXX is the customer number)
      *    http://ibmi.example.com/updateCust/XXXX
      *
      * Data should be sent to the web service in this format:
      *
      *    <updateCust>
      *      <name>NEW-CUST-NAME</name>
      *      <street>NEW-STREET-ADDRESS</street>
      *      <city>NEW-CITY</city>
      *      <state>NEW-STATE</state>
      *      <postal>NEW-POSTAL-CODE</postal>
      *    </updateCust>
      *
      *  All of the above elements are optional, only the ones sent
      *  are updated.
      *
      * To compile:
      *> CHGCURLIB SKWEBSRV
      *> CRTRPGMOD UPDCUST SRCFILE(QRPGLESRC) DBGVIEW(*LIST)
      *> CRTPGM UPDCUST BNDSRVPGM(QHTTPSVR/QZHBCGI) ACTGRP(RESTFUL)

     H OPTION(*SRCSTMT: *NODEBUGIO)

     FCUSTFILE  UF   E           K DISK

     D getenv          PR              *   extproc('getenv')
     D   var                           *   value options(*string)

     D QtmhWrStout     PR                  extproc('QtmhWrStout')
     D   DtaVar                   65535a   options(*varsize)
     D   DtaVarLen                   10I 0 const
     D   ErrorCode                32767a   options(*varsize)

     D QtmhRdStin      PR                  extproc('QtmhRdStin')
     D    result                  65535a   options(*varsize) ccsid(*hex)
     D    resultsize                 10i 0 const
     D    resultlen                  10i 0
     D    ErrorCode               32767a   options(*varsize)

     D err             ds                  qualified
     D   bytesProv                   10i 0 inz(0)
     D   bytesAvail                  10i 0 inz(0)

     D updateCust      ds                  qualified
     D   name                        30a   varying
     D   cName                       10i 0 inz(0)
     D   contact                     30a   varying
     D   cContact                    10i 0 inz(0)
     D   street                      30a   varying
     D   cStreet                     10i 0 inz(0)
     D   city                        20a   varying
     D   cCity                       10i 0 inz(0)
     D   state                        2a   varying
     D   cState                      10i 0 inz(0)
     D   postal                      10a   varying
     D   cPostal                     10i 0 inz(0)

     D CRLF            C                   x'0d25'
     D pos             s             10i 0
     D uri             s           5000a   varying
     D data            s           5000a
     D ID              c                   '/updateCust/'
     D method          s             10a   varying
     D xmlData         s           1000a   ccsid(*utf8)
     D xmlDataLen      s             10i 0

      /free
       *inlr = *on;

       // --------------------------------------------------
       // Make sure this is a PUT request.
       // --------------------------------------------------

       method = %str(getenv('REQUEST_METHOD'));
       method = %xlate('put': 'PUT': method);
       if method <> 'PUT';
          data = 'Status: 500 Invalid HTTP Method' + CRLF
               + 'Content-type: text/xml' + CRLF
               + CRLF
               + '<result success="false">'
               + 'Method must be PUT'
               + '</result>' + CRLF;
          QtmhWrStout(data: %len(%trimr(data)): err);
          return;
       endif;


       // --------------------------------------------------
       // Extract customer number from URL
       // --------------------------------------------------

       uri = %str(getenv('REQUEST_URI'));
       monitor;
          pos = %scan(ID: uri) + %len(ID);
          custno = %int(%subst(uri:pos));
       on-error;
          data = 'Status: 500 Invalid URI' + CRLF
               + 'Content-type: text/xml' + CRLF
               + CRLF
               + '<result success="false">'
               + 'Invalid URI format'
               + '</result>' + CRLF;
          QtmhWrStout(data: %len(%trimr(data)): err);
          return;
       endmon;


       // --------------------------------------------------
       // Load XML document with fields to update
       // --------------------------------------------------

       monitor;
          xmlData = *blanks;
          QtmhRdStin( xmlData
                    : %size(xmlData)
                    : xmlDataLen
                    : err );
          xml-into updateCust %XML(xmldata: 'doc=string countprefix=c');
       on-error;
          data = 'Status: 500 Invalid Input' + CRLF
               + 'Content-type: text/xml' + CRLF
               + CRLF
               + '<result success="false">'
               + 'Invalid XML Request Document'
               + '</result>' + CRLF;
          QtmhWrStout(data: %len(%trimr(data)): err);
          return;
       endmon;


       // --------------------------------------------------
       // Make updates
       // --------------------------------------------------

       chain custno CUSTFILE;
       if not %found;
          data = 'Status: 500 Unknown Customer' + CRLF
               + 'Content-type: text/xml' + CRLF
               + CRLF
               + '<result success="false">'
               + 'Unknown Customer Number'
               + '</result>' + CRLF;
          QtmhWrStout(data: %len(%trimr(data)): err);
          return;
       endif;

       if updateCust.cName = 1;
         Name = updateCust.name;
       endif;
       if updateCust.cContact = 1;
         Contact = updateCust.contact;
       endif;
       if updateCust.cStreet = 1;
         Street = updateCust.street;
       endif;
       if updateCust.cCity = 1;
         City = updateCust.city;
       endif;
       if updateCust.cState = 1;
         State = updateCust.state;
       endif;
       if updateCust.cPostal = 1;
         Postal = updateCust.postal;
       endif;

       update CUSTFILEF;

       data = 'Status: 200 OK' + CRLF
            + 'Content-type: text/xml' + CRLF
            + CRLF
            + '<result success="true">'
            + 'Customer updated successfully'
            + '</result>' + CRLF;
       QtmhWrStout(data: %len(%trimr(data)): err);
       *inlr = *on;

      /end-free
