Problem with POST request (Android)

I’m using RemObject Elements 9.0.97.2071 with Visual Studio 2015 to make an Android App.

I’m having a problem with a code similar to the following:

let Request = HttpRequest( Url("http://www.somepage.com") )

Request.Mode = HttpRequestMode.Post
Request.Content = HttpBinaryRequestContent("TEST", Encoding.UTF8)
do {
    Resultado = "OK: " + Http.GetString(Encoding.UTF8, Request)
}
catch {
    Resultado = "ERROR: " + error.description
}

The variable “Resultado” always takes the value: “ERROR: java.net.ProtocolException: method does not support a request body: GET”. It seems that sugar HttpRequest object is not handlig correctly the mode “HttpRequestMode.Post” (I get the same error if I try to use a GET method: Request.Mode = HttpRequestMode.Get)

Having looked at the (current) Sugar code for handling the request it’s not obvious to me how the Post request mode might end up incorrectly handled as a Get. Which raises the possibility that the setting of the Request.Mode itself is not working as expected.

Have you checked the value of Request.Mode at the point just prior to the request being performed ?

1 Like

Prior to executing Http.GetString the value of Request.Mode is the one assigned: HttpRequestMode.Post.

I forgot to mention that I’ve also checked current Sugar code, and it seems to be right. So, I tried to use this current version, but I keep getting the same error… The code of my post is the simplest one that throws the error, but none of the methods of Request object works to retrieve data when I set HttpRequestMode.Post…

Thanks for your help, Jolyon

Can you try stepping thru the Sugar.HTTP code to see where it goes wrong?

A lot of years has passed since last time I coded in Pascal… but today I’m lucky! :smirk:

It seems that the problem is in the method Http.ExecuteRequestSynchronous (file HTTP.bas of project Sugar.Shared). I also suppose that the method Http.ExecuteRequest has the same problem. The code of this methods begins with:

  {$IF COOPER}
  var lConnection := java.net.URL(aRequest.Url).openConnection as java.net.HttpURLConnection;
  
  for each k in aRequest.Headers.Keys do
    lConnection.setRequestProperty(k, aRequest.Headers[k]);
    //
    // OPS: Here lConnection "thinks" that method to use is 'GET'...
    //
    if assigned(aRequest.Content) then begin
      lConnection.getOutputStream().write((aRequest.Content as IHttpRequestContent).GetContentAsArray());
      lConnection.getOutputStream().flush();
    end;
    ...

I think that the solution is to “tell” lConnection which is the method to use to do the request, adding this code in the marked line (the “OPS” line):

    case aRequest.Mode of
      HttpRequestMode.Get: lConnection.setRequestMethod('GET');
      HttpRequestMode.Post: lConnection.setRequestMethod('POST');
      HttpRequestMode.Head: lConnection.setRequestMethod('HEAD');
      HttpRequestMode.Put: lConnection.setRequestMethod('PUT');
      HttpRequestMode.Delete: lConnection.setRequestMethod('DELETE');
      HttpRequestMode.Patch: lConnection.setRequestMethod('PATCH');
      HttpRequestMode.Options: lConnection.setRequestMethod('OPTIONS');
      HttpRequestMode.Trace: lConnection.setRequestMethod('TRACE');
    end;

A code similar to this is used for ECHOES and TOFFEE, so instead of repeating this code fragment 6 times in this code module (HPPT.pas), I suggest to define a function to “translate” the value of aRequest.Mode to a string code (for example, HttpRequestMode2String). With this function, the correction takes only one line of code:

  lConnection.setRequestMethod(HttpRequestMode2String(aRequest.Mode));

Looks right to me. Confession: Somehow the #ifdef’s (the requestmode handling being only for the ECHOES impl.) didn’t register when I was reading the code. :blush:

ok, so this turned out to be wrong, and in fact the code did not even TRY to set the mode. fixed, for Sugar and RTL2.

(alas not in time for todays beta, which is building now, but its on GitHub).

Correct: I didn’t know that I can debug RemObjects Pascal code with my free license of Elements, so I only visually checked the code…

This time I have REALLY debugged a copy of the code downloaded from GitHub.