2

I was trying to send a file using SFTP python library pysftp to a remote mailbox server. But when I try to put the file I get this Error:

I'm using python 3.7.4

Traceback (most recent call last):
 File "SFTP.py", line 54, in <module>
   srv.put('file.zip','file.zip')
 File "C:\Users\HP\Anaconda3\lib\site-packages\pysftp\__init__.py", line 364, in put
   confirm=confirm)
 File "C:\Users\HP\Anaconda3\lib\site-packages\paramiko\sftp_client.py", line 759, in put
   return self.putfo(fl, remotepath, file_size, callback, confirm)
 File "C:\Users\HP\Anaconda3\lib\site-packages\paramiko\sftp_client.py", line 723, in putfo
   "size mismatch in put!  {} != {}".format(s.st_size, size)
OSError: size mismatch in put!  4628344 != 330596

PS:I tried with another remote server and it works perfectly. This is my code

import pysftp
import os
cnopts = pysftp.CnOpts()
hostkeys = None
host="host.com"
username=username
password=password

if cnopts.hostkeys.lookup(host) == None:
    print("New host - will accept any host key")
    # Backup loaded .ssh/known_hosts file
    hostkeys = cnopts.hostkeys
    # And do not verify host key of the new host
    cnopts.hostkeys = None

with pysftp.Connection(host=host, username=username, password=password, cnopts=cnopts) as sftp:        
    if hostkeys != None:
        print("Connected to new host, caching its hostkey")
        hostkeys.add(host, sftp.remote_server_key.get_name(), sftp.remote_server_key)
        hostkeys.save(pysftp.helpers.known_hosts())


srv = pysftp.Connection(host=host, username=username,password=password)
srv.put('file.zip','file.zip')
Amrouane
  • 143
  • 3
  • 16
  • Perhaps the remote disk id full? – snakecharmerb Apr 12 '20 at 14:04
  • @snakecharmerb how do I make sure if this is really the case. I mean I can't log in with putty due to some security reasons – Amrouane Apr 12 '20 at 14:27
  • Can you upload that file successfully using any (GUI) SFTP client? – Martin Prikryl Apr 13 '20 at 10:13
  • @MartinPrikryl I worked with Winscp and the files have been transferred correctly. Any suggestions ? – Amrouane Apr 17 '20 at 15:22
  • Can you post a log file showing that? (make sure you keep the directory listing after the upload in the log file). – Martin Prikryl Apr 20 '20 at 05:51
  • @MartinPrikryl I found what causes the problem, bu I don't know how to fix it. The problem is due to the fact that when I upload a file via Winscp or with pysftp, it replaces the old file but it adds the size of the new uploaded file to the old one. Example i want to upload 'file1' that has a size of 100KB and there is already an old version of 'file1' in the server that has a size of 150KB, what happens is that the file gets transferred but with anew size of 100+150 = 250KB. – Amrouane Apr 25 '20 at 12:58
  • Either your SFTP server is buggy or it behaves like that by purpose. – Martin Prikryl Apr 25 '20 at 14:14

1 Answers1

4

I found a workaround solution but not recommended, I was able to go through the problem just by commenting the bloc of code where the exception is raised:

 with self.file(remotepath, "wb") as fr:
            fr.set_pipelined(True)
            size = self._transfer_with_callback(
                reader=fl, writer=fr, file_size=file_size, callback=callback
            )
        if confirm:
            s = self.stat(remotepath)
            if s.st_size != size:
                s = SFTPAttributes()
                pass
                # raise IOError(
                #     "size mismatch in put!  {} != {}".format(s.st_size, size)
                # )
        else:
            s = SFTPAttributes()
        return s

the file is site-packages\paramiko\sftp_client.py. but the solution causes other problems with file size. the file transferred in the server gets cumulated whenever I run the put() method so you need to be careful with this.

EDIT:

worked after setting the post-check parameter conform to False. So no need to modify paramiko code.

srv.put('file.zip','file.zip',confirm=False)
Amrouane
  • 143
  • 3
  • 16
  • 1
    So why don't you just set `confirm` parameter to `false`? And you won't have to modify the Paramiko code. – Like here: [Python pysftp.put raises “No such file” exception although file is uploaded](https://stackoverflow.com/q/49718668/850848). – Martin Prikryl Apr 28 '20 at 15:31
  • @MartinPrikryl yes it worked, I didn't know about this parameter before, Thanks – Amrouane Apr 28 '20 at 15:42