Newsgroups : Borland : borland.public.delphi.internet.winsock : 2006 Oct : Re: TIdTrivialFTPServer and multi-homed server?
| Subject: | Re: TIdTrivialFTPServer and multi-homed server? |
| Posted by: | "Remy Lebeau (TeamB)" (no.spam@no.spam.com) |
| Date: | Fri, 13 Oct 2006 01:02:38 |
"Philippe Auphelle" <pauphelle.No.Spam.Please@wanadoo.fr> wrote in message
news:452f41ad@newsgroups.borland.com...
> And, by the way, I have *also* tried the form you indicated in an even
> earlier message, where instead of using a "with" pointer I explicitly
> declared a TString pointer and worked from that one, but it didn't
> change a thing to the misbehavior of the application:
I never said that it would change anything regarding the issue at hand.
> In the OnReadFile event, when GrantAccess returns False, the
> server doesn't answer anything instead of returning a "file not found"
> error message to the TFTP client.
You never said anything about that earlier.
When GrantAccess is set to False, an EIdTFTPAccessViolation exception is
thrown. Incidently, if you get rid of the FileExist() call in your event
handler and just open the TFileStream using the FileName as-is, then an
EFOpenError exception will be thrown if it fails, which TIdTrivialFTPServer
will convert into an EIdTFTPFileNotFound exception internally. Either way,
if any exception is thrown as a result of a file not being accessible, then
TIdTrivialFTPServer DOES send a reply back to the client. You can see this
for yourself:
procedure TIdTrivialFTPServer.DoUDPRead(AData: TStream; ABinding:
TIdSocketHandle);
//...
begin
//...
try
//...
if wOp = TFTP_RRQ then
DoReadFile(FileName, Mode, PeerInfo, RequestedBlkSize)
//...
except
on E: EIdTFTPException do
SendError(Self, ABinding.PeerIP, ABinding.PeerPort, E); //
<-- here
on E: Exception do
begin
SendError(Self, ABinding.PeerIP, ABinding.PeerPort, E); //
<-- here
raise;
end;
end;
end;
procedure TIdTrivialFTPServer.DoReadFile(FileName: String; const Mode:
TIdTFTPMode; const PeerInfo: TPeerInfo; RequestedBlockSize: Integer = 0);
//...
begin
CanRead := True;
//...
try
if Assigned(FOnReadFile) then
FOnReadFile(Self, FileName, PeerInfo, CanRead, SourceStream,
FreeOnComplete);
if CanRead then
begin
//...
end
else
raise EIdTFTPAccessViolation.CreateFmt(RSTFTPAccessDenied,
[FileName]); // <-- here
except
on E: EFOpenError do
raise EIdTFTPFileNotFound.Create(E.Message);
end;
end;
procedure SendError(UDPBase: TIdUDPBase; APeerIP: string; const APort:
Integer; const ErrNumber: Word; ErrorString: string);
begin
UDPBase.Send(APeerIP, APort, WordToStr(GStack.WSHToNs(TFTP_ERROR)) +
WordToStr(ErrNumber) + ErrorString + #0); // <-- here
end;
procedure SendError(UDPBase: TIdUDPBase; APeerIP: string; const APort:
Integer; E: Exception);
var
ErrNumber: Word;
begin
ErrNumber := ErrUndefined;
if E is EIdTFTPFileNotFound then ErrNumber := ErrFileNotFound;
if E is EIdTFTPAccessViolation then ErrNumber := ErrAccessViolation;
if E is EIdTFTPAllocationExceeded then ErrNumber :=
ErrAllocationExceeded;
if E is EIdTFTPIllegalOperation then ErrNumber :=
ErrIllegalOperation;
if E is EIdTFTPUnknownTransferID then ErrNumber :=
ErrUnknownTransferID;
if E is EIdTFTPFileAlreadyExists then ErrNumber :=
ErrFileAlreadyExists;
if E is EIdTFTPNoSuchUser then ErrNumber := ErrNoSuchUser;
if E is EIdTFTPOptionNegotiationFailed then ErrNumber :=
ErrOptionNegotiationFailed;
SendError(UDPBase, APeerIP, APort, ErrNumber, E.Message);
end;
> I so far traced the code through the exception handlers to the point
> where it is supposed to send of a "File not found" message as a reply,
> but haven't yet got to the point where I could see what prevents the
> send from occurring.
The only thing that can be preventing it is a socket error, or a
firewall/router blocking the packet before it reaches the client.
Gambit