diff --git a/README.md b/README.md index 6ba59f5de4c66d6ee3d8b2522bf1341b76ec091a..9852054d77f03c53382aa8186315d4177a5d8158 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,246 @@ #Ferhat_HOCINE #Youva_MOKEDDES #M1GL -#SR_PROJET2_ServeurFTP \ No newline at end of file +#SR_PROJET2_ServeurFTP + + +## 1- Intoduction +L'objectif du projet est désormais de mettre en œuvre un serveur conforme au protocole applicatif File Transfer Protocol (FTP). Ce serveur doit donc utiliser l'API Socket TCP pour échanger avec un client FTP (e.g., Filezilla) pour stocker et envoyer des fichiers en respectant le standard FTP. + +## 2-Exécution: +Dans le fichier racine on exécute la commande : +->>> mvn package +//pour compliler le projet +puis la commande : +->>> mvn javadoc:javadoc +//pour générer la documentation: +puis la commande : +->>> java -jar target/serveurFTP-1.0-SNAPSHOT.jar +pour exécuter le projet +ensuite il faut connecter le client avec filezilla par exemple : +host:localhost, username: anonymous, password: anonymous, port: 2020 + + +## 3-Architecture +a)-Gestion d'erreur : +la gestion d'erreur est sois faite par un message ecrit par le bufferWriter ou bien par un levé d'exception . +exemple : +dans le fichier MKD(request/mkd) qui represente la commande MKD: +les erreurs de doits on été géré par l'erreur "550" écrite par le bufferwriter et les erreurs de connection par l exception IOException: +** + public void send() throws IOException{ + if (this.ftp.getSocket() == null ) { + throw new IOException("Ftp server error"); + + } + try { + if(!this.DIR.equals("")) { + File directory=new File(this.ftp.getDirectory()); + if(directory.canWrite() || directory.canExecute() ) { + File directory1=new File(this.ftp.getDirectory()+"/"+this.DIR); + if (directory1.exists()) { + this.ftp.getBufferedWriter().write("550 already existe.\r\n"); + this.ftp.getBufferedWriter().flush(); + } + else { + if(directory1.mkdir()) { + this.ftp.getBufferedWriter().write("250 directory created.\r\n"); + this.ftp.getBufferedWriter().flush(); + } + else { + this.ftp.getBufferedWriter().write("550 rights error.\r\n"); + this.ftp.getBufferedWriter().flush(); + } + } + } + else { + this.ftp.getBufferedWriter().write("550 rights error.\r\n"); + this.ftp.getBufferedWriter().flush(); + } + } + } + catch(IOException e){ + throw new IOException("Connexion failed"); + } + } +** + +a) interface request(request/request.java): +l'interface request a été implementer par toutes les commande dans le dossier request, graçe à la méthode send chaque class de commande envoie la réponse du server à la commande qu'il a reçu. + + + +## 3-Parcours du code (code samples) + +a) pass/pass.java +** + public void send() throws IOException{ + if (this.ftp.getSocket() == null ) { + throw new IOException("Ftp server error"); + + } + try { + if (this.pass.equals("anonymous")){ + this.ftp.getBufferedWriter().write("230 Login successful.\r\n"); + this.ftp.getBufferedWriter().flush(); + this.ftp.connect(); + }else{ + this.ftp.getBufferedWriter().write("530 unknown Password\r\n"); + this.ftp.getBufferedWriter().flush(); + } + } + catch(IOException e){ + throw new IOException("Connexion failed"); + } + } +** +dans pass on gére le mot de passe de l'utilisateur. +si le mot de pass est égale a "anonymous" alors le code renvoyé est "230" pour dire que la connection est établie puis on appele la méthode connect qui transforme notre boolean de connection dans la class ftp vers True. +dans le cas contraire un code d'erreur "530" est retourné pour dire que le mot de passe n'est pas conforme. +en cas d'autre erreurs un exception est levé. + + + +b) request/CDUP.java +** + public void send() throws IOException{ + if (this.ftp.getSocket() == null ) { + throw new IOException("Ftp server error"); + } + try { + String newPath=this.ftp.getDirectory(); + String[] pa=newPath.split("/"); + newPath=""; + if(pa.length>2) { + for(int i=1;i<pa.length-1;i++) { + newPath+="/"+pa[i]; + } + } + else { + newPath="/"; + } + this.ftp.SetDirectory(newPath); + this.ftp.getBufferedWriter().write("250 success to exit.\r\n"); + this.ftp.getBufferedWriter().flush(); + } + catch(IOException e){ + throw new IOException("Connexion failed"); + } + } +** +la méthode send de la class CDUP: +la Commande CDUP permet d'accedé au fichier parents du dossier en cours dans notre code. +on a commencé par récuperer le path du dossier en cours puis le coupé celon les "/" pour ensuite vérifier si il contient plus de d'un sous répertoir si c'est le cas on assemble tous les sous répertoir sauf le dernier dans un string avec un "/" en chaque nom de répertoir afin d'avoir le path du parents. +dans le cas contraire le parents est donc la racine "/". +finalement on affecte ce path et éxrit que la commande CDUP a été éxécuté avec succes. + + +c) request/RNFR.java +la commande RNFR permet de sauvgarder la valeur de fichier ou dossier que on va renomer avec la commande RNTO + + +** + public void send() throws IOException{ + if (this.ftp.getSocket() == null ) { + throw new IOException("Ftp server error"); + + } + try { + File file= new File(this.ftp.getDirectory()+"/"+this.name); + if(file.exists()) { + this.ftp.SetRename(this.ftp.getDirectory()+"/"+this.name); + this.ftp.getBufferedWriter().write("250 found.\r\n"); + this.ftp.getBufferedWriter().flush(); + } + else { + this.ftp.getBufferedWriter().write("553 not found.\r\n"); + this.ftp.getBufferedWriter().flush(); + } + } + + catch(IOException e){ + throw new IOException("Connexion failed"); + } + } +** + +dans la méthode send de la class RNFR on crée un file avec le chemin du dossier ou file a rénomer puis on vérifier si ce file existe. +si il existe alors le chemin est sauvgarder dans une variable static de la class ftp graçe au setter SetRename et le code "250" est renvoyé pour dire que le file a été trouvé. +dans le cas contraire le code "553" est renvoyé pour dire que le file est introuvable. +et en cas d'erreur une excéption et levé. + +d) request/RNTO.java +la commande permet de renomer un dossier ou fichier avec un chemin connu par un nouveau nom passé en paramètre de la commande +** + public void send() throws IOException{ + if (this.ftp.getSocket() == null ) { + throw new IOException("Ftp server error"); + + } + try { + File file= new File(this.ftp.getRename()); + File file2= new File(this.ftp.getDirectory()+"/"+this.name); + + if(file.renameTo(file2)){ + this.ftp.getBufferedWriter().write("250 file '"+this.ftp.getRename()+"' renamed to '"+this.ftp.getDirectory()+"/"+this.name+"'.\r\n"); + this.ftp.getBufferedWriter().flush(); + } + else { + this.ftp.getBufferedWriter().write("553 not found.\r\n"); + this.ftp.getBufferedWriter().flush(); + } + } + + catch(IOException e){ + throw new IOException("Connexion failed"); + } + } +** +dans méthode send de la class RNTO on crée deux fichier l'un avec le paramètre passé dans la commande est l'autre avec la variable sauvgardé par la commande RNTO. +ensuite on applique la méthode renameTo sur le file de la variable sauvgardé avec comme paramètre le 2 file ce qui permettera le renommage du dossier ou fichier avec le chemin sauvgardé par le nouveau nom passé en paramètre. +en cas de succès le code "250" est écrit pour annoncé le succès de l'opération. +dans le cas contraire le code "553" est écrit pour dire que le file n'a pas été trouvé. +et en cas d'erreur une excéption et levé. + + +e)request/TYPE.java +la commande TYPE permet de changer de mode +** + public void send() throws IOException{ + if (this.ftp.getSocket() == null ) { + throw new IOException("Ftp server error"); + } + try { + switch(this.type) { + case "A" : + this.type = "ASCII"; + break; + case "E" : + this.type = "EBCDIC"; + break; + case "I" : + this.type = "Switching to Binary mode"; + break; + case "L" : + this.type = "local"; + break; + default: + this.ftp.getBufferedWriter().write("400 incorrect type.\r\n"); + this.ftp.getBufferedWriter().flush(); + return; + } + this.ftp.getBufferedWriter().write("200 Type "+this.type+".\r\n"); + this.ftp.getBufferedWriter().flush(); + } + catch(IOException e){ + throw new IOException("Connexion failed"); + } + } +** +la méthode send parcour les différents choix de Type et renvoie la mode correspondant. +dans le cas ou le paramètre donné ne fais pas parti des choix de type le code "400" est écrit pour dire que le choix est incorrecte. +dans le cas contraire le choix est appliqué et le code "220" est écrit pour dire que on switch au mode correspondant au choix passé en paramètre. +et en cas d'erreur une excéption et levé. + + +## 4-UML -> racine du projet (UML.png) diff --git a/serveurFTP/.gitignore b/serveurFTP/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..b83d22266ac8aa2f8df2edef68082c789727841d --- /dev/null +++ b/serveurFTP/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/uml.png b/uml.png new file mode 100644 index 0000000000000000000000000000000000000000..707b353ab7a791b1d4fb184b70980d4d371c0085 Binary files /dev/null and b/uml.png differ