use std::io::Write; use std::path::PathBuf; use suppaftp::FtpError; use suppaftp::NativeTlsFtpStream; use suppaftp::NativeTlsConnector; use suppaftp::native_tls::Certificate; use suppaftp::native_tls::TlsConnector; fn ftp_connection_anonymous() -> Result{ ftp_connection("anonymous", "anonymous@") } pub fn test_cred(username: &str, password: &str) -> bool{ return ftp_connection(username, password).is_ok(); } fn ftp_connection(username: &str, password: &str) -> Result{ let ftp_stream = NativeTlsFtpStream::connect("gitea.piwalker.net:21")?; let cert = include_bytes!("../res/vsftpd.crt"); let cert = Certificate::from_pem(cert).unwrap(); let mut ftp_stream = ftp_stream.into_secure(NativeTlsConnector::from(TlsConnector::builder().add_root_certificate(cert).build().unwrap()), "gitea.piwalker.net").unwrap(); let result = ftp_stream.login(username, password); if result.is_ok() { return Ok(ftp_stream); } Err(result.unwrap_err()) } pub fn ftp_retr(window: Option, file: PathBuf , mut writer: impl Write, mut callback: impl FnMut(Option, usize, usize)) -> Result { let mut ftp_stream = ftp_connection_anonymous()?; let file = file.to_str().unwrap().replace("\\", "/"); let size = ftp_stream.size(&file)?; let mut total = 0; ftp_stream.retr(file.as_str(), |stream| { let mut tx_bytes = [0u8; 1500]; loop { let bytes_read = stream.read(&mut tx_bytes).unwrap(); writer.write_all(&mut tx_bytes.split_at(bytes_read).0).unwrap(); total += bytes_read; if total == size || bytes_read == 0 { callback(window.clone(), 0, size); break; }else{ callback(window.clone(), bytes_read, size); } } Ok(true) })?; Ok(true) } pub fn ftp_get_size(file: PathBuf) -> Result { let mut stream = ftp_connection_anonymous()?; stream.size(file.to_str().unwrap().replace("\\", "/")) }