jlaffaye / ftp

FTP client package for Go
ISC License
1.29k stars 359 forks source link

Using Rename() returns a successful message on fail #220

Closed fracartdev closed 3 years ago

fracartdev commented 3 years ago

Describe the bug I'm probably using the Rename method wrong, as it's not renaming anything. Anyway, the error returned is "226 File successfully transferred", which doesn't really explain what is wrong and it almost sounds as the method worked correctly

To Reproduce

err = c.Rename("./MOCK_DATA.csv", "./PROCESSED.csv")
if err != nil {
    log.Fatal(err)
}

Expected behavior An error that tells me what's wrong.

FTP server

Additional context I'm kinda new to Go so bear with me with the syntax used

fracartdev commented 3 years ago

After debugging I noticed that this behaviour happens when you call the Rename after you've called a Retr (I was cyling through a List of entries and parsing the files), I know nothing about FTP but probably these two just don't go together.

Thanks anyway for the library and hopefully this issue will help someone else like me.

sparrjen commented 12 months ago

I ran into the same issue and got the explanations that because FTP servers often are stateful, certain operations like Retr (retrieve file) and Rename might conflict if you don't handle the FTP server's state proper.

If someone else has this problem this it what solved it for me.

I closed the Retr reader (the data connection) before attempting to rename the file. The FTP protocol can be sensitive to the order of operations. Make sure you have a Close() statement immediately after reading the file data with io.ReadAll().

Like so

`

r, err := ftpConn.Retr(ftpPath + "/" + ftpFile.Name) if err != nil { //handle error } defer r.Close()

    //Reading data from the ftp server
    data, err := io.ReadAll(r)
    if err != nil {
        //handle error
    }
    r.Close().  //This is what I added to fix it.

    // Creating an S3 client
    svc := s3.NewFromConfig(cfg)

//Uploading files to s3 bucket
    _, err = svc.PutObject(ctx, &s3.PutObjectInput{
        Bucket: &s3Bucket,
        Key:    &s3Key,
        Body:   bytes.NewReader(data),
    })
    if err != nil {
        //handle error
    }

    uploadedFiles = append(uploadedFiles, ftpFile.Name)
}

// Move all uploaded to /Processed in FTP directory by using Rename.
for _, uploadedFile := range uploadedFiles {
    err = ftpConn.Rename(ftpPath+"/"+uploadedFile, ftpProcessedPath+"/"+uploadedFile)
    if err != nil {
        //handle error
    }