AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke Ich habe einen TCPServer als HTTP server und möchte daten aus einem POST JSON Data
Thema durchsuchen
Ansicht
Themen-Optionen

Ich habe einen TCPServer als HTTP server und möchte daten aus einem POST JSON Data

Ein Thema von joehd · begonnen am 12. Dez 2022 · letzter Beitrag vom 10. Jan 2023
Antwort Antwort
Seite 1 von 4  1 23     Letzte »    
joehd

Registriert seit: 8. Okt 2008
Ort: Heidelberg
107 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#1

Ich habe einen TCPServer als HTTP server und möchte daten aus einem POST JSON Data

  Alt 12. Dez 2022, 11:21
Hallo vorab ich bin neu in dem HTTP Post Kram ...
Wie empfange ich Json Data aus einem Post per TWebHTTPRequest Post

Ich habe den HTTP Server soweit geschrieben das er "normal" funktioniert. HTTp Get
Habe POST und Options rausgefiltert.

Aber wie komme ich jetzt an den Daten Stream ? Es werden Textdaten übergeben.
Der Server besteht wie zu sehen hauptsächlich aus start Stop und der Beantwortung dedr Anfragen.
Wenn ich es richtig verstehe sollte wenn der Aufbau der Verbindung fertig ist was ja wohl klappt eine Abfrage der Daten möglich sein, zumindest nachdem man sie akzeptiert hat.

Wie Bringe ich den Client dazu mir die Daten im Textformat zu senden ?
Muss ich ein Accept als Sendline zurück senden ? Wie erhalte ich die Infos über die Puffergröße ?

Herzlichen Dank an Euch ...
Grüße
Joachim

"
RequestLine:OPTIONS /Kontakt/index.html HTTP/1.1
Host: 127.0.0.1:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:107.0) Gecko/20100101 Firefox/107.0
Accept: */*
Accept-Language: de,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate, br
Access-Control-Request-Method: POST
Access-Control-Request-Headers: cache-control
Referer: http://localhost:8000/
Origin: http://localhost:8000
Connection: keep-alive
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
"


Delphi-Quellcode:
unit WebserverUnit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Sockets, ComCtrls;

type
  TForm1 = class(TForm)
    TcpServer1: TTcpServer;
    Memo1: TMemo;
    Start: TButton;
    Stop: TButton;
    StatusBar1: TStatusBar;
    Button1: TButton;
    Memo2: TMemo;
    IsOnline: TCheckBox;
    procedure StartClick(Sender: TObject);
    procedure StopClick(Sender: TObject);
    procedure TcpServer1Accept(Sender: TObject; ClientSocket: TCustomIpClient);
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure TcpServer1Listening(Sender: TObject);
    procedure TcpServer1GetThread(Sender: TObject;
      var ClientSocketThread: TClientSocketThread);
  private
    { Private-Deklarationen }

  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  mypfad : String;
  
implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
 Stop.Click;
 form1.TcpServer1.Free;
 Application.Terminate;
end;

procedure TForm1.FormCreate(Sender: TObject);
var pfad : String;
begin
  pfad := GetCurrentDir + '/webDocs';
  if not DirectoryExists(Pfad) then ForceDirectories(Pfad);
  pfad := GetCurrentDir + '/Err';
  if not DirectoryExists(Pfad) then ForceDirectories(Pfad);
end;

procedure TForm1.StartClick(Sender: TObject);
begin
 Form1.TcpServer1.Open;
 Form1.TcpServer1.Active := true;
 memo1.lines.add(Datetimetostr(now) + ' : Server Start ');
 isonline.Checked := Form1.TcpServer1.Active;
 if isonline.checked = false then
    Showmessage('Fehler beim Starten');
end;

procedure TForm1.StopClick(Sender: TObject);
begin
 Form1.TcpServer1.Close;
 Form1.TcpServer1.Active := false;
 memo1.lines.add(Datetimetostr(now) + ' : Server Stop ');
  isonline.Checked := Form1.TcpServer1.Active;
 if isonline.checked = true then
    Showmessage('Fehler beim Stoppen');
end;

procedure TForm1.TcpServer1Accept(Sender: TObject;
  ClientSocket: TCustomIpClient);
var
  rawData,Path,Agent,RawAgent:String;
  HttpPos,AgentPos:Integer;
  TmpStr,TmpStr1:String;
  RequestFile, RequestHeader:TStringList;
  I: Integer;
  DataText : TStream;
  lParamList: TStringStream;
begin
 RawData:=' ';
 RequestFile := TStringList.Create;
 RequestHeader := TStringList.create;

  while ClientSocket.Connected do
    begin

    RawData := ClientSocket.Receiveln;
    memo1.Lines.add('RawLine:' + rawdata + '#Endline'); // Logfile
    while RawData <> 'do
      begin
        RequestHeader.add(RawData);
        RawData := ClientSocket.Receiveln;
        memo2.Text := ('RequestLine:' + RequestHeader.Text );
      end;

     Sleep(100);

     for I := 0 to RequestHeader.Count -1 do
      begin

        if RequestHeader.Strings[i] = 'then
          begin
            Sleep(100);
            Continue;
          end;

        if Pos('User-Agent:', RequestHeader.Strings[i]) > 0 then
          begin
            RawAgent := RequestHeader.Strings[i];
            AgentPos := Pos('User-Agent:',RawAgent);
            Agent := Copy(RawAgent,13,Length(RawAgent)-12);
            Form1.Memo1.Lines.Add('User-Agent : ' + Agent);
          end;

        if Copy(RequestHeader.Strings[i],1,3) = 'GETthen
          begin
            Form1.Memo1.lines.add(' GET Request');
            HttpPos := Pos('HTTP',RequestHeader.Strings[i]);
            Path := Copy(RequestHeader.Strings[i],5,HttpPos -6);
            Form1.Memo1.lines.add('Request For Page : ' + Path);


          end;

        if Copy(RequestHeader.Strings[i],1,4) = 'POSTthen
          begin
            Form1.Memo1.lines.add(' POST Request');
            HttpPos := Pos('HTTP',RequestHeader.Strings[i]);
            Path := Copy(RequestHeader.Strings[i],6,HttpPos -6);
            Form1.Memo1.lines.add('Request For Page : ' + Path);
            if RequestHeader.Text = 'OPTIONS /Kontakt/index.html HTTP/1.1then
              Begin // KOntaktdaten kommen
                Clientsocket.WaitForData(10);
                TmpStr1 := Clientsocket.Receiveln('#$D#$A');
                if length(TmpStr1) > 0 then
                   Memo1.Lines.add('Receive: ' + TmpStr1 ) ;
              End;
          // Accept Post

          end;


        if Copy(RequestHeader.Strings[i],1,7) = 'OPTIONSthen
          begin
            Form1.Memo1.lines.add(' Option Request');
            HttpPos := Pos('HTTP',RequestHeader.Strings[i]);
            Path := Copy(RequestHeader.Strings[i],9,HttpPos -6);
            Form1.Memo1.lines.add('Option Page : << ' + Path + ' >>');
            if Copy(RequestHeader.Strings[i],1,7) = 'OPTIONSthen
              Begin // KOntaktdaten kommen
                // Clientsocket.ReceiveFrom(mybuffer,length(mybuffer),);
                Clientsocket.WaitForData(10);
                TmpStr1 := Clientsocket.Receiveln('#$D#$A');
                if length(TmpStr1) > 0 then
                   Memo1.Lines.add('Receive: ' + TmpStr1 ) ;

              End;
          end;


      end;
      // Behandlung der HTTP Anfrage
      if FileExists(GetCurrentDir + '/WebDocs' + Path) then
        begin
          RequestFile.LoadFromFile(GetCurrentDir + '/WebDocs' + Path);
          ClientSocket.Sendln('HTTP/1.0 200 OK');
          ClientSocket.Sendln('');
          ClientSocket.Sendln(RequestFile.Text);
          ClientSocket.Close;
          RequestFile.Clear;
          Exit;
        end
      Else
      if Not FileExists(GetCurrentDir + '/WebDocs' + Path) then
        begin
          Form1.memo1.lines.add('ERROR : 404 Page Not Found : <<'+ Path + '>>');
          RequestFile.LoadFromFile(GetCurrentDir + '/Err/' + '404.html');
          ClientSocket.Sendln('HTTP/1.0 404 Not Found');
          ClientSocket.Sendln('');
          ClientSocket.Sendln(RequestFile.Text);
          ClientSocket.Close;
          RequestFile.Clear;
          Exit;
        end;
    end;
  RequestFile.Free;

end;

end.
joe
immer wenn ich was suche finde ich es hier komisch oder ?
Arbeite mit D3 D5 D2007 DXE Prof
  Mit Zitat antworten Zitat
mjustin

Registriert seit: 14. Apr 2008
3.005 Beiträge
 
Delphi 2009 Professional
 
#2

AW: Ich habe einen TCPServer als HTTP server und möchte daten aus einem POST JSON Da

  Alt 12. Dez 2022, 11:38
Woher kommt TTCPServer, ist das die Klasse TTcpServer aus Delphi 6?

https://stackoverflow.com/a/26049268/80901

Falls ja, würde ich wie in der Antwort vorgeschlagen auf Indy, ICS oder Synapse (oder mORMot) umstellen.
Michael Justin

Geändert von mjustin (12. Dez 2022 um 12:06 Uhr)
  Mit Zitat antworten Zitat
joehd

Registriert seit: 8. Okt 2008
Ort: Heidelberg
107 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#3

AW: Ich habe einen TCPServer als HTTP server und möchte daten aus einem POST JSON Da

  Alt 12. Dez 2022, 11:47
Woher kommt TTCPServer, ist das die Klasse TTcpServer aus Delphi 6?

https://stackoverflow.com/a/26049268/80901

Falls ja, würde ich wie in der Antwort vorgeschlagen auf Indy, ICS oder Synapse (oder mORMot) umstellen.
Hallo !
Das ist aus Delphi 2007 das war der einfachste weg für mich.
Ich stelle mir vor ich muss nur noch die richtige Antwort geben und den Stream herausfinden ... Das was gesendet wird ist einfache Strings ...
Mein Problem war auch ich bin mit der Indy und dem TID Server 0 zurecht gekommen da bin ich dann zum guten alten D2007 übergegangen ...
joe
immer wenn ich was suche finde ich es hier komisch oder ?
Arbeite mit D3 D5 D2007 DXE Prof

Geändert von joehd (12. Dez 2022 um 11:49 Uhr)
  Mit Zitat antworten Zitat
mjustin

Registriert seit: 14. Apr 2008
3.005 Beiträge
 
Delphi 2009 Professional
 
#4

AW: Ich habe einen TCPServer als HTTP server und möchte daten aus einem POST JSON Da

  Alt 12. Dez 2022, 12:02
Das ist aus Delphi 2007 das war der einfachste weg für mich.
Ich stelle mir vor ich muss nur noch die richtige Antwort geben und den Stream herausfinden ... Das was gesendet wird ist einfache Strings ...
Mein Problem war auch ich bin mit der Indy und dem TID Server 0 zurecht gekommen da bin ich dann zum guten alten D2007 übergegangen ...
Mit dem Indy HTTP Server (oder Synapse etc.) wäre es einfacher zu lösen, der Code wäre wesentlich lesbarer und robuster. Es finden sich dazu mehr Codebeispiele im Internet, und mehr Entwickler, die ihn einsetzen, können bei Fragen helfen.

Das liegt möglicherweise auch daran:
Zitat:
TTcpClient and TTcpServer were originally introduced in Delphi 6 as a cross-platform socket solution for Kylix (which is a dead product). They were removed from Delphi in XE6, downgraded to demo status, not even official components anymore.
Zitat:
In my opinion, TTcpClient and TTcpServer are horrible components, you should stay away from them. (...) They are very difficult to work with, have bad error handling, and are not very flexible to use.
Michael Justin

Geändert von mjustin (12. Dez 2022 um 12:06 Uhr)
  Mit Zitat antworten Zitat
joehd

Registriert seit: 8. Okt 2008
Ort: Heidelberg
107 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#5

AW: Ich habe einen TCPServer als HTTP server und möchte daten aus einem POST JSON Da

  Alt 12. Dez 2022, 12:28
Eigentlich habe ich ja schon dinge in Indy gemacht ...
Gibt es sorry wenn ich so frage ein Beispiel für POST JSON mit der Indy Server componente...
Ich habe schon so viel durchgesucht ...

Ich stelle mir das so vor Verbindung herstellen, Stream anbinden und daten erhalten ... Daten Parsen .... aber ich hänge voll ...

Danke schon mal
joe
immer wenn ich was suche finde ich es hier komisch oder ?
Arbeite mit D3 D5 D2007 DXE Prof

Geändert von joehd (12. Dez 2022 um 12:32 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Ich habe einen TCPServer als HTTP server und möchte daten aus einem POST JSON Da

  Alt 12. Dez 2022, 13:18
Den Input liest du ja bereits (HTTP-Header) ... danach kommt eine Leerzeile und dann die Daten (von deinem POST)


Nicht nur, dass dir eine HTTP-Komponente vieles abnimmt (Header parsen/lesen und beim Senden auch generieren)
auch für HTTP/2 und HTTP/3, also z.B. HTTPS oder zukünftig QUIC müsstest du dann nichts selber bauen, weil sowas dann ja von Anderen eingebaut würde.
PS: Mit HTTP/3 überlegt man sich von TCP auf UDP umzustellen. (ja, die ersten Webseiten und Browser können es schon ... testweise)
https://www.stackscale.com/blog/http3/


Die HTTP-Komponente gibt dir einmal eine Header-Liste und auch die entsprechenden Streams vom Content (Input) und Response (zum Senden).
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
joehd

Registriert seit: 8. Okt 2008
Ort: Heidelberg
107 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#7

AW: Ich habe einen TCPServer als HTTP server und möchte daten aus einem POST JSON Da

  Alt 12. Dez 2022, 16:35
Danke für die Hinweise ich sollte es dann sicher noch umstellen aber jetzt brauche ich eine schnelle Lösung für das Problem. Ich dachte die TMS Webcore kann FTP oder einfaches SMTP um die daten aus dem Webserver zu versenden aber nein. Ich muss HTTP Post machen und da habe ich nicht mit gerechnet. Und ich habe mich mit REST und HTTP Zeugs und so noch nicht wirklich beschäftigt.

Zum Auslesen des Header ich denke auch das ich alles auslese aber da sind keine Daten, die müssten dann ja im TMEMO stehen
Aber leider finde ich in dem Header die Daten nicht.
Aber eigentlich lese ich doch alles aus.

Kann es sein das die Sende Komponente noch was benötigt?
Die Komponente ist die WebhttpRequest von TMS Web Core

Kann es sein das ich da die schleife zu früh beende du sagtest es kommt eine Leerzeile ?
Delphi-Quellcode:
********if RequestHeader.Strings[i] = ''*then
**********begin
************Sleep(100);
************Continue;
**********end;
Delphi-Quellcode:
sendstring := 'Data: ||' + PNName.Text +'||'+ pVName.Text + '||'+ pGebdat.Text+'||' +Bemerkung.text + '||'+ freitext.text;

 form1.WebHttpRequest1.URL := 'http://127.0.0.1:8080/Kontakt/index.html';
 form1.WebHttpRequest1.Command := httpPOST;
 form1.WebHttpRequest1.PostData := sendstring;
 form1.WebHttpRequest1.Execute();
joe
immer wenn ich was suche finde ich es hier komisch oder ?
Arbeite mit D3 D5 D2007 DXE Prof

Geändert von joehd (12. Dez 2022 um 16:39 Uhr)
  Mit Zitat antworten Zitat
joehd

Registriert seit: 8. Okt 2008
Ort: Heidelberg
107 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#8

AW: Ich habe einen TCPServer als HTTP server und möchte daten aus einem POST JSON Da

  Alt 12. Dez 2022, 16:53
Ich glaube mein
Delphi-Quellcode:
    RawData := ClientSocket.Receiveln; // Liest nur bis zum Zeilenede aus ggf nicht alles
    Rawdata := Clientsocket.ReceiveFrom() // das gibt es noch aber da ist mir nicht klar wie ich die Werte alle bekomme

  function TIpSocket.ReceiveFrom(var buf; bufsize: Integer; ToAddr: TSockAddr; var len: Integer; flags: Integer): Integer;

buf ist klar (String/char Buffer ) aber Bufsize müsste ich doch vom Server bekommen ? toaddr ist das meine Lokale ? .....
joe
immer wenn ich was suche finde ich es hier komisch oder ?
Arbeite mit D3 D5 D2007 DXE Prof
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Ich habe einen TCPServer als HTTP server und möchte daten aus einem POST JSON Da

  Alt 12. Dez 2022, 16:55
Kann es sein das ich da die schleife zu früh beende du sagtest es kommt eine Leerzeile ?
Ja und nein.

Du brichst vorher schon ab, da wo der Header ended.

Zitat:
while RawData <> 'do
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
joehd

Registriert seit: 8. Okt 2008
Ort: Heidelberg
107 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#10

AW: Ich habe einen TCPServer als HTTP server und möchte daten aus einem POST JSON Da

  Alt 12. Dez 2022, 17:09
Kann es sein das ich da die schleife zu früh beende du sagtest es kommt eine Leerzeile ?
Ja und nein.

Du brichst vorher schon ab, da wo der Header ended.

Zitat:
while RawData <> 'do
while Rawdata <> eof() ? ich brauche ja eine Ende markierung.
Stimmt aber ich hatte es nur weiter unten versucht weiter auszulesen das geht aber nicht da ich da ja schon abbreche

Die Größe der Empfangenen Bytes kann ich ermitteln
Statusbar1.SimpleText := inttostr(Clientsocket.BytesReceived); // = 490 Bytes
diese könnte ich dann ja auslesen oder ?
joe
immer wenn ich was suche finde ich es hier komisch oder ?
Arbeite mit D3 D5 D2007 DXE Prof

Geändert von joehd (12. Dez 2022 um 17:18 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 4  1 23     Letzte »    

 

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 01:04 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