hi Mike,
Mike wrote:
WriteResponse('Content-Type: application/xml' + cr);
WriteResponse('Content-Length: ' + %char(%len(p_UsrSpcData)));
You shouldn't be providing 'content-length' -- that part should be taken 
care of by the HTTP server. Apache might decide to used identity 
encoding as you've provided, or it might decide to use chunked encoding. 
 In either case, how it works is up to Apache, not you.  Don't provide 
content-length like this.  (Worst case scenario, it might pass that 
keyword on to the browser, and then it'd be unpredictable...)
You didn't say what 'cr' is defined as.  But, it needs to be a linefeed 
(LF), or else a carriage return/linefeed (CR/LF) pair.  It cannot be 
just a carriage return as the variable implies.
Finally (and this is the big one) you need to have a blank line (a line 
with just LF, or just CRLF) to separate the keywords like content-type 
from the data.  You're missing this altogether, and that's the likely 
cause of your 500 error.  Apache will think that all of your data is 
HTTP keywords, and none of it is actual data.
Those aren't your only errors, however... there's also a more elusive 
and dangerous one here:
     P WriteResponse   B
     D WriteResponse   PI
     D  buffer                    32767A   options(*varsize) const
      /free
       QtmhWrStout(%trim(buffer):%len(%trim(buffer)):ErrCode);
You have 'buffer' defined with options(*varsize).  That tells RPG that 
it's okay to pass a shorter variable here... and that could be an 
absolute disaster, because your code does NOTHING to determine the 
actual length passed.  It just assumes that all 32767 will be passed 
every single time.
The frightening part is that this will work a lot of the time... maybe 
even most of the time.  You won't detect this sort of bug by testing. 
Yet in production, your code might output tons of garbage, or might crash.
If you don't fully grok options(*varsize), then I strongly recommend 
that you don't use it.  In this case, your code was written as if you 
hadn't used it.  So just remove it, and keep the code like this:
     P WriteResponse   B
     D WriteResponse   PI
     D  buffer                    32767A   const
      /free
       QtmhWrStout(%trim(buffer):%len(%trim(buffer)):ErrCode);
       return;
This'll work fine.  It's not especially efficient (since you're trimming 
32000+ blanks TWICE every time you run this routine...  what a waste of 
CPU cycles!) but it'll work, and it'll be safe.
A better method is to use a VARYING variable instead of a fixed-length 
one so no blanks need to be trimmed...
As an Amazon Associate we earn from qualifying purchases.