IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

[Python 3.7] Envoyer un fichier sur un FTP SSL [Python 3.X]


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 19
    Par défaut [Python 3.7] Envoyer un fichier sur un FTP SSL
    Bonjour à tous,

    Je me permets de solliciter votre aide car je suis actuellement bloqué sur un problème de transfert d'un fichier local sur un FTP en SSL.

    Je me suis inspiré de la FAQ du forum à l'adresse suivante : https://python.developpez.com/faq/?page=FTP#FTPUpload

    J'ai un fichier "toto.txt" dans le répertoire "/tmp" en local.
    Je souhaite envoyer ce fichier dans un répertoire "/IN" en FTPES (FTP Explicite SSL).

    J'ai commencé par lister le contenu du FTPES :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    def connect():
        ftp = FTP_TLS('ftps.monsite.fr')
        ftp.debugging = 2
        ftp.login(username, password)    
        return ftp
     
    ftp = connect()
    ftp.prot_p()
    ftp.retrlines('LIST')
    Je récupère bien les données dans mon terminal


    *cmd* 'AUTH TLS'
    *put* 'AUTH TLS\r\n'
    *get* '234 AUTH command ok. Expecting TLS Negotiation.\n'
    *resp* '234 AUTH command ok. Expecting TLS Negotiation.'
    *cmd* 'USER username'
    *put* 'USER username\r\n'
    *get* '331 Password required\n'
    *resp* '331 Password required'
    *cmd* 'PASS *********'
    *put* 'PASS *********\r\n'
    *get* '230 User logged in.\n'
    *resp* '230 User logged in.'
    *cmd* 'PBSZ 0'
    *put* 'PBSZ 0\r\n'
    *get* '200 PBSZ command successful.\n'
    *resp* '200 PBSZ command successful.'
    *cmd* 'PROT P'
    *put* 'PROT P\r\n'
    *get* '200 PROT command successful.\n'
    *resp* '200 PROT command successful.'
    *cmd* 'TYPE A'
    *put* 'TYPE A\r\n'
    *get* '200 Type set to A.\n'
    *resp* '200 Type set to A.'
    *cmd* 'PASV'
    *put* 'PASV\r\n'
    *get* '227 Entering Passive Mode (217,13,61,50,196,176).\n'
    *resp* '227 Entering Passive Mode (217,13,61,50,196,176).'
    *cmd* 'LIST'
    *put* 'LIST\r\n'
    *get* '125 Data connection already open; Transfer starting.\n'
    *resp* '125 Data connection already open; Transfer starting.'
    08-22-20 01:55PM <DIR> IN
    *get* '226 Transfer complete.\n'
    *resp* '226 Transfer complete.'


    Maintenant je souhaite envoyer mon fichier '/tmp/toto.txt' qui fait une taille de 95 Ko au serveur FTPES dans le répertoire '/IN/toto.txt'
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    def connect():
        ftp = FTP_TLS('ftps.monsite.fr')
        ftp.debugging = 2
        ftp.login(username, password)    
        return ftp
     
    ftp = connect()
    ftp.prot_p()
    ftp.storbinary('STOR /IN/toto.txt', open('/tmp/toto.txt', 'rb'))
    ftp.quit()
    ftp.close()
    Voici les informations récupérées dans mon terminal après quelques minutes

    *cmd* 'AUTH TLS'
    *put* 'AUTH TLS\r\n'
    *get* '234 AUTH command ok. Expecting TLS Negotiation.\n'
    *resp* '234 AUTH command ok. Expecting TLS Negotiation.'
    *cmd* 'USER username'
    *put* 'USER username\r\n'
    *get* '331 Password required\n'
    *resp* '331 Password required'
    *cmd* 'PASS *********'
    *put* 'PASS *********\r\n'
    *get* '230 User logged in.\n'
    *resp* '230 User logged in.'
    *cmd* 'PBSZ 0'
    *put* 'PBSZ 0\r\n'
    *get* '200 PBSZ command successful.\n'
    *resp* '200 PBSZ command successful.'
    *cmd* 'PROT P'
    *put* 'PROT P\r\n'
    *get* '200 PROT command successful.\n'
    *resp* '200 PROT command successful.'
    *cmd* 'TYPE I'
    *put* 'TYPE I\r\n'
    *get* '200 Type set to I.\n'
    *resp* '200 Type set to I.'
    *cmd* 'PASV'
    *put* 'PASV\r\n'
    *get* '227 Entering Passive Mode (217,13,61,50,196,52).\n'
    *resp* '227 Entering Passive Mode (217,13,61,50,196,52).'
    *cmd* 'STOR /IN/toto.txt'
    *put* 'STOR /IN/toto.txt\r\n'
    *get* '125 Data connection already open; Transfer starting.\n'
    *resp* '125 Data connection already open; Transfer starting.'

    Traceback (most recent call last):
    File "main.py", line 46, in <module>
    ftp.storbinary('STOR /IN/toto.txt', open('/tmp/toto.txt', 'rb'))
    File "/usr/lib/python3.7/ftplib.py", line 514, in storbinary
    conn.unwrap()
    File "/usr/lib/python3.7/ssl.py", line 1094, in unwrap
    s = self._sslobj.shutdown()
    ConnectionResetError: [Errno 104] Connection reset by peer



    Je constate que lors de l'exécution du script, je visualise sous Filezilla la présence du fichier dans le répertoire '/IN' avec une taille de 0 octet.
    Lorsque j'ai le message d'erreur dans mon terminal, le fichier vide toto.txt a disparu du serveur FTPES

    J'ai fais un test en transférant le fichier manuellement avec Filezilla.
    Je n'ai eu aucun problème.
    Le transfert a bien aboutit.

    Est ce que vous pourriez me donner des conseils pour me permettre d'avancer sur la résolution du problème.

    Merci par avance.

  2. #2
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 738
    Par défaut
    Salut,

    Citation Envoyé par bibi_obs Voir le message
    Est ce que vous pourriez me donner des conseils pour me permettre d'avancer sur la résolution du problème.
    A priori, c'est le serveur FTP qui ferme la connexion, et vous devriez avoir une indication du pourquoi dans les logs du serveur.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 19
    Par défaut
    Bonsoir,

    Effectivement le serveur ferme la connexion au bout de quelques minutes par sécurité de ce que m'a dit cette semaine le responsable du serveur.
    Le transfert de données semble être bloquer pour un transfert d'un fichier avec si peu volumineux.
    Lorsque je le compare à un transfert manuel avec Filezilla c'est quasiment instantané pour le même fichier.

    Mais effectivement, je vais demander les logs de leur côté dès lundi pour essayer de déterminer la cause du problème.

    Merci pour le conseil.

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 19
    Par défaut
    Bonjour

    Le problème est résolu.
    Il y a une incompatibilité entre l'utilisation de la bibliothèque FTPLIB et un FTPS monté sur un IIS Microsoft. Avec le même programme Python, je n'ai rencontré aucun soucis avec un serveur FTPS monté sur une machine UNIX.
    Le problème se situe plus précisément dans la méthode "storbinary" pour l'upload de fichier.
    Il y a un KB dans le site de TroubleShooting de Microsoft qui en fait référence : https://docs.microsoft.com/en-us/tro...ges-in-ftp-7-5

    FTP 7.5 returns a 125 or 150 response when an FTP client sends a command needing the data connection in passive mode
    In earlier versions of IIS, the FTP service returns a 125 Data connection already open; transfer starting response for APPE, STOU, and STOR commands sent by FTP clients when the client and server are communicating over a passive mode connection. Additionally, FTP returns a 150 File status okay; about to open data connection. response for the APPE, STOU, and STOR commands over active mode connections.
    In FTP 7.5 and later versions, the response message does not depend on whether the request for the data connection is over passive mode or active mode. Instead, if the data connection is already established FTP 7.5 responds with 125 Data connection already open; transfer starting. If the data connection is not already established, FTP responds with 150 File status okay; about to open data connection.


    Dans la log côté client avec le code Python, le blocage se fait au code retour 125.

    *get* '125 Data connection already open; Transfer starting.\n'
    *resp* '125 Data connection already open; Transfer starting.'


    De ce que j'ai compris, le problème vient de la communication lors de l'ouverture du Socket et la réponse du serveur IIS.

    Pour pallier au problème, j'ai "Surcharger" la librairie ftplib dans mon code.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    class iisFTP_TLS(ftplib.FTP_TLS):
        ssl_version=ssl.PROTOCOL_TLS
        def storbinary(self, cmd, fp, blocksize=8192, callback=None, rest=None):
            self.voidcmd('TYPE I')
            with self.transfercmd(cmd, rest) as conn:
                while 1:
                    buf = fp.read(blocksize)
                    if not buf:
                        break
                    conn.sendall(buf)
                    if callback:
                        callback(buf)
                ## shutdown ssl layer
                #if _SSLSocket is not None and isinstance(conn, _SSLSocket):
                #   conn.unwrap()
            return self.voidresp()
    Ci-dessous les sites qui m'ont permis d'identifier et de résoudre mon problème
    https://www.sami-lehtinen.net/blog/p...tls-lockup-fix
    https://www.kodfor.com/Automating-fi...S-using-Python

    Je suis surpris que ce problème soit encore d'actualité quand je vois sur les sites que celui-ci a été identifié il y a déjà plusieurs années.

    En espérant que cela puisse aider certains d'entre vous.

  5. #5
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 738
    Par défaut
    Salut,

    Citation Envoyé par bibi_obs Voir le message
    Je suis surpris que ce problème soit encore d'actualité quand je vois sur les sites que celui-ci a été identifié il y a déjà plusieurs années.
    Ce qui maintiennent la bibliothèque FTPLIB de Python ne vont pas farfouiller sur le Web pour trouver les éventuels bugs, ils attendent qu'on ouvre un ticket dans la buglist qui va bien (ou l'ouvrent eux même s'ils ont suffisamment d'informations pour le faire).

    Allez y faire un tour et ouvrez un ticket sur ce sujet...
    Dans quelques temps çà vous dira si le problème a déjà été rapporté.
    note: vous pouvez aussi farfouiller dans le tas de tickets "ouverts" pour voir si le problème a été rapporté mais pas facile de s'y retrouver (un même bug peut être rencontré via des chemins différents).

    Au ticket "ouvert" sera assigné une priorité en fonction de la gravité et de l'impact (impossible de... à tous les serveurs IIS, c'est pas top). Puis le problème sera analysé après avoir éventuellement été reproduit et une idée de correction sera revue par les développeurs.

    Premier problème la bibliothèque FTPLIB, c'est Python, la bibliothèque SSL qui est utilisée dans ce cas est maintenue par un groupe externe et le soucis est apparemment constaté sur les serveurs IIS (microsoft). Ce qui fait des tiraillements pour savoir qui a la responsabilité de corriger quoi.

    Donc oui çà peut prendre du temps (pour autant que le problème ait été rapporté!).

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 19
    Par défaut
    Bonjour Wiztricks,

    Effectivement c'est d'avantage un problème SSL que Python.
    J'avais vu un bug ouvert chez Python sur ce sujet que je n'avais pas posté. J'ai regardé tellement de site pour tenter de résoudre mon problème.

    https://bugs.python.org/issue10808

    Dans le dernier commentaire qui date de 2016, il est indiqué :
    "I tend to agree with Antoine that unfortunately there is not much Python can do without help from Open SSL"

    Le bug est d'ailleurs en statut résolu.
    Comme tu l'as dit toi même c'est un problème externe à la communauté Python, mais d'avantage un problème sur la bibliothèque SSL.

    Néanmoins, j'ai envoyé un mail à notre partenaire en charge du serveur IIS en leur communiquant l'url du troubleshooting de Microsoft.
    Je leur ai demandé d'ouvrir un ticket chez Microsoft.

    Je te remercie pour tes précieux conseils !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Prendre fichiers sur un ftp en envoyer vers destination
    Par princesse95 dans le forum Shell et commandes GNU
    Réponses: 32
    Dernier message: 15/12/2011, 14h05
  2. Envoyer un fichier sur un serveur FTP
    Par zenico64 dans le forum Général VBA
    Réponses: 3
    Dernier message: 26/11/2010, 09h27
  3. Envoyer un fichier sur un serveur ftp
    Par Pascmar dans le forum Réseau/Web
    Réponses: 2
    Dernier message: 15/08/2007, 23h16
  4. envoyer un fichier sur ftp
    Par alex01pernot dans le forum Web & réseau
    Réponses: 3
    Dernier message: 26/03/2006, 18h22
  5. Envoyer un fichier sur un serveur FTP par proxy
    Par Tierisa dans le forum Access
    Réponses: 4
    Dernier message: 13/12/2005, 16h39

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo