77	"fmt" 
88	"io" 
99	"reflect" 
10+ 	"sync" 
1011
1112	sftpClient "github.com/pkg/sftp" 
1213	"golang.org/x/crypto/ssh" 
@@ -25,9 +26,33 @@ const (
2526
2627// Sftp is a binding for file operations on sftp server. 
2728type  Sftp  struct  {
28- 	metadata    * sftpMetadata 
29- 	logger      logger.Logger 
30- 	sftpClient  * sftpClient.Client 
29+ 	metadata      * sftpMetadata 
30+ 	logger        logger.Logger 
31+ 	sftpClient    * sftpClient.Client 
32+ 	clientConfig  * ssh.ClientConfig 
33+ 	lock          sync.RWMutex 
34+ }
35+ 
36+ func  (sftp  * Sftp ) Client () (* sftpClient.Client , error ) {
37+ 	sftp .lock .RLock ()
38+ 	_ , err  :=  sftp .sftpClient .Getwd ()
39+ 	sftp .lock .RUnlock ()
40+ 
41+ 	if  err  !=  nil  {
42+ 		sshClient , err  :=  ssh .Dial ("tcp" , sftp .metadata .Address , sftp .clientConfig )
43+ 		if  err  !=  nil  {
44+ 			return  nil , fmt .Errorf ("sftp binding error: error create ssh client: %w" , err )
45+ 		}
46+ 
47+ 		newSftpClient , err  :=  sftpClient .NewClient (sshClient )
48+ 		if  err  !=  nil  {
49+ 			return  nil , fmt .Errorf ("sftp binding error: error create sftp client: %w" , err )
50+ 		}
51+ 		sftp .lock .Lock ()
52+ 		sftp .sftpClient  =  newSftpClient 
53+ 		sftp .lock .Unlock ()
54+ 	}
55+ 	return  sftp .sftpClient , nil 
3156}
3257
3358// sftpMetadata defines the sftp metadata. 
@@ -125,6 +150,7 @@ func (sftp *Sftp) Init(_ context.Context, metadata bindings.Metadata) error {
125150		return  fmt .Errorf ("sftp binding error: error create sftp client: %w" , err )
126151	}
127152
153+ 	sftp .clientConfig  =  config 
128154	sftp .metadata  =  m 
129155	sftp .sftpClient  =  newSftpClient 
130156
@@ -163,12 +189,17 @@ func (sftp *Sftp) create(_ context.Context, req *bindings.InvokeRequest) (*bindi
163189
164190	dir , fileName  :=  sftpClient .Split (path )
165191
166- 	err  =  sftp .sftpClient .MkdirAll (dir )
192+ 	c , err  :=  sftp .Client ()
193+ 	if  err  !=  nil  {
194+ 		return  nil , fmt .Errorf ("sftp binding error: error getting sftp client: %w" , err )
195+ 	}
196+ 
197+ 	err  =  c .MkdirAll (dir )
167198	if  err  !=  nil  {
168199		return  nil , fmt .Errorf ("sftp binding error: error create dir %s: %w" , dir , err )
169200	}
170201
171- 	file , err  :=  sftp . sftpClient .Create (path )
202+ 	file , err  :=  c .Create (path )
172203	if  err  !=  nil  {
173204		return  nil , fmt .Errorf ("sftp binding error: error create file %s: %w" , path , err )
174205	}
@@ -211,7 +242,12 @@ func (sftp *Sftp) list(_ context.Context, req *bindings.InvokeRequest) (*binding
211242		return  nil , fmt .Errorf ("sftp binding error: %w" , err )
212243	}
213244
214- 	files , err  :=  sftp .sftpClient .ReadDir (path )
245+ 	c , err  :=  sftp .Client ()
246+ 	if  err  !=  nil  {
247+ 		return  nil , fmt .Errorf ("sftp binding error: error getting sftp client: %w" , err )
248+ 	}
249+ 
250+ 	files , err  :=  c .ReadDir (path )
215251	if  err  !=  nil  {
216252		return  nil , fmt .Errorf ("sftp binding error: error read dir %s: %w" , path , err )
217253	}
@@ -246,7 +282,12 @@ func (sftp *Sftp) get(_ context.Context, req *bindings.InvokeRequest) (*bindings
246282		return  nil , fmt .Errorf ("sftp binding error: %w" , err )
247283	}
248284
249- 	file , err  :=  sftp .sftpClient .Open (path )
285+ 	c , err  :=  sftp .Client ()
286+ 	if  err  !=  nil  {
287+ 		return  nil , fmt .Errorf ("sftp binding error: error getting sftp client: %w" , err )
288+ 	}
289+ 
290+ 	file , err  :=  c .Open (path )
250291	if  err  !=  nil  {
251292		return  nil , fmt .Errorf ("sftp binding error: error open file %s: %w" , path , err )
252293	}
@@ -272,7 +313,11 @@ func (sftp *Sftp) delete(_ context.Context, req *bindings.InvokeRequest) (*bindi
272313		return  nil , fmt .Errorf ("sftp binding error: %w" , err )
273314	}
274315
275- 	err  =  sftp .sftpClient .Remove (path )
316+ 	c , err  :=  sftp .Client ()
317+ 	if  err  !=  nil  {
318+ 		return  nil , fmt .Errorf ("sftp binding error: error getting sftp client: %w" , err )
319+ 	}
320+ 	err  =  c .Remove (path )
276321	if  err  !=  nil  {
277322		return  nil , fmt .Errorf ("sftp binding error: error remove file %s: %w" , path , err )
278323	}
@@ -296,6 +341,8 @@ func (sftp *Sftp) Invoke(ctx context.Context, req *bindings.InvokeRequest) (*bin
296341}
297342
298343func  (sftp  * Sftp ) Close () error  {
344+ 	sftp .lock .Lock ()
345+ 	defer  sftp .lock .Unlock ()
299346	return  sftp .sftpClient .Close ()
300347}
301348
0 commit comments