使用Indy处理BabyFTP MKD 250响应

时间:2017-09-13 15:12:41

标签: delphi ftp indy

我正在使用BabyFTP作为Delphi 10.1 Berlin应用程序的嵌入式FTP服务器。即使我仍然不确定它是我可以根据我的要求使用的最好的轻量级FTP服务器,它似乎运行得很好......除了一个细节:

在成功的MKD命令上,BabyFTP以250响应,而不是预期的(通过RFC和Indy)257。因此TIdFTP引发了一个EIdReplyRFCError异常,这打破了我的流量尝试做(将blob字段保存到文件中):

s := TBytesStream.Create;
Try
  Field.SaveToStream(s);
  MakeDir(TPath.GetDirectoryName(url));
  Put(s, url);
Finally
  s.Free;
End;

当然,我知道我可以在Make Except块中包装MakeDir行并忽略特定的异常类型。但这似乎有点风险,因为从提出的异常我无法确定我得到250或其他一些真正的错误。

我已经尝试过查看Indy的响应代码是否可以配置,但似乎它们在特定方法中是硬编码的。子类化TIdFTP是不可行的,因为这些方法不是虚拟的。我可以自定义IdFTP.pas单元,但我不想这样做,因为我在一个团队中工作,我不想将补丁发布到标准的Delphi单元。

我可以使用另一台FTP服务器...但我想大多数都有一些不完全标准的功能,比如这个。

有没有人知道其他解决方法?雷米?

2 个答案:

答案 0 :(得分:4)

Ondrej的回答解释了如何解决TIdFTP.MakeDir()中处理250回复的问题。

请注意,TIdFTP.MakeDir()只是TIdTCPConnection.SendCmd()的包装器:

procedure TIdFTP.MakeDir(const ADirName: string);
begin
  SendCmd('MKD ' + ADirName, 257); {do not localize}
end;

SendCmd()public,因此另一种解决方案是直接致电SendCmd()并告诉它250是可接受的回复代码:

s := TBytesStream.Create;
Try
  Field.SaveToStream(s);
  //MakeDir(TPath.GetDirectoryName(url));
  SendCmd('MKD ' + TPath.GetDirectoryName(url), [250, 257]);
  Put(s, url);
Finally
  s.Free;
End;

或者,要接受任何 2xx回复代码,您可以这样做:

s := TBytesStream.Create;
Try
  Field.SaveToStream(s);
  //MakeDir(TPath.GetDirectoryName(url));
  if (SendCmd('MKD ' + TPath.GetDirectoryName(url)) div 100) <> 2 then
    RaiseExceptionForLastCmdResult;
  Put(s, url);
Finally
  s.Free;
End;

答案 1 :(得分:3)

ErrorCode属性等于250时,您可以处理EIdReplyRFCError的特定情况,在任何其他情况下重新提升。

s := TBytesStream.Create;
Try
  Field.SaveToStream(s);
  Try
    MakeDir(TPath.GetDirectoryName(url));
  Except
    on E: EIdReplyRFCError do
      if E.ErrorCode <> 250 then raise;
  end
  Put(s, url);
Finally
  s.Free;
End;