Python FXP Client

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Peeps
User
Beiträge: 3
Registriert: Dienstag 13. Mai 2008, 20:32

hallo,

gibts die Möglichkeit Python also FXP Client einzusetzen, so dass zwischen 2 anderen FTP servern Files ausgetauscht werden können?

Wäre super wenn jemand eine Idee diesbezüglich hat. In der FTPlib hab ich leider nix finden können.
Benutzeravatar
Masaru
User
Beiträge: 425
Registriert: Mittwoch 4. August 2004, 22:17

Hallo auch.

Schau Dir mal folgende Libraray an: PyFTPdlib

Diese unterstützt seit derVersion 0.2.0 auch FXP.

>>Masaru<<
Peeps
User
Beiträge: 3
Registriert: Dienstag 13. Mai 2008, 20:32

Hallo,

das ist doch die Server Lib. und nicht die Client-Version oder lieg ich da jetzt verkehrt?!

Also ich nutze Python als Client und möchte FXP zwischen 2 entfernten FTPS damit durchführen.
Benutzeravatar
Masaru
User
Beiträge: 425
Registriert: Mittwoch 4. August 2004, 22:17

Stimmt, hast recht. Das Prinzip wird dort nur nochmal erklärt, was Du mit Python Battry-included FTPLib nachstellen sollen könntest.
Peeps
User
Beiträge: 3
Registriert: Dienstag 13. Mai 2008, 20:32

Masaru hat geschrieben:was Du mit Python Battry-included FTPLib nachstellen sollen könntest.
Das wird mit Sicherheit nichts :)) Ich bin da auch nicht so der freak...
Benutzeravatar
Masaru
User
Beiträge: 425
Registriert: Mittwoch 4. August 2004, 22:17

Hat doch nichts mit Freak-sein-oder-nicht zu tun ;):

Code: Alles auswählen

import ftplib
import re
import StringIO

## Connect to target (ftp1) and source (ftp2) FTP server test instances.
ftp1 = ftplib.FTP()
ftp1.connect('localhost', 21)
ftp1.login('test', 'test')

ftp2 = ftplib.FTP()
ftp2.connect('localhost', 22)
ftp2.login('test', 'test')

try:
    ## Preparing a test file which will be transferred from source FTP (2) to
    ## the target FTP (1) in next step 'Site-to-site Transfer'.
    test_file = StringIO.StringIO()
    test_file.write("This is content for a simple test file.\n")
    ftp2.storlines('STOR test.txt', test_file)

    ## Site-to-site Transfer.
    # Set transfer modes to BINARY on both connections.
    ftp1.sendcmd('TYPE I')
    ftp2.sendcmd('TYPE I')

    # Open passive transfer tunnel on first FTP and connect with second one.
    tunnel_address = None
    resp = ftp1.sendcmd('PASV')
    match = re.match('.*(\()(?P<tunnel>[0-9,]*)(\)).*', resp)
    if match:
        tunnel_address = match.groupdict().get('tunnel', None)
    assert tunnel_address
    ftp2.sendcmd('PORT %s' % tunnel_address)

    # Add an new empty file container on target FTP (1), which will be filled
    # with data from file of the source FTP (2).
    ftp1.sendcmd('STOR test.txt')
    ftp2.sendcmd('RETR test.txt')
finally:
    ftp1.close()
    ftp2.close()
Anhübschen musst Du es schon selber ;).

Habe das ganze mit zwei lokalen (PyFTPdlib) FTP-Server Instanzen (einmal Port 21 und dann Port 22) getestet, welche beiden den "test"-User mitbekommen hatten.
Dabei bin ich zuerst auch in die Falle getappt und hatte vergessen, dem FTP-Server den FXP-Support freizuschalten ... "mit" klappte es auf jeden Fall deutlich besser :).

Gelernt habe ich dabei, dass ein Funktionieren von FXP nicht nur vom Client, sondern auch vom Server abhängt. Unterstützt nämlich dieser die Verbindung zu anderen FTP-Adressen nicht, so kann man das ganze knicken. Eine PyFTPdlib FTP-Server Instanz benötigt z.B. folgende FTPHandler-Einstellung:

Code: Alles auswählen

...
ftp_handler = ftpserver.FTPHandler
ftp_handler.permit_foreign_addresses = True # <- default is False
...
Fazit: FXP ist weder Hexerei (kompliziert), noch braucht man eine separate Library dafür. Es reichen völlig die bei Python mitgelieferten Boardmittel und die FTP-Kommandos und Vorgehensweise aus (was ja hier zu finden war: http://www.proftpd.org/docs/howto/FXP.html).

Gruß,
>>Masasru<<
Bernd999
User
Beiträge: 1
Registriert: Samstag 2. Juni 2012, 21:07

Könnte der Site - to - Site Transfer über die Function ftpcp() gelöst werden oder zielt diese nur auf einen Transfer von Files von einem localen Server auf einen entfernten ab?

ftpcp (source, sourcename, target, targetname, type)

MFG
BlackJack

@Bernd999: Der DocString sagt: zwischen FTP-Servern.

Code: Alles auswählen

In [163]: ftplib.ftpcp?
Type:           function
Base Class:     <type 'function'>
String Form:    <function ftpcp at 0x9678454>
Namespace:      Interactive
File:           /usr/lib/python2.6/ftplib.py
Definition:     ftplib.ftpcp(source, sourcename, target, targetname='', type='I')                                                                               
Docstring:
    Copy file from one FTP-instance to another.
Und im Quelltext kann man das Vorgehen von Masaru's Beispiel wiedererkennen:

Code: Alles auswählen

def ftpcp(source, sourcename, target, targetname = '', type = 'I'):             
    '''Copy file from one FTP-instance to another.'''
    if not targetname: targetname = sourcename
    type = 'TYPE ' + type
    source.voidcmd(type)
    target.voidcmd(type)
    sourcehost, sourceport = parse227(source.sendcmd('PASV'))
    target.sendport(sourcehost, sourceport)
    # RFC 959: the user must "listen" [...] BEFORE sending the
    # transfer request.
    # So: STOR before RETR, because here the target is a "user".
    treply = target.sendcmd('STOR ' + targetname)
    if treply[:3] not in ('125', '150'): raise error_proto  # RFC 959
    sreply = source.sendcmd('RETR ' + sourcename)
    if sreply[:3] not in ('125', '150'): raise error_proto  # RFC 959
    source.voidresp()
    target.voidresp()
Einer der Vorteile von OpenSource — man kann nachschauen was genau passiert. :-)
Antworten