Parsing x-www-form-urlencoded from Memptr is missing last ch

Posted by brianlafertewk on 09-May-2018 14:20

This morning I was working with a web handler request that needs to receive data with a content type of  "application/x-www-form-urlencoded".  I thought this would be pretty easy, and it was ... until I noticed that I am missing the last character.

I am being sent a string that looks normal enough -> field1=AB&field2=CD

I am parsing the data from the poRequest:Entity using the command

lcData = CAST(poRequest.Entity,OpenEdge.Core.Memptr):GetString(1).  

Using that command, the value in lcData shows as "field1=AB&field2=C".  Notice the 'D' is missing.

Originally the data was coming from a .Net HttpClient call.  I made the same call using Postman, using x-www-form-urlencoded as the body type, and I receive the same result.

To get around the issue for today, I decided to go old school and get the value off of WEB-CONTEXT:FORM-INPUT.  When getting the data from there, the full string is retrieved (including the 'D').

Am I doing something wrong in my assignment?  Is there a 'better' way to get 'x-www-form-urlencoded' data from the poRequest that I've missed?

Posted by Peter Judge on 09-May-2018 14:47

ContentLength sometimes lies (or isn't 100% accurate).

Try

def var body as class OpenEdge.Core.Memptr.

body = CAST(poRequest:Entity,OpenEdge.Core.Memptr).

body:GetString(1,body:Size).

All Replies

Posted by Peter Judge on 09-May-2018 14:35

This is a bug in the Memptr's GetString() method. It's fixed in 11.7.3.

The fix adds the "+ 1" below.

   /** Returns a string/character representation from a given start position,

       for the remainder of the data.

       @param  int64 The start potision

       @return longchar The character/string data requested     */

   method public longchar GetString(input piStartPos as int64):

       return GetString(piStartPos, this-object:Size - piStartPos + 1).

   end.

Posted by brianlafertewk on 09-May-2018 14:38

Ok.  That being the case, do you think adding poRequest:ContentLength like this

CAST(poRequest:Entity,OpenEdge.Core.Memptr):GetString(1,poRequest:ContentLength)

would be reliable?

Posted by Peter Judge on 09-May-2018 14:47

ContentLength sometimes lies (or isn't 100% accurate).

Try

def var body as class OpenEdge.Core.Memptr.

body = CAST(poRequest:Entity,OpenEdge.Core.Memptr).

body:GetString(1,body:Size).

Posted by brianlafertewk on 09-May-2018 14:57

Thanks Peter.  That appears to work as well.  Just to note,  the AS Memptr is not old-school MEMPTR, but AS OpenEdge.Core.Memptr.

Posted by Peter Judge on 09-May-2018 15:06

Indeed - I updated my reply to reflect that.

This thread is closed