Valid URL for an FTP site with username containing @

时间:2015-09-01 21:52:23

标签: url ftp autohotkey

I want to create a valid URL to send to Windows File Explorer (or other file managers like TotalCommander) using the format:

ftp://username:password@ftp.domain.ext/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 := "username@jeanlalonde.ca"
strPassword := "********"

StringReplace, strFTPUrl, strFTPUrl, % "ftp://", % "ftp://" . strLoginName . ":" . UriEncode(strPassword) . "@"

; Before: ftp://ftp.jeanlalonde.ca
; After: ftp://testaccount@jeanlalonde.ca:********@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 
}
;------------------------------------------------------------

1 个答案:

答案 0 :(得分:1)

如果用户名中也有特殊字符(@为一个)(不仅仅是密码),您也必须对用户名进行URL编码,就像对密码进行URL编码一样。 / p>

这意味着您必须将UriEncode应用于strLoginName,就像将其应用于strPassword一样。

您需要更新UriEncode以对@进行编码,因为它不会。

@的代码为0x40

if ((ch>0x7f) || (ch<0x30) || (ch=0x3d) || (ch=0x40))

(虽然您也可以与@字面上进行比较:ch="@")。