I made a simple API in PHP to receive some variables from GET/POST requests and post it to and third-party GraphQL API. But I'm having trouble with content encoding.
The application work that way:
Delphi 5 Desktop Application send a simple GET or POST with some variables to my PHP API, and my PHP API make a query request to a third-party GraphQL API.
The GraphQL I send is:
query {
node(id: 1){
... on Organization{
fullname
entities(type: STUDENT, search: "Some Student Name"){
nodes{
dbId
fullname
eid
}
}
}
}
}
The request URL example is:
When I copy and paste the request URL to browser ou call it on command prompt cURL, works fine.
But, when Delphi 5 calls it, it broken my query string with a lot of "+" (plus sign):
Syntax Error GraphQL request (1:6) Cannot parse the unexpected character "+".
1: query+%7B%0D%0A++node%28id%3A+1%29%7B%0D%0A++++...+on+Organization%7B%0D%0A++++++fullname%0D%0A++++++entities%28type%3A+STUDENT%2C+search%3A+%22Some Student Name%22%29%7B%0D%0A++++++++nodes%7B%0D%0A++++++++++dbId%0D%0A++++++++++fullname%0D%0A++++++++++eid%0D%0A++++++++%7D%0D%0A++++++%7D%0D%0A++++%7D%0D%0A++%7D%0D%0A%7D
^
The Delphi 5 Application uses TidHTTP component to do it. Code below:
procedure TForm1.ExportaClassApp(prID : Integer; prNumBoleto, prLinhaDigitavel : String);
const cUrl = 'http://api-link/request.php?';
cToken = 'xyzwsa';
cTipo = 'boleto';
cE_Comercial = #138; (* equivalent to & *)
var sSQL : String;
qryPesquisa : TADOQuery;
oHTTP : TIdHTTP;
sRetornoClassApp : String;
HTTPClient : TidHTTP;
Lista : TStringStream;
sParametros : String;
Url_Completa : String;
sToken : String;
sId : String;
sTipo : String;
sMatricula : String;
sNome_Aluno : String;
sNome_Responsavel : String;
sDescricao : String;
sNumBoleto : String;
sVencimento : String;
sValor : String;
sLinhaDigitavel : String;
begin
oHTTP := TIdHTTP.Create(Application);
HTTPClient := TidHTTP.Create(Application);;
sDescricao := '';
sDescricao := Copy(sDescricao,1, length(sDescricao) - 2);
sToken := 'token=' + cToken;
sId := '&id=' + IntToStr(prId);
sTipo := '&tipo=' + cTipo;
sMatricula := '&mat=' + '123456';
sNome_Aluno := '&nome_aluno=' + 'Some Student Name';
sNome_Responsavel := '&nome_responsavel=' + 'Another Name';
sDescricao := '&titulo=' + 'Just a test';
sNumBoleto := '&numero=' + prNumBoleto;
sVencimento := '&venc=' + '2018-04-02';
sValor := '&valor=' + FloatToStr(843 * 100);
sLinhaDigitavel := '&linha=' + prLinhaDigitavel;
sParametros := sToken + sId + sTipo + sMatricula + sNome_Aluno + sNome_Responsavel + sDescricao + sNumBoleto + sVencimento + sValor + sLinhaDigitavel;
Url_Completa := cUrl + sPArametros;
Url_Completa := StringReplace(Url_Completa,' ','%20',[rfReplaceAll, rfIgnoreCase]);
if edtContentType.Text <> '' then
oHTTP.Request.ContentType := edtContentType.Text
else
oHTTP.Request.ContentType := '';
if edtContentEncoding.Text <> '' then
oHTTP.Request.ContentEncoding := edtContentEncoding.Text
else
oHTTP.Request.ContentEncoding := '';
sRetornoClassApp := oHTTP.URL.URLDecode(oHTTP.Get(Url_Completa));
btnLimparClick(Self);
mmoEnvio.Text := Url_Completa;
mmoRetorno.Text := sRetornoClassApp;
FreeAndNil(oHTTP);
end;
Here is the browser/cURL request/response headers (that works):
Array
(
[0] => POST /graphql HTTP/1.1
[1] => Host: joy.classapp.co
[2] => User-Agent: PHP Curl/1.6 (+https://github.com/php-mod/curl)
[3] => Accept: */*
[4] => Content-Length: 400
[5] => Content-Type: application/x-www-form-urlencoded
)
Array
(
[0] => HTTP/1.1 200 OK
[1] => Access-Control-Allow-Origin: *
[2] => Content-Type: application/json; charset=utf-8
[3] => Date: Mon, 02 Apr 2018 14:37:19 GMT
[4] => ETag: W/"4d-r2dRUM/0NEHToQUzFDAesWSzSWY"
[5] => Server: nginx/1.12.1
[6] => X-Content-Type-Options: nosniff
[7] => X-DNS-Prefetch-Control: off
[8] => X-Download-Options: noopen
[9] => X-Frame-Options: SAMEORIGIN
[10] => X-XSS-Protection: 1; mode=block
[11] => Content-Length: 77
[12] => Connection: keep-alive
)
And below the Delphi 5 TidHTTP request/response headers (that doesn't works):
Array
(
[0] => POST /graphql HTTP/1.1
[1] => Host: joy.classapp.co
[2] => User-Agent: PHP Curl/1.6 ( https://github.com/php-mod/curl)
[3] => Accept: */*
[4] => Content-Length: 407
[5] => Content-Type: application/x-www-form-urlencoded
)
Array
(
[0] => HTTP/1.1 400 Bad Request
[1] => Access-Control-Allow-Origin: *
[2] => Content-Type: application/json; charset=utf-8
[3] => Date: Mon, 02 Apr 2018 14:47:53 GMT
[4] => ETag: W/"1f6-RtlkHyZy4MNsaj0EjU9LCzebnSs"
[5] => Server: nginx/1.12.1
[6] => X-Content-Type-Options: nosniff
[7] => X-DNS-Prefetch-Control: off
[8] => X-Download-Options: noopen
[9] => X-Frame-Options: SAMEORIGIN
[10] => X-XSS-Protection: 1; mode=block
[11] => Content-Length: 502
[12] => Connection: keep-alive
)
I tried to change Content-Type em Curl Class (I'm using Curl/Curl library) to make POST to GraphQL API, unsuccessful.
I don't know why it's work perfectly in browser/cURL and not in Delphi 5. The problem is in my PHP API or in the Delphi 5 TidHTTP component? Or both?
EDIT: Tried both Delphi 5 and Delphi 2006 with Indy v10.1.5, using GET and POST http verbs. Same error.
Thanks for attention.