// handle reading a local file and sending it to the server func handlePut(filename, address string) error { f, err := os.Open(filename) if err != nil { return fmt.Errorf("Error opening file: %v", err) } defer f.Close() br := bufio.NewReader(f) serverAddr, conn, err := getAddrAndConn(address) if err != nil { return err } defer conn.Close() // Send WRQ packet wrq := common.RequestPacket{ OpCode: common.OpWRQ, Filename: filename, Mode: "octet", } _, err = conn.WriteTo(wrq.ToBytes(), serverAddr) if err != nil { return fmt.Errorf("Error sending WRQ packet: %v", err) } // Get the ACK ackBuf := make([]byte, 4) _, remoteAddr, err := conn.ReadFrom(ackBuf) if err != nil { return fmt.Errorf("Error reading ACK packet: %v", err) } _, err = common.ParseAckPacket(ackBuf) if err != nil { return fmt.Errorf("Error parsing ACK packet: %v", err) } common.ReadFileLoop(br, conn, remoteAddr, common.BlockSize) return nil }
func TestParseACKPacket(t *testing.T) { testCases := []struct { packet []byte tid uint16 errExpected bool }{ // Valid packet { packet: []byte{0, 4, 0, 1}, tid: 1, errExpected: false, }, // Wrong opcode { packet: []byte{0, 3, 0, 1}, tid: 1, errExpected: true, }, } for i, tc := range testCases { tid, err := common.ParseAckPacket(tc.packet) if tc.errExpected && err == nil { t.Errorf("Expected an error, got nil (%d)", i) continue } if !tc.errExpected && err != nil { t.Errorf("Error: %v (%d)", err, i) continue } if tc.errExpected && err != nil { continue } if tid != tc.tid { t.Errorf("Expected tid: %d, got %d (%d)", tc.tid, tid, i) } } }