Repository: dragonflyoss/Dragonfly2
Pull request #1420 (2022-06-30 03:59:38)

feat: rename client/clientutil to client/util
Signed-off-by: Gaius <gaius.qi@gmail.com>

<!--- Provide a general summary of your changes in the Title above -->

## Description
- Rename client/clientutil to client/util.
<!--- Describe your changes in detail -->

## Related Issue

<!--- This project only accepts pull requests related to open issues -->
<!--- If suggesting a new feature or change, please discuss it in an issue first -->
<!--- If fixing a bug, there should be an issue describing it with steps to reproduce -->
<!--- Please link to the issue here: -->

## Motivation and Context

<!--- Why is this change required? What problem does it solve? -->

## Screenshots (if appropriate)

## Types of changes

<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->

- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)
- [ ] Documentation Update (if none of the other choices apply)

## Checklist

<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->

- [ ] My change requires a change to the documentation.
- [ ] I have updated the documentation accordingly.
- [x] I have read the **CONTRIBUTING** document.
- [ ] I have added tests to cover my changes.


codecov-commenter: # [Codecov](https://codecov.io/gh/dragonflyoss/Dragonfly2/pull/1420?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dragonflyoss) Report
> Merging [#1420](https://codecov.io/gh/dragonflyoss/Dragonfly2/pull/1420?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dragonflyoss) (7b61108) into [main](https://codecov.io/gh/dragonflyoss/Dragonfly2/commit/726b19fbba21307b503ad509535b3d6232f9a261?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dragonflyoss) (726b19f) will **decrease** coverage by `0.14%`.
> The diff coverage is `64.28%`.

[![Impacted file tree graph](https://codecov.io/gh/dragonflyoss/Dragonfly2/pull/1420/graphs/tree.svg?width=650&height=150&src=pr&token=PUICJYSAT7&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dragonflyoss)](https://codecov.io/gh/dragonflyoss/Dragonfly2/pull/1420?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dragonflyoss)

```diff
@@            Coverage Diff             @@
##             main    #1420      +/-   ##
==========================================
- Coverage   44.55%   44.41%   -0.15%     
==========================================
  Files         113      113              
  Lines       10202    10202              
==========================================
- Hits         4546     4531      -15     
- Misses       5200     5221      +21     
+ Partials      456      450       -6     
```

| Flag | Coverage Δ | |
|---|---|---|
| e2etests | `?` | |
| unittests | `44.41% <64.28%> (-0.15%)` | :arrow_down: |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dragonflyoss#carryforward-flags-in-the-pull-request-comment) to find out more.

| [Impacted Files](https://codecov.io/gh/dragonflyoss/Dragonfly2/pull/1420?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dragonflyoss) | Coverage Δ | |
|---|---|---|
| [client/config/dfget.go](https://codecov.io/gh/dragonflyoss/Dragonfly2/pull/1420/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dragonflyoss#diff-Y2xpZW50L2NvbmZpZy9kZmdldC5nbw==) | `28.40% <ø> (ø)` | |
| [client/config/flags.go](https://codecov.io/gh/dragonflyoss/Dragonfly2/pull/1420/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dragonflyoss#diff-Y2xpZW50L2NvbmZpZy9mbGFncy5nbw==) | `0.00% <ø> (ø)` | |
| [client/config/peerhost.go](https://codecov.io/gh/dragonflyoss/Dragonfly2/pull/1420/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dragonflyoss#diff-Y2xpZW50L2NvbmZpZy9wZWVyaG9zdC5nbw==) | `32.37% <ø> (ø)` | |
| [client/daemon/daemon.go](https://codecov.io/gh/dragonflyoss/Dragonfly2/pull/1420/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dragonflyoss#diff-Y2xpZW50L2RhZW1vbi9kYWVtb24uZ28=) | `5.30% <0.00%> (ø)` | |
| [client/daemon/peer/peertask\_file.go](https://codecov.io/gh/dragonflyoss/Dragonfly2/pull/1420/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dragonflyoss#diff-Y2xpZW50L2RhZW1vbi9wZWVyL3BlZXJ0YXNrX2ZpbGUuZ28=) | `57.25% <ø> (ø)` | |
| [client/daemon/peer/peertask\_manager.go](https://codecov.io/gh/dragonflyoss/Dragonfly2/pull/1420/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dragonflyoss#diff-Y2xpZW50L2RhZW1vbi9wZWVyL3BlZXJ0YXNrX21hbmFnZXIuZ28=) | `24.70% <ø> (ø)` | |
| [client/daemon/peer/peertask\_seed.go](https://codecov.io/gh/dragonflyoss/Dragonfly2/pull/1420/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dragonflyoss#diff-Y2xpZW50L2RhZW1vbi9wZWVyL3BlZXJ0YXNrX3NlZWQuZ28=) | `88.88% <ø> (ø)` | |
| [client/daemon/peer/piece\_manager.go](https://codecov.io/gh/dragonflyoss/Dragonfly2/pull/1420/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dragonflyoss#diff-Y2xpZW50L2RhZW1vbi9wZWVyL3BpZWNlX21hbmFnZXIuZ28=) | `47.63% <ø> (ø)` | |
| [client/daemon/rpcserver/rpcserver.go](https://codecov.io/gh/dragonflyoss/Dragonfly2/pull/1420/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dragonflyoss#diff-Y2xpZW50L2RhZW1vbi9ycGNzZXJ2ZXIvcnBjc2VydmVyLmdv) | `23.84% <0.00%> (ø)` | |
| [client/daemon/rpcserver/seeder.go](https://codecov.io/gh/dragonflyoss/Dragonfly2/pull/1420/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dragonflyoss#diff-Y2xpZW50L2RhZW1vbi9ycGNzZXJ2ZXIvc2VlZGVyLmdv) | `52.87% <0.00%> (ø)` | |
| ... and [14 more](https://codecov.io/gh/dragonflyoss/Dragonfly2/pull/1420/diff?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dragonflyoss) | |


Patch:
diff --git a/client/config/dfget.go b/client/config/dfget.go
index aae2d453..4d82441d 100644
--- a/client/config/dfget.go
+++ b/client/config/dfget.go
@@ -28,7 +28,7 @@ import (
 	"syscall"
 	"time"
 
-	"d7y.io/dragonfly/v2/client/clientutil"
+	"d7y.io/dragonfly/v2/client/util"
 	"d7y.io/dragonfly/v2/cmd/dependency/base"
 	"d7y.io/dragonfly/v2/internal/dferrors"
 	logger "d7y.io/dragonfly/v2/internal/dflog"
@@ -101,7 +101,7 @@ type ClientOption struct {
 	// WorkHome is working directory of dfget.
 	WorkHome string `yaml:"workHome,omitempty" mapstructure:"workHome,omitempty"`
 
-	RateLimit clientutil.RateLimit `yaml:"rateLimit,omitempty" mapstructure:"rateLimit,omitempty"`
+	RateLimit util.RateLimit `yaml:"rateLimit,omitempty" mapstructure:"rateLimit,omitempty"`
 
 	// Config file paths,
 	// default:["/etc/dragonfly/dfget.yaml","/etc/dragonfly.conf"].
diff --git a/client/config/dfget_darwin.go b/client/config/dfget_darwin.go
index 176055e5..09cbc20d 100644
--- a/client/config/dfget_darwin.go
+++ b/client/config/dfget_darwin.go
@@ -20,9 +20,10 @@
 package config
 
 import (
-	"d7y.io/dragonfly/v2/client/clientutil"
-	"d7y.io/dragonfly/v2/pkg/unit"
 	"golang.org/x/time/rate"
+
+	"d7y.io/dragonfly/v2/client/util"
+	"d7y.io/dragonfly/v2/pkg/unit"
 )
 
 var dfgetConfig = ClientOption{
@@ -30,7 +31,7 @@ var dfgetConfig = ClientOption{
 	Output:        "",
 	Timeout:       0,
 	BenchmarkRate: 128 * unit.KB,
-	RateLimit: clientutil.RateLimit{
+	RateLimit: util.RateLimit{
 		Limit: rate.Limit(DefaultTotalDownloadLimit),
 	},
 	Md5:               "",
diff --git a/client/config/dfget_linux.go b/client/config/dfget_linux.go
index e0fa70a8..bc8c6493 100644
--- a/client/config/dfget_linux.go
+++ b/client/config/dfget_linux.go
@@ -22,14 +22,14 @@ package config
 import (
 	"golang.org/x/time/rate"
 
-	"d7y.io/dragonfly/v2/client/clientutil"
+	"d7y.io/dragonfly/v2/client/util"
 )
 
 var dfgetConfig = ClientOption{
 	URL:     "",
 	Output:  "",
 	Timeout: 0,
-	RateLimit: clientutil.RateLimit{
+	RateLimit: util.RateLimit{
 		Limit: rate.Limit(DefaultTotalDownloadLimit),
 	},
 	Md5:               "",
diff --git a/client/config/flags.go b/client/config/flags.go
index 265e9f52..f8eada27 100644
--- a/client/config/flags.go
+++ b/client/config/flags.go
@@ -26,7 +26,7 @@ import (
 	"github.com/docker/go-units"
 	"golang.org/x/time/rate"
 
-	"d7y.io/dragonfly/v2/client/clientutil"
+	"d7y.io/dragonfly/v2/client/util"
 	"d7y.io/dragonfly/v2/pkg/dfnet"
 )
 
@@ -81,10 +81,10 @@ func (nv *NetAddrsValue) Type() string {
 }
 
 type RateLimitValue struct {
-	rate *clientutil.RateLimit
+	rate *util.RateLimit
 }
 
-func NewLimitRateValue(rate *clientutil.RateLimit) *RateLimitValue {
+func NewLimitRateValue(rate *util.RateLimit) *RateLimitValue {
 	return &RateLimitValue{rate: rate}
 }
 
diff --git a/client/config/peerhost.go b/client/config/peerhost.go
index cfe00c5d..d80b3398 100644
--- a/client/config/peerhost.go
+++ b/client/config/peerhost.go
@@ -33,7 +33,7 @@ import (
 
 	"gopkg.in/yaml.v3"
 
-	"d7y.io/dragonfly/v2/client/clientutil"
+	"d7y.io/dragonfly/v2/client/util"
 	"d7y.io/dragonfly/v2/cmd/dependency/base"
 	logger "d7y.io/dragonfly/v2/internal/dflog"
 	"d7y.io/dragonfly/v2/pkg/dfnet"
@@ -48,9 +48,9 @@ type DaemonOption struct {
 	// AliveTime indicates alive duration for which daemon keeps no accessing by any uploading and download requests,
 	// after this period daemon will automatically exit
 	// when AliveTime == 0, will run infinitely
-	AliveTime  clientutil.Duration `mapstructure:"aliveTime" yaml:"aliveTime"`
-	GCInterval clientutil.Duration `mapstructure:"gcInterval" yaml:"gcInterval"`
-	Metrics    string              `yaml:"metrics" mapstructure:"metrics"`
+	AliveTime  util.Duration `mapstructure:"aliveTime" yaml:"aliveTime"`
+	GCInterval util.Duration `mapstructure:"gcInterval" yaml:"gcInterval"`
+	Metrics    string        `yaml:"metrics" mapstructure:"metrics"`
 
 	WorkHome    string `mapstructure:"workHome" yaml:"workHome"`
 	CacheDir    string `mapstructure:"cacheDir" yaml:"cacheDir"`
@@ -174,7 +174,7 @@ type SchedulerOption struct {
 	// NetAddrs is scheduler addresses.
 	NetAddrs []dfnet.NetAddr `mapstructure:"netAddrs" yaml:"netAddrs"`
 	// ScheduleTimeout is request timeout.
-	ScheduleTimeout clientutil.Duration `mapstructure:"scheduleTimeout" yaml:"scheduleTimeout"`
+	ScheduleTimeout util.Duration `mapstructure:"scheduleTimeout" yaml:"scheduleTimeout"`
 	// DisableAutoBackSource indicates not back source normally, only scheduler says back source.
 	DisableAutoBackSource bool `mapstructure:"disableAutoBackSource" yaml:"disableAutoBackSource"`
 }
@@ -224,17 +224,17 @@ type HostOption struct {
 }
 
 type DownloadOption struct {
-	DefaultPattern       string               `mapstructure:"defaultPattern" yaml:"defaultPattern"`
-	TotalRateLimit       clientutil.RateLimit `mapstructure:"totalRateLimit" yaml:"totalRateLimit"`
-	PerPeerRateLimit     clientutil.RateLimit `mapstructure:"perPeerRateLimit" yaml:"perPeerRateLimit"`
-	PieceDownloadTimeout time.Duration        `mapstructure:"pieceDownloadTimeout" yaml:"pieceDownloadTimeout"`
-	DownloadGRPC         ListenOption         `mapstructure:"downloadGRPC" yaml:"downloadGRPC"`
-	PeerGRPC             ListenOption         `mapstructure:"peerGRPC" yaml:"peerGRPC"`
-	CalculateDigest      bool                 `mapstructure:"calculateDigest" yaml:"calculateDigest"`
-	TransportOption      *TransportOption     `mapstructure:"transportOption" yaml:"transportOption"`
-	GetPiecesMaxRetry    int                  `mapstructure:"getPiecesMaxRetry" yaml:"getPiecesMaxRetry"`
-	Prefetch             bool                 `mapstructure:"prefetch" yaml:"prefetch"`
-	WatchdogTimeout      time.Duration        `mapstructure:"watchdogTimeout" yaml:"watchdogTimeout"`
+	DefaultPattern       string           `mapstructure:"defaultPattern" yaml:"defaultPattern"`
+	TotalRateLimit       util.RateLimit   `mapstructure:"totalRateLimit" yaml:"totalRateLimit"`
+	PerPeerRateLimit     util.RateLimit   `mapstructure:"perPeerRateLimit" yaml:"perPeerRateLimit"`
+	PieceDownloadTimeout time.Duration    `mapstructure:"pieceDownloadTimeout" yaml:"pieceDownloadTimeout"`
+	DownloadGRPC         ListenOption     `mapstructure:"downloadGRPC" yaml:"downloadGRPC"`
+	PeerGRPC             ListenOption     `mapstructure:"peerGRPC" yaml:"peerGRPC"`
+	CalculateDigest      bool             `mapstructure:"calculateDigest" yaml:"calculateDigest"`
+	TransportOption      *TransportOption `mapstructure:"transportOption" yaml:"transportOption"`
+	GetPiecesMaxRetry    int              `mapstructure:"getPiecesMaxRetry" yaml:"getPiecesMaxRetry"`
+	Prefetch             bool             `mapstructure:"prefetch" yaml:"prefetch"`
+	WatchdogTimeout      time.Duration    `mapstructure:"watchdogTimeout" yaml:"watchdogTimeout"`
 }
 
 type TransportOption struct {
@@ -366,7 +366,7 @@ func (p *ProxyOption) unmarshal(unmarshal func(in []byte, out any) (err error),
 
 type UploadOption struct {
 	ListenOption `yaml:",inline" mapstructure:",squash"`
-	RateLimit    clientutil.RateLimit `mapstructure:"rateLimit" yaml:"rateLimit"`
+	RateLimit    util.RateLimit `mapstructure:"rateLimit" yaml:"rateLimit"`
 }
 
 type ObjectStorageOption struct {
@@ -504,7 +504,7 @@ type StorageOption struct {
 	DataPath string `mapstructure:"dataPath" yaml:"dataPath"`
 	// TaskExpireTime indicates caching duration for which cached file keeps no accessed by any process,
 	// after this period cache file will be gc
-	TaskExpireTime clientutil.Duration `mapstructure:"taskExpireTime" yaml:"taskExpireTime"`
+	TaskExpireTime util.Duration `mapstructure:"taskExpireTime" yaml:"taskExpireTime"`
 	// DiskGCThreshold indicates the threshold to gc the oldest tasks
 	DiskGCThreshold unit.Bytes `mapstructure:"diskGCThreshold" yaml:"diskGCThreshold"`
 	// DiskGCThresholdPercent indicates the threshold to gc the oldest tasks according the disk usage
@@ -523,7 +523,7 @@ type HealthOption struct {
 }
 
 type ReloadOption struct {
-	Interval clientutil.Duration
+	Interval util.Duration
 }
 
 type FileString string
diff --git a/client/config/peerhost_darwin.go b/client/config/peerhost_darwin.go
index 41936c6a..310a4d86 100644
--- a/client/config/peerhost_darwin.go
+++ b/client/config/peerhost_darwin.go
@@ -25,7 +25,7 @@ import (
 
 	"golang.org/x/time/rate"
 
-	"d7y.io/dragonfly/v2/client/clientutil"
+	"d7y.io/dragonfly/v2/client/util"
 	"d7y.io/dragonfly/v2/manager/model"
 	"d7y.io/dragonfly/v2/pkg/dfnet"
 	"d7y.io/dragonfly/v2/pkg/net/fqdn"
@@ -33,8 +33,8 @@ import (
 )
 
 var peerHostConfig = DaemonOption{
-	AliveTime:   clientutil.Duration{Duration: DefaultDaemonAliveTime},
-	GCInterval:  clientutil.Duration{Duration: DefaultGCInterval},
+	AliveTime:   util.Duration{Duration: DefaultDaemonAliveTime},
+	GCInterval:  util.Duration{Duration: DefaultGCInterval},
 	KeepStorage: false,
 	Scheduler: SchedulerOption{
 		Manager: ManagerOption{
@@ -55,7 +55,7 @@ var peerHostConfig = DaemonOption{
 				Addr: "127.0.0.1:8002",
 			},
 		},
-		ScheduleTimeout: clientutil.Duration{Duration: DefaultScheduleTimeout},
+		ScheduleTimeout: util.Duration{Duration: DefaultScheduleTimeout},
 	},
 	Host: HostOption{
 		Hostname:       fqdn.FQDNHostname,
@@ -71,10 +71,10 @@ var peerHostConfig = DaemonOption{
 		CalculateDigest:      true,
 		PieceDownloadTimeout: 30 * time.Second,
 		GetPiecesMaxRetry:    100,
-		TotalRateLimit: clientutil.RateLimit{
+		TotalRateLimit: util.RateLimit{
 			Limit: rate.Limit(DefaultTotalDownloadLimit),
 		},
-		PerPeerRateLimit: clientutil.RateLimit{
+		PerPeerRateLimit: util.RateLimit{
 			Limit: rate.Limit(DefaultPerPeerDownloadLimit),
 		},
 		DownloadGRPC: ListenOption{
@@ -101,7 +101,7 @@ var peerHostConfig = DaemonOption{
 		},
 	},
 	Upload: UploadOption{
-		RateLimit: clientutil.RateLimit{
+		RateLimit: util.RateLimit{
 			Limit: rate.Limit(DefaultUploadLimit),
 		},
 		ListenOption: ListenOption{
@@ -149,7 +149,7 @@ var peerHostConfig = DaemonOption{
 		},
 	},
 	Storage: StorageOption{
-		TaskExpireTime: clientutil.Duration{
+		TaskExpireTime: util.Duration{
 			Duration: DefaultTaskExpireTime,
 		},
 		StoreStrategy:          AdvanceLocalTaskStoreStrategy,
@@ -157,7 +157,7 @@ var peerHostConfig = DaemonOption{
 		DiskGCThresholdPercent: 95,
 	},
 	Reload: ReloadOption{
-		Interval: clientutil.Duration{
+		Interval: util.Duration{
 			Duration: time.Minute,
 		},
 	},
diff --git a/client/config/peerhost_linux.go b/client/config/peerhost_linux.go
index 02dd14d3..711b6e43 100644
--- a/client/config/peerhost_linux.go
+++ b/client/config/peerhost_linux.go
@@ -25,7 +25,7 @@ import (
 
 	"golang.org/x/time/rate"
 
-	"d7y.io/dragonfly/v2/client/clientutil"
+	"d7y.io/dragonfly/v2/client/util"
 	"d7y.io/dragonfly/v2/manager/model"
 	"d7y.io/dragonfly/v2/pkg/dfnet"
 	"d7y.io/dragonfly/v2/pkg/net/fqdn"
@@ -33,8 +33,8 @@ import (
 )
 
 var peerHostConfig = DaemonOption{
-	AliveTime:   clientutil.Duration{Duration: DefaultDaemonAliveTime},
-	GCInterval:  clientutil.Duration{Duration: DefaultGCInterval},
+	AliveTime:   util.Duration{Duration: DefaultDaemonAliveTime},
+	GCInterval:  util.Duration{Duration: DefaultGCInterval},
 	KeepStorage: false,
 	Scheduler: SchedulerOption{
 		Manager: ManagerOption{
@@ -55,7 +55,7 @@ var peerHostConfig = DaemonOption{
 				Addr: "127.0.0.1:8002",
 			},
 		},
-		ScheduleTimeout: clientutil.Duration{Duration: DefaultScheduleTimeout},
+		ScheduleTimeout: util.Duration{Duration: DefaultScheduleTimeout},
 	},
 	Host: HostOption{
 		Hostname:       fqdn.FQDNHostname,
@@ -71,10 +71,10 @@ var peerHostConfig = DaemonOption{
 		CalculateDigest:      true,
 		PieceDownloadTimeout: 30 * time.Second,
 		GetPiecesMaxRetry:    100,
-		TotalRateLimit: clientutil.RateLimit{
+		TotalRateLimit: util.RateLimit{
 			Limit: rate.Limit(DefaultTotalDownloadLimit),
 		},
-		PerPeerRateLimit: clientutil.RateLimit{
+		PerPeerRateLimit: util.RateLimit{
 			Limit: rate.Limit(DefaultPerPeerDownloadLimit),
 		},
 		DownloadGRPC: ListenOption{
@@ -100,7 +100,7 @@ var peerHostConfig = DaemonOption{
 		},
 	},
 	Upload: UploadOption{
-		RateLimit: clientutil.RateLimit{
+		RateLimit: util.RateLimit{
 			Limit: rate.Limit(DefaultUploadLimit),
 		},
 		ListenOption: ListenOption{
@@ -148,7 +148,7 @@ var peerHostConfig = DaemonOption{
 		},
 	},
 	Storage: StorageOption{
-		TaskExpireTime: clientutil.Duration{
+		TaskExpireTime: util.Duration{
 			Duration: DefaultTaskExpireTime,
 		},
 		StoreStrategy:          AdvanceLocalTaskStoreStrategy,
@@ -156,7 +156,7 @@ var peerHostConfig = DaemonOption{
 		DiskGCThresholdPercent: 95,
 	},
 	Reload: ReloadOption{
-		Interval: clientutil.Duration{
+		Interval: util.Duration{
 			Duration: time.Minute,
 		},
 	},
diff --git a/client/daemon/daemon.go b/client/daemon/daemon.go
index 5538f4f0..19bf4287 100644
--- a/client/daemon/daemon.go
+++ b/client/daemon/daemon.go
@@ -37,7 +37,6 @@ import (
 	"google.golang.org/grpc"
 	"google.golang.org/grpc/credentials"
 
-	"d7y.io/dragonfly/v2/client/clientutil"
 	"d7y.io/dragonfly/v2/client/config"
 	"d7y.io/dragonfly/v2/client/daemon/gc"
 	"d7y.io/dragonfly/v2/client/daemon/metrics"
@@ -47,6 +46,7 @@ import (
 	"d7y.io/dragonfly/v2/client/daemon/rpcserver"
 	"d7y.io/dragonfly/v2/client/daemon/storage"
 	"d7y.io/dragonfly/v2/client/daemon/upload"
+	"d7y.io/dragonfly/v2/client/util"
 	logger "d7y.io/dragonfly/v2/internal/dflog"
 	"d7y.io/dragonfly/v2/pkg/dfnet"
 	"d7y.io/dragonfly/v2/pkg/dfpath"
@@ -530,7 +530,7 @@ func (cd *clientDaemon) Serve() error {
 			for {
 				select {
 				case <-time.After(cd.Option.AliveTime.Duration):
-					var keepalives = []clientutil.KeepAlive{
+					var keepalives = []util.KeepAlive{
 						cd.StorageManager,
 						cd.RPCManager,
 					}
diff --git a/client/daemon/objectstorage/objectstorage.go b/client/daemon/objectstorage/objectstorage.go
index 7a72a92b..f806c8cd 100644
--- a/client/daemon/objectstorage/objectstorage.go
+++ b/client/daemon/objectstorage/objectstorage.go
@@ -40,10 +40,10 @@ import (
 	ginprometheus "github.com/mcuadros/go-gin-prometheus"
 	"go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin"
 
-	"d7y.io/dragonfly/v2/client/clientutil"
 	"d7y.io/dragonfly/v2/client/config"
 	"d7y.io/dragonfly/v2/client/daemon/peer"
 	"d7y.io/dragonfly/v2/client/daemon/storage"
+	"d7y.io/dragonfly/v2/client/util"
 	logger "d7y.io/dragonfly/v2/internal/dflog"
 	"d7y.io/dragonfly/v2/pkg/digest"
 	"d7y.io/dragonfly/v2/pkg/idgen"
@@ -233,8 +233,8 @@ func (o *objectStorage) getObject(ctx *gin.Context) {
 		bucketName    = params.ID
 		objectKey     = strings.TrimPrefix(params.ObjectKey, "/")
 		filter        = query.Filter
-		artifactRange *clientutil.Range
-		ranges        []clientutil.Range
+		artifactRange *util.Range
+		ranges        []util.Range
 		err           error
 	)
 
@@ -641,8 +641,8 @@ func (o *objectStorage) client() (objectstorage.ObjectStorage, error) {
 }
 
 // parseRangeHeader uses to parse range http header for dragonfly.
-func (o *objectStorage) parseRangeHeader(rangeHeader string) ([]clientutil.Range, error) {
-	ranges, err := clientutil.ParseRange(rangeHeader, math.MaxInt)
+func (o *objectStorage) parseRangeHeader(rangeHeader string) ([]util.Range, error) {
+	ranges, err := util.ParseRange(rangeHeader, math.MaxInt)
 	if err != nil {
 		return nil, err
 	}
diff --git a/client/daemon/peer/peertask_conductor.go b/client/daemon/peer/peertask_conductor.go
index 646e124f..91a0b213 100644
--- a/client/daemon/peer/peertask_conductor.go
+++ b/client/daemon/peer/peertask_conductor.go
@@ -31,10 +31,10 @@ import (
 	"go.uber.org/atomic"
 	"golang.org/x/time/rate"
 
-	"d7y.io/dragonfly/v2/client/clientutil"
 	"d7y.io/dragonfly/v2/client/config"
 	"d7y.io/dragonfly/v2/client/daemon/metrics"
 	"d7y.io/dragonfly/v2/client/daemon/storage"
+	"d7y.io/dragonfly/v2/client/util"
 	"d7y.io/dragonfly/v2/internal/dferrors"
 	logger "d7y.io/dragonfly/v2/internal/dflog"
 	"d7y.io/dragonfly/v2/pkg/digest"
@@ -161,7 +161,7 @@ type peerTaskConductor struct {
 
 	// subtask only
 	parent *peerTaskConductor
-	rg     *clientutil.Range
+	rg     *util.Range
 }
 
 func (ptm *peerTaskManager) newPeerTaskConductor(
@@ -169,7 +169,7 @@ func (ptm *peerTaskManager) newPeerTaskConductor(
 	request *scheduler.PeerTaskRequest,
 	limit rate.Limit,
 	parent *peerTaskConductor,
-	rg *clientutil.Range,
+	rg *util.Range,
 	seed bool) *peerTaskConductor {
 	// use a new context with span info
 	ctx = trace.ContextWithSpan(context.Background(), trace.SpanFromContext(ctx))
@@ -575,7 +575,7 @@ func (pt *peerTaskConductor) storeTinyPeerTask() {
 				Num:    0,
 				Md5:    "",
 				Offset: 0,
-				Range: clientutil.Range{
+				Range: util.Range{
 					Start:  0,
 					Length: contentLength,
 				},
diff --git a/client/daemon/peer/peertask_file.go b/client/daemon/peer/peertask_file.go
index fbb7571a..e2d6591f 100644
--- a/client/daemon/peer/peertask_file.go
+++ b/client/daemon/peer/peertask_file.go
@@ -23,10 +23,10 @@ import (
 	"go.opentelemetry.io/otel/trace"
 	"golang.org/x/time/rate"
 
-	"d7y.io/dragonfly/v2/client/clientutil"
 	"d7y.io/dragonfly/v2/client/config"
 	"d7y.io/dragonfly/v2/client/daemon/metrics"
 	"d7y.io/dragonfly/v2/client/daemon/storage"
+	"d7y.io/dragonfly/v2/client/util"
 	logger "d7y.io/dragonfly/v2/internal/dflog"
 	"d7y.io/dragonfly/v2/pkg/idgen"
 	"d7y.io/dragonfly/v2/pkg/rpc/base"
@@ -39,7 +39,7 @@ type FileTaskRequest struct {
 	Limit              float64
 	DisableBackSource  bool
 	Callsystem         string
-	Range              *clientutil.Range
+	Range              *util.Range
 	KeepOriginalOffset bool
 }
 
diff --git a/client/daemon/peer/peertask_manager.go b/client/daemon/peer/peertask_manager.go
index 24f943b1..d488982b 100644
--- a/client/daemon/peer/peertask_manager.go
+++ b/client/daemon/peer/peertask_manager.go
@@ -31,10 +31,10 @@ import (
 	"go.opentelemetry.io/otel/trace"
 	"golang.org/x/time/rate"
 
-	"d7y.io/dragonfly/v2/client/clientutil"
 	"d7y.io/dragonfly/v2/client/config"
 	"d7y.io/dragonfly/v2/client/daemon/metrics"
 	"d7y.io/dragonfly/v2/client/daemon/storage"
+	"d7y.io/dragonfly/v2/client/util"
 	logger "d7y.io/dragonfly/v2/internal/dflog"
 	"d7y.io/dragonfly/v2/pkg/idgen"
 	"d7y.io/dragonfly/v2/pkg/rpc/base"
@@ -183,7 +183,7 @@ func (ptm *peerTaskManager) getPeerTaskConductor(ctx context.Context,
 	request *scheduler.PeerTaskRequest,
 	limit rate.Limit,
 	parent *peerTaskConductor,
-	rg *clientutil.Range,
+	rg *util.Range,
 	desiredLocation string,
 	seed bool) (*peerTaskConductor, error) {
 	ptc, created, err := ptm.getOrCreatePeerTaskConductor(ctx, taskID, request, limit, parent, rg, desiredLocation, seed)
@@ -206,7 +206,7 @@ func (ptm *peerTaskManager) getOrCreatePeerTaskConductor(
 	request *scheduler.PeerTaskRequest,
 	limit rate.Limit,
 	parent *peerTaskConductor,
-	rg *clientutil.Range,
+	rg *util.Range,
 	desiredLocation string,
 	seed bool) (*peerTaskConductor, bool, error) {
 	if ptc, ok := ptm.findPeerTaskConductor(taskID); ok {
@@ -234,7 +234,7 @@ func (ptm *peerTaskManager) getOrCreatePeerTaskConductor(
 	return ptc, true, ptc.initStorage(desiredLocation)
 }
 
-func (ptm *peerTaskManager) enabledPrefetch(rg *clientutil.Range) bool {
+func (ptm *peerTaskManager) enabledPrefetch(rg *util.Range) bool {
 	return ptm.enablePrefetch && rg != nil
 }
 
diff --git a/client/daemon/peer/peertask_reuse.go b/client/daemon/peer/peertask_reuse.go
index 859776c0..558aff98 100644
--- a/client/daemon/peer/peertask_reuse.go
+++ b/client/daemon/peer/peertask_reuse.go
@@ -27,9 +27,9 @@ import (
 	semconv "go.opentelemetry.io/otel/semconv/v1.7.0"
 	"go.opentelemetry.io/otel/trace"
 
-	"d7y.io/dragonfly/v2/client/clientutil"
 	"d7y.io/dragonfly/v2/client/config"
 	"d7y.io/dragonfly/v2/client/daemon/storage"
+	"d7y.io/dragonfly/v2/client/util"
 	logger "d7y.io/dragonfly/v2/internal/dflog"
 	"d7y.io/dragonfly/v2/pkg/idgen"
 	"d7y.io/dragonfly/v2/pkg/rpc/base"
@@ -50,7 +50,7 @@ func (ptm *peerTaskManager) tryReuseFilePeerTask(ctx context.Context,
 	taskID := idgen.TaskID(request.Url, request.UrlMeta)
 	var (
 		reuse      *storage.ReusePeerTask
-		reuseRange *clientutil.Range // the range of parent peer task data to read
+		reuseRange *util.Range // the range of parent peer task data to read
 		log        *logger.SugaredLoggerOnWith
 		length     int64
 		err        error
@@ -162,7 +162,7 @@ func (ptm *peerTaskManager) tryReuseFilePeerTask(ctx context.Context,
 }
 
 func (ptm *peerTaskManager) storePartialFile(ctx context.Context, request *FileTaskRequest,
-	log *logger.SugaredLoggerOnWith, reuse *storage.ReusePeerTask, rg *clientutil.Range) error {
+	log *logger.SugaredLoggerOnWith, reuse *storage.ReusePeerTask, rg *util.Range) error {
 	f, err := os.OpenFile(request.Output, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0644)
 	if err != nil {
 		log.Errorf("open dest file error when reuse peer task: %s", err)
@@ -192,7 +192,7 @@ func (ptm *peerTaskManager) tryReuseStreamPeerTask(ctx context.Context,
 	taskID := idgen.TaskID(request.URL, request.URLMeta)
 	var (
 		reuse      *storage.ReusePeerTask
-		reuseRange *clientutil.Range // the range of parent peer task data to read
+		reuseRange *util.Range // the range of parent peer task data to read
 		log        *logger.SugaredLoggerOnWith
 		length     int64
 	)
@@ -299,7 +299,7 @@ func (ptm *peerTaskManager) tryReuseSeedPeerTask(ctx context.Context,
 	taskID := idgen.TaskID(request.Url, request.UrlMeta)
 	var (
 		reuse      *storage.ReusePeerTask
-		reuseRange *clientutil.Range // the range of parent peer task data to read
+		reuseRange *util.Range // the range of parent peer task data to read
 		log        *logger.SugaredLoggerOnWith
 	)
 
diff --git a/client/daemon/peer/peertask_seed.go b/client/daemon/peer/peertask_seed.go
index d82d506f..03ca7a61 100644
--- a/client/daemon/peer/peertask_seed.go
+++ b/client/daemon/peer/peertask_seed.go
@@ -22,8 +22,8 @@ import (
 	"go.opentelemetry.io/otel/trace"
 	"golang.org/x/time/rate"
 
-	"d7y.io/dragonfly/v2/client/clientutil"
 	"d7y.io/dragonfly/v2/client/config"
+	"d7y.io/dragonfly/v2/client/util"
 	"d7y.io/dragonfly/v2/pkg/idgen"
 	"d7y.io/dragonfly/v2/pkg/rpc/scheduler"
 )
@@ -32,7 +32,7 @@ type SeedTaskRequest struct {
 	scheduler.PeerTaskRequest
 	Limit      float64
 	Callsystem string
-	Range      *clientutil.Range
+	Range      *util.Range
 }
 
 type SeedTaskResponse struct {
diff --git a/client/daemon/peer/peertask_stream.go b/client/daemon/peer/peertask_stream.go
index 58d48db6..b71b616a 100644
--- a/client/daemon/peer/peertask_stream.go
+++ b/client/daemon/peer/peertask_stream.go
@@ -25,10 +25,10 @@ import (
 	"go.opentelemetry.io/otel/trace"
 	"golang.org/x/time/rate"
 
-	"d7y.io/dragonfly/v2/client/clientutil"
 	"d7y.io/dragonfly/v2/client/config"
 	"d7y.io/dragonfly/v2/client/daemon/metrics"
 	"d7y.io/dragonfly/v2/client/daemon/storage"
+	"d7y.io/dragonfly/v2/client/util"
 	logger "d7y.io/dragonfly/v2/internal/dflog"
 	"d7y.io/dragonfly/v2/pkg/idgen"
 	"d7y.io/dragonfly/v2/pkg/rpc/base"
@@ -41,7 +41,7 @@ type StreamTaskRequest struct {
 	// url meta info
 	URLMeta *base.UrlMeta
 	// http range
-	Range *clientutil.Range
+	Range *util.Range
 	// peer's id and must be global uniqueness
 	PeerID string
 	// Pattern to register to scheduler
@@ -67,7 +67,7 @@ type streamTask struct {
 func (ptm *peerTaskManager) newStreamTask(
 	ctx context.Context,
 	request *scheduler.PeerTaskRequest,
-	rg *clientutil.Range) (*streamTask, error) {
+	rg *util.Range) (*streamTask, error) {
 	metrics.StreamTaskCount.Add(1)
 	var limit = rate.Inf
 	if ptm.perPeerRateLimit > 0 {
diff --git a/client/daemon/peer/piece_manager.go b/client/daemon/peer/piece_manager.go
index da9cc212..12d9e7a5 100644
--- a/client/daemon/peer/piece_manager.go
+++ b/client/daemon/peer/piece_manager.go
@@ -29,9 +29,9 @@ import (
 
 	"golang.org/x/time/rate"
 
-	"d7y.io/dragonfly/v2/client/clientutil"
 	"d7y.io/dragonfly/v2/client/config"
 	"d7y.io/dragonfly/v2/client/daemon/storage"
+	clientutil "d7y.io/dragonfly/v2/client/util"
 	logger "d7y.io/dragonfly/v2/internal/dflog"
 	"d7y.io/dragonfly/v2/internal/util"
 	"d7y.io/dragonfly/v2/pkg/digest"
diff --git a/client/daemon/rpcserver/rpcserver.go b/client/daemon/rpcserver/rpcserver.go
index 6988eb9d..c5b09265 100644
--- a/client/daemon/rpcserver/rpcserver.go
+++ b/client/daemon/rpcserver/rpcserver.go
@@ -35,10 +35,10 @@ import (
 	healthpb "google.golang.org/grpc/health/grpc_health_v1"
 	"google.golang.org/grpc/status"
 
-	"d7y.io/dragonfly/v2/client/clientutil"
 	"d7y.io/dragonfly/v2/client/config"
 	"d7y.io/dragonfly/v2/client/daemon/peer"
 	"d7y.io/dragonfly/v2/client/daemon/storage"
+	"d7y.io/dragonfly/v2/client/util"
 	"d7y.io/dragonfly/v2/internal/dferrors"
 	logger "d7y.io/dragonfly/v2/internal/dflog"
 	"d7y.io/dragonfly/v2/pkg/idgen"
@@ -53,14 +53,14 @@ import (
 )
 
 type Server interface {
-	clientutil.KeepAlive
+	util.KeepAlive
 	ServeDownload(listener net.Listener) error
 	ServePeer(listener net.Listener) error
 	Stop()
 }
 
 type server struct {
-	clientutil.KeepAlive
+	util.KeepAlive
 	peerHost        *scheduler.PeerHost
 	peerTaskManager peer.TaskManager
 	storageManager  storage.Manager
@@ -75,7 +75,7 @@ func New(peerHost *scheduler.PeerHost, peerTaskManager peer.TaskManager,
 	storageManager storage.Manager, defaultPattern base.Pattern,
 	downloadOpts []grpc.ServerOption, peerOpts []grpc.ServerOption) (Server, error) {
 	s := &server{
-		KeepAlive:       clientutil.NewKeepAlive("rpc server"),
+		KeepAlive:       util.NewKeepAlive("rpc server"),
 		peerHost:        peerHost,
 		peerTaskManager: peerTaskManager,
 		storageManager:  storageManager,
@@ -341,7 +341,7 @@ func (s *server) doDownload(ctx context.Context, req *dfdaemongrpc.DownRequest,
 			err = fmt.Errorf("parse range %s error: %s", req.UrlMeta.Range, err)
 			return err
 		}
-		peerTask.Range = &clientutil.Range{
+		peerTask.Range = &util.Range{
 			Start:  int64(r.StartIndex),
 			Length: int64(r.Length()),
 		}
diff --git a/client/daemon/rpcserver/seeder.go b/client/daemon/rpcserver/seeder.go
index 9ad92b91..7e3b4313 100644
--- a/client/daemon/rpcserver/seeder.go
+++ b/client/daemon/rpcserver/seeder.go
@@ -25,10 +25,10 @@ import (
 	"google.golang.org/grpc/codes"
 	"google.golang.org/grpc/status"
 
-	"d7y.io/dragonfly/v2/client/clientutil"
 	"d7y.io/dragonfly/v2/client/config"
 	"d7y.io/dragonfly/v2/client/daemon/metrics"
 	"d7y.io/dragonfly/v2/client/daemon/peer"
+	"d7y.io/dragonfly/v2/client/util"
 	logger "d7y.io/dragonfly/v2/internal/dflog"
 	"d7y.io/dragonfly/v2/pkg/idgen"
 	"d7y.io/dragonfly/v2/pkg/net/http"
@@ -84,7 +84,7 @@ func (s *seeder) ObtainSeeds(seedRequest *cdnsystem.SeedRequest, seedsServer cdn
 			log.Errorf(err.Error())
 			return err
 		}
-		req.Range = &clientutil.Range{
+		req.Range = &util.Range{
 			Start:  int64(r.StartIndex),
 			Length: int64(r.Length()),
 		}
diff --git a/client/daemon/storage/local_storage.go b/client/daemon/storage/local_storage.go
index 8de947ab..b2ee529e 100644
--- a/client/daemon/storage/local_storage.go
+++ b/client/daemon/storage/local_storage.go
@@ -30,7 +30,7 @@ import (
 
 	"go.uber.org/atomic"
 
-	"d7y.io/dragonfly/v2/client/clientutil"
+	clientutil "d7y.io/dragonfly/v2/client/util"
 	logger "d7y.io/dragonfly/v2/internal/dflog"
 	"d7y.io/dragonfly/v2/internal/util"
 	"d7y.io/dragonfly/v2/pkg/digest"
diff --git a/client/daemon/storage/local_storage_subtask.go b/client/daemon/storage/local_storage_subtask.go
index 9403085c..25e4af37 100644
--- a/client/daemon/storage/local_storage_subtask.go
+++ b/client/daemon/storage/local_storage_subtask.go
@@ -24,7 +24,7 @@ import (
 
 	"go.uber.org/atomic"
 
-	"d7y.io/dragonfly/v2/client/clientutil"
+	"d7y.io/dragonfly/v2/client/util"
 	logger "d7y.io/dragonfly/v2/internal/dflog"
 	"d7y.io/dragonfly/v2/pkg/digest"
 	"d7y.io/dragonfly/v2/pkg/rpc/base"
@@ -40,7 +40,7 @@ type localSubTaskStore struct {
 	// when digest not match, invalid will be set
 	invalid atomic.Bool
 
-	Range *clientutil.Range
+	Range *util.Range
 }
 
 func (t *localSubTaskStore) WritePiece(ctx context.Context, req *WritePieceRequest) (int64, error) {
diff --git a/client/daemon/storage/metadata.go b/client/daemon/storage/metadata.go
index a2fcab12..f89327de 100644
--- a/client/daemon/storage/metadata.go
+++ b/client/daemon/storage/metadata.go
@@ -19,7 +19,7 @@ package storage
 import (
 	"io"
 
-	"d7y.io/dragonfly/v2/client/clientutil"
+	"d7y.io/dragonfly/v2/client/util"
 	"d7y.io/dragonfly/v2/pkg/rpc/base"
 	"d7y.io/dragonfly/v2/pkg/source"
 )
@@ -44,11 +44,11 @@ type PeerTaskMetadata struct {
 }
 
 type PieceMetadata struct {
-	Num    int32            `json:"num,omitempty"`
-	Md5    string           `json:"md5,omitempty"`
-	Offset uint64           `json:"offset,omitempty"`
-	Range  clientutil.Range `json:"range,omitempty"`
-	Style  base.PieceStyle  `json:"style,omitempty"`
+	Num    int32           `json:"num,omitempty"`
+	Md5    string          `json:"md5,omitempty"`
+	Offset uint64          `json:"offset,omitempty"`
+	Range  util.Range      `json:"range,omitempty"`
+	Style  base.PieceStyle `json:"style,omitempty"`
 	// time(nanosecond) consumed
 	Cost uint64 `json:"cost,omitempty"`
 }
@@ -93,13 +93,13 @@ type ReadPieceRequest struct {
 
 type ReadAllPiecesRequest struct {
 	PeerTaskMetadata
-	Range *clientutil.Range
+	Range *util.Range
 }
 
 type RegisterSubTaskRequest struct {
 	Parent  PeerTaskMetadata
 	SubTask PeerTaskMetadata
-	Range   *clientutil.Range
+	Range   *util.Range
 }
 
 type UpdateTaskRequest struct {
diff --git a/client/daemon/storage/mocks/stroage_manager_mock.go b/client/daemon/storage/mocks/stroage_manager_mock.go
index f9a7f9ce..92c9de65 100644
--- a/client/daemon/storage/mocks/stroage_manager_mock.go
+++ b/client/daemon/storage/mocks/stroage_manager_mock.go
@@ -10,8 +10,8 @@ import (
 	reflect "reflect"
 	time "time"
 
-	clientutil "d7y.io/dragonfly/v2/client/clientutil"
 	storage "d7y.io/dragonfly/v2/client/daemon/storage"
+	util "d7y.io/dragonfly/v2/client/util"
 	base "d7y.io/dragonfly/v2/pkg/rpc/base"
 	gomock "github.com/golang/mock/gomock"
 )
@@ -328,7 +328,7 @@ func (mr *MockManagerMockRecorder) FindCompletedTask(taskID interface{}) *gomock
 }
 
 // FindPartialCompletedTask mocks base method.
-func (m *MockManager) FindPartialCompletedTask(taskID string, rg *clientutil.Range) *storage.ReusePeerTask {
+func (m *MockManager) FindPartialCompletedTask(taskID string, rg *util.Range) *storage.ReusePeerTask {
 	m.ctrl.T.Helper()
 	ret := m.ctrl.Call(m, "FindPartialCompletedTask", taskID, rg)
 	ret0, _ := ret[0].(*storage.ReusePeerTask)
diff --git a/client/daemon/storage/storage_manager.go b/client/daemon/storage/storage_manager.go
index 382c1ee0..6b012dac 100644
--- a/client/daemon/storage/storage_manager.go
+++ b/client/daemon/storage/storage_manager.go
@@ -38,9 +38,9 @@ import (
 	"go.opentelemetry.io/otel"
 	"go.opentelemetry.io/otel/trace"
 
-	"d7y.io/dragonfly/v2/client/clientutil"
 	"d7y.io/dragonfly/v2/client/config"
 	"d7y.io/dragonfly/v2/client/daemon/gc"
+	"d7y.io/dragonfly/v2/client/util"
 	logger "d7y.io/dragonfly/v2/internal/dflog"
 	"d7y.io/dragonfly/v2/pkg/rpc/base"
 )
@@ -87,7 +87,7 @@ type Reclaimer interface {
 type Manager interface {
 	TaskStorageDriver
 	// KeepAlive tests if storage is used in given time duration
-	clientutil.KeepAlive
+	util.KeepAlive
 	// RegisterTask registers a task in storage driver
 	RegisterTask(ctx context.Context, req *RegisterTaskRequest) (TaskStorageDriver, error)
 	// RegisterSubTask registers a subtask in storage driver
@@ -99,7 +99,7 @@ type Manager interface {
 	// FindCompletedSubTask try to find a completed subtask for fast path
 	FindCompletedSubTask(taskID string) *ReusePeerTask
 	// FindPartialCompletedTask try to find a partial completed task for fast path
-	FindPartialCompletedTask(taskID string, rg *clientutil.Range) *ReusePeerTask
+	FindPartialCompletedTask(taskID string, rg *util.Range) *ReusePeerTask
 	// CleanUp cleans all storage data
 	CleanUp()
 }
@@ -125,7 +125,7 @@ func init() {
 
 type storageManager struct {
 	sync.Mutex
-	clientutil.KeepAlive
+	util.KeepAlive
 	storeStrategy      config.StoreStrategy
 	storeOption        *config.StorageOption
 	tasks              sync.Map
@@ -173,7 +173,7 @@ func NewStorageManager(storeStrategy config.StoreStrategy, opt *config.StorageOp
 	}
 
 	s := &storageManager{
-		KeepAlive:             clientutil.NewKeepAlive("storage manager"),
+		KeepAlive:             util.NewKeepAlive("storage manager"),
 		storeStrategy:         storeStrategy,
 		storeOption:           opt,
 		dataPathStat:          stat.Sys().(*syscall.Stat_t),
@@ -515,7 +515,7 @@ func (s *storageManager) FindCompletedTask(taskID string) *ReusePeerTask {
 	return nil
 }
 
-func (s *storageManager) FindPartialCompletedTask(taskID string, rg *clientutil.Range) *ReusePeerTask {
+func (s *storageManager) FindPartialCompletedTask(taskID string, rg *util.Range) *ReusePeerTask {
 	s.indexRWMutex.RLock()
 	defer s.indexRWMutex.RUnlock()
 	ts, ok := s.indexTask2PeerTask[taskID]
diff --git a/client/daemon/transport/transport.go b/client/daemon/transport/transport.go
index 375f8fa9..954248ea 100644
--- a/client/daemon/transport/transport.go
+++ b/client/daemon/transport/transport.go
@@ -34,10 +34,10 @@ import (
 	"github.com/go-http-utils/headers"
 	"go.opentelemetry.io/otel/propagation"
 
-	"d7y.io/dragonfly/v2/client/clientutil"
 	"d7y.io/dragonfly/v2/client/config"
 	"d7y.io/dragonfly/v2/client/daemon/metrics"
 	"d7y.io/dragonfly/v2/client/daemon/peer"
+	"d7y.io/dragonfly/v2/client/util"
 	logger "d7y.io/dragonfly/v2/internal/dflog"
 	nethttp "d7y.io/dragonfly/v2/pkg/net/http"
 	"d7y.io/dragonfly/v2/pkg/rpc/base"
@@ -214,11 +214,11 @@ func (rt *transport) download(ctx context.Context, req *http.Request) (*http.Res
 
 	// Init meta value
 	meta := &base.UrlMeta{Header: map[string]string{}}
-	var rg *clientutil.Range
+	var rg *util.Range
 
 	// Set meta range's value
 	if rangeHeader := req.Header.Get("Range"); len(rangeHeader) > 0 {
-		rgs, err := clientutil.ParseRange(rangeHeader, math.MaxInt)
+		rgs, err := util.ParseRange(rangeHeader, math.MaxInt)
 		if err != nil {
 			return badRequest(req, err.Error())
 		}
diff --git a/client/daemon/upload/upload_manager.go b/client/daemon/upload/upload_manager.go
index 7c633260..84eacb7f 100644
--- a/client/daemon/upload/upload_manager.go
+++ b/client/daemon/upload/upload_manager.go
@@ -34,9 +34,9 @@ import (
 	"go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin"
 	"golang.org/x/time/rate"
 
-	"d7y.io/dragonfly/v2/client/clientutil"
 	"d7y.io/dragonfly/v2/client/config"
 	"d7y.io/dragonfly/v2/client/daemon/storage"
+	"d7y.io/dragonfly/v2/client/util"
 	logger "d7y.io/dragonfly/v2/internal/dflog"
 )
 
@@ -164,7 +164,7 @@ func (um *uploadManager) getDownload(ctx *gin.Context) {
 
 	log := logger.WithTaskAndPeerID(taskID, peerID).With("component", "uploadManager")
 	log.Debugf("upload piece for task %s/%s to %s, request header: %#v", taskID, peerID, ctx.Request.RemoteAddr, ctx.Request.Header)
-	rg, err := clientutil.ParseRange(ctx.GetHeader(headers.Range), math.MaxInt64)
+	rg, err := util.ParseRange(ctx.GetHeader(headers.Range), math.MaxInt64)
 	if err != nil {
 		log.Errorf("parse range with error: %s", err)
 		ctx.JSON(http.StatusBadRequest, gin.H{"errors": err.Error()})
diff --git a/client/clientutil/keepalive.go b/client/util/keepalive.go
similarity index 98%
rename from client/clientutil/keepalive.go
rename to client/util/keepalive.go
index 57ecd886..26fdb0e5 100644
--- a/client/clientutil/keepalive.go
+++ b/client/util/keepalive.go
@@ -16,7 +16,7 @@
 
 //go:generate mockgen -destination mocks/keepalive_mock.go -source keepalive.go -package mocks
 
-package clientutil
+package util
 
 import (
 	"time"
diff --git a/client/clientutil/mocks/keepalive_mock.go b/client/util/mocks/keepalive_mock.go
similarity index 100%
rename from client/clientutil/mocks/keepalive_mock.go
rename to client/util/mocks/keepalive_mock.go
diff --git a/client/clientutil/range.go b/client/util/range.go
similarity index 99%
rename from client/clientutil/range.go
rename to client/util/range.go
index 8d1f32de..327b2f82 100644
--- a/client/clientutil/range.go
+++ b/client/util/range.go
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package clientutil
+package util
 
 import (
 	"errors"
diff --git a/client/clientutil/types.go b/client/util/types.go
similarity index 99%
rename from client/clientutil/types.go
rename to client/util/types.go
index 906a90a5..53463d68 100644
--- a/client/clientutil/types.go
+++ b/client/util/types.go
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package clientutil
+package util
 
 import (
 	"encoding/json"
diff --git a/cmd/dependency/dependency.go b/cmd/dependency/dependency.go
index 3b847b7d..0f058533 100644
--- a/cmd/dependency/dependency.go
+++ b/cmd/dependency/dependency.go
@@ -41,8 +41,8 @@ import (
 	semconv "go.opentelemetry.io/otel/semconv/v1.7.0"
 	"gopkg.in/yaml.v3"
 
-	"d7y.io/dragonfly/v2/client/clientutil"
 	"d7y.io/dragonfly/v2/client/config"
+	"d7y.io/dragonfly/v2/client/util"
 	"d7y.io/dragonfly/v2/cmd/dependency/base"
 	logger "d7y.io/dragonfly/v2/internal/dflog"
 	"d7y.io/dragonfly/v2/pkg/dfnet"
@@ -191,8 +191,8 @@ func initDecoderConfig(dc *mapstructure.DecoderConfig) {
 		switch to {
 		case reflect.TypeOf(unit.B),
 			reflect.TypeOf(dfnet.NetAddr{}),
-			reflect.TypeOf(clientutil.RateLimit{}),
-			reflect.TypeOf(clientutil.Duration{}),
+			reflect.TypeOf(util.RateLimit{}),
+			reflect.TypeOf(util.Duration{}),
 			reflect.TypeOf(&config.ProxyOption{}),
 			reflect.TypeOf(config.TCPListenPortRange{}),
 			reflect.TypeOf(config.FileString("")),


Test patch:
diff --git a/client/config/peerhost_test.go b/client/config/peerhost_test.go
index 2f524073..02cfbc39 100644
--- a/client/config/peerhost_test.go
+++ b/client/config/peerhost_test.go
@@ -25,7 +25,7 @@ import (
 	testifyassert "github.com/stretchr/testify/assert"
 	"gopkg.in/yaml.v3"
 
-	"d7y.io/dragonfly/v2/client/clientutil"
+	"d7y.io/dragonfly/v2/client/util"
 	"d7y.io/dragonfly/v2/manager/model"
 	"d7y.io/dragonfly/v2/pkg/dfnet"
 	"d7y.io/dragonfly/v2/pkg/unit"
@@ -69,9 +69,9 @@ port:
 timeout: 1000000000
 `,
 			target: &struct {
-				Timeout clientutil.Duration `yaml:"timeout"`
+				Timeout util.Duration `yaml:"timeout"`
 			}{
-				Timeout: clientutil.Duration{
+				Timeout: util.Duration{
 					Duration: time.Second,
 				},
 			},
@@ -81,9 +81,9 @@ timeout: 1000000000
 timeout: 1s
 `,
 			target: &struct {
-				Timeout clientutil.Duration `yaml:"timeout"`
+				Timeout util.Duration `yaml:"timeout"`
 			}{
-				Timeout: clientutil.Duration{
+				Timeout: util.Duration{
 					Duration: time.Second,
 				},
 			},
@@ -93,9 +93,9 @@ timeout: 1s
 limit: 100Mi
 `,
 			target: &struct {
-				Limit clientutil.RateLimit `yaml:"limit"`
+				Limit util.RateLimit `yaml:"limit"`
 			}{
-				Limit: clientutil.RateLimit{
+				Limit: util.RateLimit{
 					Limit: 100 * 1024 * 1024,
 				},
 			},
@@ -105,9 +105,9 @@ limit: 100Mi
 limit: 2097152
 `,
 			target: &struct {
-				Limit clientutil.RateLimit `yaml:"limit"`
+				Limit util.RateLimit `yaml:"limit"`
 			}{
-				Limit: clientutil.RateLimit{
+				Limit: util.RateLimit{
 					Limit: 2 * 1024 * 1024,
 				},
 			},
@@ -192,19 +192,19 @@ schedulers2:
 `)
 
 	var s = struct {
-		TLSConfig   *TLSConfig           `yaml:"tls"`
-		URL         *URL                 `yaml:"url"`
-		Certs       *CertPool            `yaml:"certs"`
-		Regx        *Regexp              `yaml:"regx"`
-		Port1       TCPListenPortRange   `yaml:"port1"`
-		Port2       TCPListenPortRange   `yaml:"port2"`
-		Timeout     clientutil.Duration  `yaml:"timeout"`
-		Limit       clientutil.RateLimit `yaml:"limit"`
-		Type        dfnet.NetworkType    `yaml:"type"`
-		Proxy1      ProxyOption          `yaml:"proxy1"`
-		Proxy2      ProxyOption          `yaml:"proxy2"`
-		Schedulers1 SchedulerOption      `yaml:"schedulers1"`
-		Schedulers2 SchedulerOption      `yaml:"schedulers2"`
+		TLSConfig   *TLSConfig         `yaml:"tls"`
+		URL         *URL               `yaml:"url"`
+		Certs       *CertPool          `yaml:"certs"`
+		Regx        *Regexp            `yaml:"regx"`
+		Port1       TCPListenPortRange `yaml:"port1"`
+		Port2       TCPListenPortRange `yaml:"port2"`
+		Timeout     util.Duration      `yaml:"timeout"`
+		Limit       util.RateLimit     `yaml:"limit"`
+		Type        dfnet.NetworkType  `yaml:"type"`
+		Proxy1      ProxyOption        `yaml:"proxy1"`
+		Proxy2      ProxyOption        `yaml:"proxy2"`
+		Schedulers1 SchedulerOption    `yaml:"schedulers1"`
+		Schedulers2 SchedulerOption    `yaml:"schedulers2"`
 	}{}
 
 	if err := yaml.Unmarshal(bytes, &s); err != nil {
@@ -219,10 +219,10 @@ func TestPeerHostOption_Load(t *testing.T) {
 	hijackExp, _ := NewRegexp("mirror.aliyuncs.com:443")
 
 	peerHostOption := &DaemonOption{
-		AliveTime: clientutil.Duration{
+		AliveTime: util.Duration{
 			Duration: 0,
 		},
-		GCInterval: clientutil.Duration{
+		GCInterval: util.Duration{
 			Duration: 60000000000,
 		},
 		WorkHome:    "/tmp/dragonfly/dfdaemon/",
@@ -255,7 +255,7 @@ func TestPeerHostOption_Load(t *testing.T) {
 					Addr: "127.0.0.1:8002",
 				},
 			},
-			ScheduleTimeout: clientutil.Duration{
+			ScheduleTimeout: util.Duration{
 				Duration: 0,
 			},
 		},
@@ -270,10 +270,10 @@ func TestPeerHostOption_Load(t *testing.T) {
 		},
 		Download: DownloadOption{
 			PieceDownloadTimeout: 30 * time.Second,
-			TotalRateLimit: clientutil.RateLimit{
+			TotalRateLimit: util.RateLimit{
 				Limit: 209715200,
 			},
-			PerPeerRateLimit: clientutil.RateLimit{
+			PerPeerRateLimit: util.RateLimit{
 				Limit: 20971520,
 			},
 			DownloadGRPC: ListenOption{
@@ -306,7 +306,7 @@ func TestPeerHostOption_Load(t *testing.T) {
 			},
 		},
 		Upload: UploadOption{
-			RateLimit: clientutil.RateLimit{
+			RateLimit: util.RateLimit{
 				Limit: 104857600,
 			},
 			ListenOption: ListenOption{
@@ -349,7 +349,7 @@ func TestPeerHostOption_Load(t *testing.T) {
 		},
 		Storage: StorageOption{
 			DataPath: "/tmp/storage/data",
-			TaskExpireTime: clientutil.Duration{
+			TaskExpireTime: util.Duration{
 				Duration: 180000000000,
 			},
 			StoreStrategy: StoreStrategy("io.d7y.storage.v2.simple"),
diff --git a/client/daemon/peer/peertask_manager_test.go b/client/daemon/peer/peertask_manager_test.go
index 98779720..fd23118f 100644
--- a/client/daemon/peer/peertask_manager_test.go
+++ b/client/daemon/peer/peertask_manager_test.go
@@ -42,10 +42,10 @@ import (
 	"google.golang.org/grpc/codes"
 	"google.golang.org/grpc/status"
 
-	"d7y.io/dragonfly/v2/client/clientutil"
 	"d7y.io/dragonfly/v2/client/config"
 	"d7y.io/dragonfly/v2/client/daemon/storage"
 	"d7y.io/dragonfly/v2/client/daemon/test"
+	"d7y.io/dragonfly/v2/client/util"
 	"d7y.io/dragonfly/v2/internal/dferrors"
 	logger "d7y.io/dragonfly/v2/internal/dflog"
 	"d7y.io/dragonfly/v2/pkg/dfnet"
@@ -266,7 +266,7 @@ func setupPeerTaskManagerComponents(ctrl *gomock.Controller, opt componentsOptio
 		config.SimpleLocalTaskStoreStrategy,
 		&config.StorageOption{
 			DataPath: tempDir,
-			TaskExpireTime: clientutil.Duration{
+			TaskExpireTime: util.Duration{
 				Duration: -1 * time.Second,
 			},
 		}, func(request storage.CommonTaskRequest) {})
@@ -289,9 +289,9 @@ func (m *mockManager) CleanUp() {
 
 func setupMockManager(ctrl *gomock.Controller, ts *testSpec, opt componentsOption) *mockManager {
 	schedulerClient, storageManager := setupPeerTaskManagerComponents(ctrl, opt)
-	scheduleTimeout := clientutil.Duration{Duration: 10 * time.Minute}
+	scheduleTimeout := util.Duration{Duration: 10 * time.Minute}
 	if ts.scheduleTimeout > 0 {
-		scheduleTimeout = clientutil.Duration{Duration: ts.scheduleTimeout}
+		scheduleTimeout = util.Duration{Duration: ts.scheduleTimeout}
 	}
 	ptm := &peerTaskManager{
 		calculateDigest: true,
@@ -333,7 +333,7 @@ type testSpec struct {
 	taskType           int
 	name               string
 	taskData           []byte
-	httpRange          *clientutil.Range // only used in back source cases
+	httpRange          *util.Range // only used in back source cases
 	pieceParallelCount int32
 	pieceSize          int
 	sizeScope          base.SizeScope
@@ -350,7 +350,7 @@ type testSpec struct {
 	backSource      bool
 
 	mockPieceDownloader  func(ctrl *gomock.Controller, taskData []byte, pieceSize int) PieceDownloader
-	mockHTTPSourceClient func(t *testing.T, ctrl *gomock.Controller, rg *clientutil.Range, taskData []byte, url string) source.ResourceClient
+	mockHTTPSourceClient func(t *testing.T, ctrl *gomock.Controller, rg *util.Range, taskData []byte, url string) source.ResourceClient
 
 	cleanUp []func()
 }
@@ -423,7 +423,7 @@ func TestPeerTaskManager_TaskSuite(t *testing.T) {
 			url:                 "http://localhost/test/data",
 			sizeScope:           base.SizeScope_NORMAL,
 			mockPieceDownloader: nil,
-			mockHTTPSourceClient: func(t *testing.T, ctrl *gomock.Controller, rg *clientutil.Range, taskData []byte, url string) source.ResourceClient {
+			mockHTTPSourceClient: func(t *testing.T, ctrl *gomock.Controller, rg *util.Range, taskData []byte, url string) source.ResourceClient {
 				sourceClient := sourcemocks.NewMockResourceClient(ctrl)
 				sourceClient.EXPECT().GetContentLength(source.RequestEq(url)).AnyTimes().DoAndReturn(
 					func(request *source.Request) (int64, error) {
@@ -446,18 +446,18 @@ func TestPeerTaskManager_TaskSuite(t *testing.T) {
 			backSource:         true,
 			url:                "http://localhost/test/data",
 			sizeScope:          base.SizeScope_NORMAL,
-			httpRange: &clientutil.Range{
+			httpRange: &util.Range{
 				Start:  0,
 				Length: 4096,
 			},
 			mockPieceDownloader: nil,
-			mockHTTPSourceClient: func(t *testing.T, ctrl *gomock.Controller, rg *clientutil.Range, taskData []byte, url string) source.ResourceClient {
+			mockHTTPSourceClient: func(t *testing.T, ctrl *gomock.Controller, rg *util.Range, taskData []byte, url string) source.ResourceClient {
 				sourceClient := sourcemocks.NewMockResourceClient(ctrl)
 				sourceClient.EXPECT().GetContentLength(source.RequestEq(url)).AnyTimes().DoAndReturn(
 					func(request *source.Request) (int64, error) {
 						assert := testifyassert.New(t)
 						if rg != nil {
-							rgs, err := clientutil.ParseRange(request.Header.Get(headers.Range), math.MaxInt)
+							rgs, err := util.ParseRange(request.Header.Get(headers.Range), math.MaxInt)
 							assert.Nil(err)
 							assert.Equal(1, len(rgs))
 							assert.Equal(rg.String(), rgs[0].String())
@@ -468,7 +468,7 @@ func TestPeerTaskManager_TaskSuite(t *testing.T) {
 					func(request *source.Request) (*source.Response, error) {
 						assert := testifyassert.New(t)
 						if rg != nil {
-							rgs, err := clientutil.ParseRange(request.Header.Get(headers.Range), math.MaxInt)
+							rgs, err := util.ParseRange(request.Header.Get(headers.Range), math.MaxInt)
 							assert.Nil(err)
 							assert.Equal(1, len(rgs))
 							assert.Equal(rg.String(), rgs[0].String())
@@ -489,7 +489,7 @@ func TestPeerTaskManager_TaskSuite(t *testing.T) {
 			url:                 "http://localhost/test/data",
 			sizeScope:           base.SizeScope_NORMAL,
 			mockPieceDownloader: nil,
-			mockHTTPSourceClient: func(t *testing.T, ctrl *gomock.Controller, rg *clientutil.Range, taskData []byte, url string) source.ResourceClient {
+			mockHTTPSourceClient: func(t *testing.T, ctrl *gomock.Controller, rg *util.Range, taskData []byte, url string) source.ResourceClient {
 				sourceClient := sourcemocks.NewMockResourceClient(ctrl)
 				sourceClient.EXPECT().GetContentLength(source.RequestEq(url)).AnyTimes().DoAndReturn(
 					func(request *source.Request) (int64, error) {
@@ -513,7 +513,7 @@ func TestPeerTaskManager_TaskSuite(t *testing.T) {
 			url:                 "http://localhost/test/data",
 			sizeScope:           base.SizeScope_NORMAL,
 			mockPieceDownloader: nil,
-			mockHTTPSourceClient: func(t *testing.T, ctrl *gomock.Controller, rg *clientutil.Range, taskData []byte, url string) source.ResourceClient {
+			mockHTTPSourceClient: func(t *testing.T, ctrl *gomock.Controller, rg *util.Range, taskData []byte, url string) source.ResourceClient {
 				sourceClient := sourcemocks.NewMockResourceClient(ctrl)
 				sourceClient.EXPECT().GetContentLength(source.RequestEq(url)).AnyTimes().DoAndReturn(
 					func(request *source.Request) (int64, error) {
diff --git a/client/daemon/peer/peertask_reuse_test.go b/client/daemon/peer/peertask_reuse_test.go
index 9c117608..79f119d3 100644
--- a/client/daemon/peer/peertask_reuse_test.go
+++ b/client/daemon/peer/peertask_reuse_test.go
@@ -29,10 +29,10 @@ import (
 	"github.com/golang/mock/gomock"
 	testifyassert "github.com/stretchr/testify/assert"
 
-	"d7y.io/dragonfly/v2/client/clientutil"
 	"d7y.io/dragonfly/v2/client/daemon/storage"
 	"d7y.io/dragonfly/v2/client/daemon/storage/mocks"
 	"d7y.io/dragonfly/v2/client/daemon/test"
+	"d7y.io/dragonfly/v2/client/util"
 	"d7y.io/dragonfly/v2/pkg/rpc/base"
 	"d7y.io/dragonfly/v2/pkg/rpc/scheduler"
 )
@@ -117,7 +117,7 @@ func TestReuseFilePeerTask(t *testing.T) {
 			enablePrefetch: false,
 			storageManager: func(sm *mocks.MockManager) {
 				//sm.EXPECT().FindPartialCompletedTask(gomock.Any(), gomock.Any()).DoAndReturn(
-				//	func(taskID string, rg *clientutil.Range) *storage.ReusePeerTask {
+				//	func(taskID string, rg *util.Range) *storage.ReusePeerTask {
 				//		return nil
 				//	})
 				//sm.EXPECT().FindCompletedSubTask(gomock.Any()).DoAndReturn(
@@ -149,7 +149,7 @@ func TestReuseFilePeerTask(t *testing.T) {
 					},
 				},
 				Output: testOutput,
-				Range:  &clientutil.Range{Start: 200, Length: 100},
+				Range:  &util.Range{Start: 200, Length: 100},
 			},
 			enablePrefetch: true,
 			storageManager: func(sm *mocks.MockManager) {
@@ -193,12 +193,12 @@ func TestReuseFilePeerTask(t *testing.T) {
 					},
 				},
 				Output: testOutput,
-				Range:  &clientutil.Range{Start: 0, Length: 10},
+				Range:  &util.Range{Start: 0, Length: 10},
 			},
 			enablePrefetch: true,
 			storageManager: func(sm *mocks.MockManager) {
 				sm.EXPECT().FindPartialCompletedTask(gomock.Any(), gomock.Any()).DoAndReturn(
-					func(taskID string, rg *clientutil.Range) *storage.ReusePeerTask {
+					func(taskID string, rg *util.Range) *storage.ReusePeerTask {
 						return nil
 					})
 				sm.EXPECT().FindCompletedSubTask(gomock.Any()).DoAndReturn(
@@ -226,7 +226,7 @@ func TestReuseFilePeerTask(t *testing.T) {
 					},
 				},
 				Output: testOutput,
-				Range:  &clientutil.Range{Start: 300, Length: 100},
+				Range:  &util.Range{Start: 300, Length: 100},
 			},
 			enablePrefetch: true,
 			storageManager: func(sm *mocks.MockManager) {
@@ -236,7 +236,7 @@ func TestReuseFilePeerTask(t *testing.T) {
 						return nil
 					})
 				sm.EXPECT().FindPartialCompletedTask(gomock.Any(), gomock.Any()).DoAndReturn(
-					func(id string, rg *clientutil.Range) *storage.ReusePeerTask {
+					func(id string, rg *util.Range) *storage.ReusePeerTask {
 						taskID = id
 						return &storage.ReusePeerTask{
 							PeerTaskMetadata: storage.PeerTaskMetadata{
@@ -275,7 +275,7 @@ func TestReuseFilePeerTask(t *testing.T) {
 					},
 				},
 				Output: testOutput,
-				Range:  &clientutil.Range{Start: 300, Length: 100000},
+				Range:  &util.Range{Start: 300, Length: 100000},
 			},
 			enablePrefetch: true,
 			storageManager: func(sm *mocks.MockManager) {
@@ -285,7 +285,7 @@ func TestReuseFilePeerTask(t *testing.T) {
 						return nil
 					})
 				sm.EXPECT().FindPartialCompletedTask(gomock.Any(), gomock.Any()).DoAndReturn(
-					func(id string, rg *clientutil.Range) *storage.ReusePeerTask {
+					func(id string, rg *util.Range) *storage.ReusePeerTask {
 						taskID = id
 						return &storage.ReusePeerTask{
 							PeerTaskMetadata: storage.PeerTaskMetadata{
@@ -410,7 +410,7 @@ func TestReuseStreamPeerTask(t *testing.T) {
 			enablePrefetch: false,
 			storageManager: func(sm *mocks.MockManager) {
 				//sm.EXPECT().FindPartialCompletedTask(gomock.Any(), gomock.Any()).DoAndReturn(
-				//	func(taskID string, rg *clientutil.Range) *storage.ReusePeerTask {
+				//	func(taskID string, rg *util.Range) *storage.ReusePeerTask {
 				//		return nil
 				//	})
 				//sm.EXPECT().FindCompletedSubTask(gomock.Any()).DoAndReturn(
@@ -439,7 +439,7 @@ func TestReuseStreamPeerTask(t *testing.T) {
 					Filter: "",
 					Header: nil,
 				},
-				Range:  &clientutil.Range{Start: 0, Length: 10},
+				Range:  &util.Range{Start: 0, Length: 10},
 				PeerID: "",
 			},
 			enablePrefetch: true,
@@ -491,13 +491,13 @@ func TestReuseStreamPeerTask(t *testing.T) {
 					Filter: "",
 					Header: nil,
 				},
-				Range:  &clientutil.Range{Start: 0, Length: 10},
+				Range:  &util.Range{Start: 0, Length: 10},
 				PeerID: "",
 			},
 			enablePrefetch: true,
 			storageManager: func(sm *mocks.MockManager) {
 				sm.EXPECT().FindPartialCompletedTask(gomock.Any(), gomock.Any()).DoAndReturn(
-					func(taskID string, rg *clientutil.Range) *storage.ReusePeerTask {
+					func(taskID string, rg *util.Range) *storage.ReusePeerTask {
 						return nil
 					})
 				sm.EXPECT().FindCompletedSubTask(gomock.Any()).DoAndReturn(
@@ -522,7 +522,7 @@ func TestReuseStreamPeerTask(t *testing.T) {
 					Filter: "",
 					Header: nil,
 				},
-				Range:  &clientutil.Range{Start: 0, Length: 10},
+				Range:  &util.Range{Start: 0, Length: 10},
 				PeerID: "",
 			},
 			enablePrefetch: true,
@@ -533,7 +533,7 @@ func TestReuseStreamPeerTask(t *testing.T) {
 						return nil
 					})
 				sm.EXPECT().FindPartialCompletedTask(gomock.Any(), gomock.Any()).DoAndReturn(
-					func(id string, rg *clientutil.Range) *storage.ReusePeerTask {
+					func(id string, rg *util.Range) *storage.ReusePeerTask {
 						taskID = id
 						return &storage.ReusePeerTask{
 							PeerTaskMetadata: storage.PeerTaskMetadata{
@@ -578,7 +578,7 @@ func TestReuseStreamPeerTask(t *testing.T) {
 					Filter: "",
 					Header: nil,
 				},
-				Range:  &clientutil.Range{Start: 0, Length: 100},
+				Range:  &util.Range{Start: 0, Length: 100},
 				PeerID: "",
 			},
 			enablePrefetch: true,
@@ -589,7 +589,7 @@ func TestReuseStreamPeerTask(t *testing.T) {
 						return nil
 					})
 				sm.EXPECT().FindPartialCompletedTask(gomock.Any(), gomock.Any()).DoAndReturn(
-					func(id string, rg *clientutil.Range) *storage.ReusePeerTask {
+					func(id string, rg *util.Range) *storage.ReusePeerTask {
 						taskID = id
 						return &storage.ReusePeerTask{
 							PeerTaskMetadata: storage.PeerTaskMetadata{
@@ -638,7 +638,7 @@ func TestReuseStreamPeerTask(t *testing.T) {
 					Filter: "",
 					Header: nil,
 				},
-				Range:  &clientutil.Range{Start: 100, Length: 100000},
+				Range:  &util.Range{Start: 100, Length: 100000},
 				PeerID: "",
 			},
 			enablePrefetch: true,
@@ -649,7 +649,7 @@ func TestReuseStreamPeerTask(t *testing.T) {
 						return nil
 					})
 				sm.EXPECT().FindPartialCompletedTask(gomock.Any(), gomock.Any()).DoAndReturn(
-					func(id string, rg *clientutil.Range) *storage.ReusePeerTask {
+					func(id string, rg *util.Range) *storage.ReusePeerTask {
 						taskID = id
 						return &storage.ReusePeerTask{
 							PeerTaskMetadata: storage.PeerTaskMetadata{
diff --git a/client/daemon/peer/peertask_stream_backsource_partial_test.go b/client/daemon/peer/peertask_stream_backsource_partial_test.go
index a4777fd1..5bf57c7e 100644
--- a/client/daemon/peer/peertask_stream_backsource_partial_test.go
+++ b/client/daemon/peer/peertask_stream_backsource_partial_test.go
@@ -38,10 +38,10 @@ import (
 	"google.golang.org/grpc/codes"
 	"google.golang.org/grpc/status"
 
-	"d7y.io/dragonfly/v2/client/clientutil"
 	"d7y.io/dragonfly/v2/client/config"
 	"d7y.io/dragonfly/v2/client/daemon/storage"
 	"d7y.io/dragonfly/v2/client/daemon/test"
+	"d7y.io/dragonfly/v2/client/util"
 	"d7y.io/dragonfly/v2/internal/dferrors"
 	"d7y.io/dragonfly/v2/pkg/dfnet"
 	"d7y.io/dragonfly/v2/pkg/digest"
@@ -183,7 +183,7 @@ func setupBackSourcePartialComponents(ctrl *gomock.Controller, testBytes []byte,
 		config.SimpleLocalTaskStoreStrategy,
 		&config.StorageOption{
 			DataPath: tempDir,
-			TaskExpireTime: clientutil.Duration{
+			TaskExpireTime: util.Duration{
 				Duration: -1 * time.Second,
 			},
 		}, func(request storage.CommonTaskRequest) {})
@@ -259,7 +259,7 @@ func TestStreamPeerTask_BackSource_Partial_WithContentLength(t *testing.T) {
 		storageManager:   storageManager,
 		schedulerClient:  schedulerClient,
 		schedulerOption: config.SchedulerOption{
-			ScheduleTimeout: clientutil.Duration{Duration: 10 * time.Minute},
+			ScheduleTimeout: util.Duration{Duration: 10 * time.Minute},
 		},
 	}
 	req := &scheduler.PeerTaskRequest{
diff --git a/client/daemon/peer/piece_downloader_test.go b/client/daemon/peer/piece_downloader_test.go
index e3419689..5d5caf00 100644
--- a/client/daemon/peer/piece_downloader_test.go
+++ b/client/daemon/peer/piece_downloader_test.go
@@ -34,8 +34,8 @@ import (
 	testifyassert "github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 
-	"d7y.io/dragonfly/v2/client/clientutil"
 	"d7y.io/dragonfly/v2/client/daemon/test"
+	"d7y.io/dragonfly/v2/client/util"
 	logger "d7y.io/dragonfly/v2/internal/dflog"
 	"d7y.io/dragonfly/v2/pkg/rpc/base"
 	"d7y.io/dragonfly/v2/pkg/source"
@@ -77,7 +77,7 @@ func TestPieceDownloader_DownloadPiece(t *testing.T) {
 		{
 			handleFunc: func(w http.ResponseWriter, r *http.Request) {
 				assert.Equal("/download/tas/task-1", r.URL.Path)
-				rg := clientutil.MustParseRange(r.Header.Get("Range"), math.MaxInt64)
+				rg := util.MustParseRange(r.Header.Get("Range"), math.MaxInt64)
 				w.Header().Set(headers.ContentLength, fmt.Sprintf("%d", rg.Length))
 				if _, err := w.Write(testData[rg.Start : rg.Start+rg.Length]); err != nil {
 					t.Error(err)
@@ -92,7 +92,7 @@ func TestPieceDownloader_DownloadPiece(t *testing.T) {
 		{
 			handleFunc: func(w http.ResponseWriter, r *http.Request) {
 				assert.Equal("/download/tas/task-2", r.URL.Path)
-				rg := clientutil.MustParseRange(r.Header.Get("Range"), math.MaxInt64)
+				rg := util.MustParseRange(r.Header.Get("Range"), math.MaxInt64)
 				w.Header().Set(headers.ContentLength, fmt.Sprintf("%d", rg.Length))
 				if _, err := w.Write(testData[rg.Start : rg.Start+rg.Length]); err != nil {
 					t.Error(err)
@@ -107,7 +107,7 @@ func TestPieceDownloader_DownloadPiece(t *testing.T) {
 		{
 			handleFunc: func(w http.ResponseWriter, r *http.Request) {
 				assert.Equal("/download/tas/task-3", r.URL.Path)
-				rg := clientutil.MustParseRange(r.Header.Get("Range"), math.MaxInt64)
+				rg := util.MustParseRange(r.Header.Get("Range"), math.MaxInt64)
 				w.Header().Set(headers.ContentLength, fmt.Sprintf("%d", rg.Length))
 				if _, err := w.Write(testData[rg.Start : rg.Start+rg.Length]); err != nil {
 					t.Error(err)
diff --git a/client/daemon/peer/piece_manager_test.go b/client/daemon/peer/piece_manager_test.go
index b8d9f0f7..75fc187a 100644
--- a/client/daemon/peer/piece_manager_test.go
+++ b/client/daemon/peer/piece_manager_test.go
@@ -34,10 +34,10 @@ import (
 	"github.com/stretchr/testify/require"
 	"go.uber.org/atomic"
 
-	"d7y.io/dragonfly/v2/client/clientutil"
 	"d7y.io/dragonfly/v2/client/config"
 	"d7y.io/dragonfly/v2/client/daemon/storage"
 	"d7y.io/dragonfly/v2/client/daemon/test"
+	"d7y.io/dragonfly/v2/client/util"
 	logger "d7y.io/dragonfly/v2/internal/dflog"
 	"d7y.io/dragonfly/v2/pkg/rpc/base"
 	_ "d7y.io/dragonfly/v2/pkg/rpc/dfdaemon/server"
@@ -66,7 +66,7 @@ func TestPieceManager_DownloadSource(t *testing.T) {
 		config.SimpleLocalTaskStoreStrategy,
 		&config.StorageOption{
 			DataPath: t.TempDir(),
-			TaskExpireTime: clientutil.Duration{
+			TaskExpireTime: util.Duration{
 				Duration: -1 * time.Second,
 			},
 		}, func(request storage.CommonTaskRequest) {})
diff --git a/client/daemon/rpcserver/rpcserver_test.go b/client/daemon/rpcserver/rpcserver_test.go
index 0e4bafb8..1dc93690 100644
--- a/client/daemon/rpcserver/rpcserver_test.go
+++ b/client/daemon/rpcserver/rpcserver_test.go
@@ -30,10 +30,10 @@ import (
 	"github.com/phayes/freeport"
 	testifyassert "github.com/stretchr/testify/assert"
 
-	"d7y.io/dragonfly/v2/client/clientutil"
 	"d7y.io/dragonfly/v2/client/daemon/peer"
 	"d7y.io/dragonfly/v2/client/daemon/storage"
 	"d7y.io/dragonfly/v2/client/daemon/storage/mocks"
+	"d7y.io/dragonfly/v2/client/util"
 	"d7y.io/dragonfly/v2/pkg/dfnet"
 	"d7y.io/dragonfly/v2/pkg/idgen"
 	"d7y.io/dragonfly/v2/pkg/net/ip"
@@ -76,7 +76,7 @@ func Test_ServeDownload(t *testing.T) {
 			return ch, false, nil
 		})
 	m := &server{
-		KeepAlive:       clientutil.NewKeepAlive("test"),
+		KeepAlive:       util.NewKeepAlive("test"),
 		peerHost:        &scheduler.PeerHost{},
 		peerTaskManager: mockPeerTaskManager,
 	}
@@ -145,7 +145,7 @@ func Test_ServePeer(t *testing.T) {
 		}, nil
 	})
 	s := &server{
-		KeepAlive:      clientutil.NewKeepAlive("test"),
+		KeepAlive:      util.NewKeepAlive("test"),
 		peerHost:       &scheduler.PeerHost{},
 		storageManager: mockStorageManger,
 	}
@@ -482,7 +482,7 @@ func Test_SyncPieceTasks(t *testing.T) {
 					})
 
 				s := &server{
-					KeepAlive:       clientutil.NewKeepAlive("test"),
+					KeepAlive:       util.NewKeepAlive("test"),
 					peerHost:        &scheduler.PeerHost{},
 					storageManager:  mockStorageManger,
 					peerTaskManager: mockTaskManager,
diff --git a/client/daemon/rpcserver/seeder_test.go b/client/daemon/rpcserver/seeder_test.go
index 346061ed..cfe6e086 100644
--- a/client/daemon/rpcserver/seeder_test.go
+++ b/client/daemon/rpcserver/seeder_test.go
@@ -30,11 +30,11 @@ import (
 	"go.opentelemetry.io/otel"
 	"go.opentelemetry.io/otel/trace"
 
-	"d7y.io/dragonfly/v2/client/clientutil"
 	"d7y.io/dragonfly/v2/client/config"
 	"d7y.io/dragonfly/v2/client/daemon/peer"
 	"d7y.io/dragonfly/v2/client/daemon/storage"
 	"d7y.io/dragonfly/v2/client/daemon/storage/mocks"
+	"d7y.io/dragonfly/v2/client/util"
 	"d7y.io/dragonfly/v2/pkg/dfnet"
 	"d7y.io/dragonfly/v2/pkg/rpc/base"
 	"d7y.io/dragonfly/v2/pkg/rpc/base/common"
@@ -312,7 +312,7 @@ func Test_ObtainSeeds(t *testing.T) {
 					})
 
 				s := &server{
-					KeepAlive:       clientutil.NewKeepAlive("test"),
+					KeepAlive:       util.NewKeepAlive("test"),
 					peerHost:        &scheduler.PeerHost{},
 					storageManager:  mockStorageManger,
 					peerTaskManager: mockTaskManager,
diff --git a/client/daemon/storage/local_storage_test.go b/client/daemon/storage/local_storage_test.go
index 04f4ef2b..738f3137 100644
--- a/client/daemon/storage/local_storage_test.go
+++ b/client/daemon/storage/local_storage_test.go
@@ -31,9 +31,9 @@ import (
 
 	testifyassert "github.com/stretchr/testify/assert"
 
-	"d7y.io/dragonfly/v2/client/clientutil"
 	"d7y.io/dragonfly/v2/client/config"
 	"d7y.io/dragonfly/v2/client/daemon/test"
+	clientutil "d7y.io/dragonfly/v2/client/util"
 	logger "d7y.io/dragonfly/v2/internal/dflog"
 	"d7y.io/dragonfly/v2/internal/util"
 	"d7y.io/dragonfly/v2/pkg/digest"
diff --git a/client/clientutil/range_test.go b/client/util/range_test.go
similarity index 99%
rename from client/clientutil/range_test.go
rename to client/util/range_test.go
index 37587506..594661ca 100644
--- a/client/clientutil/range_test.go
+++ b/client/util/range_test.go
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package clientutil
+package util
 
 import (
 	"testing"
diff --git a/scheduler/resource/peer_test.go b/scheduler/resource/peer_test.go
index eb807575..801cc390 100644
--- a/scheduler/resource/peer_test.go
+++ b/scheduler/resource/peer_test.go
@@ -29,7 +29,7 @@ import (
 	"github.com/golang/mock/gomock"
 	"github.com/stretchr/testify/assert"
 
-	"d7y.io/dragonfly/v2/client/clientutil"
+	"d7y.io/dragonfly/v2/client/util"
 	"d7y.io/dragonfly/v2/pkg/idgen"
 	"d7y.io/dragonfly/v2/pkg/rpc/base"
 	"d7y.io/dragonfly/v2/pkg/rpc/scheduler"
@@ -868,7 +868,7 @@ func TestPeer_DownloadTinyFile(t *testing.T) {
 			assert.Equal(r.URL.Path, fmt.Sprintf("/download/%s/%s", peer.Task.ID[:3], peer.Task.ID))
 			assert.Equal(r.URL.RawQuery, fmt.Sprintf("peerId=%s", peer.ID))
 
-			rgs, err := clientutil.ParseRange(r.Header.Get(headers.Range), 128)
+			rgs, err := util.ParseRange(r.Header.Get(headers.Range), 128)
 			assert.Nil(err)
 			assert.Equal(1, len(rgs))
 			rg := rgs[0]
diff --git a/test/e2e/dfget_test.go b/test/e2e/dfget_test.go
index a9aec610..d1bfa00e 100644
--- a/test/e2e/dfget_test.go
+++ b/test/e2e/dfget_test.go
@@ -26,7 +26,7 @@ import (
 	. "github.com/onsi/ginkgo/v2" //nolint
 	. "github.com/onsi/gomega"    //nolint
 
-	"d7y.io/dragonfly/v2/client/clientutil"
+	"d7y.io/dragonfly/v2/client/util"
 	"d7y.io/dragonfly/v2/test/e2e/e2eutil"
 )
 
@@ -58,7 +58,7 @@ func getFileSizes() map[string]int {
 	return details
 }
 
-func getRandomRange(size int) *clientutil.Range {
+func getRandomRange(size int) *util.Range {
 	rnd := rand.New(rand.NewSource(time.Now().UnixNano()))
 	r1 := rnd.Intn(size - 1)
 	r2 := rnd.Intn(size - 1)
@@ -70,7 +70,7 @@ func getRandomRange(size int) *clientutil.Range {
 	}
 
 	// range for [start, end]
-	rg := &clientutil.Range{
+	rg := &util.Range{
 		Start:  int64(start),
 		Length: int64(end + 1 - start),
 	}
@@ -125,7 +125,7 @@ func singleDfgetTest(name, ns, label, podNamePrefix, container string, fileDetai
 	})
 }
 
-func downloadSingleFile(ns string, pod *e2eutil.PodExec, path, url string, size int, rg *clientutil.Range) {
+func downloadSingleFile(ns string, pod *e2eutil.PodExec, path, url string, size int, rg *util.Range) {
 	var (
 		sha256sum []string
 		dfget     []string