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.
I finally overcame the problem with the following solution which assumes, however, that we have access to our own server.
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);
?>
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;
The job done! my server acts as a proxy and it doesn't seem to deal with the "Unsupported Media Type" issue.