linux-web-console/app/src/main/java/webshell/app/files/BinaryDataController.java

185 lines
5.3 KiB
Java

/**
*
*/
package webshell.app.files;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import webshell.app.Application;
/**
* @author subhro
*
*/
@RestController
@CrossOrigin(allowCredentials = "true")
@RequestMapping("/bin")
public class BinaryDataController {
@Autowired
private FileTypeDetector typeDetector;
private void validateToken(String token) throws Exception {
Jws<Claims> parsedToken = Jwts.parser()
.setSigningKey(Application.SECRET_KEY).parseClaimsJws(token);
String username = parsedToken.getBody().getSubject();
if (username != null && username.length() > 0
&& username.equals(System.getProperty("app.default-user"))) {
System.out.println("Token and user is valid");
return;
}
throw new Exception("Invalid username: " + username);
}
@GetMapping("/image/{encodedPath}")
public ResponseEntity<byte[]> getImage(@PathVariable String encodedPath,
@RequestParam String token) throws Exception {
validateToken(token);
String path = new String(Base64.getDecoder().decode(encodedPath));
byte[] b = Files.readAllBytes(Paths.get(path));
MultiValueMap<String, String> headers = new HttpHeaders();
headers.add("Content-Type", getImageType(path));
ResponseEntity<byte[]> resp = new ResponseEntity<byte[]>(b, headers,
HttpStatus.OK);
return resp;
}
@GetMapping("/blob/{encodedPath}")
public void getBlob(@PathVariable String encodedPath,
@RequestParam String token, HttpServletRequest request,
HttpServletResponse resp) throws Exception {
validateToken(token);
String path = new String(Base64.getDecoder().decode(encodedPath));
System.out.println("Get file: " + path);
long fileSize = Files.size(Paths.get(path));
String r = request.getHeader("Range");
long upperBound = fileSize - 1;
long lowerBound = 0;
if (r != null) {
System.out.println(r);
String rstr = r.split("=")[1];
String arr[] = rstr.split("-");
lowerBound = Long.parseLong(arr[0]);
if (arr.length > 1 && arr[1].length() > 0) {
upperBound = Long.parseLong(arr[1]);
}
}
System.out.println("lb: " + lowerBound + " ub: " + fileSize);
if (r != null) {
resp.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
}
resp.addHeader("Content-Length", (fileSize - lowerBound) + "");
resp.addHeader("Content-Range",
"bytes " + lowerBound + "-" + upperBound + "/" + fileSize);// (fileSize
// -
// lowerBound)
// +
// "");
resp.addHeader("Content-Type", typeDetector.getType(new File(path)));
long rem = fileSize - lowerBound;
try (InputStream in = new FileInputStream(path)) {
in.skip(lowerBound);
byte[] b = new byte[8192];
while (rem > 0) {
int x = in.read(b, 0, (int) (rem > b.length ? b.length : rem));
if (x == -1)
break;
resp.getOutputStream().write(b, 0, x);
rem -= x;
}
}
// Files.copy(Paths.get(path), resp.getOutputStream());
}
@GetMapping("/download")
public void downloadFiles(
@RequestParam(name = "folder") String encodedFolder,
@RequestParam(name = "files", required = false) String encodedFiles,
@RequestParam String token, HttpServletResponse response)
throws Exception {
validateToken(token);
int fileCount = 0;
String folder = new String(Base64.getDecoder().decode(encodedFolder),
"utf-8");
List<String> fileList = new ArrayList<>();
if (encodedFiles != null) {
String files = new String(Base64.getDecoder().decode(encodedFiles),
"utf-8");
String[] arr1 = files.split("/");
if (arr1 != null && arr1.length > 0) {
fileCount = arr1.length;
for (String str : arr1) {
fileList.add(new File(folder, str).getAbsolutePath());
}
}
}
if (fileList.size() == 0) {
throw new IOException();
}
String name = "download.zip";
boolean compress = false;
if (fileCount == 1) {
File f = new File(fileList.get(0));
name = f.getName();
compress = f.isDirectory();
if (name.length() < 1) {
name = "files";
}
} else {
compress = true;
}
response.addHeader("Content-Disposition",
"attachment; filename=\"" + name + ".zip" + "\"");
response.setContentType("application/octet-stream");
FileTransfer fs = new FileTransfer(compress);
fs.transferFiles(fileList, response.getOutputStream());
}
/**
* @param path
* @return
*/
private String getImageType(String path) {
return typeDetector.getTypeByName(path);
}
}