Autor Beitrag
middel86
Hält's aus hier
Beiträge: 4



BeitragVerfasst: Di 07.08.12 16:54 
Hallo,

Ich versuche gerade mit Hilfe der TIdFTP Komponente (Version 10 in Delphi 2010) eine Verbindung über IPv6 zu einem FTP Server zu erstellen, um dann eine Datei zu transferieren. Das connecten scheint auch zu funktionieren, will ich dann aber eine Datei vom Server herunter- oder heraufladen bekomme ich im Passive Mode folgende Exception:

Zitat:
"You are connected using Ipv6. PASV is only for Ipv4. You have to use the EPSV command instead."


Setze ich den Passive Mode auf False erhalte ich eine andere Exception:

Zitat:
„“FE80:0:0:0:xxxx:xxxx:xxxx:xxxx“ is not a valid integer value“


Als FTP-Server verwende ich FileZilla (Version 0.9.41) welcher auf Port 21 hört. Habe es aber auch schon erfolglos mit anderen Ports versucht. Firewalls sind auch nicht aktiv.

Wenn ich das gleiche mit einem bestehenden FTP-Client veruche (z.B. FileZilla oder Total Commander) funktioniert der Datentransfer problemlos, sowohl im aktiv wie im passiv modus für GET und PUT.


Hier mein Code:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
try
  FIdFTP  := TIdFTP.Create(nil);
  FURL    := TIdURI.Create();

  try
    // config FTP
    //------------
    // Set the URI
    // --> Format: Protocol://[username:password@]Host[:Port]/Path/Document
    // --> e.g.: ftp://xxx:xxx@[fe80::xxxx:xxxx:xxxx:xxxx]:21/100kb.dat
    FURL.URI := edURI.Text;

    // connection attempt timeout is 60s
    TIdFTP(FIdFTP).ConnectTimeout := 60 * 1000;
    // Set binary mode
    TIdFTP(FIdFTP).TransferType := ftBinary;

    // set authentication stuff if requested
    if FURL.Username <> '' then
    begin
      TIdFTP(FIdFTP).Username := FURL.Username;
      TIdFTP(FIdFTP).Password := FURL.Password;
    end;

    // Host
    TIdFTP(FIdFTP).Host := FURL.Host; // '[' + FURL.Host + ']';

    // Set IP version
    TIdFTP(FIdFTP).IPVersion := FURL.IPVersion;

    // set active/passive mode
    TIdFTP(FIdFTP).Passive := True;

    // Connect
    //---------
    TIdFTP(FIdFTP).Connect();

    // Get
    //-----
    FPWorkerFile := PChar(FWorkerFileName);
    TIdFTP(FIdFTP).Get( FURL.Document, FPWorkerFile, False );

    // Disconnect
    //------------
    TIdFTP(FIdFTP).Disconnect;

  finally
    FreeAndNil(FIdFTP);
    FreeAndNil(FURL);
  end;

except
  on e : Exception do
    ShowMessage( 'Exception - ' + e.Message )
end;


Scheint mir ein Problem mit der Indy-Komponente zu sein welche IPv6 noch nicht so richtig handhabt. Denn versuche ich das ganze mit der IPv4 Adresse des Servers, funktioniert es.

Bin um jede Hilfe dankbar,

middel86
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19276
Erhaltene Danke: 1741

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mi 08.08.12 07:00 
Eigentlich sollte die Komponente EPSV schon seit einigen Jahren können. :gruebel:

Da bleibt wohl nur im Quelltext zu schauen. Vielleicht muss man dafür etwas einstellen.

Benutzt du die aktuellste Version?

// EDIT:
Ein Blick (20 Sekunden) in die IdFtp.pas sagt mir, dass du (laut Kommentar) die NAT Extensions nach RFC 2428 aktivieren musst. Ein weiterer Blick sagt mir, dass es dafür reichen sollte UseExtensionDataPort auf True zu stellen. ;-)
middel86 Threadstarter
Hält's aus hier
Beiträge: 4



BeitragVerfasst: Mi 08.08.12 09:41 
Hallo jaenicke!

Danke für deine Antwort. Leider bringt das auf True setzen des UseExtensionDataPort Flags nichts, da es während des Connects in der Komponente selbst wieder auf False gesetzt wird. Dies geschieht bei folgender Prüfung:

ausblenden Delphi-Quelltext
1:
FUsingExtDataPort := IsExtSupported('EPRT'and IsExtSupported('EPSV');  {do not localize}					

Beide IsExtSupported Aufrufe liefern False zurück, da der FTP-Server auf die FEAT Anfrage folgende Antwort gibt:
Zitat:
Command: FEAT
Response: 211-Features:
Response: MDTM
Response: REST STREAM
Response: SIZE
Response: MLST type*;size*;modify*;
Response: MLSD
Response: UTF8
Response: CLNT
Response: MFMT
Response: 211 End

Diese Antwort wird ja dann in die StringList FCapabilities geschrieben und mit IsExtSupported() geprüft ob die beiden Ausdrücke 'EPRT' und 'EPSV' enthalten sind. Da dies nicht der Fall ist wird FUsingExtDataPort auf False gesetzt und während der PUT oder GET Operation SendPassive() anstelle von SendEPassive() aufgerufen...

Soweit wie ich das verstanden habe, sollte der FileZilla FTP-Server eigentlich die 'EPRT' und 'EPSV' Commands unter den Features auflisten, tut dies aber nicht. Die anderen FTP-Clients scheinen aber keine Probleme damit zu haben...keine Ahnung wieso.

Weitere Vorschläge sind sehr willkommen...

middel86

p.s.: Ja ich benutze die aktuellste Version der Indy-Komponente.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19276
Erhaltene Danke: 1741

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mi 08.08.12 09:48 
Stimmt, ich habe kurz nochmal reingeschaut. Soweit ich das sehe sollte es aber reichen AutoIssueFEAT auf False zu setzen, so dass IssueFEAT gar nicht erst aufgerufen wird. Dann werden die Features beim Login nicht geprüft.
middel86 Threadstarter
Hält's aus hier
Beiträge: 4



BeitragVerfasst: Mi 08.08.12 12:30 
Super das hat den PASV Fehler behoben, danke!

Aber jetzt bekomme ich eine neue Exception beim GET:
Zitat:
EIdSocketError: Socket Error # 11001 Host not found

Das Problem ist, dass beim connect zum DataChannel als Host die IPv6 Adresse verwendet wird, aber als FIPVersion (TIdTCPClientCustom) der Default Wert Id_IPv4 genommen wird. Dann kann natürlich die IP-Adresse nicht aufgelöst werden.
Gibt es für hierfür auch ein magisches Flag welches ich noch nicht gesetzt habe? :?

Danke für deine Hilfe!
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19276
Erhaltene Danke: 1741

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mi 08.08.12 12:56 
Ein Flag nicht, aber mir fällt da das Event OnDataChannelCreate ins Auge. Ich schätze mal darin kannst du das setzen. Den Channel bekommst du ja als Parameter. Und der Connect passiert erst danach. ;-)
(Also sprich (ADataChannel as TIdTCPClient).IPVersion := ...)
middel86 Threadstarter
Hält's aus hier
Beiträge: 4



BeitragVerfasst: Mi 08.08.12 13:32 
Yeah, super jetzt hats endlich funktioniert!!

Ein fettes DANKE an dich jaenicke, jetzt kann die IPv6 Umstellung kommen! :D

Gruss