I want to create a valid URL to send to Windows File Explorer (or other file managers like TotalCommander) using the format:
ftp://username:[email protected]/folder/
In Explorer, it works with very straight username and password. But I receive errors (or Explorer just display the My Document instead of the FTP site) when password contains certain special characters. I played with URI encoding to encode the password with some success but not 100% reliable.
Can someone help me finding the correct requirements for a valid FTP URL including username and password? Thanks.
Here is a sample of the code using AutoHotkey "Run" command (on Windows 7 64-bit environment):
#NoEnv
#SingleInstance force
strFTPUrl := "ftp://www.jeanlalonde.ca"
strLoginName := "[email protected]"
strPassword := "********"
StringReplace, strFTPUrl, strFTPUrl, % "ftp://", % "ftp://" . strLoginName . ":" . UriEncode(strPassword) . "@"
; Before: ftp://ftp.jeanlalonde.ca
; After: ftp://[email protected]:********@ftp.jeanlalonde.ca
MsgBox, %strFTPUrl%
Run, Explorer "%strFTPUrl%"
return
;------------------------------------------------------------
UriEncode(str)
; from GoogleTranslate by Mikhail Kuropyatnikov
; http://www.autohotkey.net/~sumon/GoogleTranslate.ahk
;------------------------------------------------------------
{
b_Format := A_FormatInteger
data := ""
SetFormat,Integer,H
SizeInBytes := StrPutVar(str,var,"utf-8")
Loop, %SizeInBytes%
{
ch := NumGet(var,A_Index-1,"UChar")
If (ch=0)
Break
if ((ch>0x7f) || (ch<0x30) || (ch=0x3d))
s .= "%" . ((StrLen(c:=SubStr(ch,3))<2) ? "0" . c : c)
Else
s .= Chr(ch)
}
SetFormat,Integer,%b_format%
return s
}
;------------------------------------------------------------
;------------------------------------------------------------
StrPutVar(string, ByRef var, encoding)
;------------------------------------------------------------
{
; Ensure capacity.
SizeInBytes := VarSetCapacity( var, StrPut(string, encoding)
; StrPut returns char count, but VarSetCapacity needs bytes.
* ((encoding="utf-16"||encoding="cp1200") ? 2 : 1) )
; Copy or convert the string.
StrPut(string, &var, encoding)
Return SizeInBytes
}
;------------------------------------------------------------
If there are special characters (@
being one) in the username too (not only in the password), you have to URL-encode the username too, the same way you URL-encode the password.
That means you have to apply the UriEncode
to strLoginName
, the same way you apply it to strPassword
.
And you need to update the UriEncode
to encode the @
, as it does not.
The code for @
is 0x40
.
if ((ch>0x7f) || (ch<0x30) || (ch=0x3d) || (ch=0x40))
(Though you can compare to @
literally too: ch="@"
).