056de22edb
* Feat: retrieve nodes from data table * Feat: master node ping slave node in REST API * Feat: master send scheduled ping request * Feat: inactive nodes recover loop * Modify: remove database operations from aria2 RPC caller implementation * Feat: init aria2 client in master node * Feat: Round Robin load balancer * Feat: create and monitor aria2 task in master node * Feat: salve receive and handle heartbeat * Fix: Node ID will be 0 in download record generated in older version * Feat: sign request headers with all `X-` prefix * Feat: API call to slave node will carry meta data in headers * Feat: call slave aria2 rpc method from master * Feat: get slave aria2 task status Feat: encode slave response data using gob * Feat: aria2 callback to master node / cancel or select task to slave node * Fix: use dummy aria2 client when caller initialize failed in master node * Feat: slave aria2 status event callback / salve RPC auth * Feat: prototype for slave driven filesystem * Feat: retry for init aria2 client in master node * Feat: init request client with global options * Feat: slave receive async task from master * Fix: competition write in request header * Refactor: dependency initialize order * Feat: generic message queue implementation * Feat: message queue implementation * Feat: master waiting slave transfer result * Feat: slave transfer file in stateless policy * Feat: slave transfer file in slave policy * Feat: slave transfer file in local policy * Feat: slave transfer file in OneDrive policy * Fix: failed to initialize update checker http client * Feat: list slave nodes for dashboard * Feat: test aria2 rpc connection in slave * Feat: add and save node * Feat: add and delete node in node pool * Fix: temp file cannot be removed when aria2 task fails * Fix: delete node in admin panel * Feat: edit node and get node info * Modify: delete unused settings
110 lines
2.1 KiB
Go
110 lines
2.1 KiB
Go
package request
|
|
|
|
import (
|
|
"context"
|
|
"github.com/cloudreve/Cloudreve/v3/pkg/auth"
|
|
"net/http"
|
|
"net/url"
|
|
"time"
|
|
)
|
|
|
|
// Option 发送请求的额外设置
|
|
type Option interface {
|
|
apply(*options)
|
|
}
|
|
|
|
type options struct {
|
|
timeout time.Duration
|
|
header http.Header
|
|
sign auth.Auth
|
|
signTTL int64
|
|
ctx context.Context
|
|
contentLength int64
|
|
masterMeta bool
|
|
endpoint *url.URL
|
|
slaveNodeID string
|
|
}
|
|
|
|
type optionFunc func(*options)
|
|
|
|
func (f optionFunc) apply(o *options) {
|
|
f(o)
|
|
}
|
|
|
|
func newDefaultOption() *options {
|
|
return &options{
|
|
header: http.Header{},
|
|
timeout: time.Duration(30) * time.Second,
|
|
contentLength: -1,
|
|
}
|
|
}
|
|
|
|
// WithTimeout 设置请求超时
|
|
func WithTimeout(t time.Duration) Option {
|
|
return optionFunc(func(o *options) {
|
|
o.timeout = t
|
|
})
|
|
}
|
|
|
|
// WithContext 设置请求上下文
|
|
func WithContext(c context.Context) Option {
|
|
return optionFunc(func(o *options) {
|
|
o.ctx = c
|
|
})
|
|
}
|
|
|
|
// WithCredential 对请求进行签名
|
|
func WithCredential(instance auth.Auth, ttl int64) Option {
|
|
return optionFunc(func(o *options) {
|
|
o.sign = instance
|
|
o.signTTL = ttl
|
|
})
|
|
}
|
|
|
|
// WithHeader 设置请求Header
|
|
func WithHeader(header http.Header) Option {
|
|
return optionFunc(func(o *options) {
|
|
for k, v := range header {
|
|
o.header[k] = v
|
|
}
|
|
})
|
|
}
|
|
|
|
// WithoutHeader 设置清除请求Header
|
|
func WithoutHeader(header []string) Option {
|
|
return optionFunc(func(o *options) {
|
|
for _, v := range header {
|
|
delete(o.header, v)
|
|
}
|
|
|
|
})
|
|
}
|
|
|
|
// WithContentLength 设置请求大小
|
|
func WithContentLength(s int64) Option {
|
|
return optionFunc(func(o *options) {
|
|
o.contentLength = s
|
|
})
|
|
}
|
|
|
|
// WithMasterMeta 请求时携带主机信息
|
|
func WithMasterMeta() Option {
|
|
return optionFunc(func(o *options) {
|
|
o.masterMeta = true
|
|
})
|
|
}
|
|
|
|
// WithSlaveMeta 请求时携带从机信息
|
|
func WithSlaveMeta(s string) Option {
|
|
return optionFunc(func(o *options) {
|
|
o.slaveNodeID = s
|
|
})
|
|
}
|
|
|
|
// Endpoint 使用同一的请求Endpoint
|
|
func WithEndpoint(endpoint string) Option {
|
|
endpointURL, _ := url.Parse(endpoint)
|
|
return optionFunc(func(o *options) {
|
|
o.endpoint = endpointURL
|
|
})
|
|
}
|