Domanda

Sto avendo difficoltà implementare un server HTTP con indy 10 in Delphi 2007.

Ho creato un semplice gestore di eventi per l'evento CommandGet.

Quando si risponde ai dati inviati utilizzando il metodo GET posso analizzare i params e sul retro i dati di invio XML senza problemi. (Vedi codice qui sotto)

    Download := ARequestInfo.Params.Values['dld'];
    Config := ARequestInfo.Params.Values['config'];
    Flash := ARequestInfo.Params.Values['flash'];
    Employees := ARequestInfo.Params.Values['employees'];
    Schedule := ARequestInfo.Params.Values['schedules'];
    AppTables := ARequestInfo.Params.Values['apptables'];

    Heartbeat :=  NewHeartbeat;

    Heartbeat.Version.Dld := Download;
    Heartbeat.Version.Config := Config;
    Heartbeat.Version.Flash := Flash;
    Heartbeat.Version.Employee := Employees;
    Heartbeat.Version.Schedule := Schedule;
    Heartbeat.Version.AppTables := AppTables;

    AResponseInfo.ContentType := 'application/xml';
    AResponseInfo.ResponseNo := 200;
    AResponseInfo.ContentText := '<?xml version="1.0" encoding="utf-8"?>' +
      #13+#10 + FormatXMLData(Heartbeat.XML);

Quando provo a rispondere ai dati che vengono inviati tramite un POST la risposta non viene mai inviata da Indy, invece un EidConnClosedGracefully sia aumentata di TIdIOHandler.WriteDirect formano la linea di CheckForDisconnect (true, true). ecco come sto gestire i dati POST in arrivo

    XMLDocument1.xml.Clear;
    XMLDocument1.Active := True;
    XMLDocument1.XML.text := ARequestInfo.FormParams;

    SynMemo1.Lines.Add(ARequestInfo.FormParams);
    SynMemo1.Lines.Add(#13+#10);

    if XMLDocument1.XML.Count > 0 then
    begin
      XMLDocument1.XML.Delete(0);
      XMLDocument1.XML.Delete(0);

      for i := pred(xmldocument1.xml.count) downto 0 do
      begin
        stmp := XMLDocument1.XML.Strings[i];

        if Length(stmp) > 0 then
        begin
          if Copy(stmp,1,1) = '<' then
            break
          else
            XMLDocument1.XML.Delete(i);
        end
        else
          XMLDocument1.XML.Delete(i);

      end;

      XMLDocument1.XML.Text := StringReplace(XMLDocument1.XML.Text,
        '<Punches ', '<Punches xmlns="http://ats/punch" ', [rfReplaceAll]);



    end;

    Punch := GetPunches(XMLDocument1);

    PunchReply := NewOperationStatus;
    PunchReply.Uid := Punch.Uid;
    PunchReply.NodeValue := 'OK';

    stmp := '<?xml version="1.0" encoding="utf-8"?>' +
      #13+#10 + FormatXMLData(PunchReply.XML);
    SynMemo1.Lines.Add(stmp);
    SynMemo1.Lines.Add(#13+#10);

    AResponseInfo.ContentType := 'text/html';
    AResponseInfo.ContentStream := TStringStream.Create(stmp);

Ho usato Wireshark per vedere cosa sta succedendo e sembra che Indy è l'invio di un ACK indietro prima che la risposta viene inviata e causando al cliente di disconnessione.

per testare questo I set-up Apache con PHP e ha scritto uno script PHP per fare lo stesso lavoro e tutto funziona bene, la differenza sono i dati POST è risposto con il contenuto della risposta non un ACK.

qualche suggerimento su come risolvere questo in modo da rispondere ai dati POST e GET.


mi sono bloccato con questo ora, come si può vedere da questa traccia Wireshark (cliccare sul link per un'immagine) Ho aumentato il timeout a 20 secondi. e la sua ancora non funziona. Ho intenzione di fare un po 'di più indagini. e vedere cosa riesco a scoprire. Il suo aspetto di Indy pensa che la disconnessione è verificato prima che abbia

Clicca qui per un'immagine

È stato utile?

Soluzione

Sembra che il http viene inviato come

Transfer-Encoding: chunked

Quindi non v'è alcun content-length. ma la versione di Indy sto usando non supporta questa modalità.

Altri suggerimenti

ACK non sono inviati da Indy sé, ma dal socket sottostante invece, e anche allora solo in risposta ai pacchetti ricevuti dall'altra parte. EIdConnClosedGracefully significa che il client è intenzionalmente di scollegare la presa sulla sua fine prima della lattina server ha inviato i suoi dati di risposta. Il fatto che un ACK è presente aiuta a dimostrare che (il socket è probabile ACK'ing pacchetto FIN del cliente durante la disconnessione).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top