tIdHttpServer - EidConnClosed antes de enviar una respuesta a POST
-
26-09-2019 - |
Pregunta
Tengo problemas para la implementación de un servidor HTTP con indy 10 en Delphi 2007.
He creado un simple controlador de eventos para el evento CommandGet.
Al responder a los datos enviados mediante el método GET puedo analizar los parametros y posterior envío de datos XML sin problemas. (Ver código de abajo)
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);
Cuando intento para responder a los datos que se envían mediante un POST la respuesta no es enviado por Indy, en lugar de un EidConnClosedGracefully se eleva por TIdIOHandler.WriteDirect formar la línea CheckForDisconnect (True, True). Así es como yo estoy manejando los datos de entrada de correos
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);
he utilizado Wireshark para ver lo que está pasando y parece que Indy es el envío de un ACK de vuelta antes de enviar la respuesta y haciendo que el cliente para desconectar.
Para probar esto configuración de Apache con PHP y escribió un script PHP para hacer el mismo trabajo y todo funciona bien, la diferencia es que los datos POST se respondió a con el contenido de la respuesta no un ACK.
alguna sugerencia sobre cómo resolver esto, así que responden a los datos POST, así como GET.
tengo que cargar con esto ahora, como se puede ver en esta traza Wireshark (haga clic en enlace de imagen) que he aumentado el tiempo de espera a 20 segundos. y su aún no funciona. Voy a hacer algunas investigaciones más. y ver qué puedo averiguar. Su aspecto de Indy piensa que se ha producido la desconexión antes de que tenga
Solución
Parece que el HTTP está siendo enviado como
Transfer-Encoding: chunked
Por lo tanto no hay contenido de longitud. pero la versión de Indy estoy usando no soporta este modo.
Otros consejos
ACK no se envían por sí mismo Indy, sino por la toma subyacente lugar, e incluso entonces sólo en respuesta a los paquetes recibidos de la otra parte. medios EIdConnClosedGracefully que el cliente está desconectando la toma intencionadamente en su extremo antes de que su servidor puede enviar sus datos de respuesta. El hecho de que un ACK está presente ayuda a demostrar que (el enchufe es probable que ACK'ing paquete FIN del cliente durante la desconexión).