Just as a long outstanding note.
I made an extension to EnsLib.FTP.OutboundAdapter that adds handling for Use Session Resumption as a parameter, but it appears as of the 2024 version of IRIS this has been added to the core IRIS code.
We've only recently been able to use it as we had an old OpenSSL version that did not support the flags required, so this has been left and not looked at in a few years.
For reference the extension I wrote is listed below:
Include Ensemble Class Custom.Operations.FTP.OutboundAdapter Extends EnsLib.FTP.OutboundAdapter [ ClassType = "", Inheritance = right, ProcedureBlock, System = 4 ]
{ Property SSLUseSessionResumption As %Boolean [ InitialExpression = 0 ]; /// These properties can be configured or set by the associated Business Operation
Parameter SETTINGS = "SSLUseSessionResumption:Connection"; /// Connect to the FTP server and log in, setting the directory and transfer mode
Method Connect(pTimeout As %Numeric = 30, pInbound As %Boolean = 0) As %Status
{
Set $ZT="Trap", tSC=$$$OK, tFTPPort=..FTPPort
Do {
If ..Connected { Do ..TestConnection(pInbound) Quit:..Connected } #; Connect to the FTP server
If '$IsObject(..%CredentialsObj) Do ..CredentialsSet(..Credentials) If '$IsObject(..%CredentialsObj) { Set tSC=$$$ERROR($$$EnsErrNoCredentials,..Credentials) Quit }
Set ..%LastSetFilePath="" #; find FTP type; get a configuration-settings instance, use it to open an FTP Session instance
If ..%isSFTP {
#; Connect using an SFTP object
Set:""=tFTPPort tFTPPort=22
Set tIOAddr=..FTPServer_":"_tFTPPort_"/"_..Credentials_"/SSL='"_..SSLConfig_"'/PubKey='"_..SFTPPublicKeyFile_"'/PrivKey='"_..SFTPPrivateKeyFile_"'"
$$$catTRACE("connwait","Connecting to "_tIOAddr_"/"_..Credentials_"'/PubKey='"_..SFTPPublicKeyFile_"'/PrivKey='"_..SFTPPrivateKeyFile_"' with timeout="_pTimeout)
Set:'$IsObject(..FTP)||'..FTP.%Extends("EnsLib.FTP.CommonSSH") ..FTP=$this
Set ..FTP.SSLUseSessionResumption=..SSLUseSessionResumption
Set t0=$zh
Set tSC=..FTP.ConnectSSH(pTimeout, pInbound, tFTPPort)
} Else {
#; Connect using standard FTP, or FTPS with SSLConfig
Set:""=tFTPPort tFTPPort=21
Set tIOAddr=..FTPServer_":"_tFTPPort_"/"_..Credentials_"/SSL='"_..SSLConfig
$$$catTRACE("connwait","Connecting to "_tIOAddr_"/"_..Credentials_" with timeout="_pTimeout)
Set:'$IsObject(..FTP)||'..FTP.%Extends("%Net.FtpSession") ..FTP=##class(%Net.FtpSession).%New()
Set ..FTP.SSLUseSessionResumption=..SSLUseSessionResumption
Set t0=$zh, ..FTP.Timeout=pTimeout, ..FTP.UsePASV=..UsePASV, ..FTP.LegacySSL=("*"=$E(..SSLConfig,*)), ..FTP.SSLConfiguration=$S("*"=$E(..SSLConfig,*):$E(..SSLConfig,1,*-1),1:..SSLConfig)
If (..FTP.SSLConfiguration'="") {
Set ..FTP.SSLCheckServerIdentity = ..SSLCheckServerIdentity
Set ..FTP.SSLUseSessionResumption = ..SSLUseSessionResumption
}
If '..FTP.Connect(..FTPServer,..%CredentialsObj.Username,..%CredentialsObj.Password,tFTPPort) {
Set tSC=$$$ERROR($$$EnsErrFTPConnectFailed,tIOAddr_"/"_..Credentials,..FTP.ReturnMessage,..FTP.ReturnCode)
}
#; Set after connect since FTP class will query server if empty string
Set ..FTP.CommandTranslateTable = ..CommandTranslateTable
}
If $$$ISERR(tSC) {
Set tSC=$S((-1'=pTimeout)&&(t0+pTimeout<=$zh): $$$ADDSC($$$ERROR($$$EnsErrOutConnectExpired,pTimeout,$S(..%isSFTP:"SFTP",1:"FTP"),tIOAddr),tSC)
, 1: $$$ERROR($$$EnsErrOutConnectFailed,$$$StatusDisplayString(tSC),$S(..%isSFTP:"SFTP",1:"FTP"),tIOAddr))
Set ..FTP=$$$NULLOREF
Quit
}
#; Get the system declaration from the FTP server
Set ..%Syst="" Set:..FTP.System(.tSystem) ..%Syst=tSystem
If ""'=..%Syst {
Set ..%isVMS = ("VMS " = $E(..%Syst,1,$L("VMS ")))
$$$catTRACE("connwait","Detected FTP server system type '"_..%Syst_"'")
}
#; Set the current directory
Set ..%LastSetFilePath=..fixSvrPath(..FilePath,0)
If ""=..%LastSetFilePath {
$$$catTRACE("connwait","Not setting FTP working directory because FilePath is empty")
} Else {
If ..FTP.SetDirectory(..%LastSetFilePath) {
$$$catTRACE("connwait","Set FTP working directory to "_..%LastSetFilePath)
} Else {
Set tSC=$$$ERROR($$$EnsErrFTPDirectoryChangeFailed,..%LastSetFilePath,..FTP.ReturnMessage,..FTP.ReturnCode)
Set ..%LastSetFilePath=""
Quit
}
}
#; Set the transfer mode
Set tTable = "RAW"
Set csetlc=$ZCVT(..Charset,"L")
Set tAscii=$Case($E(csetlc,1,5),"":1,"defau":1,"ascii":1,"latin":1,"iso-8":1,"utf-8":1,:0)
If 'tAscii {
If '..FTP.Binary() {
Set tSC=$$$ERROR($$$EnsErrFTPModeChangeFailed,"Binary",..FTP.ReturnMessage,..FTP.ReturnCode)
Set ..FTP.TranslateTable = ""
Quit
}
If "binary"'=csetlc {
Set tEnc=..Charset Set:"*"=$E(tEnc) $E(tEnc)=""
Set tTable = ##class(%IO.I.TranslationDevice).GetCharEncodingTable(tEnc)
Set:tTable="" tTable="RAW"
}
} Else {
If '..FTP.Ascii() {
Set tSC=$$$ERROR($$$EnsErrFTPModeChangeFailed,"Ascii",..FTP.ReturnMessage,..FTP.ReturnCode)
Quit
}
If "ascii"'=csetlc {
If $Case(csetlc,"":0,"default":0,"native":0,:1) {
Set tTable = ##class(%IO.I.TranslationDevice).GetCharEncodingTable(..Charset)
} Else { Set tTable = "" }
Set:tTable="" tTable=$$DefIO^%NLS(5)
}
}
#; Success
Set ..FTP.TranslateTable = tTable
Set tTxt="Connected to FTP Server '"_tIOAddr_"' at path '"_..%LastSetFilePath_"' using Credentials '"_..Credentials_"'"
If ..StayConnected<0 { $$$LOGINFO(tTxt) }
Else {
If pInbound&&'..StayConnected { $$$catTRACE("connwait",tTxt) }
ElseIf ..%logTransfers { $$$LOGINFO(tTxt) }
Else { $$$sysTRACE(tTxt) }
}
Set ..Connected=1
$$$ASSERT(..FTP.Connected)
If (..BusinessHost.%LastReportedError [ "ERROR <Ens>ErrOutConnect")
||(..BusinessHost.%LastReportedError [ ..%LastNetErr) {
Set ..BusinessHost.%LastReportedError=""
$$$SetHostMonitor(..BusinessHost.%ConfigName,$$$eMonitorStatus,"OK")
}
Set ..%LastNetErr="%%%%%"
Set i%%IOAddr=tIOAddr
} While 0
Exit
If $$$ISERR(tSC) {
$$$ASSERT('..Connected)
Do:..FTP.Connected ..FTP.Logout() ; force FTP class into sync in case it made a mistake
}
Quit tSC
Trap
Set $ZT="",tSC=$$$EnsSystemError
Set tSC =$$$ERROR($$$EnsErrOutConnectException,$$$StatusText(tSC),$S(..%isSFTP:"SFTP",1:"FTP"),tIOAddr_"/"_..Credentials)
Goto Exit
} }- Log in to post comments