diff --git a/README-EN.md b/README-EN.md
index 5226734..022d4b0 100644
--- a/README-EN.md
+++ b/README-EN.md
@@ -4,7 +4,7 @@
> A cross-platform resource downloader built with Go + [Wails](https://github.com/wailsapp/wails).
Clean UI, easy to use, and supports a wide range of resource sniffing and downloading.
-### 📖 [中文](./README.md) | English
+### 📖 [中文](./README.md) | English
---
diff --git a/README.md b/README.md
index 5bb43cd..e440355 100644
--- a/README.md
+++ b/README.md
@@ -20,7 +20,7 @@
## 📚 文档 & 版本
- 📘 [在线文档](https://res.putyy.com/)
-- 🧩 [Mini版 UI使用默认浏览器展示](https://github.com/putyy/res-downloader) | [Electron旧版 支持Win7](https://github.com/putyy/res-downloader/tree/old)
+- 🧩 [Mini版 UI使用默认浏览器展示](https://github.com/putyy/resd-mini) | [Electron旧版 支持Win7](https://github.com/putyy/res-downloader/tree/old)
- 💬 [加入交流群](https://www.putyy.com/app/admin/upload/img/20250418/6801d9554dc7.webp)
> *群满时可加微信 `AmorousWorld`,请备注“来源”*
@@ -32,7 +32,7 @@
- 🆕 [蓝奏云下载(密码:9vs5)](https://wwjv.lanzoum.com/b04wgtfyb)
- ⚠️ *Win7 用户请下载 `2.3.0` 版本*
----
+---
## 🚀 使用方法
diff --git a/build/README.md b/build/README.md
index 5ff65d0..3a32135 100644
--- a/build/README.md
+++ b/build/README.md
@@ -9,7 +9,6 @@ mv -f "build/bin/res-downloader $(jq -r '.info.productVersion' wails.json).dmg"
```bash
wails build -f -nsis -platform "windows/amd64" -webview2 Embed -skipbindings && mv -f "build/bin/res-downloader-amd64-installer.exe" "build/bin/res-downloader_$(jq -r '.info.productVersion' wails.json)_win_amd64.exe"
wails build -f -nsis -platform "windows/arm64" -webview2 Embed -skipbindings && mv -f "build/bin/res-downloader-arm64-installer.exe" "build/bin/res-downloader_$(jq -r '.info.productVersion' wails.json)_win_arm64.exe"
-
```
## Linux
diff --git a/build/windows/installer/wails_tools.nsh b/build/windows/installer/wails_tools.nsh
index fd35a46..24eac16 100644
--- a/build/windows/installer/wails_tools.nsh
+++ b/build/windows/installer/wails_tools.nsh
@@ -14,7 +14,7 @@
!define INFO_PRODUCTNAME "res-downloader"
!endif
!ifndef INFO_PRODUCTVERSION
- !define INFO_PRODUCTVERSION "3.0.4"
+ !define INFO_PRODUCTVERSION "3.0.5"
!endif
!ifndef INFO_COPYRIGHT
!define INFO_COPYRIGHT "Copyright © 2023"
diff --git a/core/config.go b/core/config.go
index ca5f2ab..89c5a42 100644
--- a/core/config.go
+++ b/core/config.go
@@ -24,6 +24,7 @@ type Config struct {
WxAction bool `json:"WxAction"`
TaskNumber int `json:"TaskNumber"`
UserAgent string `json:"UserAgent"`
+ UseHeaders string `json:"UseHeaders"`
}
func initConfig() *Config {
@@ -43,7 +44,8 @@ func initConfig() *Config {
"AutoProxy": true,
"WxAction": true,
"TaskNumber": __TaskNumber__,
- "UserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36"
+ "UserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36",
+ "UseHeaders": "User-Agent,Referer,Authorization,Cookie"
}
`
def = strings.ReplaceAll(def, "__TaskNumber__", strconv.Itoa(runtime.NumCPU()*2))
@@ -51,9 +53,23 @@ func initConfig() *Config {
storage: NewStorage("config.json", []byte(def)),
}
+ defaultMap := make(map[string]interface{})
+ _ = json.Unmarshal([]byte(def), &defaultMap)
+
data, err := globalConfig.storage.Load()
if err == nil {
- _ = json.Unmarshal(data, &globalConfig)
+ var loadedMap map[string]interface{}
+ _ = json.Unmarshal(data, &loadedMap)
+
+ for key, val := range defaultMap {
+ if _, ok := loadedMap[key]; !ok {
+ loadedMap[key] = val
+ }
+ }
+
+ finalBytes, _ := json.Marshal(loadedMap)
+ _ = json.Unmarshal(finalBytes, &globalConfig)
+
} else {
globalLogger.Esg(err, "load config err")
}
@@ -77,6 +93,7 @@ func (c *Config) setConfig(config Config) {
c.AutoProxy = config.AutoProxy
c.TaskNumber = config.TaskNumber
c.WxAction = config.WxAction
+ c.UseHeaders = config.UseHeaders
if oldProxy != c.UpstreamProxy {
proxyOnce.setTransport()
}
diff --git a/core/downloader.go b/core/downloader.go
index a910561..e7a013b 100644
--- a/core/downloader.go
+++ b/core/downloader.go
@@ -5,7 +5,6 @@ import (
"io"
"log"
"net/http"
- "net/http/cookiejar"
"net/url"
"os"
"path/filepath"
@@ -32,17 +31,19 @@ type FileDownloader struct {
totalTasks int
TotalSize int64
IsMultiPart bool
+ Headers map[string]string
DownloadTaskList []*DownloadTask
progressCallback ProgressCallback
}
-func NewFileDownloader(url, filename string, totalTasks int) *FileDownloader {
+func NewFileDownloader(url, filename string, totalTasks int, headers map[string]string) *FileDownloader {
return &FileDownloader{
Url: url,
FileName: filename,
totalTasks: totalTasks,
IsMultiPart: false,
TotalSize: 0,
+ Headers: headers,
DownloadTaskList: make([]*DownloadTask, 0),
}
}
@@ -53,10 +54,16 @@ func (fd *FileDownloader) buildClient() *http.Client {
transport.Proxy = http.ProxyURL(fd.ProxyUrl)
}
// Cookie handle
- jar, _ := cookiejar.New(nil)
return &http.Client{
Transport: transport,
- Jar: jar,
+ }
+}
+
+func (fd *FileDownloader) setHeaders(request *http.Request) {
+ for key, values := range fd.Headers {
+ if strings.Contains(globalConfig.UseHeaders, key) {
+ request.Header.Set(key, values)
+ }
}
}
@@ -76,21 +83,22 @@ func (fd *FileDownloader) init() error {
}
}
- req, err := http.NewRequest("HEAD", fd.Url, nil)
+ request, err := http.NewRequest("HEAD", fd.Url, nil)
if err != nil {
return fmt.Errorf("create request failed")
}
- // 设置请求头
- if globalConfig.UserAgent != "" {
- req.Header.Set("User-Agent", globalConfig.UserAgent)
+ if _, ok := fd.Headers["User-Agent"]; !ok {
+ fd.Headers["User-Agent"] = globalConfig.UserAgent
}
- if fd.Referer != "" {
- req.Header.Set("Referer", fd.Referer)
+ if _, ok := fd.Headers["Referer"]; !ok {
+ fd.Headers["Referer"] = fd.Referer
}
- resp, err := fd.buildClient().Do(req)
+ fd.setHeaders(request)
+
+ resp, err := fd.buildClient().Do(request)
if err != nil {
return fmt.Errorf("request failed" + err.Error())
}
@@ -182,8 +190,9 @@ func (fd *FileDownloader) startDownloadTask(waitGroup *sync.WaitGroup, progressC
globalLogger.Error().Stack().Err(err).Msgf("任务%d创建请求出错", task.taskID)
return
}
- request.Header.Set("User-Agent", globalConfig.UserAgent)
- request.Header.Set("Referer", fd.Referer)
+
+ fd.setHeaders(request)
+
if fd.IsMultiPart {
request.Header.Set("Range", fmt.Sprintf("bytes=%d-%d", task.rangeStart, task.rangeEnd))
}
diff --git a/core/proxy.go b/core/proxy.go
index ed372c9..31bb4ac 100644
--- a/core/proxy.go
+++ b/core/proxy.go
@@ -336,6 +336,12 @@ func (p *Proxy) httpResponseEvent(resp *http.Response, ctx *goproxy.ProxyCtx) *h
Description: "",
ContentType: resp.Header.Get("Content-Type"),
}
+
+ // Store entire request headers as JSON
+ if headers, err := json.Marshal(resp.Request.Header); err == nil {
+ res.OtherData["headers"] = string(headers)
+ }
+
resourceOnce.markMedia(urlSign)
httpServerOnce.send("newResources", res)
}
diff --git a/core/resource.go b/core/resource.go
index 573ea20..de858c8 100644
--- a/core/resource.go
+++ b/core/resource.go
@@ -2,6 +2,8 @@ package core
import (
"encoding/base64"
+ "encoding/json"
+ "fmt"
"io"
"net/url"
"os"
@@ -142,7 +144,9 @@ func (r *Resource) download(mediaInfo MediaInfo, decodeStr string) {
}
}
- downloader := NewFileDownloader(rawUrl, mediaInfo.SavePath, globalConfig.TaskNumber)
+ headers, _ := r.parseHeaders(mediaInfo)
+
+ downloader := NewFileDownloader(rawUrl, mediaInfo.SavePath, globalConfig.TaskNumber, headers)
downloader.progressCallback = func(totalDownloaded float64) {
r.progressEventsEmit(mediaInfo, strconv.Itoa(int(totalDownloaded))+"%", DownloadStatusRunning)
}
@@ -162,6 +166,27 @@ func (r *Resource) download(mediaInfo MediaInfo, decodeStr string) {
}(mediaInfo)
}
+// 解析并组装 headers
+func (r *Resource) parseHeaders(mediaInfo MediaInfo) (map[string]string, error) {
+ headers := make(map[string]string)
+
+ if hh, ok := mediaInfo.OtherData["headers"]; ok {
+ var tempHeaders map[string][]string
+ // 解析 JSON 字符串为 map[string][]string
+ if err := json.Unmarshal([]byte(hh), &tempHeaders); err != nil {
+ return headers, fmt.Errorf("parse headers JSON err: %v", err)
+ }
+
+ for key, values := range tempHeaders {
+ if len(values) > 0 {
+ headers[key] = values[0]
+ }
+ }
+ }
+
+ return headers, nil
+}
+
func (r *Resource) wxFileDecode(mediaInfo MediaInfo, fileName, decodeStr string) (string, error) {
sourceFile, err := os.Open(fileName)
if err != nil {
diff --git a/frontend/src/stores/index.ts b/frontend/src/stores/index.ts
index d88412f..fa5837e 100644
--- a/frontend/src/stores/index.ts
+++ b/frontend/src/stores/index.ts
@@ -27,6 +27,7 @@ export const useIndexStore = defineStore("index-store", () => {
WxAction: false,
TaskNumber: 8,
UserAgent: "",
+ UseHeaders: "",
})
const envInfo = ref({
diff --git a/frontend/src/types/app.d.ts b/frontend/src/types/app.d.ts
index d9f15bf..14bee2c 100644
--- a/frontend/src/types/app.d.ts
+++ b/frontend/src/types/app.d.ts
@@ -21,6 +21,7 @@ export namespace appType {
WxAction: boolean
TaskNumber: number
UserAgent: string
+ UseHeaders: string
}
interface MediaInfo {
diff --git a/frontend/src/views/setting.vue b/frontend/src/views/setting.vue
index 7a4efd6..d76bb60 100644
--- a/frontend/src/views/setting.vue
+++ b/frontend/src/views/setting.vue
@@ -138,6 +138,17 @@
如不清楚请保持默认
+
+
+
+
+
+
+
+
+ 3.0.4版本缓存了请求header信息,这个参数定义在下载时可使用的header参数: ,分割
+
+
diff --git a/wails.json b/wails.json
index 538c86c..eb0339b 100644
--- a/wails.json
+++ b/wails.json
@@ -13,8 +13,8 @@
"info": {
"companyName": "res-downloader",
"productName": "res-downloader",
- "productVersion": "3.0.4",
+ "productVersion": "3.0.5",
"copyright": "Copyright © 2023",
- "comments": "This is a high-value, high-performance, and diverse resource downloader called res-downloader."
+ "comments": "This is a high-value high-performance and diverse resource downloader called res-downloader."
}
}