tIdHttpServer - EidConnClosed before sending a reply to POST
I am having trouble implementing a HTTP server with indy 10 in delphi 2007.
I have set up a simple event handler for the CommandGet event.
When replying to data sent using the GET method I can parse the params and send XML data back with no problems. (see code below)
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);
When I try to reply to the data that is sent using a POST the response is never sent by indy, instead a EidConnClosedGracefully is raised by TIdIOHandler.WriteDirect form the CheckForDisconnect(True, True) line. here is how i'm handling the incoming POST data
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);
开发者_JAVA百科
I have used wireshark to see what is happening and it looks like indy is sending an ACK back before the response is sent and causing the client to disconnect.
to test this I set-up Apache with PHP and wrote a PHP script to do the same job and everything works ok, The difference is the POST data is replied to with the response content not an ACK.
any suggestions on how to resolve this so I respond to the POST data as well as GET.
I'm stuck with this now, as you can see from this wireshark trace (click link for image) i have increased the timeout to 20 seconds. and its still not working. I'm going to do some more investigations. and see what I can find out. Its looking like Indy thinks the disconnect has occurred before it has
Click here for image
Looks like the http is being sent as
Transfer-Encoding: chunked
Therefore there is no content-length. but the version of Indy I am using doesn't support this mode.
ACKs are not sent by Indy itself, but by the underlying socket instead, and even then only in reply to packets received from the other party. EIdConnClosedGracefully means that the client is intentionally disconnecting the socket on its end before your server can sent its reply data. The fact that an ACK is present helps prove that (the socket is likely ACK'ing the client's FIN packet during disconnection).
精彩评论