mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-02-07 17:10:07 +08:00
fix: 解决 chunked 文件无法下载的BUG
This commit is contained in:
parent
53d0b45f8a
commit
f2ca4a88dd
@ -512,7 +512,7 @@ func (b *BaseApi) Ws(c *gin.Context) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
wsClient := websocket2.NewWsClient("13232", ws)
|
wsClient := websocket2.NewWsClient("wsClient", ws)
|
||||||
go wsClient.Read()
|
go wsClient.Read()
|
||||||
go wsClient.Write()
|
go wsClient.Write()
|
||||||
}
|
}
|
||||||
|
@ -143,9 +143,8 @@ func (f FileService) ChangeMode(op request.FileCreate) error {
|
|||||||
func (f FileService) Compress(c request.FileCompress) error {
|
func (f FileService) Compress(c request.FileCompress) error {
|
||||||
fo := files.NewFileOp()
|
fo := files.NewFileOp()
|
||||||
if !c.Replace && fo.Stat(filepath.Join(c.Dst, c.Name)) {
|
if !c.Replace && fo.Stat(filepath.Join(c.Dst, c.Name)) {
|
||||||
return errors.New("file is exist")
|
return buserr.New(constant.ErrFileIsExit)
|
||||||
}
|
}
|
||||||
|
|
||||||
return fo.Compress(c.Files, c.Dst, c.Name, files.CompressType(c.Type))
|
return fo.Compress(c.Files, c.Dst, c.Name, files.CompressType(c.Type))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,7 +215,6 @@ func (f FileService) MvFile(m request.FileMove) error {
|
|||||||
if errString != "" {
|
if errString != "" {
|
||||||
return errors.New(errString)
|
return errors.New(errString)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,18 +130,18 @@ func (w *WriteCounter) Write(p []byte) (n int, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (w *WriteCounter) SaveProcess() {
|
func (w *WriteCounter) SaveProcess() {
|
||||||
percent := float64(w.Written) / float64(w.Total) * 100
|
percentValue := 0.0
|
||||||
percentValue, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", percent), 64)
|
if w.Total > 0 {
|
||||||
|
percent := float64(w.Written) / float64(w.Total) * 100
|
||||||
|
percentValue, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", percent), 64)
|
||||||
|
}
|
||||||
process := Process{
|
process := Process{
|
||||||
Total: w.Total,
|
Total: w.Total,
|
||||||
Written: w.Written,
|
Written: w.Written,
|
||||||
Percent: percentValue,
|
Percent: percentValue,
|
||||||
Name: w.Name,
|
Name: w.Name,
|
||||||
}
|
}
|
||||||
|
|
||||||
by, _ := json.Marshal(process)
|
by, _ := json.Marshal(process)
|
||||||
|
|
||||||
if percentValue < 100 {
|
if percentValue < 100 {
|
||||||
if err := global.CACHE.Set(w.Key, string(by)); err != nil {
|
if err := global.CACHE.Set(w.Key, string(by)); err != nil {
|
||||||
global.LOG.Errorf("save cache error, err %s", err.Error())
|
global.LOG.Errorf("save cache error, err %s", err.Error())
|
||||||
@ -154,33 +154,49 @@ func (w *WriteCounter) SaveProcess() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (f FileOp) DownloadFileWithProcess(url, dst, key string) error {
|
func (f FileOp) DownloadFileWithProcess(url, dst, key string) error {
|
||||||
resp, err := http.Get(url)
|
client := &http.Client{}
|
||||||
|
request, err := http.NewRequest("GET", url, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
request.Header.Set("Accept-Encoding", "identity")
|
||||||
|
resp, err := client.Do(request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
global.LOG.Errorf("get download file [%s] error, err %s", dst, err.Error())
|
global.LOG.Errorf("get download file [%s] error, err %s", dst, err.Error())
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
header, err := http.Head(url)
|
|
||||||
if err != nil {
|
|
||||||
global.LOG.Errorf("get download file [%s] error, err %s", dst, err.Error())
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
out, err := os.Create(dst)
|
out, err := os.Create(dst)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
global.LOG.Errorf("create download file [%s] error, err %s", dst, err.Error())
|
global.LOG.Errorf("create download file [%s] error, err %s", dst, err.Error())
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
counter := &WriteCounter{}
|
counter := &WriteCounter{}
|
||||||
counter.Key = key
|
counter.Key = key
|
||||||
counter.Total = uint64(header.ContentLength)
|
if resp.ContentLength > 0 {
|
||||||
|
counter.Total = uint64(resp.ContentLength)
|
||||||
|
}
|
||||||
counter.Name = filepath.Base(dst)
|
counter.Name = filepath.Base(dst)
|
||||||
if _, err = io.Copy(out, io.TeeReader(resp.Body, counter)); err != nil {
|
if _, err = io.Copy(out, io.TeeReader(resp.Body, counter)); err != nil {
|
||||||
global.LOG.Errorf("save download file [%s] error, err %s", dst, err.Error())
|
global.LOG.Errorf("save download file [%s] error, err %s", dst, err.Error())
|
||||||
}
|
}
|
||||||
out.Close()
|
out.Close()
|
||||||
resp.Body.Close()
|
resp.Body.Close()
|
||||||
|
|
||||||
|
value, err := global.CACHE.Get(counter.Key)
|
||||||
|
if err != nil {
|
||||||
|
global.LOG.Errorf("get cache error,err %s", err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
process := &Process{}
|
||||||
|
_ = json.Unmarshal(value, process)
|
||||||
|
process.Percent = 100
|
||||||
|
process.Name = counter.Name
|
||||||
|
process.Total = process.Written
|
||||||
|
by, _ := json.Marshal(process)
|
||||||
|
if err := global.CACHE.SetWithTTL(counter.Key, string(by), time.Second*time.Duration(10)); err != nil {
|
||||||
|
global.LOG.Errorf("save cache error, err %s", err.Error())
|
||||||
|
}
|
||||||
}()
|
}()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,6 @@ func (c *Client) Read() {
|
|||||||
defer func() {
|
defer func() {
|
||||||
close(c.Msg)
|
close(c.Msg)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
_, message, err := c.Socket.ReadMessage()
|
_, message, err := c.Socket.ReadMessage()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -46,7 +45,6 @@ func (c *Client) Write() {
|
|||||||
defer func() {
|
defer func() {
|
||||||
c.Socket.Close()
|
c.Socket.Close()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
message, ok := <-c.Msg
|
message, ok := <-c.Msg
|
||||||
if !ok {
|
if !ok {
|
||||||
@ -57,7 +55,6 @@ func (c *Client) Write() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ProcessData(c *Client, msg *WsMsg) {
|
func ProcessData(c *Client, msg *WsMsg) {
|
||||||
|
|
||||||
if msg.Type == "wget" {
|
if msg.Type == "wget" {
|
||||||
var res []files.Process
|
var res []files.Process
|
||||||
for _, k := range msg.Keys {
|
for _, k := range msg.Keys {
|
||||||
@ -66,7 +63,6 @@ func ProcessData(c *Client, msg *WsMsg) {
|
|||||||
global.LOG.Errorf("get cache error,err %s", err.Error())
|
global.LOG.Errorf("get cache error,err %s", err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
process := &files.Process{}
|
process := &files.Process{}
|
||||||
_ = json.Unmarshal(value, process)
|
_ = json.Unmarshal(value, process)
|
||||||
res = append(res, *process)
|
res = append(res, *process)
|
||||||
|
@ -1,12 +1,19 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog width="30%" v-model="open" @open="onOpen" :before-close="handleClose">
|
<el-dialog
|
||||||
<template #header>
|
width="30%"
|
||||||
<DrawerHeader :header="$t('file.downloadProcess')" :back="handleClose" />
|
v-model="open"
|
||||||
</template>
|
@open="onOpen"
|
||||||
|
:before-close="handleClose"
|
||||||
|
:title="$t('file.downloadProcess')"
|
||||||
|
>
|
||||||
<div v-for="(value, index) in res" :key="index">
|
<div v-for="(value, index) in res" :key="index">
|
||||||
<span>{{ $t('file.downloading') }} {{ value['name'] }}</span>
|
<span>{{ $t('file.downloading') }} {{ value['name'] }}</span>
|
||||||
<el-progress :text-inside="true" :stroke-width="15" :percentage="value['percent']"></el-progress>
|
<el-progress v-if="value['total'] == 0" :percentage="100" :indeterminate="true" :duration="1" />
|
||||||
<span>{{ getFileSize(value['written']) }}/{{ getFileSize(value['total']) }}</span>
|
<el-progress v-else :text-inside="true" :stroke-width="15" :percentage="value['percent']"></el-progress>
|
||||||
|
<span>
|
||||||
|
{{ getFileSize(value['written']) }}/
|
||||||
|
<span v-if="value['total'] > 0">{{ getFileSize(value['total']) }}</span>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</template>
|
</template>
|
||||||
@ -15,7 +22,6 @@
|
|||||||
import { FileKeys } from '@/api/modules/files';
|
import { FileKeys } from '@/api/modules/files';
|
||||||
import { computeSize } from '@/utils/util';
|
import { computeSize } from '@/utils/util';
|
||||||
import { onBeforeUnmount, ref, toRefs } from 'vue';
|
import { onBeforeUnmount, ref, toRefs } from 'vue';
|
||||||
import DrawerHeader from '@/components/drawer-header/index.vue';
|
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
open: {
|
open: {
|
||||||
@ -54,7 +60,7 @@ const onClose = () => {};
|
|||||||
|
|
||||||
const initProcess = () => {
|
const initProcess = () => {
|
||||||
let href = window.location.href;
|
let href = window.location.href;
|
||||||
let protocol = href.split('//')[0] === 'http:' ? 'ws' : 'wss';
|
let protocol = href.split('//')[0] === 'http' ? 'ws' : 'wss';
|
||||||
let ipLocal = href.split('//')[1].split('/')[0];
|
let ipLocal = href.split('//')[1].split('/')[0];
|
||||||
processSocket = new WebSocket(`${protocol}://${ipLocal}/api/v1/files/ws`);
|
processSocket = new WebSocket(`${protocol}://${ipLocal}/api/v1/files/ws`);
|
||||||
processSocket.onopen = onOpenProcess;
|
processSocket.onopen = onOpenProcess;
|
||||||
@ -65,6 +71,8 @@ const initProcess = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const getKeys = () => {
|
const getKeys = () => {
|
||||||
|
keys.value = [];
|
||||||
|
res.value = [];
|
||||||
FileKeys().then((res) => {
|
FileKeys().then((res) => {
|
||||||
if (res.data.keys.length > 0) {
|
if (res.data.keys.length > 0) {
|
||||||
keys.value = res.data.keys;
|
keys.value = res.data.keys;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user