Pergunta

Estou tendo problemas para implementar um servidor HTTP com Indy 10 em Delphi 2007.

Eu configurei um manipulador de eventos simples para o evento CommandGet.

Ao responder aos dados enviados usando o método GET, posso analisar os parâmetros e enviar os dados XML de volta sem problemas. (Veja o código abaixo)

    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 tento responder aos dados enviados usando uma postagem, a resposta nunca é enviada por Indy, em vez disso, um eidconnClotedGracely é criado por TidioHandler.WriteDirect Form the checkfordisconnect (true, true) linha. Aqui está como estou lidando com os dados de postagem de entrada

    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);

Eu usei o Wireshark para ver o que está acontecendo e parece que Indy está enviando um ACK de volta antes que a resposta seja enviada e fazendo com que o cliente se desconecte.

Para testar isso, configurei o Apache com o PHP e escrevi um script PHP para fazer o mesmo trabalho e tudo funciona bem, a diferença é que os dados da postagem são respondidos com o conteúdo da resposta, não um ACK.

Quaisquer sugestões sobre como resolver isso, para que eu responda aos dados da postagem e também a obter.


Estou com isso agora, como você pode ver neste rastreamento do Wireshark (clique em Link para a imagem), aumentei o tempo limite para 20 segundos. E ainda não está funcionando. Vou fazer mais algumas investigações. E veja o que posso descobrir. Parece que Indy acha que a desconexão ocorreu antes de ter

Clique aqui para a imagem

Foi útil?

Solução

Parece que o http está sendo enviado como

Transfer-Encoding: chunked

Portanto, não há comprimento de conteúdo. Mas a versão do Indy que estou usando não suporta esse modo.

Outras dicas

Os ACKs não são enviados pelo próprio Indy, mas pelo soquete subjacente, e mesmo assim apenas em resposta aos pacotes recebidos da outra parte. O eidconnClonesedGraceRly significa que o cliente está desconectando intencionalmente o soquete antes que seu servidor possa enviar seus dados de resposta. O fato de um ACK estar presente ajuda a provar que (o soquete provavelmente está ack'ing o pacote de barbatana do cliente durante a desconexão).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top