Select Git revision
ServiceFTPEndPoint.java
-
Hocine Bouali authoredHocine Bouali authored
ServiceFTPEndPoint.java 18.75 KiB
package fil.sr2.endpoints;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.SocketException;
import java.util.zip.ZipOutputStream;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.core.StreamingOutput;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.glassfish.jersey.media.multipart.FormDataParam;
import fil.sr2.Main;
import fil.sr2.Secured;
import fil.sr2.utils.Utils;
/**
* Cette classe représente la ressource "/ftp", cette ressource permet de
* telecharger , de supprimer, de renommer et de lister le contenu d'un
* repertoire
*
* @author Bouali Hocine
*
*/
@Path("ftp")
public class ServiceFTPEndPoint {
private FTPClient ftp;
private String server;
/**
* Methode qui permet d'initialiser une connexion à un serveur FTP ou FTPS
*
* @param alias l'alias du serveur FTP
* @param type FTP ou FTPS
* @param username le username
* @param psw le mot de passe
* @param mode le mode d'echange avec le serveur (PASV ou PORT)
* @param port le Port de connexion
* @return un statut http
*/
private Response init(String alias, String type, String username, String psw, String mode, int port) {
try {
server = Utils.findAddress(alias, Main.allAlias);
} catch (NullPointerException e) {
return Response.status(Response.Status.FORBIDDEN).entity(alias + " not exist").build();
}
try {
switch (type.toLowerCase()) {
case "ftp":
ftp = Utils.initftp(server, username, psw, port, mode);
break;
case "ftps":
ftp = Utils.initftps(server, username, psw, port, mode);
break;
default:
return Response.status(Response.Status.FORBIDDEN).entity(type + " not supported or not exist").build();
}
} catch (SocketException e1) {
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity("try later pls !").build();
} catch (IOException e2) {
return Response.status(Response.Status.FORBIDDEN).entity("impossible to connect to " + server).build();
}
return Response.status(Response.Status.ACCEPTED).build();
}
/**
* Methode qui permet de lister le contenu d'un repertoire
*
* @param alias l'alias du serveur
* @param path le chemin d'acces vers le dossier
* @param username le username par defaut anonymous
* @param psw le mot de passe par defaut anonymous
* @param mode le mode d'echange avec le serveur (PASV ou PORT) par defaut
* en PASV
* @param type FTP ou FTPS par defaut FTP
* @param port le port d'ecoute
* @return un statut http
*/
@GET
@Secured
@Path("{alias}/list/{path: .*}")
@Produces(MediaType.TEXT_PLAIN)
public Response listing(@PathParam("alias") String alias, @PathParam("path") String path,
@DefaultValue("anonymous") @HeaderParam("username") String username,
@DefaultValue("anonymous") @HeaderParam("password") String psw,
@DefaultValue("pasv") @HeaderParam("mode") String mode,
@DefaultValue("FTP") @HeaderParam("type") String type, @DefaultValue("21") @HeaderParam("port") int port) {
Response r = init(alias, type, username, psw, mode, port);
if (!(r.getStatus() == Response.Status.ACCEPTED.getStatusCode())) {// on verifie que l'init s'est bien passer
return r;
}
FTPFile[] files;
try {
files = ftp.listFiles(path);
} catch (IOException e) {
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity("try later pls !").build();
} finally {
try {
ftp.disconnect();
} catch (IOException e) {
}
}
return Response.status(Response.Status.OK).entity(Utils.fileDetails(files)).type(MediaType.APPLICATION_JSON)
.build();
}
/**
* Methode qui permet de télécharger un fichier
*
* @param alias l'alias du serveur
* @param path le chemin d'acces vers le fichier
* @param username le username par defaut anonymous
* @param psw le mot de passe par defaut anonymous
* @param mode le mode d'echange avec le serveur (PASV ou PORT) par defaut
* en PASV
* @param type FTP ou FTPS par defaut FTP
* @param port le port d'ecoute
* @return un statut http
*/
@GET
@Secured
@Path("{alias}/file/{path: .*}")
@Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response downloadHttpFile(@PathParam("alias") String alias, @PathParam("path") String path,
@DefaultValue("anonymous") @HeaderParam("username") String username,
@DefaultValue("anonymous") @HeaderParam("password") String psw,
@DefaultValue("pasv") @HeaderParam("mode") String mode,
@DefaultValue("FTP") @HeaderParam("type") String type, @DefaultValue("21") @HeaderParam("port") int port) {
Response r = init(alias, type, username, psw, mode, port);
if (!(r.getStatus() == Response.Status.ACCEPTED.getStatusCode())) {// on verifie que l'init s'est bien passer
return r;
}
String filename = path.substring(path.lastIndexOf("/") + 1, path.length());
File file = new File("./Downloads/" + filename);
OutputStream output;
try {
output = new FileOutputStream(file);
if (!ftp.retrieveFile(path, output)) {
output.close();
throw new IOException();
}
output.close();
} catch (IOException e) {
return Response.status(Response.Status.FORBIDDEN)
.entity("file " + path + " not exist on the ftp server or you don't have the right to download it")
.build();
} finally {
try {
ftp.disconnect();
} catch (IOException e) {
}
}
return Response.ok(file).header("Content-Disposition", "attachment; filename=\"" + filename + "\"").build();
}
@GET
@Secured
@Path("{alias}/file/last-modified/{path: .*}")
@Produces(MediaType.TEXT_PLAIN)
public Response getLastDateFile(@PathParam("alias") String alias, @PathParam("path") String path,
@DefaultValue("anonymous") @HeaderParam("username") String username,
@DefaultValue("anonymous") @HeaderParam("password") String psw,
@DefaultValue("pasv") @HeaderParam("mode") String mode,
@DefaultValue("FTPS") @HeaderParam("type") String type, @DefaultValue("21") @HeaderParam("port") int port) {
Response r = init(alias, type, username, psw, mode, port);
if (!(r.getStatus() == Response.Status.ACCEPTED.getStatusCode())) {// on verifie que l'init s'est bien passer
return r;
}
String date;
try {
date = ftp.getModificationTime(path);
if(date ==null) {
return Response.status(Response.Status.FORBIDDEN)
.entity("file " + path + " not exist on the ftp server ")
.build();
}
System.out.println(date);
} catch (IOException e) {
return Response.status(Response.Status.FORBIDDEN)
.entity("file " + path + " not exist on the ftp server or you don't have the right to download it")
.build();
} finally {
try {
ftp.disconnect();
} catch (IOException e) {
}
}
return Response.ok(date).build();
}
/*
* Méthode non fonctionnel qui permet de récuperer un dossier, de le zipper et
* de l'envoyer au client
*
*/
/*
@GET
@Secured
@Path("{alias}/dir/{path: .*}")
@Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response downloadRep(@PathParam("alias") String alias, @PathParam("path") String path,
@DefaultValue("anonymous") @HeaderParam("username") String username,
@DefaultValue("anonymous") @HeaderParam("password") String psw,
@DefaultValue("pasv") @HeaderParam("mode") String mode,
@DefaultValue("FTP") @HeaderParam("type") String type, @DefaultValue("21") @HeaderParam("port") int port) {
Response r = init(alias, type, username, psw, mode, port);
if (!(r.getStatus() == Response.Status.ACCEPTED.getStatusCode())) {// on verifie que l'init s'est bien passer
return r;
}
if (path.endsWith("/")) {
path = path.substring(0, path.length() - 1);
}
String dirname = path.substring(path.lastIndexOf("/") + 1, path.length());
StreamingOutput stream = new StreamingOutput() {
@Override
public void write(OutputStream output) throws IOException, WebApplicationException {
ZipOutputStream zip = new ZipOutputStream(new BufferedOutputStream(output));
//Utils.zip(ftp, path, zip);
output.flush();
output.close();
}
};
ResponseBuilder response = Response.ok(stream);
response.header("Content-Disposition", "attachment; filename=\"" + dirname + "\"");
return response.build();
}*/
/**
* Methode qui permet de supprimer un fichier sur le serveur
*
* @param alias l'alias du serveur
* @param path le chemin d'acces vers le fichier
* @param username le username par defaut anonymous
* @param psw le mot de passe par defaut anonymous
* @param mode le mode d'echange avec le serveur (PASV ou PORT) par defaut
* en PASV
* @param type FTP ou FTPS par defaut FTP
* @param port le port d'ecoute
* @return un statut http
*/
@DELETE
@Secured
@Path("{alias}/file/{path: .*}")
@Produces(MediaType.TEXT_PLAIN)
public Response deleteFile(@PathParam("alias") String alias, @PathParam("path") String path,
@DefaultValue("anonymous") @HeaderParam("username") String username,
@DefaultValue("anonymous") @HeaderParam("password") String psw,
@DefaultValue("pasv") @HeaderParam("mode") String mode,
@DefaultValue("FTP") @HeaderParam("type") String type, @DefaultValue("21") @HeaderParam("port") int port) {
Response r = init(alias, type, username, psw, mode, port);
if (!(r.getStatus() == Response.Status.ACCEPTED.getStatusCode())) {// on verifie que l'init s'est bien passer
return r;
}
if (path.endsWith("/")) {
path = path.substring(0, path.length() - 1);
}
try {
if (!ftp.deleteFile(path)) {
return Response.status(Response.Status.FORBIDDEN).entity("can't delete the file").build();
}
} catch (IOException e) {
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity("try later pls !").build();
} finally {
try {
ftp.disconnect();
} catch (IOException e) {
}
}
return Response.status(Response.Status.OK).entity("file deleted").build();
}
/**
* Methode qui permet de supprimer un dossier sur le serveur
*
* @param alias l'alias du serveur
* @param path le chemin d'acces vers le dossier
* @param username le username par defaut anonymous
* @param psw le mot de passe par defaut anonymous
* @param mode le mode d'echange avec le serveur (PASV ou PORT) par defaut
* en PASV
* @param type FTP ou FTPS par defaut FTP
* @param port le port d'ecoute
* @return un statut http
*/
@DELETE
@Secured
@Path("{alias}/dir/{path: .*}")
@Produces(MediaType.TEXT_PLAIN)
public Response deleteDir(@PathParam("alias") String alias, @PathParam("path") String path,
@DefaultValue("anonymous") @HeaderParam("username") String username,
@DefaultValue("anonymous") @HeaderParam("password") String psw,
@DefaultValue("pasv") @HeaderParam("mode") String mode,
@DefaultValue("FTP") @HeaderParam("type") String type, @DefaultValue("21") @HeaderParam("port") int port) {
Response r = init(alias, type, username, psw, mode, port);
if (!(r.getStatus() == Response.Status.ACCEPTED.getStatusCode())) {// on verifie que l'init s'est bien passer
return r;
}
if (path.endsWith("/")) {
path = path.substring(0, path.length() - 1);
}
try {
Utils.removedir(ftp, path);
} catch (IOException e) {
return Response.status(Response.Status.FORBIDDEN)
.entity("can't delete one file from the folder" + path + "!").build();
} finally {
try {
ftp.disconnect();
} catch (IOException e) {
}
}
return Response.ok("successfully removed").build();
}
/**
* methode qui permet de rename un fichier ou un dossier sur le serveur
*
* @param alias l'alias du serveur
* @param path le chemin d'acces
* @param username le username par defaut anonymous
* @param psw le mot de passe par defaut anonymous
* @param mode le mode d'echange avec le serveur (PASV ou PORT) par defaut
* en PASV
* @param type FTP ou FTPS par defaut FTP
* @param rename le nouveau nom
* @param port le port d'ecoute
* @return un statut http
*/
@PUT
@Secured
@Path("{alias}/{path: .*}")
@Produces(MediaType.TEXT_PLAIN)
public Response rename(@PathParam("alias") String alias, @PathParam("path") String path,
@DefaultValue("anonymous") @HeaderParam("username") String username,
@DefaultValue("anonymous") @HeaderParam("password") String psw,
@DefaultValue("pasv") @HeaderParam("mode") String mode,
@DefaultValue("FTP") @HeaderParam("type") String type, @QueryParam("name") String rename,
@DefaultValue("21") @HeaderParam("port") int port) {
Response r = init(alias, type, username, psw, mode, port);
if (!(r.getStatus() == Response.Status.ACCEPTED.getStatusCode())) {// on verifie que l'init s'est bien passer
return r;
}
if (path.endsWith("/")) {
path = path.substring(0, path.length() - 1);
}
String tmp = path.substring(0, path.lastIndexOf("/") + 1);
try {
if (!ftp.rename(path, tmp + rename)) {
return Response.status(Response.Status.BAD_REQUEST).build();
}
} catch (IOException e) {
return Response.status(Response.Status.FORBIDDEN).entity("can't rename one file " + path + "!").build();
} finally {
try {
ftp.disconnect();
} catch (IOException e) {
}
}
return Response.ok("successfully renamed to " + rename).build();
}
@PUT
@Secured
@Path("{alias}/relocate/{path: .*}")
@Produces(MediaType.TEXT_PLAIN)
public Response relocate(@PathParam("alias") String alias, @PathParam("path") String path,
@DefaultValue("anonymous") @HeaderParam("username") String username,
@DefaultValue("anonymous") @HeaderParam("password") String psw,
@DefaultValue("pasv") @HeaderParam("mode") String mode,
@DefaultValue("FTP") @HeaderParam("type") String type, @QueryParam("to") String rename,
@DefaultValue("21") @HeaderParam("port") int port) {
Response r = init(alias, type, username, psw, mode, port);
if (!(r.getStatus() == Response.Status.ACCEPTED.getStatusCode())) {// on verifie que l'init s'est bien passer
return r;
}
// if (path.endsWith("/")) {
// path = path.substring(0, path.length() - 1);
// }
try {
if (!ftp.rename(path, rename)) {
return Response.status(Response.Status.BAD_REQUEST).build();
}
} catch (IOException e) {
return Response.status(Response.Status.FORBIDDEN).entity("can't rename one file " + path + "!").build();
} finally {
try {
ftp.disconnect();
} catch (IOException e) {
}
}
return Response.ok("successfully renamed to " + rename).build();
}
/**
* Methode qui permet d'upload un fichier sur le serveur, pour envoyer un
* dossier,il faut prealablement le zipper
*
* @param alias l'alias du serveur
* @param path le chemin de destination
* @param uploadedInputStream le fichier à upload
* @param fileDetail details du fichier à upload
* @param mode le mode d'echange avec le serveur (PASV ou PORT)
* par defaut
* @param type FTP ou FTPS par defaut FTP
* @param username le username par defaut anonymous
* @param psw le mot de passe par defaut anonymous
* @param port le port d'ecoute
* @return un statut http
*/
@POST
@Secured
@Path("{alias}/file/{path: .*}")
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.TEXT_PLAIN)
public Response uploadHttpFile(@PathParam("alias") String alias, @PathParam("path") String path,
@FormDataParam("file") InputStream uploadedInputStream,
@FormDataParam("file") FormDataContentDisposition fileDetail,
@DefaultValue("pasv") @HeaderParam("mode") String mode,
@DefaultValue("FTP") @HeaderParam("type") String type,
@DefaultValue("anonymous") @HeaderParam("username") String username,
@DefaultValue("anonymous") @HeaderParam("password") String psw,
@DefaultValue("21") @HeaderParam("port") int port) {
Response r = init(alias, type, username, psw, mode, port);
if (!(r.getStatus() == Response.Status.ACCEPTED.getStatusCode())) {// on verifie que l'init s'est bien passer
return r;
}
if (path.endsWith("/")) {
path = path.substring(0, path.length() - 1);
}
try {
if (!Utils.uploadFile(ftp, path + "/" + fileDetail.getFileName(), uploadedInputStream)) {
return Response.status(Response.Status.BAD_REQUEST).build();
}
} catch (IOException e) {
return Response.status(Response.Status.FORBIDDEN)
.entity("can't upload the file " + fileDetail.getFileName() + "!").build();
} finally {
try {
ftp.disconnect();
} catch (IOException e) {
}
}
String output = "File uploaded to: " + path;
return Response.status(Response.Status.OK).entity(output).build();
}
/**
* Methode qui permet de creer un repertoire sur le serveur
*
* @param alias l'alias du serveur
* @param path le chemin d'acces vers le repertoire parent
* @param username le username par defaut anonymous
* @param psw le mot de passe par defaut anonymous
* @param mode le mode d'echange avec le serveur (PASV ou PORT) par defaut
* en PASV
* @param type FTP ou FTPS par defaut FTP
* @param name le nom du reperoire à creer
* @param port le port d'ecoute
* @return un statut http
*/
@POST
@Secured
@Path("{alias}/new-dir/{path: .*}")
@Produces(MediaType.TEXT_PLAIN)
public Response createDir(@PathParam("alias") String alias, @PathParam("path") String path,
@DefaultValue("anonymous") @HeaderParam("username") String username,
@DefaultValue("anonymous") @HeaderParam("password") String psw,
@DefaultValue("pasv") @HeaderParam("mode") String mode,
@DefaultValue("FTP") @HeaderParam("type") String type, @QueryParam("name") String name,
@DefaultValue("21") @HeaderParam("port") int port) {
Response r = init(alias, type, username, psw, mode, port);
if (!(r.getStatus() == Response.Status.ACCEPTED.getStatusCode())) {// on verifie que l'init s'est bien passer
return r;
}
if (path.endsWith("/")) {
path = path.substring(0, path.length() - 1);
}
try {
if (!ftp.makeDirectory(path + "/" + name)) {
return Response.status(Response.Status.BAD_REQUEST).build();
}
} catch (IOException e) {
return Response.status(Response.Status.FORBIDDEN).entity("can't create the folder" + path + "!").build();
} finally {
try {
ftp.disconnect();
} catch (IOException e) {
}
}
return Response.ok("directory " + name + " created").build();
}
}