我在delphi 2007中使用indy 10实现HTTP服务器时遇到了麻烦。
我为CommandGet事件设置了一个简单的事件处理程序。
当回复使用GET方法发送的数据时,我可以解析参数并发回XML数据而没有任何问题。 (见下面的代码)
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);
当我尝试回复使用POST发送的数据时,indy从不发送响应,而是由CheckForDisconnect(True,True)行的TIdIOHandler.WriteDirect引发EidConnClosedGracefully。这是我如何处理传入的POST数据
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);
我已经使用wireshark查看发生了什么,看起来indy在发送响应之前发回ACK并导致客户端断开连接。
测试这个我用PHP设置Apache并写了一个PHP脚本来做同样的工作,一切正常,不同的是POST数据被回复,响应内容不是ACK。
有关如何解决此问题的任何建议,以便我回复POST数据以及GET。
我现在坚持这一点,你可以从这个wireshark跟踪(点击图片链接)看到我已经将超时时间增加到20秒。它仍然无法正常工作。我要做更多的调查。看看我能找到什么。它看起来像Indy认为它已经发生了断开连接
答案 0 :(得分:2)
看起来http正在以
的形式发送Transfer-Encoding: chunked
因此没有内容长度。但我使用的Indy版本不支持此模式。
答案 1 :(得分:0)
Indy本身不会发送ACK,而是通过底层套接字发送,甚至只能回复从另一方收到的数据包。 EIdConnClosedGracefully意味着客户端在服务器发送其回复数据之前故意断开其端的套接字。存在ACK的事实有助于证明(套接字可能在断开连接时确认客户端的FIN数据包)。