Moin,
bei einer (XE6-)REST-Kommunikation via
Indy IdHTTP als POST tritt ein Problem mit der Content-Length und dem JSON-Format auf.
Wenn ein JSON gesendet wird:
Body:
Code:
{
"recordtype" : "REC1",
"dealer": "xxxx",
"branch":xx,
"ordernumber": xxxxxx
}
komme eine Socket-Error#10054 und keine Response-JSON vom Server zurück.
Das funktioniert übrigens in POSTMAN problemlos:
Code:
POST https://xxxxxxmobile-xx.xxxxx.com/xxx/
api/v2/xxx/xxxx/xxxxxxxxxxxx
POST /xxx/
api/v2/xxx/xxxx/xxxxxxxxxxxxx HTTP/1.1
Content-Type: application/json
Authorization: Bearer ey...Tw
Host: xxxxxxmobile-xx.xxxxx.com
Content-Length: 88
Cookie: 053...20a; TS0172207b=01...94b
{
"recordtype" : "REC1",
"dealer": "xxxx",
"branch":xx,
"ordernumber": xxxxxx
}
HTTP/1.1 200 OK
content-type: application/json; charset=utf-8
date: Tue, 15 Aug 2023 11:18:56 GMT
vary: Accept-Encoding
x-kong-upstream-latency: 90
x-kong-proxy-latency: 18
via: kong/2.0.4
Set-Cookie: TS0172207b=01...c72bf; Path=/; Domain=.xxxxxxmobile-xx.xxxxx.com; Secure; HTTPOnly
Transfer-Encoding: chunked
{
"recordtype": "REC1",
"dealer": "xxxx ",
"branch": xx,
"ordernumber": xxxxxx,
"returncode": "00"
}
Dann ein JSON im Format:
Code:
{"recordtype":"REC1","dealer":"xxxx","branch":xx,"ordernumber":xxxxxx}
mit der "Content-Length: 0" (! s.u.)
Jetzt reagiert der Server mit der Antwort:
Code:
HTTP/1.1 400 Bad Request
{
"errorCode": "URL0001",
"message": "No input dataÜ"
}
Code:
Req:
POST /xxx/
api/v2/xxx/xxxx/xxxxxxxxxxxx HTTP/1.1
Content-Type: application/json
Content-Length: 0
Authorization: Bearer ey...5AQ
Cookie: 053...20a; TS0172207b=01...1c
Body: {"recordtype":"REC1","dealer":"xxxx","branch":xx,"ordernumber":xxxxxx}
Host: xxxxxxmobile-xx.xxxxx.com
Accept: */*
Accept-Encoding: identity
User-Agent: Mozilla/3.0 (compatible;
Indy Library)
Resp: HTTP/1.1 400 Bad Request
content-type: application/json; charset=utf-8
date: Tue, 15 Aug 2023 17:57:22 GMT
x-kong-upstream-latency: 50
x-kong-proxy-latency: 17
via: kong/2.0.4
Set-Cookie: TS0......c75; Path=/; Domain=.xxxxxxmobile-xx.xxxxx.com; Secure; HTTPOnly
Transfer-Encoding: chunked
Resp:
{
"errorCode": "URL0001",
"message": "No input dataÜ"
}
Da Content-Length: 0 ist, wie von IdHTTP/POST generiert, diesmal MIT Content-Length: 0 UND Content-Length: 72:
Code:
Req:
POST /xxx/
api/v2/xxx/xxxx/xxxxxxxxxxxxx HTTP/1.1
Content-Type: application/json
Content-Length: 0
Authorization: Bearer ey..qg
Cookie: 053...0a; TS0172207b=01f...1c
Body: {"recordtype":"REC1","dealer":"xxxx","branch":xx,"ordernumber":xxxxxx}
Content-Length: 72
Host: xxxxxxmobile-xx.xxxxx.com
Accept: */*
Accept-Encoding: identity
User-Agent: Mozilla/3.0 (compatible;
Indy Library)
das POST und das Programm hängt ohne response.
Delphi-Quellcode:
IdLogFile.Filename:='
LogOrder.txt';
IdLogFile.Active:=true;
IdHTTP.Response.Clear;
IdHTTP.Request.Clear;
with IdSSLIOHandlerSocketOpenSSL
do
begin
SSLOptions.SSLVersions := [sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2];
SSLOptions.Mode := sslmClient;
SSLOptions.VerifyMode := [];
SSLOptions.VerifyDepth := 0;
DefStringEncoding := enUTF8;
ReadTimeout := 1000;
ConnectTimeout := 1000;
end;
with IdHTTP
do
begin
ConnectTimeout := 1000;
AllowCookies := True;
HandleRedirects := True;
IOHandler := IdSSLIOHandlerSocketOpenSSL;
end;
with IdHTTP.Request
do
begin
Clear;
BasicAuthentication := false;
Accept:='
*/*';
ContentType:='
application/json';
CustomHeaders.AddValue('
Authorization', '
Bearer ' + token);
CustomHeaders.AddValue('
Cookie','
053...20a; TS0172207b=01f...1c');
CustomHeaders.AddValue('
Body',Body);
// ContentLength:=length(Body); //see Remy Lebeau !
// CustomHeaders.AddValue('Content-Length',length(Body).ToString());
end;
rs :=IdHTTP.Post(BaseURL, ResponseList);
except
on E:
Exception do
begin
Der Server hat offenbar ein Problem mit dem JSON-Format des IdHTTP-Body. Gut, das darf er, er nimmt ja das formatlose JSON.
Mal rhetorisch gefragt: was macht IdHTTP mit dem JSON dass der Server es nicht annimmt? Im Log sieht es harmlos aus.
IdHTTP/POST generiert eine Content-Length: 0 und das mag der Server auch nicht.
Wie Remy Lebeau so richtig sagt: DO NOT set a ContentLength manually, let Post() fill it in for you..
Ok, wie überrede ich IdHTTP/POST dazu, eine richtige Content-Length über length(Body) zu bilden?
mny tnx!
Thomas