Re: FTP - Get Errors

Giganews Newsgroups
Subject: Re: FTP - Get Errors
Posted by:  Remy Lebeau (Indy Team) (no.spam@no.spam.com)
Date: Thu, 8 Feb 2007

"DaveR" <dav…@safeauto.com> wrote in message
news:CAC0EDD13E1AE340dav…@safeauto.com...

> Currently I suspect there is a problem in Indy 10.1.5 GET procedure?

Have you tried upgrading to 10.1.6 yet?

> On GET I recieve "Destination File Already Exists" Error when I
> am certain it does not.

Yes, it does exist.  That is the only way that error could occur.
Look at the code for Get():

    procedure TIdFTP.Get(const ASourceFile, ADestFile: string; const
ACanOverwrite: Boolean = False; AResume: Boolean = False);
    var
        LDestStream: TIdStream;
    begin
        AResume := AResume and CanResume;
        if ACanOverwrite and (not AResume) then begin
            Sys.DeleteFile(ADestFile);
            LDestStream := TIdFileCreateStream.Create(ADestFile);
        end
        else if (not ACanOverwrite) and AResume then begin
            LDestStream := TIdAppendFileStream.Create(ADestFile);
        end
        else if not Sys.FileExists(ADestFile) then begin // <-- HERE
            LDestStream := TIdFileCreateStream.Create(ADestFile);
        end
        else begin
            raise
EIdFTPFileAlreadyExists.Create(RSDestinationFileAlreadyExists); // <--
HERE
        end;
        //...
    end;

If the file did not already exist, then Sys.FileExists() would return
False, and Get() would create a TIdFileCreateStream object.  The only
way for that exception to occur is if Sys.FileExists() is returning
True instead of False.

> My current problem is a read timeout error on GET.  The server I am
> connected to requires the port to be 20021 passive mode.  As I step
> through the code I am seeing LPort with a different value, the
> IOHandler port is debugging with 20021.

For a Passive transfer, Get() always uses whichever Port the server
actually reports in reply to the PASV and EPSV commands.  The only way
that would not be the case is if either 1) the server's reply is in a
non-standard format that TIdFTP cannot parse, or 2) you have an
OnDataChannelCreate event handler that is overriding the Port value.
There is no other way that LPort would not be set to the Port value
that the server actually reports.

> My understanding with passive is that everything occurs on one
channel?

That is not true.  All data exchanges beyond simple command replies
(directory listings, stats, and file transfers), whether Active or
Passive, are always performed on their own separate socket
connections.  That is how the FTP protocol has always worked (and why
FTP is not a router/firewall-friendly protocol).

> It appears a LPASSIVECL is being cretaed with a different port?

It is supposed to be.  The whole point of a Passive transfer is that
the server opens up a new listening port on its side that the client
application can connect to in order to exchange the requested data.
In an Active transfer, the client opens its own listeing port that the
server connects to instead.

> My code is as follows:

Your code is wrong.

> Prior to this procedure I have made a secure SSL conneciton and PUT
> a file on the server, I can also LIST the directory, this works
consistently
> well. I just cannot GET a file.

There is no difference between a PUT, LIST, and GET.  They all
exchange data with the server in exactly the same manner.  You can use
a packet sniffer, such as Ethereal, to see that in action for
yourself.  If you can perform a LIST without problem, then there is no
reason that GET would not work as well.

> ReadTimeOut = 0

Setting ReadTimeout to 0 is the same as setting it to
IdTimeoutInfinite.  In any case, ReadTimeout has no effect on
transfers anyway.  You would need to use the TransferTimeout property
instead.

> DataPort - 20021
> DataPortMax - 20021
> DataPortMin - 20021

Those properties only apply to Active transfers.  They have no effect
on Passive transfers.

> idSSLIOHandlerSkt
> Port - 20021
> BoundPort - 20021
> DefaultPort - 20021

Those also have no effect on data transfers.  They only effect which
Port is bound to locally for the main command/reply socket, not for
any of the transfer sockets.  Those should all be set to 0 anyway to
let the OS pick random ports to avoid conflicts.

Gambit

Replies

In response to

FTP - Get Errors posted by DaveR on Thu, 8 Feb 2007