From 27789be2025e2b0870ed62aac3154ae818af5310 Mon Sep 17 00:00:00 2001 From: EndMove Date: Sat, 5 Mar 2022 17:21:46 +0100 Subject: [PATCH 01/11] Fixed spelling mistake in project name, restructuring. Correction of Golang convention error. --- .idea/ StorBackEnd.iml | 3 +-- .idea/StoreBackEnd.iml | 9 ++++++++ cmd/main.go | 21 +++++++++---------- go.mod | 2 +- pkg/config/AppConfig.go | 2 +- pkg/network/ClientMulticast.go | 9 ++++---- pkg/network/ServerUnicast.go | 4 ++-- pkg/protocol/managers/RequestManager.go | 2 +- pkg/protocol/repository/ProtocolRepository.go | 2 +- pkg/protocol/rules/readers/EraseFileRule.go | 2 +- pkg/protocol/rules/writers/HelloRule.go | 2 +- resources/AppConfig.json | 2 +- 12 files changed, 33 insertions(+), 27 deletions(-) create mode 100644 .idea/StoreBackEnd.iml diff --git a/.idea/ StorBackEnd.iml b/.idea/ StorBackEnd.iml index 5e764c4..eeb7bce 100644 --- a/.idea/ StorBackEnd.iml +++ b/.idea/ StorBackEnd.iml @@ -1,9 +1,8 @@ - + - \ No newline at end of file diff --git a/.idea/StoreBackEnd.iml b/.idea/StoreBackEnd.iml new file mode 100644 index 0000000..5e764c4 --- /dev/null +++ b/.idea/StoreBackEnd.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/cmd/main.go b/cmd/main.go index 2807cd8..5add847 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -1,30 +1,30 @@ package main import ( - "StorBackEnd/pkg/config" - "StorBackEnd/pkg/network" - "StorBackEnd/pkg/protocol/managers" - "StorBackEnd/pkg/protocol/repository" - "StorBackEnd/pkg/protocol/rules/readers" - "StorBackEnd/pkg/protocol/rules/writers" + "StoreBackEnd/pkg/config" + "StoreBackEnd/pkg/network" + "StoreBackEnd/pkg/protocol/managers" + "StoreBackEnd/pkg/protocol/repository" + "StoreBackEnd/pkg/protocol/rules/readers" + "StoreBackEnd/pkg/protocol/rules/writers" "time" ) const ( - FILE_PATH = "resources/AppConfig.json" + FilePath = "resources/AppConfig.json" ) func main() { - println("StorBackEnd started !") + println("StoreBackEnd started !") // Loading App config - appConfig, err := config.Read(FILE_PATH) + appConfig, err := config.Read(FilePath) if err != nil { println("Impossible de charger la configuration du server : " + err.Error()) return } - println("Adresse multicast : " + appConfig.MulticastAddress) + println("Address multicast : " + appConfig.MulticastAddress) protocolRepository := repository.CreateProtocolRepository() @@ -43,5 +43,4 @@ func main() { server := network.ServerUnicast{Network: "tcp", Port: appConfig.UnicastPort, ReqManager: &requestManager} server.Run() - } diff --git a/go.mod b/go.mod index 6a92a91..7b67ed0 100644 --- a/go.mod +++ b/go.mod @@ -1 +1 @@ -module StorBackEnd +module StoreBackEnd diff --git a/pkg/config/AppConfig.go b/pkg/config/AppConfig.go index 9b5e2e5..018a884 100644 --- a/pkg/config/AppConfig.go +++ b/pkg/config/AppConfig.go @@ -8,7 +8,7 @@ type AppConfig struct { // multicastSecond Contient le nombre de seconde entre chaque annonce MulticastSecond int `json:"multicastSecond"` - // domain Domain du StorBackEnd + // domain Domain du StoreBackEnd Domain string `json:"domain"` // unicastPort Contient le port unicast auquel le FileFrontEnd se connecte diff --git a/pkg/network/ClientMulticast.go b/pkg/network/ClientMulticast.go index 8a26121..6bb46f5 100644 --- a/pkg/network/ClientMulticast.go +++ b/pkg/network/ClientMulticast.go @@ -1,8 +1,8 @@ package network import ( - "StorBackEnd/pkg/protocol/repository" - "StorBackEnd/pkg/protocol/rules/writers" + "StoreBackEnd/pkg/protocol/repository" + "StoreBackEnd/pkg/protocol/rules/writers" "fmt" "net" "time" @@ -25,7 +25,7 @@ type ClientMulticast struct { // address Adresse de multicast address string - // address Domain de du StorBackEnd + // address Domain de du StoreBackEnd domain string // port Port de connexion en unicast @@ -57,7 +57,7 @@ func (cMult ClientMulticast) Run() { } for { - con.Write([]byte(cmd)) + _, _ = con.Write([]byte(cmd)) time.Sleep(time.Second * cMult.second) } @@ -71,7 +71,6 @@ func (cMult ClientMulticast) ResolveAddr() (*net.UDPAddr, bool) { println(errResUdp.Error()) return nil, true } - return addr, false } diff --git a/pkg/network/ServerUnicast.go b/pkg/network/ServerUnicast.go index ecb24ed..2ff83c0 100644 --- a/pkg/network/ServerUnicast.go +++ b/pkg/network/ServerUnicast.go @@ -1,7 +1,7 @@ package network import ( - "StorBackEnd/pkg/protocol/managers" + "StoreBackEnd/pkg/protocol/managers" "bufio" "fmt" "net" @@ -36,7 +36,7 @@ func (server ServerUnicast) Run() { } result := server.ReqManager.Execute(line) - con.Write(append([]byte(result), '\n')) // TODO : ATTENTION laisser les \n + _, _ = con.Write(append([]byte(result), '\n')) // TODO : ATTENTION laisser les \n } } diff --git a/pkg/protocol/managers/RequestManager.go b/pkg/protocol/managers/RequestManager.go index 9c0b7d2..4228335 100644 --- a/pkg/protocol/managers/RequestManager.go +++ b/pkg/protocol/managers/RequestManager.go @@ -1,6 +1,6 @@ package managers -import "StorBackEnd/pkg/protocol/repository" +import "StoreBackEnd/pkg/protocol/repository" type RequestManager struct { Repository *repository.ProtocolRepository diff --git a/pkg/protocol/repository/ProtocolRepository.go b/pkg/protocol/repository/ProtocolRepository.go index 9e613c5..e5ee8ac 100644 --- a/pkg/protocol/repository/ProtocolRepository.go +++ b/pkg/protocol/repository/ProtocolRepository.go @@ -1,6 +1,6 @@ package repository -import "StorBackEnd/pkg/protocol" +import "StoreBackEnd/pkg/protocol" func CreateProtocolRepository() *ProtocolRepository { return &ProtocolRepository{ diff --git a/pkg/protocol/rules/readers/EraseFileRule.go b/pkg/protocol/rules/readers/EraseFileRule.go index 0d75f14..e6a9de8 100644 --- a/pkg/protocol/rules/readers/EraseFileRule.go +++ b/pkg/protocol/rules/readers/EraseFileRule.go @@ -1,6 +1,6 @@ package readers -import "StorBackEnd/pkg/protocol" +import "StoreBackEnd/pkg/protocol" // EraseFileRuleName Identifiant de cette règle const EraseFileRuleName = "ffe_erasefile" diff --git a/pkg/protocol/rules/writers/HelloRule.go b/pkg/protocol/rules/writers/HelloRule.go index e2d3cf6..e61f26b 100644 --- a/pkg/protocol/rules/writers/HelloRule.go +++ b/pkg/protocol/rules/writers/HelloRule.go @@ -1,6 +1,6 @@ package writers -import "StorBackEnd/pkg/protocol" +import "StoreBackEnd/pkg/protocol" const HelloRuleName = "sbe_hello" diff --git a/resources/AppConfig.json b/resources/AppConfig.json index a25c31e..d878c64 100644 --- a/resources/AppConfig.json +++ b/resources/AppConfig.json @@ -1,6 +1,6 @@ { "multicastAddress" : "226.66.66.1:42500", "multicastSecond" : 10, - "domain" : "benjamin", + "domain" : "lightcontainer.storebacked-01", "unicastPort" : 58000 } \ No newline at end of file From b942166f69dfb4fa2054ddcca02e8988d9ea8c9e Mon Sep 17 00:00:00 2001 From: EndMove Date: Sat, 5 Mar 2022 17:27:19 +0100 Subject: [PATCH 02/11] idea name fixing --- .idea/ StorBackEnd.iml | 8 -------- .idea/modules.xml | 2 +- 2 files changed, 1 insertion(+), 9 deletions(-) delete mode 100644 .idea/ StorBackEnd.iml diff --git a/.idea/ StorBackEnd.iml b/.idea/ StorBackEnd.iml deleted file mode 100644 index eeb7bce..0000000 --- a/.idea/ StorBackEnd.iml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml index 2dd3b57..e9fb66c 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -2,7 +2,7 @@ - + \ No newline at end of file From 8c443d43e4bdba9c11347dd5dcd281170ab9d51e Mon Sep 17 00:00:00 2001 From: EndMove Date: Sat, 5 Mar 2022 18:32:27 +0100 Subject: [PATCH 03/11] Fixing some issues, backed project study --- cmd/main.go | 3 ++- pkg/config/JsonConfigReader.go | 3 ++- pkg/network/ClientMulticast.go | 16 ++++++++-------- pkg/network/ServerUnicast.go | 2 -- pkg/protocol/IProtocolWriter.go | 2 +- pkg/protocol/RegexMatcher.go | 1 - pkg/protocol/managers/RequestManager.go | 2 +- pkg/protocol/repository/ProtocolRepository.go | 1 - pkg/protocol/rules/readers/EraseFileRule.go | 1 - resources/AppConfig.json | 2 +- 10 files changed, 15 insertions(+), 18 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index 5add847..d312423 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -24,7 +24,8 @@ func main() { return } - println("Address multicast : " + appConfig.MulticastAddress) + println("Multicast Address : " + appConfig.MulticastAddress) + println("StoreBacked Domain : " + appConfig.Domain) protocolRepository := repository.CreateProtocolRepository() diff --git a/pkg/config/JsonConfigReader.go b/pkg/config/JsonConfigReader.go index 1cd3e96..f063606 100644 --- a/pkg/config/JsonConfigReader.go +++ b/pkg/config/JsonConfigReader.go @@ -5,6 +5,8 @@ import ( "io/ioutil" ) +// Read Méthode permettant de lire le fichier de donfiguration +// return AppConfig func Read(filePath string) (*AppConfig, error) { config := AppConfig{} file, err := ioutil.ReadFile(filePath) @@ -16,6 +18,5 @@ func Read(filePath string) (*AppConfig, error) { if errJson != nil { return nil, errJson } - return &config, nil } diff --git a/pkg/network/ClientMulticast.go b/pkg/network/ClientMulticast.go index 6bb46f5..097f18f 100644 --- a/pkg/network/ClientMulticast.go +++ b/pkg/network/ClientMulticast.go @@ -39,18 +39,18 @@ type ClientMulticast struct { } // Run Cette méthode démarre une commmunication multicast -func (cMult ClientMulticast) Run() { - addr, done := cMult.ResolveAddr() +func (client ClientMulticast) Run() { + addr, done := client.ResolveAddr() if done { return } - con, done2 := cMult.DialUdp(addr) + con, done2 := client.DialUdp(addr) if done2 { return } - cmd, correct := cMult.repository.ExecuteWriter(writers.HelloRuleName, cMult.domain, fmt.Sprintf("%d", cMult.port)) + cmd, correct := client.repository.ExecuteWriter(writers.HelloRuleName, client.domain, fmt.Sprintf("%d", client.port)) if !correct { println("[ClientMulticast] Hello rule isn't correct (" + cmd + ")") return @@ -58,14 +58,14 @@ func (cMult ClientMulticast) Run() { for { _, _ = con.Write([]byte(cmd)) - time.Sleep(time.Second * cMult.second) + time.Sleep(time.Second * client.second) } } // ResolveAddr Permet de résoude l'addresse -func (cMult ClientMulticast) ResolveAddr() (*net.UDPAddr, bool) { - addr, errResUdp := net.ResolveUDPAddr("udp", cMult.address) +func (client ClientMulticast) ResolveAddr() (*net.UDPAddr, bool) { + addr, errResUdp := net.ResolveUDPAddr("udp", client.address) if errResUdp != nil { println(errResUdp.Error()) @@ -75,7 +75,7 @@ func (cMult ClientMulticast) ResolveAddr() (*net.UDPAddr, bool) { } // DialUdp Ouvre une connection UDP -func (cMult ClientMulticast) DialUdp(addr *net.UDPAddr) (*net.UDPConn, bool) { +func (client ClientMulticast) DialUdp(addr *net.UDPAddr) (*net.UDPConn, bool) { con, errDial := net.DialUDP("udp", nil, addr) if errDial != nil { println(errDial.Error()) diff --git a/pkg/network/ServerUnicast.go b/pkg/network/ServerUnicast.go index 2ff83c0..f76b81d 100644 --- a/pkg/network/ServerUnicast.go +++ b/pkg/network/ServerUnicast.go @@ -14,7 +14,6 @@ type ServerUnicast struct { } func (server ServerUnicast) Run() { - listen, err := net.Listen(server.Network, fmt.Sprintf("0.0.0.0:%d", server.Port)) // "tcp", "0.0.0.0:58000" if err != nil { @@ -39,5 +38,4 @@ func (server ServerUnicast) Run() { _, _ = con.Write(append([]byte(result), '\n')) // TODO : ATTENTION laisser les \n } } - } diff --git a/pkg/protocol/IProtocolWriter.go b/pkg/protocol/IProtocolWriter.go index adbd040..688f51d 100644 --- a/pkg/protocol/IProtocolWriter.go +++ b/pkg/protocol/IProtocolWriter.go @@ -1,6 +1,6 @@ package protocol -// IProtocolReader Représentation abstraite d'un protocol +// IProtocolWriter Représentation abstraite d'un protocol type IProtocolWriter interface { // GetCmd Permet de récupérer le nom de la commande GetCmd() string diff --git a/pkg/protocol/RegexMatcher.go b/pkg/protocol/RegexMatcher.go index 517be7e..679cadb 100644 --- a/pkg/protocol/RegexMatcher.go +++ b/pkg/protocol/RegexMatcher.go @@ -8,7 +8,6 @@ func CreateRegexMatcher(pattern string) *RegexMatcher { if err != nil { return nil } - return &RegexMatcher{matcher: compile} } diff --git a/pkg/protocol/managers/RequestManager.go b/pkg/protocol/managers/RequestManager.go index 4228335..6ee6044 100644 --- a/pkg/protocol/managers/RequestManager.go +++ b/pkg/protocol/managers/RequestManager.go @@ -15,6 +15,6 @@ func (receiver RequestManager) Execute(request string) string { return result } else { // TODO : Renvoyer qu'une erreur est survenue - return "Error occured while execute command" + return "Error occurred while execute command" } } diff --git a/pkg/protocol/repository/ProtocolRepository.go b/pkg/protocol/repository/ProtocolRepository.go index e5ee8ac..6470360 100644 --- a/pkg/protocol/repository/ProtocolRepository.go +++ b/pkg/protocol/repository/ProtocolRepository.go @@ -42,7 +42,6 @@ func (repo ProtocolRepository) ExecuteReader(data string) (string, bool) { return (*reader).Execute(data) } } - return "", false } diff --git a/pkg/protocol/rules/readers/EraseFileRule.go b/pkg/protocol/rules/readers/EraseFileRule.go index e6a9de8..34bfbbf 100644 --- a/pkg/protocol/rules/readers/EraseFileRule.go +++ b/pkg/protocol/rules/readers/EraseFileRule.go @@ -27,7 +27,6 @@ func (rule EraseFileRule) GetCmd() string { } func (rule EraseFileRule) Execute(data string) (string, bool) { - if rule.Match(data) { values := rule.matcher.Parse(data) println(values[1], " est le hash du fichier à supprimer") diff --git a/resources/AppConfig.json b/resources/AppConfig.json index d878c64..feb7042 100644 --- a/resources/AppConfig.json +++ b/resources/AppConfig.json @@ -1,6 +1,6 @@ { "multicastAddress" : "226.66.66.1:42500", "multicastSecond" : 10, - "domain" : "lightcontainer.storebacked-01", + "domain" : "lightcontainerSB01", "unicastPort" : 58000 } \ No newline at end of file From e9fafd3cd80d9b48c712cbb65d868ab6811d7f3c Mon Sep 17 00:00:00 2001 From: EndMove Date: Tue, 8 Mar 2022 10:25:00 +0100 Subject: [PATCH 04/11] =?UTF-8?q?Ajout=20des=203r=C3=A8gles=20SendFileRule?= =?UTF-8?q?.go,=20SendOkRule.go,=20SendErrorRule.go=20et=20corrections=20d?= =?UTF-8?q?e=20bugs=20mineurs.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/main.go | 30 ++++++++++-- pkg/network/ClientMulticast.go | 10 ++-- pkg/protocol/IProtocolWriter.go | 2 +- pkg/protocol/repository/ProtocolRepository.go | 6 +-- pkg/protocol/rules/readers/EraseFileRule.go | 6 +-- pkg/protocol/rules/readers/SendFileRule.go | 49 +++++++++++++++++++ pkg/protocol/rules/writers/HelloRule.go | 21 ++++---- pkg/protocol/rules/writers/SendErrorRule.go | 32 ++++++++++++ pkg/protocol/rules/writers/SendOkRule.go | 32 ++++++++++++ 9 files changed, 163 insertions(+), 25 deletions(-) create mode 100644 pkg/protocol/rules/readers/SendFileRule.go create mode 100644 pkg/protocol/rules/writers/SendErrorRule.go create mode 100644 pkg/protocol/rules/writers/SendOkRule.go diff --git a/cmd/main.go b/cmd/main.go index d312423..9735c98 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -29,19 +29,43 @@ func main() { protocolRepository := repository.CreateProtocolRepository() - // Création des Writers + /** + ===== Init all Write here ===== + */ + // Creation of the HelloRule helloRule := writers.CreateHelloRule("^HELLO ([A-Za-z0-9]{5,20}) ([0-9]{1,5})\r\n$") protocolRepository.AddWriter(&helloRule) - // Création des Readers + // Creation of the SendOkRule + sendOkRule := writers.CreateSendOkRule("^SEND_OK\n$") + protocolRepository.AddWriter(&sendOkRule) + + // Creation of the SendErrorRule + sendErrorRule := writers.CreateSendOkRule("^SEND_ERROR\n$") + protocolRepository.AddWriter(&sendErrorRule) + + /** + ===== Init all Reader here ===== + */ + // Creation of the EraseFileRule eraseFileRule := readers.CreateEraseFileRule("^ERASEFILE ([A-Za-z0-9.]{50,200})\r\n$") protocolRepository.AddReader(&eraseFileRule) + // Creation of the SendFileRule + sendFileRule := readers.CreateSendFileRule("^SENDFILE ([A-Za-z0-9.]{50,200} [0-9]{1,10} [A-Za-z0-9.]{50,200})\r\n$") + protocolRepository.AddReader(&sendFileRule) + + // Create a Multicast Client & run it multicast := network.CreateClientMulticast(appConfig.MulticastAddress, appConfig.Domain, appConfig.UnicastPort, time.Duration(appConfig.MulticastSecond), protocolRepository) go multicast.Run() requestManager := managers.RequestManager{Repository: protocolRepository} server := network.ServerUnicast{Network: "tcp", Port: appConfig.UnicastPort, ReqManager: &requestManager} - server.Run() + server.Run() // TODO : -> pourquoi ne pas partir dans un thread ici. + + //reader := bufio.NewReader(os.Stdin) TODO ne pas oublier ici de mettre en place un point de sortie pour le programme. + //fmt.Print("Type Enter to quite: ") + //cmd, _ := reader.ReadString('\n') + //println(cmd) } diff --git a/pkg/network/ClientMulticast.go b/pkg/network/ClientMulticast.go index 097f18f..2a39dd7 100644 --- a/pkg/network/ClientMulticast.go +++ b/pkg/network/ClientMulticast.go @@ -40,17 +40,17 @@ type ClientMulticast struct { // Run Cette méthode démarre une commmunication multicast func (client ClientMulticast) Run() { - addr, done := client.ResolveAddr() - if done { + addr, failedRA := client.ResolveAddr() + if failedRA { return } - con, done2 := client.DialUdp(addr) - if done2 { + con, failedDU := client.DialUdp(addr) + if failedDU { return } - cmd, correct := client.repository.ExecuteWriter(writers.HelloRuleName, client.domain, fmt.Sprintf("%d", client.port)) + cmd, correct := client.repository.ExecuteWriter(writers.HelloRulePrefix, client.domain, fmt.Sprintf("%d", client.port)) if !correct { println("[ClientMulticast] Hello rule isn't correct (" + cmd + ")") return diff --git a/pkg/protocol/IProtocolWriter.go b/pkg/protocol/IProtocolWriter.go index 688f51d..d12d960 100644 --- a/pkg/protocol/IProtocolWriter.go +++ b/pkg/protocol/IProtocolWriter.go @@ -5,6 +5,6 @@ type IProtocolWriter interface { // GetCmd Permet de récupérer le nom de la commande GetCmd() string - // Execute Permet de vérifier la validité d'une donnée censée suivre les règles d'un protocol + // Execute Permet de créer une règle à envoyer Execute(argsData ...string) (string, bool) } diff --git a/pkg/protocol/repository/ProtocolRepository.go b/pkg/protocol/repository/ProtocolRepository.go index 6470360..e47615a 100644 --- a/pkg/protocol/repository/ProtocolRepository.go +++ b/pkg/protocol/repository/ProtocolRepository.go @@ -17,7 +17,6 @@ type ProtocolRepository struct { // AddReader Permet d'ajouter une règle servant à lire une commande func (repo ProtocolRepository) AddReader(reader *protocol.IProtocolReader) { cmd := (*reader).GetCmd() - if cmd != "" && !repo.containsReader(cmd) { repo.protocolReaders[cmd] = reader } @@ -26,7 +25,6 @@ func (repo ProtocolRepository) AddReader(reader *protocol.IProtocolReader) { // AddWriter Permet d'ajouter une règle servant à construire une commande func (repo ProtocolRepository) AddWriter(writer *protocol.IProtocolWriter) { cmd := (*writer).GetCmd() - if cmd != "" && !repo.containsWriter(cmd) { repo.protocolWriters[cmd] = writer } @@ -49,10 +47,10 @@ func (repo ProtocolRepository) ExecuteReader(data string) (string, bool) { ExecuteReader Permet d'exécuter un Wrier et de récupérer la commande construite avec nos argument et un indicateur de réussite. */ func (repo ProtocolRepository) ExecuteWriter(ruleName string, data ...string) (string, bool) { - protWriter, has := repo.protocolWriters[ruleName] + protocolWriter, has := repo.protocolWriters[ruleName] if has { println("OHOH") - return (*protWriter).Execute(data...) + return (*protocolWriter).Execute(data...) } else { return "", false } diff --git a/pkg/protocol/rules/readers/EraseFileRule.go b/pkg/protocol/rules/readers/EraseFileRule.go index 34bfbbf..5d68d47 100644 --- a/pkg/protocol/rules/readers/EraseFileRule.go +++ b/pkg/protocol/rules/readers/EraseFileRule.go @@ -2,8 +2,8 @@ package readers import "StoreBackEnd/pkg/protocol" -// EraseFileRuleName Identifiant de cette règle -const EraseFileRuleName = "ffe_erasefile" +// EraseFileRulePrefix Identifiant de cette règle +const EraseFileRulePrefix = "ERASEFILE" // EraseFileRule Demande de suppression d'un fichier type EraseFileRule struct { @@ -17,7 +17,7 @@ type EraseFileRule struct { // CreateEraseFileRule Création d'une instance de EraseFileRule func CreateEraseFileRule(pattern string) protocol.IProtocolReader { return &EraseFileRule{ - Cmd: EraseFileRuleName, + Cmd: EraseFileRulePrefix, matcher: protocol.CreateRegexMatcher(pattern), } } diff --git a/pkg/protocol/rules/readers/SendFileRule.go b/pkg/protocol/rules/readers/SendFileRule.go new file mode 100644 index 0000000..9cd6f93 --- /dev/null +++ b/pkg/protocol/rules/readers/SendFileRule.go @@ -0,0 +1,49 @@ +package readers + +import "StoreBackEnd/pkg/protocol" + +// SendFileRulePrefix Rule command prefix +const SendFileRulePrefix = "ffe_sendfile" + +// SendFileRule Storage structure for the SendFileRule +type SendFileRule struct { + // cmd Rule name + cmd string + // matcher Allow to make a regex match + matcher *protocol.RegexMatcher +} + +// CreateSendFileRule Creating an instance of SendFileRule +func CreateSendFileRule(pattern string) protocol.IProtocolReader { + return &SendFileRule{ + cmd: SendFileRulePrefix, + matcher: protocol.CreateRegexMatcher(pattern), + } +} + +// GetCmd retrieve the command name. +func (rule SendFileRule) GetCmd() string { + return rule.cmd +} + +// Execute the Rule with a string command. +func (rule SendFileRule) Execute(data string) (string, bool) { + if rule.Match(data) { // TODO : cloture this command. + values := rule.matcher.Parse(data) + //callback := func() { + // + //} + //callback() + println(values[1], " File Name Hash") + println(values[2], " File Size") + println(values[3], " File Content Hash") + return "SEND_OK\r\n", true + } else { + return "jjdjd", false + } +} + +// Match make a match with the current Rule and check if it matches. +func (rule SendFileRule) Match(data string) bool { + return rule.matcher.Match(data) +} diff --git a/pkg/protocol/rules/writers/HelloRule.go b/pkg/protocol/rules/writers/HelloRule.go index e61f26b..e5b0b9f 100644 --- a/pkg/protocol/rules/writers/HelloRule.go +++ b/pkg/protocol/rules/writers/HelloRule.go @@ -2,28 +2,31 @@ package writers import "StoreBackEnd/pkg/protocol" -const HelloRuleName = "sbe_hello" +// HelloRulePrefix Rule command prefix +const HelloRulePrefix = "HELLO" +// HelloRule Storage structure for the HelloRule type HelloRule struct { - // Cmd Nom de la règle - Cmd string - - // matcher Permet d'extraire de éléments d'une chaine + // cmd Rule name + cmd string + // matcher Allow to make a regex match matcher *protocol.RegexMatcher } -// CreateHelloRule Création d'une instance de HelloRule +// CreateHelloRule Creating an instance of HelloRule func CreateHelloRule(pattern string) protocol.IProtocolWriter { return &HelloRule{ - Cmd: HelloRuleName, + cmd: HelloRulePrefix, matcher: protocol.CreateRegexMatcher(pattern), } } +// GetCmd retrieve the command name. func (rule HelloRule) GetCmd() string { - return rule.Cmd + return rule.cmd } +// Execute the Rule with a string command. func (rule HelloRule) Execute(argsData ...string) (string, bool) { - return rule.matcher.Build("HELLO", argsData...) + return rule.matcher.Build(HelloRulePrefix, argsData...) } diff --git a/pkg/protocol/rules/writers/SendErrorRule.go b/pkg/protocol/rules/writers/SendErrorRule.go new file mode 100644 index 0000000..fe6c27b --- /dev/null +++ b/pkg/protocol/rules/writers/SendErrorRule.go @@ -0,0 +1,32 @@ +package writers + +import "StoreBackEnd/pkg/protocol" + +// SendErrorRulePrefix Rule command prefix +const SendErrorRulePrefix = "SEND_ERROR" + +// SendErrorRule Storage structure for the SendErrorRule +type SendErrorRule struct { + // cmd Rule name + cmd string + // matcher Allow to make a regex match + matcher *protocol.RegexMatcher +} + +// CreateSendErrorRule Creating an instance of SendErrorRule +func CreateSendErrorRule(pattern string) protocol.IProtocolWriter { + return &SendErrorRule{ + cmd: SendErrorRulePrefix, + matcher: protocol.CreateRegexMatcher(pattern), + } +} + +// GetCmd retrieve the command name. +func (rule SendErrorRule) GetCmd() string { + return rule.cmd +} + +// Execute the Rule with a string command. +func (rule SendErrorRule) Execute(argsData ...string) (string, bool) { + return rule.matcher.Build(SendErrorRulePrefix, argsData...) +} diff --git a/pkg/protocol/rules/writers/SendOkRule.go b/pkg/protocol/rules/writers/SendOkRule.go new file mode 100644 index 0000000..2d1e850 --- /dev/null +++ b/pkg/protocol/rules/writers/SendOkRule.go @@ -0,0 +1,32 @@ +package writers + +import "StoreBackEnd/pkg/protocol" + +// SendOkRulePrefix Rule command prefix +const SendOkRulePrefix = "SEND_OK" + +// SendOkRule Storage structure for the SendOkRule +type SendOkRule struct { + // cmd Rule name + cmd string + // matcher Allow to make a regex match + matcher *protocol.RegexMatcher +} + +// CreateSendOkRule Creating an instance of SendOkRule +func CreateSendOkRule(pattern string) protocol.IProtocolWriter { + return &SendOkRule{ + cmd: SendOkRulePrefix, + matcher: protocol.CreateRegexMatcher(pattern), + } +} + +// GetCmd retrieve the command name. +func (rule SendOkRule) GetCmd() string { + return rule.cmd +} + +// Execute the Rule with a string command. +func (rule SendOkRule) Execute(argsData ...string) (string, bool) { + return rule.matcher.Build(SendOkRulePrefix, argsData...) +} From 30e21ce0420357296799c17e79cec36c1ec1751e Mon Sep 17 00:00:00 2001 From: EndMove Date: Tue, 8 Mar 2022 12:01:51 +0100 Subject: [PATCH 05/11] =?UTF-8?q?Recherche=20d'un=20bug=20d'interface=20r?= =?UTF-8?q?=C3=A9seaux=20multicast?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/main.go | 4 ++-- pkg/network/ServerUnicast.go | 9 +++++--- pkg/protocol/IProtocolReader.go | 4 +++- pkg/protocol/managers/RequestManager.go | 15 +++++++++--- pkg/protocol/repository/ProtocolRepository.go | 9 +++++--- pkg/protocol/rules/readers/EraseFileRule.go | 11 +++++---- pkg/protocol/rules/readers/SendFileRule.go | 23 ++++++++++++------- pkg/utils/FileReceiver.go | 1 + resources/AppConfig.json | 2 +- 9 files changed, 53 insertions(+), 25 deletions(-) create mode 100644 pkg/utils/FileReceiver.go diff --git a/cmd/main.go b/cmd/main.go index 9735c98..9e76eee 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -51,8 +51,8 @@ func main() { eraseFileRule := readers.CreateEraseFileRule("^ERASEFILE ([A-Za-z0-9.]{50,200})\r\n$") protocolRepository.AddReader(&eraseFileRule) - // Creation of the SendFileRule - sendFileRule := readers.CreateSendFileRule("^SENDFILE ([A-Za-z0-9.]{50,200} [0-9]{1,10} [A-Za-z0-9.]{50,200})\r\n$") + // Creation of the SendFileRule // TODO reset to 50,200 + sendFileRule := readers.CreateSendFileRule("^SENDFILE ([A-Za-z0-9.]{1,200} [0-9]{1,10} [A-Za-z0-9.]{50,200})\r\n$") protocolRepository.AddReader(&sendFileRule) // Create a Multicast Client & run it diff --git a/pkg/network/ServerUnicast.go b/pkg/network/ServerUnicast.go index f76b81d..bd9bccd 100644 --- a/pkg/network/ServerUnicast.go +++ b/pkg/network/ServerUnicast.go @@ -23,18 +23,21 @@ func (server ServerUnicast) Run() { // Attente connexion du FileFrontEnd con, err := listen.Accept() + print("connection ok") if err != nil { fmt.Printf("Error while accepting client : %s\n", err) return } else { for { // TODO : Extraire cette partie de code - line, err := bufio.NewReader(con).ReadString('\n') + reader := bufio.NewReader(con) + line, err := reader.ReadString('\n') + println("OK ") // TODO REMOVE + println(line) if err != nil { return } - - result := server.ReqManager.Execute(line) + result := server.ReqManager.Execute(line, reader) _, _ = con.Write(append([]byte(result), '\n')) // TODO : ATTENTION laisser les \n } } diff --git a/pkg/protocol/IProtocolReader.go b/pkg/protocol/IProtocolReader.go index 26b0ea4..b34727b 100644 --- a/pkg/protocol/IProtocolReader.go +++ b/pkg/protocol/IProtocolReader.go @@ -1,12 +1,14 @@ package protocol +import "bufio" + // IProtocolReader Représentation abstraite d'un protocol type IProtocolReader interface { // GetCmd Permet de récupérer le nom de la commande GetCmd() string // Execute Permet d'exécuter l'action implémentée par une règle. Retourne le message (rule) de retour et bool pour savoir si tout s'est bien passé ou non - Execute(data string) (string, bool) + Execute(data string) (string, bool, func(r *bufio.Reader) (string, bool)) // Match Permet de vérifier la validité d'une donnée censée suivre les règles d'un protocol Match(data string) bool diff --git a/pkg/protocol/managers/RequestManager.go b/pkg/protocol/managers/RequestManager.go index 6ee6044..946d728 100644 --- a/pkg/protocol/managers/RequestManager.go +++ b/pkg/protocol/managers/RequestManager.go @@ -1,17 +1,26 @@ package managers -import "StoreBackEnd/pkg/protocol/repository" +import ( + "StoreBackEnd/pkg/protocol/repository" + "bufio" +) type RequestManager struct { Repository *repository.ProtocolRepository } -func (receiver RequestManager) Execute(request string) string { +func (receiver RequestManager) Execute(request string, reader *bufio.Reader) string { // On lis ce que l'on reçoit - result, executed := receiver.Repository.ExecuteReader(request) + result, executed, readCb := receiver.Repository.ExecuteReader(request) // On renvoie la réponse (Comment pour fichier ?) if executed { + if readCb != nil { + cbResult, _ := readCb(reader) + if cbResult != "" { + result = cbResult + } + } return result } else { // TODO : Renvoyer qu'une erreur est survenue diff --git a/pkg/protocol/repository/ProtocolRepository.go b/pkg/protocol/repository/ProtocolRepository.go index e47615a..27d5669 100644 --- a/pkg/protocol/repository/ProtocolRepository.go +++ b/pkg/protocol/repository/ProtocolRepository.go @@ -1,6 +1,9 @@ package repository -import "StoreBackEnd/pkg/protocol" +import ( + "StoreBackEnd/pkg/protocol" + "bufio" +) func CreateProtocolRepository() *ProtocolRepository { return &ProtocolRepository{ @@ -33,14 +36,14 @@ func (repo ProtocolRepository) AddWriter(writer *protocol.IProtocolWriter) { /* ExecuteReader Permet d'exécuter un Reader et de récupérer la commande à renvoyer. La deuxième valeur de retour permet de savoir si une commande a put être exécuté */ -func (repo ProtocolRepository) ExecuteReader(data string) (string, bool) { +func (repo ProtocolRepository) ExecuteReader(data string) (string, bool, func(r *bufio.Reader) (string, bool)) { for _, reader := range repo.protocolReaders { if (*reader).Match(data) { // Exécuter si match // Récupérer résultat à renvoyer (Donc donner ProtocolRepository aux reader ?!) return (*reader).Execute(data) } } - return "", false + return "", false, nil } /* diff --git a/pkg/protocol/rules/readers/EraseFileRule.go b/pkg/protocol/rules/readers/EraseFileRule.go index 5d68d47..1467aa6 100644 --- a/pkg/protocol/rules/readers/EraseFileRule.go +++ b/pkg/protocol/rules/readers/EraseFileRule.go @@ -1,6 +1,9 @@ package readers -import "StoreBackEnd/pkg/protocol" +import ( + "StoreBackEnd/pkg/protocol" + "bufio" +) // EraseFileRulePrefix Identifiant de cette règle const EraseFileRulePrefix = "ERASEFILE" @@ -26,13 +29,13 @@ func (rule EraseFileRule) GetCmd() string { return rule.Cmd } -func (rule EraseFileRule) Execute(data string) (string, bool) { +func (rule EraseFileRule) Execute(data string) (string, bool, func(r *bufio.Reader) (string, bool)) { if rule.Match(data) { values := rule.matcher.Parse(data) println(values[1], " est le hash du fichier à supprimer") - return "Parsing : Fichier avec le hash " + values[1] + " supprimé", true + return "Parsing : Fichier avec le hash " + values[1] + " supprimé", true, nil } else { - return "Parsing : EraseFileRule command incorrecte", false + return "Parsing : EraseFileRule command incorrecte", false, nil } } diff --git a/pkg/protocol/rules/readers/SendFileRule.go b/pkg/protocol/rules/readers/SendFileRule.go index 9cd6f93..1cf2c20 100644 --- a/pkg/protocol/rules/readers/SendFileRule.go +++ b/pkg/protocol/rules/readers/SendFileRule.go @@ -1,6 +1,9 @@ package readers -import "StoreBackEnd/pkg/protocol" +import ( + "StoreBackEnd/pkg/protocol" + "bufio" +) // SendFileRulePrefix Rule command prefix const SendFileRulePrefix = "ffe_sendfile" @@ -27,19 +30,23 @@ func (rule SendFileRule) GetCmd() string { } // Execute the Rule with a string command. -func (rule SendFileRule) Execute(data string) (string, bool) { +func (rule SendFileRule) Execute(data string) (string, bool, func(r *bufio.Reader) (string, bool)) { if rule.Match(data) { // TODO : cloture this command. values := rule.matcher.Parse(data) - //callback := func() { - // - //} - //callback() + + // print received data println(values[1], " File Name Hash") println(values[2], " File Size") println(values[3], " File Content Hash") - return "SEND_OK\r\n", true + + // function callback + callback := func(r *bufio.Reader) (string, bool) { + + return "", false + } + return "SEND_OK\r\n", true, callback } else { - return "jjdjd", false + return "jjdjd", false, nil } } diff --git a/pkg/utils/FileReceiver.go b/pkg/utils/FileReceiver.go new file mode 100644 index 0000000..d4b585b --- /dev/null +++ b/pkg/utils/FileReceiver.go @@ -0,0 +1 @@ +package utils diff --git a/resources/AppConfig.json b/resources/AppConfig.json index feb7042..6908b10 100644 --- a/resources/AppConfig.json +++ b/resources/AppConfig.json @@ -1,5 +1,5 @@ { - "multicastAddress" : "226.66.66.1:42500", + "multicastAddress" : "226.66.66.1:15502", "multicastSecond" : 10, "domain" : "lightcontainerSB01", "unicastPort" : 58000 From bcf8cdd256324f7fa3dbfceef51f7bc82bb02683 Mon Sep 17 00:00:00 2001 From: Benjamin Date: Tue, 8 Mar 2022 14:48:14 +0100 Subject: [PATCH 06/11] =?UTF-8?q?Mse=20=C3=A0=20jours=20du=20syst=C3=A8me?= =?UTF-8?q?=20de=20r=C3=A9ception=20message=20+=20fichier.=20Il=20reste=20?= =?UTF-8?q?=C3=A0=20pouvoir=20vider=20correctement=20un=20fichier=20lorsqu?= =?UTF-8?q?'il=20est=20re=C3=A7u?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/StoreBackEnd.iml | 3 +-- cmd/main.go | 6 +++--- pkg/network/ServerUnicast.go | 4 ++-- pkg/protocol/managers/RequestManager.go | 3 ++- pkg/protocol/rules/readers/SendFileRule.go | 19 ++++++++++++++++--- 5 files changed, 24 insertions(+), 11 deletions(-) diff --git a/.idea/StoreBackEnd.iml b/.idea/StoreBackEnd.iml index 5e764c4..eeb7bce 100644 --- a/.idea/StoreBackEnd.iml +++ b/.idea/StoreBackEnd.iml @@ -1,9 +1,8 @@ - + - \ No newline at end of file diff --git a/cmd/main.go b/cmd/main.go index 9e76eee..3241a39 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -37,11 +37,11 @@ func main() { protocolRepository.AddWriter(&helloRule) // Creation of the SendOkRule - sendOkRule := writers.CreateSendOkRule("^SEND_OK\n$") + sendOkRule := writers.CreateSendOkRule("^SEND_OK\r\n$") protocolRepository.AddWriter(&sendOkRule) // Creation of the SendErrorRule - sendErrorRule := writers.CreateSendOkRule("^SEND_ERROR\n$") + sendErrorRule := writers.CreateSendOkRule("^SEND_ERROR\r\n$") protocolRepository.AddWriter(&sendErrorRule) /** @@ -52,7 +52,7 @@ func main() { protocolRepository.AddReader(&eraseFileRule) // Creation of the SendFileRule // TODO reset to 50,200 - sendFileRule := readers.CreateSendFileRule("^SENDFILE ([A-Za-z0-9.]{1,200} [0-9]{1,10} [A-Za-z0-9.]{50,200})\r\n$") + sendFileRule := readers.CreateSendFileRule("^SENDFILE ([A-Za-z0-9.]{1,200}) ([0-9]{1,10}) ([A-Za-z0-9.]{50,200})\r\n$") protocolRepository.AddReader(&sendFileRule) // Create a Multicast Client & run it diff --git a/pkg/network/ServerUnicast.go b/pkg/network/ServerUnicast.go index bd9bccd..bdb838f 100644 --- a/pkg/network/ServerUnicast.go +++ b/pkg/network/ServerUnicast.go @@ -32,12 +32,12 @@ func (server ServerUnicast) Run() { for { // TODO : Extraire cette partie de code reader := bufio.NewReader(con) line, err := reader.ReadString('\n') - println("OK ") // TODO REMOVE - println(line) + println("AH " + line) if err != nil { return } result := server.ReqManager.Execute(line, reader) + println("Réponse : ", result) _, _ = con.Write(append([]byte(result), '\n')) // TODO : ATTENTION laisser les \n } } diff --git a/pkg/protocol/managers/RequestManager.go b/pkg/protocol/managers/RequestManager.go index 946d728..77aa6f9 100644 --- a/pkg/protocol/managers/RequestManager.go +++ b/pkg/protocol/managers/RequestManager.go @@ -12,7 +12,7 @@ type RequestManager struct { func (receiver RequestManager) Execute(request string, reader *bufio.Reader) string { // On lis ce que l'on reçoit result, executed, readCb := receiver.Repository.ExecuteReader(request) - + println("TESTTESTETTETT") // On renvoie la réponse (Comment pour fichier ?) if executed { if readCb != nil { @@ -23,6 +23,7 @@ func (receiver RequestManager) Execute(request string, reader *bufio.Reader) str } return result } else { + println("HMMM") // TODO : Renvoyer qu'une erreur est survenue return "Error occurred while execute command" } diff --git a/pkg/protocol/rules/readers/SendFileRule.go b/pkg/protocol/rules/readers/SendFileRule.go index 1cf2c20..99c8f4d 100644 --- a/pkg/protocol/rules/readers/SendFileRule.go +++ b/pkg/protocol/rules/readers/SendFileRule.go @@ -3,6 +3,7 @@ package readers import ( "StoreBackEnd/pkg/protocol" "bufio" + "io" ) // SendFileRulePrefix Rule command prefix @@ -41,12 +42,24 @@ func (rule SendFileRule) Execute(data string) (string, bool, func(r *bufio.Reade // function callback callback := func(r *bufio.Reader) (string, bool) { + //var fileContent []byte + // readedByte := -1 + /* + for readedByte == -1 || readedByte > 0 { + readedByte, _ = r.Read(fileContent) + println("SendFileRule Reading file ", " - Hey - ", string(readedByte)) + } - return "", false + */ + var fileContent []byte + readedCount, err := io.ReadFull(r, fileContent) + println("Un test ici : ", readedCount, err) + return "SEND_OK\r", true } - return "SEND_OK\r\n", true, callback + return "SEND_OK\r", true, callback } else { - return "jjdjd", false, nil + println("AHAHAHAHAHAHA") + return "SEND_ERROR\r", false, nil } } From 51defc39ac7fd932972c4a5f35e858e3c85ff446 Mon Sep 17 00:00:00 2001 From: EndMove Date: Tue, 8 Mar 2022 14:58:41 +0100 Subject: [PATCH 07/11] =?UTF-8?q?Ajout=20syst=C3=A8me=20d'interface?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/main.go | 11 +++++-- pkg/config/AppConfig.go | 11 ++++--- pkg/network/ClientMulticast.go | 53 ++++++++++++++++++++++++---------- pkg/utils/NetworkLister.go | 24 +++++++++++++++ resources/AppConfig.json | 1 + 5 files changed, 77 insertions(+), 23 deletions(-) create mode 100644 pkg/utils/NetworkLister.go diff --git a/cmd/main.go b/cmd/main.go index 9e76eee..7d68c63 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -7,6 +7,7 @@ import ( "StoreBackEnd/pkg/protocol/repository" "StoreBackEnd/pkg/protocol/rules/readers" "StoreBackEnd/pkg/protocol/rules/writers" + "StoreBackEnd/pkg/utils" "time" ) @@ -15,6 +16,7 @@ const ( ) func main() { + utils.NetworkLister() // TODO REMOVE println("StoreBackEnd started !") // Loading App config @@ -24,8 +26,9 @@ func main() { return } - println("Multicast Address : " + appConfig.MulticastAddress) - println("StoreBacked Domain : " + appConfig.Domain) + println(" - Multicast Network Interface : " + appConfig.MulticastNetworkInterface) + println(" - Multicast Address : " + appConfig.MulticastAddress) + println(" - StoreBacked Domain : " + appConfig.Domain) protocolRepository := repository.CreateProtocolRepository() @@ -56,7 +59,9 @@ func main() { protocolRepository.AddReader(&sendFileRule) // Create a Multicast Client & run it - multicast := network.CreateClientMulticast(appConfig.MulticastAddress, appConfig.Domain, appConfig.UnicastPort, time.Duration(appConfig.MulticastSecond), protocolRepository) + multicast := network.CreateClientMulticast( + appConfig.MulticastNetworkInterface, appConfig.MulticastAddress, appConfig.Domain, + appConfig.UnicastPort, time.Duration(appConfig.MulticastSecond), protocolRepository) go multicast.Run() requestManager := managers.RequestManager{Repository: protocolRepository} diff --git a/pkg/config/AppConfig.go b/pkg/config/AppConfig.go index 018a884..3777a54 100644 --- a/pkg/config/AppConfig.go +++ b/pkg/config/AppConfig.go @@ -2,15 +2,18 @@ package config // AppConfig Contient toute la configuration du server type AppConfig struct { - // multicastAddress Contient l'adresse multicast du FileFrontEnd + // MulticastNetworkInterface + MulticastNetworkInterface string `json:"multicastNetworkInterface"` + + // MulticastAddress Contient l'adresse multicast du FileFrontEnd MulticastAddress string `json:"multicastAddress"` - // multicastSecond Contient le nombre de seconde entre chaque annonce + // MulticastSecond Contient le nombre de seconde entre chaque annonce MulticastSecond int `json:"multicastSecond"` - // domain Domain du StoreBackEnd + // Domain du StoreBackEnd Domain string `json:"domain"` - // unicastPort Contient le port unicast auquel le FileFrontEnd se connecte + // UnicastPort Contient le port unicast auquel le FileFrontEnd se connecte UnicastPort int `json:"unicastPort"` } diff --git a/pkg/network/ClientMulticast.go b/pkg/network/ClientMulticast.go index 2a39dd7..4ff5c0f 100644 --- a/pkg/network/ClientMulticast.go +++ b/pkg/network/ClientMulticast.go @@ -9,8 +9,9 @@ import ( ) // CreateClientMulticast Méthode de construction d'un instance de la stuct ClientMulticast -func CreateClientMulticast(address string, domain string, port int, second time.Duration, repository *repository.ProtocolRepository) ClientMulticast { +func CreateClientMulticast(netInterface string, address string, domain string, port int, second time.Duration, repository *repository.ProtocolRepository) ClientMulticast { return ClientMulticast{ + netInter: netInterface, address: address, domain: domain, port: port, @@ -22,30 +23,37 @@ func CreateClientMulticast(address string, domain string, port int, second time. // ClientMulticast Cette structure représente une communication en multicast. // TODO : Prévoir une fermeture de la connection (con.Close()) type ClientMulticast struct { + // netInter Interface réseaux multicast + netInter string // address Adresse de multicast address string - // address Domain de du StoreBackEnd domain string - // port Port de connexion en unicast port int - // second Temps en seconde entre chaque ping second time.Duration - - // Repository de protocol permettant de + // repository de protocol permettant de repository *repository.ProtocolRepository } // Run Cette méthode démarre une commmunication multicast func (client ClientMulticast) Run() { - addr, failedRA := client.ResolveAddr() + // Resolve multicast addr + rAddr, failedRA := client.ResolveAddr() if failedRA { return } - con, failedDU := client.DialUdp(addr) + // Resolve interface addr + lAddr, failedRIA := ResolveInterfaceAddr(client.netInter) + if failedRIA { + println("finish") + return + } + + // Init UDP server flux + con, failedDU := client.DialUdp(lAddr, rAddr) if failedDU { return } @@ -60,23 +68,36 @@ func (client ClientMulticast) Run() { _, _ = con.Write([]byte(cmd)) time.Sleep(time.Second * client.second) } - } -// ResolveAddr Permet de résoude l'addresse +// ResolveAddr Permet de résoude l'addresse multicast func (client ClientMulticast) ResolveAddr() (*net.UDPAddr, bool) { - addr, errResUdp := net.ResolveUDPAddr("udp", client.address) - - if errResUdp != nil { - println(errResUdp.Error()) + addr, err := net.ResolveUDPAddr("udp", client.address) + if err != nil { + println(err.Error()) return nil, true } return addr, false } +// ResolveInterfaceAddr Resolves the network interface address. +func ResolveInterfaceAddr(inter string) (*net.UDPAddr, bool) { // TODO Work in progress ! do not touch + i, err := net.InterfaceByName(inter) + if err != nil { + println(err.Error()) + return nil, true + } + addrs, _ := i.Addrs() + println("INFO ABOUT THE SELECTED INTERFACE (TEMPORAIRE)") + for a, v := range addrs { + println(a, v.(*net.IPNet).String()) + } + return nil, false +} + // DialUdp Ouvre une connection UDP -func (client ClientMulticast) DialUdp(addr *net.UDPAddr) (*net.UDPConn, bool) { - con, errDial := net.DialUDP("udp", nil, addr) +func (client ClientMulticast) DialUdp(lAddr *net.UDPAddr, rAddr *net.UDPAddr) (*net.UDPConn, bool) { + con, errDial := net.DialUDP("udp", nil, rAddr) if errDial != nil { println(errDial.Error()) return nil, true diff --git a/pkg/utils/NetworkLister.go b/pkg/utils/NetworkLister.go new file mode 100644 index 0000000..3e0c0de --- /dev/null +++ b/pkg/utils/NetworkLister.go @@ -0,0 +1,24 @@ +package utils + +import ( + "fmt" + "net" +) + +func NetworkLister() { + // Retrieve Interfaces + inter, err := net.Interfaces() + + // Process errors + if err != nil { + println("[ERROR] An error occurred : " + err.Error()) + return + } + + // Display items + println("\n\nNetwork interface list :") + for i, val := range inter { + fmt.Printf("%d. %s\n", i, val.Name) + } + print("\n") +} diff --git a/resources/AppConfig.json b/resources/AppConfig.json index 6908b10..16552c9 100644 --- a/resources/AppConfig.json +++ b/resources/AppConfig.json @@ -1,4 +1,5 @@ { + "multicastNetworkInterface" : "Wi-Fi", "multicastAddress" : "226.66.66.1:15502", "multicastSecond" : 10, "domain" : "lightcontainerSB01", From 38a177aa51cc98d5682efb1c5137d5f9903aa652 Mon Sep 17 00:00:00 2001 From: EndMove Date: Tue, 8 Mar 2022 17:44:10 +0100 Subject: [PATCH 08/11] =?UTF-8?q?Tentative=20de=20r=C3=A9cup=C3=A9ration?= =?UTF-8?q?=20de=20fichier=20(probl=C3=A8me:=20r=C3=A9cup=C3=A9ration=20bl?= =?UTF-8?q?oquante)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/main.go | 3 +- pkg/network/ServerUnicast.go | 9 +++--- pkg/protocol/IProtocolReader.go | 6 ++-- pkg/protocol/managers/RequestManager.go | 8 ++--- pkg/protocol/repository/ProtocolRepository.go | 4 +-- pkg/protocol/rules/readers/EraseFileRule.go | 4 +-- pkg/protocol/rules/readers/SendFileRule.go | 32 +++++++++++-------- 7 files changed, 34 insertions(+), 32 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index 93747c3..993f11a 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -7,7 +7,6 @@ import ( "StoreBackEnd/pkg/protocol/repository" "StoreBackEnd/pkg/protocol/rules/readers" "StoreBackEnd/pkg/protocol/rules/writers" - "StoreBackEnd/pkg/utils" "time" ) @@ -16,7 +15,7 @@ const ( ) func main() { - utils.NetworkLister() // TODO REMOVE + //utils.NetworkLister() // TODO REMOVE println("StoreBackEnd started !") // Loading App config diff --git a/pkg/network/ServerUnicast.go b/pkg/network/ServerUnicast.go index bdb838f..7e42a76 100644 --- a/pkg/network/ServerUnicast.go +++ b/pkg/network/ServerUnicast.go @@ -30,14 +30,13 @@ func (server ServerUnicast) Run() { return } else { for { // TODO : Extraire cette partie de code - reader := bufio.NewReader(con) - line, err := reader.ReadString('\n') - println("AH " + line) + line, err := bufio.NewReader(con).ReadString('\n') + println("[REQUEST] " + line) if err != nil { return } - result := server.ReqManager.Execute(line, reader) - println("Réponse : ", result) + result := server.ReqManager.Execute(line, con) + println("[RESPONSE] : ", result) _, _ = con.Write(append([]byte(result), '\n')) // TODO : ATTENTION laisser les \n } } diff --git a/pkg/protocol/IProtocolReader.go b/pkg/protocol/IProtocolReader.go index b34727b..e63cd02 100644 --- a/pkg/protocol/IProtocolReader.go +++ b/pkg/protocol/IProtocolReader.go @@ -1,6 +1,8 @@ package protocol -import "bufio" +import ( + "net" +) // IProtocolReader Représentation abstraite d'un protocol type IProtocolReader interface { @@ -8,7 +10,7 @@ type IProtocolReader interface { GetCmd() string // Execute Permet d'exécuter l'action implémentée par une règle. Retourne le message (rule) de retour et bool pour savoir si tout s'est bien passé ou non - Execute(data string) (string, bool, func(r *bufio.Reader) (string, bool)) + Execute(data string) (string, bool, func(r net.Conn) (string, bool)) // Match Permet de vérifier la validité d'une donnée censée suivre les règles d'un protocol Match(data string) bool diff --git a/pkg/protocol/managers/RequestManager.go b/pkg/protocol/managers/RequestManager.go index 77aa6f9..81b28cb 100644 --- a/pkg/protocol/managers/RequestManager.go +++ b/pkg/protocol/managers/RequestManager.go @@ -2,17 +2,17 @@ package managers import ( "StoreBackEnd/pkg/protocol/repository" - "bufio" + "net" ) type RequestManager struct { Repository *repository.ProtocolRepository } -func (receiver RequestManager) Execute(request string, reader *bufio.Reader) string { +func (receiver RequestManager) Execute(request string, reader net.Conn) string { // On lis ce que l'on reçoit result, executed, readCb := receiver.Repository.ExecuteReader(request) - println("TESTTESTETTETT") + // On renvoie la réponse (Comment pour fichier ?) if executed { if readCb != nil { @@ -23,8 +23,6 @@ func (receiver RequestManager) Execute(request string, reader *bufio.Reader) str } return result } else { - println("HMMM") - // TODO : Renvoyer qu'une erreur est survenue return "Error occurred while execute command" } } diff --git a/pkg/protocol/repository/ProtocolRepository.go b/pkg/protocol/repository/ProtocolRepository.go index 27d5669..168717a 100644 --- a/pkg/protocol/repository/ProtocolRepository.go +++ b/pkg/protocol/repository/ProtocolRepository.go @@ -2,7 +2,7 @@ package repository import ( "StoreBackEnd/pkg/protocol" - "bufio" + "net" ) func CreateProtocolRepository() *ProtocolRepository { @@ -36,7 +36,7 @@ func (repo ProtocolRepository) AddWriter(writer *protocol.IProtocolWriter) { /* ExecuteReader Permet d'exécuter un Reader et de récupérer la commande à renvoyer. La deuxième valeur de retour permet de savoir si une commande a put être exécuté */ -func (repo ProtocolRepository) ExecuteReader(data string) (string, bool, func(r *bufio.Reader) (string, bool)) { +func (repo ProtocolRepository) ExecuteReader(data string) (string, bool, func(r net.Conn) (string, bool)) { for _, reader := range repo.protocolReaders { if (*reader).Match(data) { // Exécuter si match // Récupérer résultat à renvoyer (Donc donner ProtocolRepository aux reader ?!) diff --git a/pkg/protocol/rules/readers/EraseFileRule.go b/pkg/protocol/rules/readers/EraseFileRule.go index 1467aa6..54bc455 100644 --- a/pkg/protocol/rules/readers/EraseFileRule.go +++ b/pkg/protocol/rules/readers/EraseFileRule.go @@ -2,7 +2,7 @@ package readers import ( "StoreBackEnd/pkg/protocol" - "bufio" + "net" ) // EraseFileRulePrefix Identifiant de cette règle @@ -29,7 +29,7 @@ func (rule EraseFileRule) GetCmd() string { return rule.Cmd } -func (rule EraseFileRule) Execute(data string) (string, bool, func(r *bufio.Reader) (string, bool)) { +func (rule EraseFileRule) Execute(data string) (string, bool, func(r net.Conn) (string, bool)) { if rule.Match(data) { values := rule.matcher.Parse(data) println(values[1], " est le hash du fichier à supprimer") diff --git a/pkg/protocol/rules/readers/SendFileRule.go b/pkg/protocol/rules/readers/SendFileRule.go index 99c8f4d..abf4238 100644 --- a/pkg/protocol/rules/readers/SendFileRule.go +++ b/pkg/protocol/rules/readers/SendFileRule.go @@ -2,8 +2,10 @@ package readers import ( "StoreBackEnd/pkg/protocol" - "bufio" + "fmt" "io" + "net" + "os" ) // SendFileRulePrefix Rule command prefix @@ -31,29 +33,31 @@ func (rule SendFileRule) GetCmd() string { } // Execute the Rule with a string command. -func (rule SendFileRule) Execute(data string) (string, bool, func(r *bufio.Reader) (string, bool)) { +func (rule SendFileRule) Execute(data string) (string, bool, func(r net.Conn) (string, bool)) { if rule.Match(data) { // TODO : cloture this command. values := rule.matcher.Parse(data) + // Values + fileName := values[1] + // fileSize := values[2] + // fileContentHash := values[3] + // print received data println(values[1], " File Name Hash") println(values[2], " File Size") println(values[3], " File Content Hash") // function callback - callback := func(r *bufio.Reader) (string, bool) { - //var fileContent []byte - // readedByte := -1 - /* - for readedByte == -1 || readedByte > 0 { - readedByte, _ = r.Read(fileContent) - println("SendFileRule Reading file ", " - Hey - ", string(readedByte)) - } + callback := func(con net.Conn) (string, bool) { + file, _ := os.Create(fmt.Sprintf("D:\\tmp\\%s", fileName)) - */ - var fileContent []byte - readedCount, err := io.ReadFull(r, fileContent) - println("Un test ici : ", readedCount, err) + _, err := io.Copy(file, con) + println("HEY1") + if err != nil { + println("Can't copy file") + return "SEND_ERROR\r", false + } + println("HEY2") return "SEND_OK\r", true } return "SEND_OK\r", true, callback From a987a7eb64a8854d6b54f85f9361fede0cdd94f5 Mon Sep 17 00:00:00 2001 From: EndMove Date: Tue, 8 Mar 2022 19:41:54 +0100 Subject: [PATCH 09/11] =?UTF-8?q?Tentative=20d'impl=C3=A9mentation=20syst?= =?UTF-8?q?=C3=A8me=20d'interface=20->=20toujours=20en=20=C3=A9chec?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/main.go | 3 ++- pkg/network/ClientMulticast.go | 43 +++++++++++++++++++++++++--------- 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index 993f11a..93747c3 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -7,6 +7,7 @@ import ( "StoreBackEnd/pkg/protocol/repository" "StoreBackEnd/pkg/protocol/rules/readers" "StoreBackEnd/pkg/protocol/rules/writers" + "StoreBackEnd/pkg/utils" "time" ) @@ -15,7 +16,7 @@ const ( ) func main() { - //utils.NetworkLister() // TODO REMOVE + utils.NetworkLister() // TODO REMOVE println("StoreBackEnd started !") // Loading App config diff --git a/pkg/network/ClientMulticast.go b/pkg/network/ClientMulticast.go index 4ff5c0f..1bda350 100644 --- a/pkg/network/ClientMulticast.go +++ b/pkg/network/ClientMulticast.go @@ -81,18 +81,39 @@ func (client ClientMulticast) ResolveAddr() (*net.UDPAddr, bool) { } // ResolveInterfaceAddr Resolves the network interface address. -func ResolveInterfaceAddr(inter string) (*net.UDPAddr, bool) { // TODO Work in progress ! do not touch - i, err := net.InterfaceByName(inter) - if err != nil { - println(err.Error()) - return nil, true - } - addrs, _ := i.Addrs() - println("INFO ABOUT THE SELECTED INTERFACE (TEMPORAIRE)") - for a, v := range addrs { - println(a, v.(*net.IPNet).String()) - } +func ResolveInterfaceAddr(inter string) (*net.UDPAddr, bool) { + //i, err := net.InterfaceByName(inter) + //addrs, err := i.Addrs() + //println(addrs[0]) + //addr, err := net.ResolveUDPAddr("udp", addrs[0].String()) + //if err != nil { + // println(err.Error()) + // return nil, true + //} return nil, false + //var ipv4Addr net.IP + //ief, err := net.InterfaceByName(inter) + //if err != nil { + // println(err.Error()) + // return nil, true + //} + //addrs, err := ief.Addrs() + //if err != nil { + // println(err.Error()) + // return nil, true + //} + //for _, addr := range addrs { + // if ipv4Addr = addr.(*net.IPNet).IP; ipv4Addr != nil { + // break + // } + //} + //println(ipv4Addr.String()) + //addr, err := net.ResolveUDPAddr("udp", ipv4Addr.String()) + //if err != nil { + // println(err.Error()) + // return nil, true + //} + //return addr, false } // DialUdp Ouvre une connection UDP From 6fa5f6c1c40dc7777b00c97409457d4cb114a143 Mon Sep 17 00:00:00 2001 From: Benjamin Date: Tue, 8 Mar 2022 20:37:49 +0100 Subject: [PATCH 10/11] =?UTF-8?q?R=C3=A9ception=20d'un=20fichier=20et=20sa?= =?UTF-8?q?uvegarde=20de=20celui-ci=20termin=C3=A9e?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/network/ServerUnicast.go | 5 ++-- pkg/protocol/IProtocolReader.go | 4 +-- pkg/protocol/managers/RequestManager.go | 4 +-- pkg/protocol/repository/ProtocolRepository.go | 4 +-- pkg/protocol/rules/readers/EraseFileRule.go | 4 +-- pkg/protocol/rules/readers/SendFileRule.go | 30 +++++++++++-------- pkg/utils/FileReceiver.go | 24 +++++++++++++++ 7 files changed, 53 insertions(+), 22 deletions(-) diff --git a/pkg/network/ServerUnicast.go b/pkg/network/ServerUnicast.go index 7e42a76..8bfbe78 100644 --- a/pkg/network/ServerUnicast.go +++ b/pkg/network/ServerUnicast.go @@ -30,12 +30,13 @@ func (server ServerUnicast) Run() { return } else { for { // TODO : Extraire cette partie de code - line, err := bufio.NewReader(con).ReadString('\n') + reader := bufio.NewReader(con) + line, err := reader.ReadString('\n') println("[REQUEST] " + line) if err != nil { return } - result := server.ReqManager.Execute(line, con) + result := server.ReqManager.Execute(line, reader) println("[RESPONSE] : ", result) _, _ = con.Write(append([]byte(result), '\n')) // TODO : ATTENTION laisser les \n } diff --git a/pkg/protocol/IProtocolReader.go b/pkg/protocol/IProtocolReader.go index e63cd02..ad6d0ed 100644 --- a/pkg/protocol/IProtocolReader.go +++ b/pkg/protocol/IProtocolReader.go @@ -1,7 +1,7 @@ package protocol import ( - "net" + "bufio" ) // IProtocolReader Représentation abstraite d'un protocol @@ -10,7 +10,7 @@ type IProtocolReader interface { GetCmd() string // Execute Permet d'exécuter l'action implémentée par une règle. Retourne le message (rule) de retour et bool pour savoir si tout s'est bien passé ou non - Execute(data string) (string, bool, func(r net.Conn) (string, bool)) + Execute(data string) (string, bool, func(reader *bufio.Reader) (string, bool)) // Match Permet de vérifier la validité d'une donnée censée suivre les règles d'un protocol Match(data string) bool diff --git a/pkg/protocol/managers/RequestManager.go b/pkg/protocol/managers/RequestManager.go index 81b28cb..0ce0d9c 100644 --- a/pkg/protocol/managers/RequestManager.go +++ b/pkg/protocol/managers/RequestManager.go @@ -2,14 +2,14 @@ package managers import ( "StoreBackEnd/pkg/protocol/repository" - "net" + "bufio" ) type RequestManager struct { Repository *repository.ProtocolRepository } -func (receiver RequestManager) Execute(request string, reader net.Conn) string { +func (receiver RequestManager) Execute(request string, reader *bufio.Reader) string { // On lis ce que l'on reçoit result, executed, readCb := receiver.Repository.ExecuteReader(request) diff --git a/pkg/protocol/repository/ProtocolRepository.go b/pkg/protocol/repository/ProtocolRepository.go index 168717a..fc3341c 100644 --- a/pkg/protocol/repository/ProtocolRepository.go +++ b/pkg/protocol/repository/ProtocolRepository.go @@ -2,7 +2,7 @@ package repository import ( "StoreBackEnd/pkg/protocol" - "net" + "bufio" ) func CreateProtocolRepository() *ProtocolRepository { @@ -36,7 +36,7 @@ func (repo ProtocolRepository) AddWriter(writer *protocol.IProtocolWriter) { /* ExecuteReader Permet d'exécuter un Reader et de récupérer la commande à renvoyer. La deuxième valeur de retour permet de savoir si une commande a put être exécuté */ -func (repo ProtocolRepository) ExecuteReader(data string) (string, bool, func(r net.Conn) (string, bool)) { +func (repo ProtocolRepository) ExecuteReader(data string) (string, bool, func(reader *bufio.Reader) (string, bool)) { for _, reader := range repo.protocolReaders { if (*reader).Match(data) { // Exécuter si match // Récupérer résultat à renvoyer (Donc donner ProtocolRepository aux reader ?!) diff --git a/pkg/protocol/rules/readers/EraseFileRule.go b/pkg/protocol/rules/readers/EraseFileRule.go index 54bc455..1467aa6 100644 --- a/pkg/protocol/rules/readers/EraseFileRule.go +++ b/pkg/protocol/rules/readers/EraseFileRule.go @@ -2,7 +2,7 @@ package readers import ( "StoreBackEnd/pkg/protocol" - "net" + "bufio" ) // EraseFileRulePrefix Identifiant de cette règle @@ -29,7 +29,7 @@ func (rule EraseFileRule) GetCmd() string { return rule.Cmd } -func (rule EraseFileRule) Execute(data string) (string, bool, func(r net.Conn) (string, bool)) { +func (rule EraseFileRule) Execute(data string) (string, bool, func(r *bufio.Reader) (string, bool)) { if rule.Match(data) { values := rule.matcher.Parse(data) println(values[1], " est le hash du fichier à supprimer") diff --git a/pkg/protocol/rules/readers/SendFileRule.go b/pkg/protocol/rules/readers/SendFileRule.go index abf4238..ee0f96c 100644 --- a/pkg/protocol/rules/readers/SendFileRule.go +++ b/pkg/protocol/rules/readers/SendFileRule.go @@ -2,10 +2,9 @@ package readers import ( "StoreBackEnd/pkg/protocol" - "fmt" - "io" - "net" - "os" + "StoreBackEnd/pkg/utils" + "bufio" + "strconv" ) // SendFileRulePrefix Rule command prefix @@ -33,13 +32,13 @@ func (rule SendFileRule) GetCmd() string { } // Execute the Rule with a string command. -func (rule SendFileRule) Execute(data string) (string, bool, func(r net.Conn) (string, bool)) { +func (rule SendFileRule) Execute(data string) (string, bool, func(reader *bufio.Reader) (string, bool)) { if rule.Match(data) { // TODO : cloture this command. values := rule.matcher.Parse(data) // Values fileName := values[1] - // fileSize := values[2] + fileSize, _ := strconv.Atoi(values[2]) // fileContentHash := values[3] // print received data @@ -48,13 +47,20 @@ func (rule SendFileRule) Execute(data string) (string, bool, func(r net.Conn) (s println(values[3], " File Content Hash") // function callback - callback := func(con net.Conn) (string, bool) { - file, _ := os.Create(fmt.Sprintf("D:\\tmp\\%s", fileName)) - - _, err := io.Copy(file, con) + callback := func(reader *bufio.Reader) (string, bool) { + hasReceive := utils.ReceiveFile(fileName, fileSize, reader) println("HEY1") - if err != nil { - println("Can't copy file") + /* + file, _ := os.Create(fmt.Sprintf("/home/benjamin/sbe/%s", fileName)) + _, err := io.Copy(file, reader) + println("HEY1") + if err != nil { + println("Can't copy file") + return "SEND_ERROR\r", false + } + + */ + if !hasReceive { return "SEND_ERROR\r", false } println("HEY2") diff --git a/pkg/utils/FileReceiver.go b/pkg/utils/FileReceiver.go index d4b585b..292cd5f 100644 --- a/pkg/utils/FileReceiver.go +++ b/pkg/utils/FileReceiver.go @@ -1 +1,25 @@ package utils + +import ( + "bufio" + "fmt" + "io" + "os" +) + +// ReceiveFile Permet de récupérer un fichier sur un reader +func ReceiveFile(fileName string, fileSize int, reader *bufio.Reader) bool { + file, fileErr := os.Create(fmt.Sprintf("/home/benjamin/sbe/%s", fileName)) + if fileErr != nil { + return false + } + + println(1) + defer file.Close() + _, err := io.CopyN(file, reader, int64(fileSize)) + println(2) + if err != nil { + return false + } + return true +} From b198f51c1e00ad85ee7caa8c500d34cf009888c5 Mon Sep 17 00:00:00 2001 From: Benjamin Date: Thu, 10 Mar 2022 14:35:41 +0100 Subject: [PATCH 11/11] =?UTF-8?q?R=C3=A9cup=C3=A9ration=20d'un=20fichier?= =?UTF-8?q?=20avec=20BUFFER.=20DOnc=20plus=20optimis=C3=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/utils/FileReceiver.go | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/pkg/utils/FileReceiver.go b/pkg/utils/FileReceiver.go index 292cd5f..46b299b 100644 --- a/pkg/utils/FileReceiver.go +++ b/pkg/utils/FileReceiver.go @@ -3,7 +3,6 @@ package utils import ( "bufio" "fmt" - "io" "os" ) @@ -14,12 +13,19 @@ func ReceiveFile(fileName string, fileSize int, reader *bufio.Reader) bool { return false } - println(1) defer file.Close() - _, err := io.CopyN(file, reader, int64(fileSize)) - println(2) - if err != nil { - return false + currentSize := 0 + buffer := make([]byte, 1024) + + for currentSize < fileSize { + length, err := reader.Read(buffer) + if err != nil { + return false + } + + currentSize += length + file.WriteAt(buffer, int64(currentSize)) } + return true }