Post
by X » Sun Jun 21, 2009 5:11 pm
Actually its all down to understanding the nature of FTP protocol.
FTP, unlike HTTP uses two channels to communicate and exchange data.
1. First channel (usually on port 21) is called 'Control Channel' (PI - Protocol Interpreter).
You use it to pass FTP commands to the server and server will respond to you on that channel as well.
2. Second channel (usually port 20) is called 'Data Channel' (DTP - Data Transmission Process).
This channel is for sending/receiving (uploading/downloading) content (your files, directory listings).
So in short, you talk to server on one channel but transfer files on other.
In Rev, as you may already guessed, you'll need to open and maintain communication on TWO sockets.
Now, first socket is easy and sraightforward:
open socket to "myhost:21"
But opening second, the Data socket, is a bit tricky.
This is where you learn another important FTP feature - the Passive Mode.
In most cases you will need this mode enabled.
You pass PASV command to the server on the Control Channel and server
will respond with confirmation like this:
227 Entering Passive Mode (123,123,123,123,111,222)
In the brackets is ASCII (32+16 bit) representation of host IP address and port number.
Item 1 to 4 of it is host IP address and last two items represent the port number, so logically it looks like this:
[123,123,123,123],[111,222]
With Passive Mode, you must connect on that port for Data Transmission.
You will open socket on that port to upload and download files.
It is easy to convert host IP part to a format we use simply be replacing commas with periods:
replace "," with "." in hostIP -->> 123.123.123.123
Now the crucial part - translating 16 bit (2x8) of ASCII port representation into single 16 bit port number.
[111,222] is two items, two (ASCII, base 10) groups of digits. Each group is in range 0...255 (2^8).
We need to convert it to single 16 bit format by combining these two,
but because they are in ASCII (base 10) representation, we first must convert them to either binary or hex format, then combine:
baseConvert ( part1, 10, 16) & baseConvert ( part2, 10, 16)
so the final code may look like this:
--// assuming server response on 'PASV' command you put into response var //--
if matchText(response,"\([0-9]*,[0-9]*,[0-9]*,[0-9]*,([0-9]*),([0-9]*)\)",p1,p2) then
get baseConvert(p1,10,16) & baseConvert(p2,10,16)
put baseConvert(it,16,10) into dataPort
put myHostName & ":" & dataPort into dataChannel
--// Open Data Port //--
open socket dataChannel
end if
Note the use of Perl alike Wildcard expression to find and extract two parts of the port number from the server response string.
So now you should be set and ready to talk to your FTP server and exchange data the proper way, far beyond revlibFTP and libURL limits all together ;-)
VX.