From f06bab353985a2f230c1dfdb41bb0abb36aa6bbd Mon Sep 17 00:00:00 2001 From: fabiovandewaeter <vandewaeter.fabio@gmail.com> Date: Thu, 20 Mar 2025 19:49:07 +0100 Subject: [PATCH] =?UTF-8?q?save=20entrain=20de=20g=C3=A9rer=20upload=20dos?= =?UTF-8?q?siers?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 5 +- dossier_serveur_ftp/fichier2 | 1 + .../java/fil/sr2/flopbox/FTPResource.java | 21 +++++ src/main/java/fil/sr2/flopbox/FTPService.java | 94 +++++++++++++++++++ 4 files changed, 120 insertions(+), 1 deletion(-) create mode 100644 dossier_serveur_ftp/fichier2 diff --git a/README.md b/README.md index ef4fe88..7b84331 100644 --- a/README.md +++ b/README.md @@ -104,12 +104,15 @@ unzip dossier1.zip - upload fichier : ```shell -curl -X POST -H "Content-Type: application/json" -H "Authorization: Bearer valid-token-1" -d '{"alias":"mon-ftp","host":"localhost","port":2121}' http://localhost:8080/ftps +curl -X PUT -H "Authorization: Bearer valid-token-1" -H "X-FTP-User: user" -H "X-FTP-Pass: password" --upload-file fichier2 http://localhost:8080/ftps/mon-ftp/fichier2 ``` - upload dossier : ```shell +curl -X PUT -H "Authorization: Bearer valid-token-1" -H "X-FTP-User: user" -H "X-FTP-Pass: password" --upload-file dossier2.zip http://localhost:8080/ftps/mon-ftp/dossier2.zip + +curl -X POST -H "Authorization: Bearer valid-token-1" -H "X-FTP-User: user" -H "X-FTP-Pass: password" -H "Content-Type: application/octet-stream" --data-binary @dossier2.zip http://localhost:8080/ftps/mon-ftp/upload-dir/ ``` **Note comprise entre 12 et 13 si—en plus—le proxy FlopBox, permet de télécharger (download) et téléverser (upload) un gros fichier binaire (image, vidéo, etc.):** diff --git a/dossier_serveur_ftp/fichier2 b/dossier_serveur_ftp/fichier2 new file mode 100644 index 0000000..deae8dc --- /dev/null +++ b/dossier_serveur_ftp/fichier2 @@ -0,0 +1 @@ +FICHIER2 diff --git a/src/main/java/fil/sr2/flopbox/FTPResource.java b/src/main/java/fil/sr2/flopbox/FTPResource.java index 9281a6a..5c48aca 100644 --- a/src/main/java/fil/sr2/flopbox/FTPResource.java +++ b/src/main/java/fil/sr2/flopbox/FTPResource.java @@ -162,6 +162,27 @@ public class FTPResource { } } + @POST + @Path("/{alias}/upload-dir/{path: .*}") + @Consumes(MediaType.APPLICATION_OCTET_STREAM) + public Response uploadDirectory( + @PathParam("alias") String alias, + @PathParam("path") String path, + @HeaderParam("X-FTP-User") String user, + @HeaderParam("X-FTP-Pass") String pass, + InputStream zipStream) { + + System.out.println("uploadDirectory()"); + try { + ftpService.uploadDirectoryAsZip(alias, path, user, pass, zipStream); + return Response.ok().build(); + } catch (FTPException e) { + return Response.status(e.getStatus()).entity(e.getMessage()).build(); + } catch (IOException e) { + return Response.serverError().entity("Erreur FTP : " + e.getMessage()).build(); + } + } + // POST pour créer une ressource (fichier ou répertoire) @POST @Path("/{alias}/{path: .+}") diff --git a/src/main/java/fil/sr2/flopbox/FTPService.java b/src/main/java/fil/sr2/flopbox/FTPService.java index c380c81..90fe9e0 100644 --- a/src/main/java/fil/sr2/flopbox/FTPService.java +++ b/src/main/java/fil/sr2/flopbox/FTPService.java @@ -9,6 +9,10 @@ import java.util.ArrayList; import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; +import java.util.zip.ZipInputStream; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; public class FTPService { @@ -257,4 +261,94 @@ public class FTPService { } } } + + public void uploadDirectoryAsZip(String alias, String targetPath, String user, String pass, InputStream zipStream) + throws IOException, FTPException { + + System.out.println("[DEBUG] Début upload ZIP vers: " + targetPath); + FTPClient ftp = FTPClientFactory.createClient(alias); + try { + if (!ftp.login(user, pass)) { + throw new FTPException("Authentification FTP échouée", 401); + } + ftp.enterLocalPassiveMode(); + ftp.setFileType(FTPClient.BINARY_FILE_TYPE); + + try (ZipInputStream zis = new ZipInputStream(zipStream)) { + ZipEntry entry; + while ((entry = zis.getNextEntry()) != null) { + String entryName = entry.getName(); + String fullPath = constructPath(targetPath, entryName); + System.out.println("[DEBUG] Traitement entrée: " + entry.getName() + + " → " + fullPath); + + if (entry.isDirectory()) { + createDirectories(ftp, fullPath); + } else { + createParentDirectories(ftp, fullPath); + uploadFileEntry(ftp, fullPath, zis); + } + zis.closeEntry(); + } + } + } finally { + FTPClientFactory.disconnect(ftp); + } + System.out.println("[DEBUG] Upload ZIP terminé avec succès"); + } + + private String constructPath(String basePath, String entryPath) { + // Ignorer le premier segment du chemin (dossier racine du ZIP) + String[] parts = entryPath.split("/"); + if (parts.length > 1) { + String normalizedEntry = String.join("/", Arrays.copyOfRange(parts, 1, parts.length)); + return basePath.isEmpty() ? normalizedEntry : basePath + "/" + normalizedEntry; + } + return entryPath; // Cas où l'entrée est déjà à la racine + } + + private void createParentDirectories(FTPClient ftp, String filePath) throws IOException { + int lastSlash = filePath.lastIndexOf('/'); + if (lastSlash != -1) { + String parentDir = filePath.substring(0, lastSlash); + createDirectories(ftp, parentDir); + } + } + + private void createDirectories(FTPClient ftp, String path) throws IOException { + String normalizedPath = path.replaceAll("/+", "/"); + if (normalizedPath.startsWith("/")) { + ftp.changeWorkingDirectory("/"); + } + + String[] parts = normalizedPath.split("/"); + StringBuilder currentPath = new StringBuilder(); + + for (String part : parts) { + if (part.isEmpty()) + continue; + + currentPath.append(part).append("/"); + + if (!ftp.changeWorkingDirectory(currentPath.toString())) { + if (!ftp.makeDirectory(currentPath.toString())) { + throw new IOException("Échec création dossier: " + currentPath); + } + ftp.changeWorkingDirectory(currentPath.toString()); + } + } + } + + private void uploadFileEntry(FTPClient ftp, String path, InputStream is) + throws IOException, FTPException { + + // Supprimer URLDecoder.decode() ! + String decodedPath = path; + + try (InputStream bais = is) { + if (!ftp.storeFile(decodedPath, bais)) { + throw new FTPException("Échec upload: " + decodedPath, 500); + } + } + } } -- GitLab