Einzelnen Beitrag anzeigen

thomaskroger

Registriert seit: 22. Mär 2009
16 Beiträge
 
#1

REST via Indy IdHTTP, Problem mit JSON/Content-Length

  Alt 16. Aug 2023, 12:01
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
  Mit Zitat antworten Zitat