AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Die Delphi-IDE REST via Indy IdHTTP, Problem mit JSON/Content-Length
Thema durchsuchen
Ansicht
Themen-Optionen

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

Ein Thema von thomaskroger · begonnen am 16. Aug 2023 · letzter Beitrag vom 16. Aug 2023
Antwort Antwort
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
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.582 Beiträge
 
Delphi 11 Alexandria
 
#2

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

  Alt 16. Aug 2023, 12:19
So etwas debugge ich meistens sehr einfach:
Ich lege mir ein Skript auf einen Server, das loggt, was dorthin gesendet wird.

Auf diese Weise kann ich auch einfach an eine URL ohne SSL die Anfragen schicken und so beide z.B. in Wireshark vergleichen, da diese dort im Klartext erscheinen.

Das kann man natürlich auch mit einem Proxy oder ähnlichem erreichen, aber so ist es ganz einfach.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
thomaskroger

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

gelöst: REST via Indy IdHTTP, Problem mit JSON/Content-Length

  Alt 16. Aug 2023, 12:29
@Sebastian
Guter Tip!


Die Lösung für Content-Length ist einfach: (JSON im Body:string)
Delphi-Quellcode:
  RequestBody:=TStringStream.Create(Body,TEncoding.UTF8);
...
  Response:=IdHTTP.Post(Base, RequestBody);
Und schon stimmt die Content-Length. Also nicht: CustomHeaders.AddValue('Body',Body);

... wer lesen kann ist klar im Vorteil...
mny tnx
Thomas
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.062 Beiträge
 
Delphi 12 Athens
 
#4

AW: gelöst: REST via Indy IdHTTP, Problem mit JSON/Content-Length

  Alt 16. Aug 2023, 13:58
Jupp, die Daten "nach" den Headern, mit einer Leerzeile dawischen (welche das Ende der Header kennzeichnet)

Drum kann das so
Code:
Cookie: 053...20a; TS0172207b=01...94b
{
eigentlich auch nicht richtig sein.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
mjustin

Registriert seit: 14. Apr 2008
3.006 Beiträge
 
Delphi 2009 Professional
 
#5

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

  Alt 16. Aug 2023, 14:17
bei einer (XE6-)REST-Kommunikation via Indy IdHTTP als POST tritt ein Problem mit der Content-Length und dem JSON-Format auf.
Ist es die Indy Version in XE6 oder eine aktuelle?
Wenn es ein Bug in der alten Indy Version ist, stehen die Chancen gut dass dieser mittlerweile behoben ist.

Die neue Version kann testweise einfach in einem neuen Verzeichnis entpackt werden - eine Package-Installation ist nicht unbedingt notwendig.
Michael Justin
  Mit Zitat antworten Zitat
thomaskroger

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

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

  Alt 16. Aug 2023, 14:56
@himitsu
Zitat:
die Daten "nach" den Headern, mit einer Leerzeile dazwischen
jap, richtig. Ich habe den Text zur Darstellung komprimiert.

@mjustin
Zitat:
Die neue Version kann testweise einfach in einem neuen Verzeichnis entpackt werden
Gibt es einen Link für eine Anleitung zur harmlosen Test-Installation? Ich hab mit letztens einen Wolf geritten um eine gescheiterte Indy-Installation wieder herzustellen:
https://www.delphipraxis.net/213521-...rt-werden.html
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.062 Beiträge
 
Delphi 12 Athens
 
#7

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

  Alt 16. Aug 2023, 17:12
Einfach z.B. von GitHub runterladen,
dann das SourceVerzeichnis im Suchpfad (Projektoptionen) des aktuellen Programms.
Oder die Indy-Quellcodes ins Projektverzeichnis kopieren.

Es werden dann direkt die PAS einkompiliert (Laufzeitpackages=False),
drum sind keine DCU oder DCP/BPL nötig, weswegen es auch nicht nörtig ist das Indy-Setup auszuführen.

Du kannst dabei bloß keine Form im FormDesigner öffnen, wo komponenten drauf liegen.
(bzw. es geht womöglich, wobei im Designer dann aber die derzeit installierte Version genutzt würde)
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
Antwort Antwort

 

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:41 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz