B4J Question [Server] How to dump a payload from an HTML form submission

avalle

Active Member
Licensed User
Longtime User
Hi
I have an HTML form submitted to my B4J web server and I need to dump the full HTTP request for logging purposes, including the x-www-form-urlencoded payload.
The form is POST-ed to a URL containing query parameters (e.g. https://my.server.online/sample.html?id=12345&type=flat) as well as additional key/value parameters in the request payload.

Using req.FullRequestURI returns the full URL including the query parameters, however the payload is not present.
I tried req.InputStream and it actually contains the payload:

B4X:
'Parse payload
Dim data() As Byte = Bit.InputStreamToBytes(req.InputStream)
Dim payload As String = BytesToString(data, 0, data.Length, "UTF8")
Log("Payload: " & payload)

...however after this is executed I can't read anymore the parameters from the payload using req.GetParameter as they become empty.
On the contrary, if req.InputStream is used after req.GetParameter to read the payload, the stream would be empty as well.
In summary, reading the payload with both req.InputStream and req.GetParameter does not seem possible as they are mutually exclusive.

Am I doing something wrong?
Any other suggestion in addition to read the InputStream and parse the payload instead of using GetParameter ?

Thanks
Andrea
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
In summary, reading the payload with both req.InputStream and req.GetParameter does not seem possible as they are mutually exclusive.
That's true. Getting the parameters causes the handler to parse the payload. Reading the input stream consumes the payload.

Maybe log ParameterMap instead...
 
Upvote 0

avalle

Active Member
Licensed User
Longtime User
The problem with ParameterMap is that it requires to know the name of the parameters in advance. This means I can't log any wrong parameters that the client could send.

InputStream instead contains everything that is sent, including incomplete and wrong parameters/values.

If there's no better solution then I think I'll use InputStream and I'll parse it to extract the parameters from the payload.
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
The problem with ParameterMap is that it requires to know the name of the parameters in advance. This means I can't log any wrong parameters that the client could send.
No it doesn't.

B4X:
Dim m As Map = req.ParameterMap
For Each Key As String In m.Keys
 Log($"${key}: ${m.Get(key)}"$)
Next
 
Last edited:
Upvote 0

avalle

Active Member
Licensed User
Longtime User
Thanks Erel. I'm sorry but for some reasons I confused ParameterMap with GetParameterValues.
I think it would work.
 
Upvote 0

avalle

Active Member
Licensed User
Longtime User
The code above does not handle the case of multiple instances with the same key name.
In addition the values are returned as [Ljava.lang.String;

Actually the following code works better:
B4X:
    Dim m As Map = req.ParameterMap
    For Each Key As String In m.Keys
        Dim Values() As String = m.Get(Key)
        For Each Val As String In Values
            Log($"${Key}: ${Val}"$)
        Next
    Next
 
Upvote 0
Top