func HandleRequest(conn net.Conn) { readWriter := bufio.NewReadWriter(bufio.NewReader(conn), bufio.NewWriterSize(conn, 1)) command, parameters, err := common.ReadMessage(readWriter.Reader) if err != nil { log.Println(err) conn.Close() return } if command == "get" { ReadFileHandler(parameters, readWriter) } else if command == "put" { WriteFileHandler(parameters, readWriter) } else { log.Printf("Unknown command '%d'", command) } conn.Close() }
func GetFileCore(request *GetFileRequest) { conn := request.Socket file := request.File commandParameters := request.FileName if request.VerifyMode { commandParameters = fmt.Sprintf("%s -v", commandParameters) } // Send the command err := common.WriteMessage("get", commandParameters, conn) if err != nil { fmt.Println("Error writing command:", err) return } // Read the status response command, value, err := common.ReadMessage(conn.Reader) if err != nil { fmt.Println("Error reading status:", err) return } if command == "error" { fmt.Println("Server sent error:", value) return } if command != "length" { fmt.Printf("Unexpected message type '%s'\n", command) return } segments := strings.Split(value, " ") var hash string if request.VerifyMode { hash = segments[1] } length, err := strconv.Atoi(segments[0]) if err != nil { fmt.Printf("Protocol error: %s. DEBUG: %s", err, segments[0]) return } fmt.Printf("Status OK, starting transfer of %d bytes\n", length) hasher := md5.New() totalRead := 0 buffer := make([]byte, 1024) for totalRead < length { read, err := conn.Read(buffer) if err == io.EOF { break } if err != nil { fmt.Printf("Error reading from network: %s. Aborting transfer\n", err) return } _, err = file.Write(buffer[:read]) if err != nil { fmt.Println("Error writing to file; aborting transfer") return } if request.Udp { conn.Write([]byte("get-ack")) } hasher.Write(buffer[:read]) totalRead += read } if totalRead == length { fmt.Println("Transfer complete") realHash := hex.EncodeToString(hasher.Sum([]byte{})) if request.VerifyMode && (len(realHash) == 0 || len(hash) == 0) { fmt.Println("Checksum calculation failed") } else if request.VerifyMode { if realHash == hash { fmt.Printf("Checksum OK") } else { fmt.Println("Checksum failed; file is corrupt") fmt.Println("Expected: ", hash) fmt.Println("Actual: ", realHash) } } } else { fmt.Println("Connection closed before transfer completed. File contents are likely incomplete.") } }
func putFile(conn *bufio.ReadWriter, file *os.File, source string, conntype int) { // Send the command err := common.WriteMessage("put", source, conn) if err != nil { fmt.Println("Error writing command:", err) return } // Read the status response command, value, err := common.ReadMessage(conn.Reader) if err != nil { fmt.Println("Error reading status:", err) return } if command == "ok" { fmt.Printf("Status OK, starting transfer of %d bytes\n", source) buffer := make([]byte, 1024) if err != nil { fmt.Println("Client file error:", file) return } if conntype == 0 { for { n, err := file.Read(buffer) if err == io.EOF { fmt.Println("Transfer complete") break } bytes := []byte(buffer) _, err = conn.Write(bytes[0:n]) } } else if conntype == 1 { for { file := context.file buffer := make([]byte, 1024) // Read into buffer len, err := file.Read(buffer) if len > 0 { // Write to socket bytes := []byte(buffer) _, err = conn.Write(bytes[0:n]) if err != nil { log.Println("Failed to write data to socket; abandoning transfer") } } // EOF? if err == io.EOF { log.Println("Transfer completed") break } // Some other error if err != nil { log.Println("Error reading file; abandoning transfer") return } for { if message != "put-ack" { log.Println("Protocol error: expected get-ack") continue } break } } } command, value, err := common.ReadMessage(conn.Reader) if err != nil { fmt.Println("Error reading status:", err) return } if command == "error" { fmt.Println("Server sent error:", value) return } } else if command == "error" { fmt.Println("Server sent error:", value) return } else { fmt.Printf("Unexpected message type '%s'\n", command) return } }