I am building an api with Java Spring Boot and what I want to do is use an endpoint to download a file. The problem is that the api accesses the file through ssh. I don't want the api to download the file and then return it, what I want is to make a direct stream from ssh to the response. Is this possible?
To connect by ssh and get the file I am using JSch. The files I want to download can be up to 2 GB in size. Thank you
Edit: I finally did this and it worked. Many thanks to @Martin Prikryl for his help.
@RequestMapping(value = "/endpoint-test/download-file-stream", method = RequestMethod.GET)
@ResponseStatus(HttpStatus.OK)
public static void sendFileInResponse (HttpServletResponse response) throws Exception {
String path_file = "/opt/dir/file_test.txt"; //this path is inside the remote server
ConexionJSch new_conection_to_filesystem = new ConexionJSch();
ChannelSftp channelSftp = new_conection_to_filesystem.setupJsch();
channelSftp.connect();
SftpATTRS data = channelSftp.lstat(path_file);
long fsize = data.getSize();
try (InputStream inputStream = channelSftp.get(path_file)){
response.setContentType("application/octet-stream");
response.setContentLengthLong(fsize);
response.setHeader("Content-Disposition", "inline;filename=test.bam");
OutputStream outputStream = response.getOutputStream()
byte[] buff = new byte[2048];
int length = 0;
while ((length = inputStream.read(buff)) > 0) {
outputStream.write(buff, 0, length);
outputStream.flush();
}
inputStream.close();
response.setHeader("Cache-Control", "private");
response.setDateHeader("Expires", 0);
} finally{
channelSftp.exit();
}
}
public class ConexionJSch {
private final String remoteHost;
private final String username;
private final String password;
public ConexionJSch() {
this.remoteHost = "xxx.xxx.xxx.xxx";
this.username = "user";
this.password = "pass";
}
public ChannelSftp setupJsch() throws JSchException {
JSch jsch = new JSch();
jsch.setKnownHosts("/home/ubuntu_user/.ssh/known_hosts");
Session jschSession = jsch.getSession(username, remoteHost);
jschSession.setPassword(password);
jschSession.connect();
return (ChannelSftp) jschSession.openChannel("sftp");
}
}