Idhttp on PHP Android cannot accept error 406
I am trying to publish inserts on MySQL database using idhttp and PHP script. This is the PHP script to insert into the database:
$MysqLi = new MysqLi($servidor, $usuario, $senha, $banco);
// Caso algo tenha dado errado, exibe uma mensagem de erro
if (MysqLi_connect_errno()) trigger_error(MysqLi_connect_error());
$iduser = quoted_printable_decode($_POST['iduser']);
$nome = quoted_printable_decode($_POST['nome']);
$data = quoted_printable_decode($_POST['data']);
$hora = quoted_printable_decode($_POST['hora']);
$mensagem = quoted_printable_decode($_POST['mensagem']);
$latitude = quoted_printable_decode($_POST['latitude']);
$longitude = quoted_printable_decode($_POST['longitude']);
$imagem = $_FILES["imagem"]['tmp_name'];
$tamanho = $_FILES['imagem']['size'];
header($_SERVER["SERVER_PROTOCOL"] . " 200 OK");
header('Content-Type: text/plain; charset="utf-8"');
if ( $imagem != "none" )
{
$fp = fopen($imagem, "rb");
$conteudo = fread($fp, $tamanho);
$conteudo = addslashes($conteudo);
fclose($fp);
$queryInsercao = "INSERT INTO tabpainel (iduser, nome, data, hora, mensagem, latitude, longitude, imagem) VALUES ('$iduser', '$nome', '$data','$hora','$mensagem', '$latitude', '$longitude', '$conteudo')";
MysqLi_query($MysqLi,$queryInsercao) or die("Algo deu errado ao inserir o registro. Tente novamente.");
if (MysqLi_affected_rows($MysqLi) > 0)
include 'baixarpainel.PHP';
else
print utf8_encode("Não foi possível inserir o registro");
}
else
print utf8_encode("Não foi possível carregar a imagem.");
?>
In Delphi, I use:
FormPHP := TIdMultiPartFormDataStream.Create;
FormPHP.AddFile ('imagem', AImagem, 'image/jpeg');
FormPHP.AddFormField ('iduser', AIDUser, 'utf-8');
FormPHP.AddFormField ('nome', ANome, 'utf-8');
FormPHP.AddFormField ('data', AData, 'utf-8');
FormPHP.AddFormField ('hora', AHora, 'utf-8');
FormPHP.AddFormField ('mensagem', AMensagem, 'utf-8');
FormPHP.AddFormField ('latitude', '1');
FormPHP.AddFormField ('longitude', '1');
Response := TStringStream.Create('',TEncoding.UTF8);
HTTP:= TIdHTTP.Create(self);
HTTP.Post('http://addressexample.com/cadastro.PHP',FormPHP,Response);
It works well until the hosting company has to be replaced. Using hostinger can, but not using Hostgator. Using Hostgator, idhttp will throw an exception in the class eidhttpprotocalexception and display the message: "http / 1.1 406 not acceptable". The support of Hostgator has disabled mod_ Security, which may cause problems
This exception only occurs on Android. Using the same application on windows works well
Update: I tried another thing. The PHP script is like this:
// Conecta-se ao banco de dados MysqL
$MysqLi = new MysqLi($servidor, $usuario, $senha, $banco);
// Caso algo tenha dado errado, exibe uma mensagem de erro
if (MysqLi_connect_errno()) trigger_error(MysqLi_connect_error());
# Instanciando o XMLWriter
$xml = new XMLWriter;
$xml->openMemory();
# Definindo o encoding do XML
$xml->startDocument( '1.0', 'UTF-8');
# Primeiro elemento do XML
$xml->startElement("DATAPACKET");
$xml->writeAttribute("version", "2.0");
$xml->StartElement("MetaDATA");
$xml->startElement("FIELDS");
$xml->startElement("FIELD");
$xml->writeAttribute("attrname", "id");
$xml->writeAttribute("fieldtype", "I4");
$xml->endElement();
$xml->startElement("FIELD");
$xml->writeAttribute("attrname", "iduser");
$xml->writeAttribute("fieldtype", "String");
$xml->writeAttribute("Width", "30");
$xml->endElement();
$xml->startElement("FIELD");
$xml->writeAttribute("attrname", "nome");
$xml->writeAttribute("fieldtype", "String");
$xml->writeAttribute("Width", "200");
$xml->endElement();
$xml->startElement("FIELD");
$xml->writeAttribute("attrname", "data");
$xml->writeAttribute("fieldtype", "String");
$xml->writeAttribute("Width", "8");
$xml->endElement();
$xml->startElement("FIELD");
$xml->writeAttribute("attrname", "hora");
$xml->writeAttribute("fieldtype", "String");
$xml->writeAttribute("Width", "5");
$xml->endElement();
$xml->startElement("FIELD");
$xml->writeAttribute("attrname", "mensagem");
$xml->writeAttribute("fieldtype", "String");
$xml->writeAttribute("Width", "3000");
$xml->endElement();
$xml->startElement("FIELD");
$xml->writeAttribute("attrname", "latitude");
$xml->writeAttribute("fieldtype", "r8");
$xml->endElement();
$xml->startElement("FIELD");
$xml->writeAttribute("attrname", "longitude");
$xml->writeAttribute("fieldtype", "r8");
$xml->endElement();
$xml->startElement("FIELD");
$xml->writeAttribute("attrname", "imagem");
$xml->writeAttribute("fieldtype", "bin.hex");
$xml->writeAttribute("subtype", "Binary");
$xml->endElement();
$xml->endElement(); //FIELDS
$xml->endElement(); //MetaDATA
$xml->StartElement("ROWDATA");
# Query na tabela escolhida
$rs_table = $MysqLi->query("select * from tabpainel ORDER BY id DESC LIMIT 50");
while($table = $rs_table->fetch_array(MysqLI_ASSOC))
{
# Transformando array em objeto
$table = (object)$table;
# Criando elemento tabela
$xml->StartElement("ROW");
# Setando os atributos
$xml->writeAttribute("id", "$table->id");
$xml->writeAttribute("iduser", "$table->iduser");
$xml->writeAttribute("nome", "$table->nome");
$xml->writeAttribute("data", "$table->data");
$xml->writeAttribute("hora", "$table->hora");
$xml->writeAttribute("mensagem", "$table->mensagem");
$xml->writeAttribute("latitude", "$table->latitude");
$xml->writeAttribute("longitude","$table->longitude");
$xml->writeAttribute("imagem", base64_encode("$table->imagem"));
$xml->endElement();
}
# Fechando o ROWDATA
$xml->endElement();
# Fechando o elemento DATAPACKET
$xml->endElement();
# Encerrando a conexao
//$con->close();
# Definindo cabecalho de saida
header("content-type: application/xml; charset=utf-8");
# Imprimindo a saida do XML
print $xml->outputMemory(true);
?>
And I use http.get to receive XML:
Http.HandleRedirects:= true;
Http.request.useragent := 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; MAAU)';
MS.Text:= Http.get('http://addressexample.com/baixarpainel.PHP');
MS.SaveToFile(FarquivoBaixado);
This also works well on Android. The problem is still only http.post on Android
Since Indy uses a single cross platform code base, tidhttp works exactly the same on all platforms. Therefore, the generated HTTP requests should be exactly the same on all platforms
An HTTP 406 error occurs when an HTTP request contains an accept header that does not specify any media type in which the server can render a response. Per RFC 2616 section 14.1:
Your PHP script is sending a text / plain text response, so if you send an accept header that does not allow text / plain text, it may cause 406 error. It sounds that the enforcement of Hostgator is stronger than that of hostinger
By default, tidhttp sets its request.accept property to the following string value:
'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'
Technically, it allows all media types passing through * / *, but its priority is lower than some other media types. However, if the server implements "accept" processing correctly, this default value should still be sufficient to allow text / plain text response
You need to contact the Hostgator and discuss the problem with them, because the problem is theirs, not yours
Having said that, since you know that the server response is always text / plain text, you can add the following to the code before calling post():
HTTP.Request.Accept := 'text/plain';
HTTP.Request.AcceptCharset := 'utf-8';