androidrestdelphi

Delphi/Android application error : "Unsupported Media Type"


I made a multi-platform applet with Delphi 11.3. I'm using the TNetHTTPClient component to POST an XML formatted text to a REST API. Running it in Win32 mode works fine. Running it in Android mode throws an error:

Unsupported Media Type

Here is the code:

procedure TForm13.Button1Click(Sender: TObject);
var
  HttpClient: TNetHTTPClient;
  Response: IHTTPResponse;
  URL,user,key,XML, AFM: string;
  s, F : TstringStream;
  FormData: TMultipartFormData;
  XMLData: TBytesStream;
  PostData: TBytes;
begin
  HttpClient := TNetHTTPClient.Create(nil);
  try
      URL := 'https://www1.gsis.gr/wsaade/RgWsPublic2/RgWsPublic2?WSDL';
      XML := '<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:ns1="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:ns2="http://rgwspublic2/RgWsPublic2Service" xmlns:ns3="http://rgwspublic2/RgWsPublic2">'
            +'   <env:Header>'
            +'      <ns1:Security>'
            +'         <ns1:UsernameToken>'
            +'            <ns1:Username>username</ns1:Username>'
            +'            <ns1:Password>key</ns1:Password>'
            +'         </ns1:UsernameToken>'
            +'      </ns1:Security>'
            +'   </env:Header>'
            +'   <env:Body>'
            +'      <ns2:rgWsPublic2AfmMethod>'
            +'         <ns2:INPUT_REC>'
            +'            <ns3:afm_called_by/>'
            +'            <ns3:afm_called_for>'+AFM+'</ns3:afm_called_for>'
            +'            <ns3:as_on_date>'+formatDateTime('yyyy-mm-dd',date)+'</ns3:as_on_date>'
            +'         </ns2:INPUT_REC>'
            +'      </ns2:rgWsPublic2AfmMethod>'
            +'   </env:Body>'
            +'</env:Envelope>';
            s := TstringStream.create(UTF8encode(XML));
       Response := HttpClient.Post(URL, s, nil); // succeeds in win32, fails in Android
     //  Response := HttpClient.Post(URL, s, nil, [TNetHeader.Create('Content-Type', 'text/xml')]); // fails in both platforms
    if Response.StatusCode = 200 then
    begin
      Memo1.Lines.Text := Response.ContentAsString();
    end
    else
    begin
      ShowMessage('Error: ' + Response.StatusCode.ToString + ' - ' + Response.StatusText);
    end;
  finally
    HttpClient.Free;
  end;
end;

I have tried to post as TMultipartFormData or as XMLData := TBytesStream.Create(TEncoding.UTF8.GetBytes(XML)) or as Response := HttpClient.Post(URL, s, nil, [TNetHeader.Create('Content-Type', 'text or application/xml')]) but it always fails.


Solution

  • I finally overcame the problem with the following solution which assumes, however, that we have access to our own server.

    1. I saved to my server a php file (post2otherServer.php) with content:

      <?php
      $url      = $_SERVER['HTTP_URL'];
      $username = $_SERVER['HTTP_NAME'];
      $password = $_SERVER['HTTP_KEY'];
      $XML      = file_get_contents('php://input');
      $ch = curl_init($url);
      //curl_setopt($ch, CURLOPT_URL, $url);
      curl_setopt($ch, CURLOPT_POST, true);
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
      curl_setopt($ch, CURLOPT_POSTFIELDS, $XML);
      curl_setopt($ch, CURLOPT_HTTPHEADER, array(
          'Content-Type: application/xml',  // Inform the server the data is XML
          'Content-Length: ' . strlen($XML),
          'user: '.$username,        // Custom header for username
          'Key: '.$password         // Custom header for password
      ));
      $response = curl_exec($ch);
      if (curl_errno($ch)) {
          echo 'Error:' . curl_error($ch);
      } else {
          echo htmlspecialchars($response);
      }
      curl_close($ch);
      ?>
      
    2. I execute the code

      s := TstringStream.create(UTF8encode(XML));
      Response := POST('https://myserver.gr/post2otherServer.php',
                      s,nil,[TNetHeader.Create('URL',otherServer),
                              TNetHeader.Create('NAME',user),
                               TNetHeader.Create('KEY',pass)]);
      res := Response.ContentAsString;
      
    3. The job done! my server acts as a proxy and it doesn't seem to deal with the "Unsupported Media Type" issue.