0

I'm uploading a file ftp and keep getting a "ssl.SSLEOFError: EOF occurred in violation of protocol (_ssl.c:2756)" error.

    class MyFTP_TLS(ftplib.FTP_TLS):
    """Explicit FTPS, with shared TLS session"""
    def ntransfercmd(self, cmd, rest=None):
        conn, size = ftplib.FTP.ntransfercmd(self, cmd, rest)
        if self._prot_p:
            session = self.sock.session
            if isinstance(self.sock, ssl.SSLSocket):
                    session = self.sock.session
            conn = self.context.wrap_socket(conn,
                                            server_hostname=self.host,
                                            session=session)  # this is the fix
        return conn, size
tp = MyFTP_TLS()
ftp.ssl_version = ssl.PROTOCOL_TLSv1_2
ftp.connect(server, 21)
ftp.set_pasv(True)
ftp.auth()
ftp.prot_p()
ftp.login(user, passwd)
print("Success connection")
ftp.set_debuglevel(2)
ftp.encoding = "utf-8"
#ftp.getwelcome()
with open(dest_filename,"rb") as file:
    try:
        ftp.storbinary(f"STOR {dest_filename}", file)
    except:
        ftp.quit()
        os.remove(dest_filename)
ftp.quit()
os.remove(dest_filename)

Why is this throwing an error? Ideas?

  • So, I fixed the problem. The issue was that it wasn't keeping the connection alive. Seems to be a bug? If you extend the class, it works. – Eric Dannewitz May 15 '22 at 02:15
  • `class MyFTP_TLS(ftplib.FTP_TLS): #Explicit FTPS, with shared TLS session def ntransfercmd(self, cmd, rest=None): conn, size = ftplib.FTP.ntransfercmd(self, cmd, rest) if self._prot_p: conn = self.context.wrap_socket(conn, server_hostname=self.host, session=self.sock.session) # reuses TLS session conn.__class__ = ReusedSslSocket # we should not close reused ssl socket when file transfers finish return conn, size` – Eric Dannewitz May 16 '22 at 15:08

1 Answers1

-1

This is the code I ended up using. It extends the ftp python class. Basically, do a ftp = MyFTP_TLS() and then do all the calls you want, like ftp.login(user,passwd) etc like normal.

`class MyFTP_TLS(ftplib.FTP_TLS):
#Explicit FTPS, with shared TLS session
def ntransfercmd(self, cmd, rest=None):
    conn, size = ftplib.FTP.ntransfercmd(self, cmd, rest)
    if self._prot_p:
        conn = self.context.wrap_socket(conn,
                                        server_hostname=self.host,
                                        session=self.sock.session)  # reuses TLS session            
        conn.__class__ = ReusedSslSocket  # we should not close reused ssl socket when file transfers finish
    return conn, size`
  • So basically, this is the solution: https://stackoverflow.com/q/46633536/850848 + I saw that you did use its code from the beginning, but I didn't check it in details, so I didn't notice that you didn't copy over the `ReusedSslSocket` code. Why did you omit that, if you new the code? – Martin Prikryl May 16 '22 at 17:13
  • Yes, you are right. I forgot that part. 'class ReusedSslSocket(SSLSocket): def unwrap(self): pass' – Eric Dannewitz May 17 '22 at 20:38