Repository: AlistGo/alist (language: go)

Issue:
挂载夸克播放有问题，阿里云open正常播放，播放70g的原盘都可以
### Please make sure of the following things

- [X] I have read the [documentation](https://alist.nn.ci).
我已经阅读了[文档](https://alist.nn.ci)。

- [X] I'm sure there are no duplicate issues or discussions.
我确定没有重复的issue或讨论。

- [X] I'm sure it's due to `AList` and not something else(such as [Network](https://alist.nn.ci/faq/howto.html#tls-handshake-timeout-read-connection-reset-by-peer-dns-lookup-failed-connect-connection-refused-client-timeout-exceeded-while-awaiting-headers-no-such-host) ,`Dependencies` or `Operational`).
我确定是`AList`的问题，而不是其他原因（例如[网络](https://alist.nn.ci/zh/faq/howto.html#tls-handshake-timeout-read-connection-reset-by-peer-dns-lookup-failed-connect-connection-refused-client-timeout-exceeded-while-awaiting-headers-no-such-host)，`依赖`或`操作`）。

- [X] I'm sure this issue is not fixed in the latest version.
我确定这个问题在最新版本中没有被修复。


### AList Version / AList 版本

3.25.1

### Driver used / 使用的存储驱动

夸克

### Describe the bug / 问题描述

阿里云open正常播放，速度也正常，播放70g的原盘都可以，开始速度30M，后面降至10M
夸克在路由器刚重启好的时候，可以播放小文件，1G左右，速度峰值10几M，后面慢慢降至几百K
然后夸克播放（10几G的电影），就卡死，且连接速度很慢（pc端potplayer测试），
大概1分钟左右。路由器上的alist就显示未运行，必须重启路由器。。

路由器是红米ax6   刷的openwrt
路由器使用的是luci-app-alist   3.25.1版本

但是我手机用115小幸运挂载夸克没问题，可以流畅播放40G原盘
小幸运的alist版本是3.19  

莫非是路由器性能不够，但是阿里播放70G原盘都可以啊。。

夸克配置截图

![image](https://github.com/alist-org/alist/assets/38907613/4e36832a-409a-4cff-9483-708738481078)

![image](https://github.com/alist-org/alist/assets/38907613/9141b4d0-7457-46b0-b1ab-dabbdeea62d3)


### Reproduction / 复现链接

无

### Config / 配置

{
  "force": false,
  "site_url": "",
  "cdn": "",
  "jwt_secret": "",
  "token_expires_in": 48,
  "database": {
    "type": "sqlite3",
    "host": "",
    "port": 3306,
    "user": "",
    "password": "",
    "name": "",
    "db_file": "/etc/alist/data.db",
    "table_prefix": "x_",
    "ssl_mode": ""
  },
  "scheme": {
    "address": "192.168.1.1",
    "http_port": 5244,
    "https_port": -1,
    "force_https": false,
    "cert_file": "",
    "key_file": "",
    "unix_file": "/var/alist.sock",
    "unix_file_perm": ""
  },
  "temp_dir": "/tmp/alist",
  "bleve_dir": "/etc/alist/bleve",
  "log": {
    "enable": true,
    "name": "/tmp/alist/alist.log",
    "max_size": 10,
    "max_backups": 5,
    "max_age": 28,
    "compress": false
  },
  "delayed_start": 0,
  "max_connections": 0,
  "tls_insecure_skip_verify": true
}

### Logs / 日志

[GIN] 2023/08/10 - 03:04:30 | 200 |     354.375µs |   192.168.1.199 | GET      "/"
[GIN] 2023/08/10 - 03:04:30 | 200 |   10.812242ms |   192.168.1.199 | GET      "/api/public/settings"
[GIN] 2023/08/10 - 03:04:30 | 200 |     316.562µs |   192.168.1.199 | GET      "/api/me"
[GIN] 2023/08/10 - 03:04:30 | 200 |     58.7071ms |   192.168.1.199 | POST     "/api/fs/get"
[GIN] 2023/08/10 - 03:04:30 | 200 |     6.54719ms |   192.168.1.199 | POST     "/api/fs/list"
[GIN] 2023/08/10 - 03:04:31 | 200 |  672.942075ms |   192.168.1.199 | POST     "/api/fs/list"
[GIN] 2023/08/10 - 03:04:33 | 200 |  245.857105ms |   192.168.1.199 | POST     "/api/fs/list"
[GIN] 2023/08/10 - 03:04:34 | 200 |  111.678627ms |   192.168.1.199 | POST     "/api/fs/list"
[GIN] 2023/08/10 - 03:04:41 | 200 |     219.479µs |   192.168.1.199 | GET      "/@manage"
[GIN] 2023/08/10 - 03:04:41 | 200 |     296.667µs |   192.168.1.199 | GET      "/api/public/settings"
[GIN] 2023/08/10 - 03:04:41 | 200 |     305.938µs |   192.168.1.199 | GET      "/api/me"
[GIN] 2023/08/10 - 03:04:42 | 200 |   22.535632ms |   192.168.1.199 | GET      "/assets/Wether.9ebcb124.js"
[GIN] 2023/08/10 - 03:04:42 | 200 |   26.135893ms |   192.168.1.199 | GET      "/assets/Users.675617ef.js"
[GIN] 2023/08/10 - 03:04:42 | 200 |  172.506613ms |   192.168.1.199 | GET      "/api/admin/user/list"
[GIN] 2023/08/10 - 03:04:42 | 200 |    1.454375ms |   192.168.1.199 | GET      "/api/admin/driver/names"
[GIN] 2023/08/10 - 03:04:42 | 200 |   30.024852ms |   192.168.1.199 | GET      "/api/admin/storage/list"
[GIN] 2023/08/10 - 03:04:44 | 200 |   10.372503ms |   192.168.1.199 | GET      "/api/admin/storage/get?id=1"
[GIN] 2023/08/10 - 03:04:44 | 200 |   10.333649ms |   192.168.1.199 | GET      "/api/admin/driver/info?driver=AliyundriveOpen"
[GIN] 2023/08/10 - 03:05:00 | 200 |    2.514845ms |   192.168.1.199 | GET      "/api/admin/storage/list"
[GIN] 2023/08/10 - 03:05:00 | 200 |   10.374117ms |   192.168.1.199 | GET      "/api/admin/driver/names"
[GIN] 2023/08/10 - 03:05:01 | 200 |    1.300625ms |   192.168.1.199 | GET      "/api/admin/storage/get?id=2"
[GIN] 2023/08/10 - 03:05:01 | 200 |    2.972709ms |   192.168.1.199 | GET      "/api/admin/driver/info?driver=Quark"
[GIN] 2023/08/10 - 03:05:12 | 200 |     378.021µs |   192.168.1.199 | GET      "/api/admin/driver/names"
[GIN] 2023/08/10 - 03:05:12 | 200 |    2.127552ms |   192.168.1.199 | GET      "/api/admin/storage/list"
[GIN] 2023/08/10 - 03:05:13 | 200 |    1.233125ms |   192.168.1.199 | GET      "/api/admin/storage/get?id=1"
[GIN] 2023/08/10 - 03:05:13 | 200 |     416.354µs |   192.168.1.199 | GET      "/api/admin/driver/info?driver=AliyundriveOpen"
[GIN] 2023/08/10 - 03:05:15 | 200 |     304.427µs |   192.168.1.199 | GET      "/api/admin/driver/names"
[GIN] 2023/08/10 - 03:05:15 | 200 |    1.924844ms |   192.168.1.199 | GET      "/api/admin/storage/list"
[GIN] 2023/08/10 - 03:05:16 | 200 |    1.302865ms |   192.168.1.199 | GET      "/api/admin/storage/get?id=1"
[GIN] 2023/08/10 - 03:05:16 | 200 |     493.907µs |   192.168.1.199 | GET      "/api/admin/driver/info?driver=AliyundriveOpen"
[GIN] 2023/08/10 - 03:05:37 | 200 |  132.012695ms |   192.168.1.199 | POST     "/api/admin/storage/update"
[GIN] 2023/08/10 - 03:05:38 | 200 |     373.125µs |   192.168.1.199 | GET      "/api/admin/driver/names"
[GIN] 2023/08/10 - 03:05:38 | 200 |    2.115208ms |   192.168.1.199 | GET      "/api/admin/storage/list"
[GIN] 2023/08/10 - 03:05:39 | 200 |     254.948µs |   192.168.1.199 | GET      "/@manage/storages"
[GIN] 2023/08/10 - 03:05:39 | 200 |     281.562µs |   192.168.1.199 | GET      "/api/public/settings"
[GIN] 2023/08/10 - 03:05:39 | 200 |     375.208µs |   192.168.1.199 | GET      "/api/me"
[GIN] 2023/08/10 - 03:05:39 | 200 |     326.562µs |   192.168.1.199 | GET      "/api/admin/driver/names"
[GIN] 2023/08/10 - 03:05:39 | 200 |    1.874948ms |   192.168.1.199 | GET      "/api/admin/storage/list"
[GIN] 2023/08/10 - 03:05:41 | 200 |      841.25µs |   192.168.1.199 | POST     "/api/fs/list"
[GIN] 2023/08/10 - 03:05:42 | 200 |     258.646µs |   192.168.1.199 | GET      "/"
[GIN] 2023/08/10 - 03:05:42 | 200 |     266.667µs |   192.168.1.199 | GET      "/api/public/settings"
[GIN] 2023/08/10 - 03:05:42 | 200 |     312.396µs |   192.168.1.199 | GET      "/api/me"
[GIN] 2023/08/10 - 03:05:42 | 200 |     9.88193ms |   192.168.1.199 | POST     "/api/fs/get"
[GIN] 2023/08/10 - 03:05:42 | 200 |     571.146µs |   192.168.1.199 | POST     "/api/fs/list"
[GIN] 2023/08/10 - 03:05:43 | 200 |  498.056448ms |   192.168.1.199 | POST     "/api/fs/list"
[GIN] 2023/08/10 - 03:05:45 | 200 |  178.350938ms |   192.168.1.199 | POST     "/api/fs/list"
[GIN] 2023/08/10 - 03:05:45 | 200 |     631.562µs |   192.168.1.199 | POST     "/api/fs/list"
[GIN] 2023/08/10 - 03:05:46 | 200 |  131.586549ms |   192.168.1.199 | POST     "/api/fs/list"
[GIN] 2023/08/10 - 03:05:47 | 200 |   96.719299ms |   192.168.1.199 | POST     "/api/fs/list"
[GIN] 2023/08/10 - 03:05:53 | 302 |  385.046518ms |   192.168.1.199 | GET      "/d/root/电影/阿丽塔：战斗天使  4K INTERNAL 国语音轨/Alita.Battle.Angel.2019.2160p.BluRay.REMUX.HEVC.DTS-HD.MA.TrueHD.7.1..mkv"
[GIN] 2023/08/10 - 03:05:53 | 302 |     409.271µs |   192.168.1.199 | GET      "/d/root/电影/阿丽塔：战斗天使  4K INTERNAL 国语音轨/Alita.Battle.Angel.2019.2160p.BluRay.REMUX.HEVC.DTS-HD.MA.TrueHD.7.1..mkv"
[GIN] 2023/08/10 - 03:05:53 | 302 |     366.198µs |   192.168.1.199 | GET      "/d/root/电影/阿丽塔：战斗天使  4K INTERNAL 国语音轨/Alita.Battle.Angel.2019.2160p.BluRay.REMUX.HEVC.DTS-HD.MA.TrueHD.7.1..mkv"
[GIN] 2023/08/10 - 03:05:54 | 302 |     353.751µs |   192.168.1.199 | GET      "/d/root/电影/阿丽塔：战斗天使  4K INTERNAL 国语音轨/Alita.Battle.Angel.2019.2160p.BluRay.REMUX.HEVC.DTS-HD.MA.TrueHD.7.1..mkv"
[GIN] 2023/08/10 - 03:05:54 | 302 |     348.386µs |   192.168.1.199 | GET      "/d/root/电影/阿丽塔：战斗天使  4K INTERNAL 国语音轨/Alita.Battle.Angel.2019.2160p.BluRay.REMUX.HEVC.DTS-HD.MA.TrueHD.7.1..mkv"
[GIN] 2023/08/10 - 03:05:54 | 302 |     349.166µs |   192.168.1.199 | GET      "/d/root/电影/阿丽塔：战斗天使  4K INTERNAL 国语音轨/Alita.Battle.Angel.2019.2160p.BluRay.REMUX.HEVC.DTS-HD.MA.TrueHD.7.1..mkv"
[GIN] 2023/08/10 - 03:05:55 | 302 |     297.604µs |   192.168.1.199 | GET      "/d/root/电影/阿丽塔：战斗天使  4K INTERNAL 国语音轨/Alita.Battle.Angel.2019.2160p.BluRay.REMUX.HEVC.DTS-HD.MA.TrueHD.7.1..mkv"
[GIN] 2023/08/10 - 03:05:55 | 302 |     353.854µs |   192.168.1.199 | GET      "/d/root/电影/阿丽塔：战斗天使  4K INTERNAL 国语音轨/Alita.Battle.Angel.2019.2160p.BluRay.REMUX.HEVC.DTS-HD.MA.TrueHD.7.1..mkv"
[GIN] 2023/08/10 - 03:06:19 | 200 |  109.894875ms |   192.168.1.199 | POST     "/api/fs/list"
[GIN] 2023/08/10 - 03:06:19 | 200 |  213.099541ms |   192.168.1.199 | POST     "/api/fs/list"
[GIN] 2023/08/10 - 03:06:24 | 200 |    5.577554ms |   192.168.1.199 | GET      "/assets/About.24aa24fc.js"
[GIN] 2023/08/10 - 03:06:27 | 200 |    3.182605ms |   192.168.1.199 | GET      "/assets/Metas.bb86a2f4.js"
[GIN] 2023/08/10 - 03:06:27 | 200 |   12.663389ms |   192.168.1.199 | GET      "/api/admin/meta/list"
[GIN] 2023/08/10 - 03:06:27 | 200 |    1.328022ms |   192.168.1.199 | GET      "/api/admin/driver/names"
[GIN] 2023/08/10 - 03:06:28 | 200 |    45.94293ms |   192.168.1.199 | GET      "/api/admin/storage/list"
[GIN] 2023/08/10 - 03:06:48 | 200 |    3.809324ms |   192.168.1.199 | GET      "/api/admin/storage/get?id=1"
[GIN] 2023/08/10 - 03:06:48 | 200 |    3.647293ms |   192.168.1.199 | GET      "/api/admin/driver/info?driver=AliyundriveOpen"
[GIN] 2023/08/10 - 03:07:29 | 200 |  367.214688ms |   192.168.1.199 | POST     "/api/admin/storage/update"
[GIN] 2023/08/10 - 03:07:29 | 200 |     341.458µs |   192.168.1.199 | GET      "/api/admin/driver/names"
[GIN] 2023/08/10 - 03:07:29 | 200 |    1.845418ms |   192.168.1.199 | GET      "/api/admin/storage/list"
[GIN] 2023/08/10 - 03:07:36 | 200 |     3.33974ms |   192.168.1.199 | POST     "/api/fs/list"
[GIN] 2023/08/10 - 03:07:37 | 200 |   277.16435ms |   192.168.1.199 | POST     "/api/fs/list"
[GIN] 2023/08/10 - 03:07:39 | 200 |  408.338137ms |   192.168.1.199 | POST     "/api/fs/list"
[GIN] 2023/08/10 - 03:07:41 | 200 |     589.479µs |   192.168.1.199 | POST     "/api/fs/list"
[GIN] 2023/08/10 - 03:07:41 | 200 |   94.385912ms |   192.168.1.199 | POST     "/api/fs/list"
[GIN] 2023/08/10 - 03:07:43 | 200 |   67.332988ms |   192.168.1.199 | POST     "/api/fs/list"
🔧[33mWARN🔧[0m[2023-08-10 03:07:50] ServeHttp error. err: write tcp 192.168.1.1:5244->192.168.1.199:49875: write: broken pipe  
🔧[33mWARN🔧[0m[2023-08-10 03:07:50] Maybe size incorrect or reader not giving correct/full data, or connection closed before finish. written bytes: 69006 ,sendSize:30596857629,  
[GIN] 2023/08/10 - 03:07:50 | 200 |  2.180234164s |   192.168.1.199 | GET      "/d/af9708f1a4e346b4bd49e96f009587f1/来自：云收藏/满江红.Full.River.Red.2023.60FPS.V2.2160p.WEB-DL.H265.10bit.DTS.5.1-GPTHD/满江红.Full.River.Red.2023.60FPS.V2.2160p.WEB-DL.H265.10bit.DTS.5.1-GPTHD.mkv"
🔧[33mWARN🔧[0m[2023-08-10 03:08:22] ServeHttp error. err: write tcp 192.168.1.1:5244->192.168.1.199:49883: write: broken pipe  
🔧[33mWARN🔧[0m[2023-08-10 03:08:22] ServeHttp error. err: write tcp 192.168.1.1:5244->192.168.1.199:49880: write: broken pipe  
🔧[33mWARN🔧[0m[2023-08-10 03:08:22] Maybe size incorrect or reader not giving correct/full data, or connection closed before finish. written bytes: 3668 ,sendSize:30596857629,  
🔧[33mWARN🔧[0m[2023-08-10 03:08:22] ServeHttp error. err: write tcp 192.168.1.1:5244->192.168.1.199:49881: write: broken pipe  
🔧[33mWARN🔧[0m[2023-08-10 03:08:22] Maybe size incorrect or reader not giving correct/full data, or connection closed before finish. written bytes: 3668 ,sendSize:30596857629,  
🔧[33mWARN🔧[0m[2023-08-10 03:08:22] ServeHttp error. err: write tcp 192.168.1.1:5244->192.168.1.199:49882: write: broken pipe  
🔧[33mWARN🔧[0m[2023-08-10 03:08:22] Maybe size incorrect or reader not giving correct/full data, or connection closed before finish. written bytes: 3668 ,sendSize:30596857629,  
🔧[33mWARN🔧[0m[2023-08-10 03:08:22] Maybe size incorrect or reader not giving correct/full data, or connection closed before finish. written bytes: 3668 ,sendSize:30596857629,  
[GIN] 2023/08/10 - 03:08:22 | 200 | 20.785429804s |   192.168.1.199 | GET      "/d/af9708f1a4e346b4bd49e96f009587f1/来自：云收藏/满江红.Full.River.Red.2023.60FPS.V2.2160p.WEB-DL.H265.10bit.DTS.5.1-GPTHD/满江红.Full.River.Red.2023.60FPS.V2.2160p.WEB-DL.H265.10bit.DTS.5.1-GPTHD.mkv"
[GIN] 2023/08/10 - 03:08:22 | 200 | 16.338629738s |   192.168.1.199 | GET      "/d/af9708f1a4e346b4bd49e96f009587f1/来自：云收藏/满江红.Full.River.Red.2023.60FPS.V2.2160p.WEB-DL.H265.10bit.DTS.5.1-GPTHD/满江红.Full.River.Red.2023.60FPS.V2.2160p.WEB-DL.H265.10bit.DTS.5.1-GPTHD.mkv"
[GIN] 2023/08/10 - 03:08:22 | 200 |  6.327064136s |   192.168.1.199 | GET      "/d/af9708f1a4e346b4bd49e96f009587f1/来自：云收藏/满江红.Full.River.Red.2023.60FPS.V2.2160p.WEB-DL.H265.10bit.DTS.5.1-GPTHD/满江红.Full.River.Red.2023.60FPS.V2.2160p.WEB-DL.H265.10bit.DTS.5.1-GPTHD.mkv"
[GIN] 2023/08/10 - 03:08:22 | 200 | 11.336207797s |   192.168.1.199 | GET      "/d/af9708f1a4e346b4bd49e96f009587f1/来自：云收藏/满江红.Full.River.Red.2023.60FPS.V2.2160p.WEB-DL.H265.10bit.DTS.5.1-GPTHD/满江红.Full.River.Red.2023.60FPS.V2.2160p.WEB-DL.H265.10bit.DTS.5.1-GPTHD.mkv"
🔧[33mWARN🔧[0m[2023-08-10 03:08:22] ServeHttp error. err: write tcp 192.168.1.1:5244->192.168.1.199:49878: write: broken pipe  
🔧[33mWARN🔧[0m[2023-08-10 03:08:22] Maybe size incorrect or reader not giving correct/full data, or connection closed before finish. written bytes: 7764 ,sendSize:30596857629,  
[GIN] 2023/08/10 - 03:08:22 | 200 |   20.9474386s |   192.168.1.199 | GET      "/d/af9708f1a4e346b4bd49e96f009587f1/来自：云收藏/满江红.Full.River.Red.2023.60FPS.V2.2160p.WEB-DL.H265.10bit.DTS.5.1-GPTHD/满江红.Full.River.Red.2023.60FPS.V2.2160p.WEB-DL.H265.10bit.DTS.5.1-GPTHD.mkv"
🔧[33mWARN🔧[0m[2023-08-10 03:08:22] ServeHttp error. err: write tcp 192.168.1.1:5244->192.168.1.199:49877: write: broken pipe  
🔧[33mWARN🔧[0m[2023-08-10 03:08:22] Maybe size incorrect or reader not giving correct/full data, or connection closed before finish. written bytes: 28046 ,sendSize:30596857629,  
[GIN] 2023/08/10 - 03:08:22 | 200 | 32.312412045s |   192.168.1.199 | GET      "/d/af9708f1a4e346b4bd49e96f009587f1/来自：云收藏/满江红.Full.River.Red.2023.60FPS.V2.2160p.WEB-DL.H265.10bit.DTS.5.1-GPTHD/满江红.Full.River.Red.2023.60FPS.V2.2160p.WEB-DL.H265.10bit.DTS.5.1-GPTHD.mkv"
🔧[33mWARN🔧[0m[2023-08-10 03:08:33] not enable search                            
🔧[33mWARN🔧[0m[2023-08-10 03:08:41] not enable search                            
🔧[33mWARN🔧[0m[2023-08-10 03:08:46] not enable search                            
🔧[33mWARN🔧[0m[2023-08-10 03:08:51] not enable search                            
🔧[33mWARN🔧[0m[2023-08-10 03:08:57] not enable search                            
🔧[33mWARN🔧[0m[2023-08-10 03:09:02] not enable search                            


下面是播放1G文件的夸克日志


🔧[33mWARN🔧[0m[2023-08-10 03:21:24] ServeHttp error. err: write tcp 192.168.1.1:5244->192.168.1.199:54552: write: broken pipe  
🔧[33mWARN🔧[0m[2023-08-10 03:21:24] Maybe size incorrect or reader not giving correct/full data, or connection closed before finish. written bytes: 36244 ,sendSize:956853132,  
[GIN] 2023/08/10 - 03:21:24 | 200 |  740.056042ms |   192.168.1.199 | GET      "/d/af9708f1a4e346b4bd49e96f009587f1/来自：BT磁力链下载/使徒行者.全30集.Line.Walker.Ep01-30.2014.HD720P.X264.AAC.Mandarin&Cantonese.CHS.Mp4Ba/使徒行者.Line.Walker.Ep09.2014.HD720P.X264.AAC.Mandarin&Cantonese.CHS.Mp4Ba.mp4"
🔧[33mWARN🔧[0m[2023-08-10 03:21:25] ServeHttp error. err: write tcp 192.168.1.1:5244->192.168.1.199:54553: write: connection reset by peer  
🔧[33mWARN🔧[0m[2023-08-10 03:21:25] Maybe size incorrect or reader not giving correct/full data, or connection closed before finish. written bytes: 343845 ,sendSize:956853132,  
[GIN] 2023/08/10 - 03:21:25 | 200 |  615.004245ms |   192.168.1.199 | GET      "/d/af9708f1a4e346b4bd49e96f009587f1/来自：BT磁力链下载/使徒行者.全30集.Line.Walker.Ep01-30.2014.HD720P.X264.AAC.Mandarin&Cantonese.CHS.Mp4Ba/使徒行者.Line.Walker.Ep09.2014.HD720P.X264.AAC.Mandarin&Cantonese.CHS.Mp4Ba.mp4"
🔧[33mWARN🔧[0m[2023-08-10 03:21:25] ServeHttp error. err: write tcp 192.168.1.1:5244->192.168.1.199:54554: write: broken pipe  
🔧[33mWARN🔧[0m[2023-08-10 03:21:25] Maybe size incorrect or reader not giving correct/full data, or connection closed before finish. written bytes: 224125 ,sendSize:956853132,  
[GIN] 2023/08/10 - 03:21:25 | 200 |   539.84847ms |   192.168.1.199 | GET      "/d/af9708f1a4e346b4bd49e96f009587f1/来自：BT磁力链下载/使徒行者.全30集.Line.Walker.Ep01-30.2014.HD720P.X264.AAC.Mandarin&Cantonese.CHS.Mp4Ba/使徒行者.Line.Walker.Ep09.2014.HD720P.X264.AAC.Mandarin&Cantonese.CHS.Mp4Ba.mp4"
🔧[33mWARN🔧[0m[2023-08-10 03:21:26] ServeHttp error. err: write tcp 192.168.1.1:5244->192.168.1.199:54555: write: broken pipe  
🔧[33mWARN🔧[0m[2023-08-10 03:21:26] Maybe size incorrect or reader not giving correct/full data, or connection closed before finish. written bytes: 3505764 ,sendSize:956853132,  
[GIN] 2023/08/10 - 03:21:26 | 200 |  633.410275ms |   192.168.1.199 | GET      "/d/af9708f1a4e346b4bd49e96f009587f1/来自：BT磁力链下载/使徒行者.全30集.Line.Walker.Ep01-30.2014.HD720P.X264.AAC.Mandarin&Cantonese.CHS.Mp4Ba/使徒行者.Line.Walker.Ep09.2014.HD720P.X264.AAC.Mandarin&Cantonese.CHS.Mp4Ba.mp4"
[GIN] 2023/08/10 - 03:21:27 | 206 |   410.59234ms |   192.168.1.199 | GET      "/d/af9708f1a4e346b4bd49e96f009587f1/来自：BT磁力链下载/使徒行者.全30集.Line.Walker.Ep01-30.2014.HD720P.X264.AAC.Mandarin&Cantonese.CHS.Mp4Ba/使徒行者.Line.Walker.Ep09.2014.HD720P.X264.AAC.Mandarin&Cantonese.CHS.Mp4Ba.mp4"
🔧[33mWARN🔧[0m[2023-08-10 03:22:24] ServeHttp error. err: write tcp 192.168.1.1:5244->192.168.1.199:54556: write: broken pipe  
🔧[33mWARN🔧[0m[2023-08-10 03:22:24] Maybe size incorrect or reader not giving correct/full data, or connection closed before finish. written bytes: 29986188 ,sendSize:953412492,  
[GIN] 2023/08/10 - 03:22:24 | 206 | 57.469875751s |   192.168.1.199 | GET      "/d/af9708f1a4e346b4bd49e96f009587f1/来自：BT磁力链下载/使徒行者.全30集.Line.Walker.Ep01-30.2014.HD720P.X264.AAC.Mandarin&Cantonese.CHS.Mp4Ba/使徒行者.Line.Walker.Ep09.2014.HD720P.X264.AAC.Mandarin&Cantonese.CHS.Mp4Ba.mp4"



Discussion / hints:
Thanks for opening your first issue here! Be sure to follow the issue template!

本次更新 夸克网盘启用了多线程加速，默认每个连接会申请20m内存，实测在pc等性能强大的机器上会提升体验。初步猜测是你的路由器内存不够，使用了swap，所以缓慢，后期golang回收内存不及时造成程序退出。我看到日志中好多次broken pipe，猜测是你不断的关闭播放器再打开播放器？你路由多少内存？有没有配置内存的限制？


夸克即使是会员，官方也做了限速，所以必须本地代理，走alist中转并加一些特殊逻辑才能高速提供数据。而其他大部分网盘，都是302重定向：
阿里是使用了302重定向，也就是说alist服务器会消耗一点点资源告诉请求者一个url，后面请求者将跳过alist直接访问这个url，alist不再使用任何资源，所以你就算是100t的数据，本地100G的带宽，因为数据并不由alist中转，所以速度完全取决于阿里云和你pc/手机 客户端
Hello @Rem1x-2019, please input issue by template and add detail. Issues labeled by `question` will be closed if no activities in 3 days.
你好 @Rem1x-2019，请按照issue模板填写, 并详细说明问题/日志记录/复现步骤/复现链接/实现思路或提供更多信息等, 3天内未回复issue自动关闭。
> 本次更新 夸克网盘启用了多线程加速，默认每个连接会申请20m内存，实测在pc等性能强大的机器上会提升体验。初步猜测是你的路由器内存不够，使用了swap，所以缓慢，后期golang回收内存不及时造成程序退出。我看到日志中好多次broken pipe，猜测是你不断的关闭播放器再打开播放器？你路由多少内存？有没有配置内存的限制？
> 
> 夸克即使是会员，官方也做了限速，所以必须本地代理，走alist中转并加一些特殊逻辑才能高速提供数据。而其他大部分网盘，都是302重定向： 阿里是使用了302重定向，也就是说alist服务器会消耗一点点资源告诉请求者一个url，后面请求者将跳过alist直接访问这个url，alist不再使用任何资源，所以你就算是100t的数据，本地100G的带宽，因为数据并不由alist中转，所以速度完全取决于阿里云和你pc/手机 客户端

内存512，实际可用差不多350，连接数没有限制，如果说1个连接20M内存，那么最大内存是400，会爆内存
频繁关闭播放器倒没有，我是开始打开一个1G的文件，没问题，再打开15G的，刚打开就不行了，
swap这个好像没开，
所以现在解决办法，就是限制链接数。。或者加大内存，是这个意思吧！
没有sawp，刚刚把链接数调到10，播放了15秒左右，就卡的不行，
然后进路由器，发现alist未运行，然后查看日志，又出现上面的错误，
但是在播放的时候我一直在看路由器内存，发现占用一直在30%，根本爆内存。。或许是硬盘不够？
我路由器可用空间只有12M，会不会是这个问题？
> 没有sawp，刚刚把链接数调到10，播放了15秒左右，就卡的不行， 然后进路由器，发现alist未运行，然后查看日志，又出现上面的错误， 但是在播放的时候我一直在看路由器内存，发现占用一直在30%，根本爆内存。。或许是硬盘不够？ 我路由器可用空间只有12M，会不会是这个问题？

几个问题：
1. 各大平台的各种播放器例如potplayer，iina等都是单线程请求数据的，所以我不知道你说的连接数指的是什么？ 你是在用idm等下载工具多线程下载吗？难道某些播放器可以多线程预下载后段视频？
3. 我对openwrt没有那么熟悉，但是alist代码中确实是申请的是两个10m内存块的。不同系统的可能有不同实现和优化，有可能内存紧张后调用存储做临时内存。
4. 你除了内存还观测cpu了吗？有没有可能是什么其他软件或系统的限制，在发现占用cpu或内存到达一定程度就杀死进程？也许系统日志里面会有信息？
> > 没有sawp，刚刚把链接数调到10，播放了15秒左右，就卡的不行， 然后进路由器，发现alist未运行，然后查看日志，又出现上面的错误， 但是在播放的时候我一直在看路由器内存，发现占用一直在30%，根本爆内存。。或许是硬盘不够？ 我路由器可用空间只有12M，会不会是这个问题？
> 
> 几个问题：
> 
> 1. 各大平台的各种播放器例如potplayer，iina等都是单线程请求数据的，所以我不知道你说的连接数指的是什么？ 你是在用idm等下载工具多线程下载吗？难道某些播放器可以多线程预下载后段视频？
> 2. 我对openwrt没有那么熟悉，但是alist代码中确实是申请的是两个10m内存块的。不同系统的可能有不同实现和优化，有可能内存紧张后调用存储做临时内存。
> 3. 你除了内存还观测cpu了吗？有没有可能是什么其他软件或系统的限制，在发现占用cpu或内存到达一定程度就杀死进程？也许系统日志里面会有信息？


1。我说的是luci-app-alist设置里面的最大并发连接数，一个连接20m内存，我以为说的是这个

3。cpu占用很低，没超过30%，红米ax6是高通的cpu，性能还可以，路由器可用空间只有12m，会不会是这个问题。

kodi或者potplayer播放小文件没问题，大文件才会出问题。。

我用手机安装115小幸运开启alist是没问题的(版本3.19)，应该是我的路由器问题，只是不知道问题在哪




> 

我用pc虚拟机装了openwrt x86_64 ， 实测内存和cpu并没有暴增，内存在播放器关闭后也会慢慢回收。单看一个大视频10g，完全正常，拖动也正常。
> > 
> 
> 我用pc虚拟机装了openwrt x86_64 ， 实测内存和cpu并没有暴增，内存在播放器关闭后也会慢慢回收。单看一个大视频10g，完全正常，拖动也正常。

那可能是可用空间问题，我的可用空间太小。。才12m，cpu内存应该是够用的，或者晚点我装个3.19版本试试
今天有另外一个人也遇到了相似问题，夸克网盘，有会员，cpu是J4125，openwrt  luci-app-alist 3.25.1。
现象是看大文件视频正常，但是一旦多次快速跳过15s或者快速切换播放文件（播放列表里面有多个文件）这种会关闭原有连接并开启新的连接的操作，就会越来越慢，cpu占用率很高，只有重启程序才能解决。内存并没有看到明显升高。
猜测和downloader.go 内 sync.Mutex， **notify chan int** 的使用有关，但又在centos，slackware等发行版中使用docker或者直接使用alist并无此问题。
暂时的总结是只有openwrt下使用夸克网盘才有问题。具体原因可能需要更多人review源码或者后面有空了在openwrt上测试才能找到真正原因
我也是这个问题，已经装回3.24了，目前使用夸克一切正常。
> 我也是这个问题，已经装回3.24了，目前使用夸克一切正常。

你也是一样的情况吗？ 频繁开启新的连接， openwrt 夸克网盘 cpu占用率高？ （用top命令看，不要用其他的网页看，有延时，top上是比较准的，然后用free -h 看内存剩余）
> > 我也是这个问题，已经装回3.24了，目前使用夸克一切正常。
> 
> 
> 
> 你也是一样的情况吗？ 频繁开启新的连接， openwrt 夸克网盘 cpu占用率高？ （用top命令看，不要用其他的网页看，有延时，top上是比较准的，然后用free -h 看内存剩余）

我是小白，不太懂这些，但是上面问题描述跟我遇到的很像。我已经用回3.24了，就没再出现过同样的问题。
> > > 我也是这个问题，已经装回3.24了，目前使用夸克一切正常。
> > 
> > 
> > 你也是一样的情况吗？ 频繁开启新的连接， openwrt 夸克网盘 cpu占用率高？ （用top命令看，不要用其他的网页看，有延时，top上是比较准的，然后用free -h 看内存剩余）
> 
> 我是小白，不太懂这些，但是上面问题描述跟我遇到的很像。我已经用回3.24了，就没再出现过同样的问题。

你也是路由器挂载夸克吗，什么路由器，我用最新版本的不能播放大文件（50g或以上的原盘，可能30g也不行），
我的夸克也有会员，但是手机用115小幸运（alist版本3.19）挂载没问题
低配置设备在openwrt上使用夸克有问题的，可以先退回旧版本。这个上传的特性改好了之后我会看，即使不好修也可以增加一个低配置兼容模式，使用原来的逻辑来单线程处理

Fix patch:
diff --git a/internal/net/request.go b/internal/net/request.go
index 087e44b2f19..0bcd966d2af 100644
--- a/internal/net/request.go
+++ b/internal/net/request.go
@@ -1,6 +1,7 @@
 package net
 
 import (
+	"bytes"
 	"context"
 	"fmt"
 	"io"
@@ -202,7 +203,6 @@ func (d *downloader) downloadPart() {
 	//defer d.wg.Done()
 	for {
 		c, ok := <-d.chunkChannel
-		log.Debugf("downloadPart tried to get chunk")
 		if !ok {
 			break
 		}
@@ -211,7 +211,7 @@ func (d *downloader) downloadPart() {
 			// of download producer.
 			continue
 		}
-
+		log.Debugf("downloadPart tried to get chunk")
 		if err := d.downloadChunk(&c); err != nil {
 			d.setErr(err)
 		}
@@ -220,7 +220,7 @@ func (d *downloader) downloadPart() {
 
 // downloadChunk downloads the chunk
 func (d *downloader) downloadChunk(ch *chunk) error {
-	log.Debugf("start new chunk %+v buffer_id =%d", ch, ch.buf.buffer.id)
+	log.Debugf("start new chunk %+v buffer_id =%d", ch, ch.id)
 	var n int64
 	var err error
 	params := d.getParamsFromChunk(ch)
@@ -262,6 +262,7 @@ func (d *downloader) tryDownloadChunk(params *HttpRequestParams, ch *chunk) (int
 	if err != nil {
 		return 0, err
 	}
+	defer resp.Body.Close()
 	//only check file size on the first task
 	if ch.id == 0 {
 		err = d.checkTotalBytes(resp)
@@ -279,7 +280,6 @@ func (d *downloader) tryDownloadChunk(params *HttpRequestParams, ch *chunk) (int
 		err = fmt.Errorf("chunk download size incorrect, expected=%d, got=%d", ch.size, n)
 		return n, &errReadingBody{err: err}
 	}
-	defer resp.Body.Close()
 
 	return n, nil
 }
@@ -402,13 +402,8 @@ func (e *errReadingBody) Unwrap() error {
 }
 
 type MultiReadCloser struct {
-	io.ReadCloser
-
-	//total int //total bufArr
-	//wPos    int //current reader wPos
 	cfg    *cfg
 	closer closerFunc
-	//getBuf getBufFunc
 	finish finishBufFUnc
 }
 
@@ -449,99 +444,26 @@ func (mr MultiReadCloser) Close() error {
 	return mr.closer()
 }
 
-type Buffer struct {
-	data []byte
-	wPos int //writer position
-	id   int
-	rPos int //reader position
-	lock sync.Mutex
-
-	once   bool     //combined use with notify & lock, to get notify once
-	notify chan int // notifies new writes
-}
-
-func (buf *Buffer) Write(p []byte) (n int, err error) {
-	inSize := len(p)
-	if inSize == 0 {
-		return 0, nil
-	}
-
-	if inSize > len(buf.data)-buf.wPos {
-		return 0, fmt.Errorf("exceeding buffer max size,inSize=%d ,buf.data.len=%d , buf.wPos=%d",
-			inSize, len(buf.data), buf.wPos)
-	}
-	copy(buf.data[buf.wPos:], p)
-	buf.wPos += inSize
-
-	//give read a notice if once==true
-	buf.lock.Lock()
-	if buf.once == true {
-		buf.notify <- inSize //struct{}{}
-	}
-	buf.once = false
-	buf.lock.Unlock()
-
-	return inSize, nil
-}
-
-func (buf *Buffer) getPos() (n int) {
-	return buf.wPos
-}
-func (buf *Buffer) reset() {
-	buf.wPos = 0
-	buf.rPos = 0
-}
-
-// waitTillNewWrite notify caller that new write happens
-func (buf *Buffer) waitTillNewWrite(pos int) error {
-	//log.Debugf("waitTillNewWrite, current wPos=%d", pos)
-	var err error
-
-	//defer buffer.lock.Unlock()
-	if pos >= len(buf.data) {
-		err = fmt.Errorf("there will not be any new write")
-	} else if pos > buf.wPos {
-		err = fmt.Errorf("illegal read position")
-	} else if pos == buf.wPos {
-		buf.lock.Lock()
-		buf.once = true
-		//buffer.wg1.Add(1)
-		buf.lock.Unlock()
-		//wait for write
-		log.Debugf("waitTillNewWrite wait for notify")
-		writes := <-buf.notify
-		log.Debugf("waitTillNewWrite got new write from notify, last writes:%+v", writes)
-		//if pos >= buf.wPos {
-		//	//wrote 0 bytes
-		//	return fmt.Errorf("write has error")
-		//}
-		return nil
-	}
-	//only case: wPos < buffer.wPos
-	return err
-}
-
 type Buf struct {
-	buffer *Buffer // Buffer we read from
-	size   int     //expected size
+	buffer *bytes.Buffer
+	size   int //expected size
 	ctx    context.Context
+	off    int
+	rw     sync.RWMutex
+	notify chan struct{}
 }
 
 // NewBuf is a buffer that can have 1 read & 1 write at the same time.
 // when read is faster write, immediately feed data to read after written
 func NewBuf(ctx context.Context, maxSize int, id int) *Buf {
 	d := make([]byte, maxSize)
-	buffer := &Buffer{data: d, id: id, notify: make(chan int)}
-	buffer.reset()
-	return &Buf{ctx: ctx, buffer: buffer, size: maxSize}
+	return &Buf{ctx: ctx, buffer: bytes.NewBuffer(d), size: maxSize, notify: make(chan struct{})}
 
 }
 func (br *Buf) Reset(size int) {
-	br.buffer.reset()
+	br.buffer.Reset()
 	br.size = size
-}
-func (br *Buf) GetId() int {
-	return br.buffer.id
+	br.off = 0
 }
 
 func (br *Buf) Read(p []byte) (n int, err error) {
@@ -551,48 +473,49 @@ func (br *Buf) Read(p []byte) (n int, err error) {
 	if len(p) == 0 {
 		return 0, nil
 	}
-	if br.buffer.rPos == br.size {
+	if br.off >= br.size {
 		return 0, io.EOF
 	}
-	//persist buffer position as another thread is keep increasing it
-	bufPos := br.buffer.getPos()
-	outSize := bufPos - br.buffer.rPos
-
-	if outSize == 0 {
-		//var wg sync.WaitGroup
-		err := br.waitTillNewWrite(br.buffer.rPos)
-		if err != nil {
-			return 0, err
-		}
-		bufPos = br.buffer.getPos()
-		outSize = bufPos - br.buffer.rPos
+	br.rw.RLock()
+	n, err = br.buffer.Read(p)
+	br.rw.RUnlock()
+	if err == nil {
+		br.off += n
+		return n, err
 	}
-
-	if len(p) < outSize {
-		// p is not big enough
-		outSize = len(p)
+	if err != io.EOF {
+		return n, err
 	}
-	copy(p, br.buffer.data[br.buffer.rPos:br.buffer.rPos+outSize])
-	br.buffer.rPos += outSize
-	if br.buffer.rPos == br.size {
-		err = io.EOF
+	if n != 0 {
+		br.off += n
+		return n, nil
+	}
+	// n==0, err==io.EOF
+	// wait for new write for 200ms
+	select {
+	case <-br.ctx.Done():
+		return 0, br.ctx.Err()
+	case <-br.notify:
+		return 0, nil
+	case <-time.After(time.Millisecond * 200):
+		return 0, nil
 	}
-
-	return outSize, err
-}
-
-// waitTillNewWrite is expensive, since we just checked that no new data, wait 0.2s
-func (br *Buf) waitTillNewWrite(pos int) error {
-	time.Sleep(200 * time.Millisecond)
-	return br.buffer.waitTillNewWrite(br.buffer.rPos)
 }
 
 func (br *Buf) Write(p []byte) (n int, err error) {
 	if err := br.ctx.Err(); err != nil {
 		return 0, err
 	}
-	return br.buffer.Write(p)
+	br.rw.Lock()
+	defer br.rw.Unlock()
+	n, err = br.buffer.Write(p)
+	select {
+	case br.notify <- struct{}{}:
+	default:
+	}
+	return
 }
+
 func (br *Buf) Close() {
-	close(br.buffer.notify)
+	close(br.notify)
 }
diff --git a/internal/net/serve.go b/internal/net/serve.go
index b2da536aa89..688882b98c5 100644
--- a/internal/net/serve.go
+++ b/internal/net/serve.go
@@ -215,14 +215,10 @@ func RequestHttp(httpMethod string, headerOverride http.Header, URL string) (*ht
 		return nil, err
 	}
 	req.Header = headerOverride
-	log.Debugln("request Header: ", req.Header)
-	log.Debugln("request URL: ", URL)
 	res, err := HttpClient().Do(req)
 	if err != nil {
 		return nil, err
 	}
-	log.Debugf("response status: %d", res.StatusCode)
-	log.Debugln("response Header: ", res.Header)
 	// TODO clean header with blocklist or passlist
 	res.Header.Del("set-cookie")
 	if res.StatusCode >= 400 {
@@ -231,7 +227,6 @@ func RequestHttp(httpMethod string, headerOverride http.Header, URL string) (*ht
 		log.Debugln(msg)
 		return res, errors.New(msg)
 	}
-
 	return res, nil
 }
 
diff --git a/pkg/http_range/range.go b/pkg/http_range/range.go
index 0d6598f26be..6a5451a1b1b 100644
--- a/pkg/http_range/range.go
+++ b/pkg/http_range/range.go
@@ -109,16 +109,11 @@ func ParseRange(s string, size int64) ([]Range, error) { // nolint:gocognit
 
 func (r Range) MimeHeader(contentType string, size int64) textproto.MIMEHeader {
 	return textproto.MIMEHeader{
-		"Content-Range": {r.contentRange(size)},
+		"Content-Range": {r.ContentRange(size)},
 		"Content-Type":  {contentType},
 	}
 }
 
-// for http response header
-func (r Range) contentRange(size int64) string {
-	return fmt.Sprintf("bytes %d-%d/%d", r.Start, r.Start+r.Length-1, size)
-}
-
 // ApplyRangeToHttpHeader for http request header
 func ApplyRangeToHttpHeader(p Range, headerRef http.Header) http.Header {
 	header := headerRef


Test patch:
diff --git a/internal/net/request_test.go b/internal/net/request_test.go
index 39bfd82a825..edc38c1ce5a 100644
--- a/internal/net/request_test.go
+++ b/internal/net/request_test.go
@@ -7,14 +7,15 @@ import (
 	"bytes"
 	"context"
 	"fmt"
-	"github.com/alist-org/alist/v3/pkg/http_range"
-	"github.com/sirupsen/logrus"
-	"golang.org/x/exp/slices"
 	"io"
 	"io/ioutil"
 	"net/http"
 	"sync"
 	"testing"
+
+	"github.com/alist-org/alist/v3/pkg/http_range"
+	"github.com/sirupsen/logrus"
+	"golang.org/x/exp/slices"
 )
 
 var buf22MB = make([]byte, 1024*1024*22)
@@ -55,7 +56,7 @@ func TestDownloadOrder(t *testing.T) {
 	if err != nil {
 		t.Fatalf("expect no error, got %v", err)
 	}
-	resultBuf, err := io.ReadAll(*readCloser)
+	resultBuf, err := io.ReadAll(readCloser)
 	if err != nil {
 		t.Fatalf("expect no error, got %v", err)
 	}
@@ -111,7 +112,7 @@ func TestDownloadSingle(t *testing.T) {
 	if err != nil {
 		t.Fatalf("expect no error, got %v", err)
 	}
-	resultBuf, err := io.ReadAll(*readCloser)
+	resultBuf, err := io.ReadAll(readCloser)
 	if err != nil {
 		t.Fatalf("expect no error, got %v", err)
 	}