unc srv ImageService ExportImagec ginContext name = cQueryname id = cQueryid raw _ err = srvcliImageInspectWithRawcontextBackground id if err != nil loggerErrorerrError save err = srvcliImageSavec
这个方法的问题在于它没有正确地将save的内容写入到writer中,并且没有将writer的内容写入到c.Writer中。
要解决这个问题,你需要将save的内容写入到writer中,并在循环结束后将writer的内容写入到c.Writer中。以下是修改后的代码:
func (srv *ImageService) ExportImage(c *gin.Context) {
name := c.Query("name")
id := c.Query("id")
raw, _, err := srv.cli.ImageInspectWithRaw(context.Background(), id)
if err != nil {
logger.Error(err.Error())
}
save, err := srv.cli.ImageSave(context.Background(), raw.RepoTags)
if err != nil {
logger.Error(err.Error())
msg := response.WsMsg{
Code: 2015,
Msg: err.Error(),
Name: raw.RepoTags[0],
}
wsResp := response.WsResp{
Type: "docker",
Data: msg,
}
marshal, err := json.Marshal(wsResp)
if err != nil {
logger.Error(err.Error())
return
}
_, err = srv.dbus.GetWithTimeout(5*time.Second, ipc.ClientParam{
Dest: "com.ugreen.entry.wss",
Path: "/com/ugreen/entry/wss",
Method: "SendWssDbus",
}, string(marshal))
if err != nil {
logger.Error(err.Error())
return
}
}
defer func() {
err = save.Close()
if err != nil {
logger.Error(err.Error())
}
}()
name = fmt.Sprintf("%s.sync.tar", name)
reader, writer := io.Pipe()
go func() {
defer writer.Close()
_, err := io.Copy(writer, save)
if err != nil {
logger.Error(err.Error())
}
}()
c.Header("Content-Disposition", "attachment; filename="+name)
c.Header("Content-Type", "application/octet-stream")
_, err = io.Copy(c.Writer, reader)
if err != nil {
logger.Error(err.Error())
c.String(http.StatusInternalServerError, "Failed to write response stream")
msg := response.WsMsg{
Code: 2015,
Msg: err.Error(),
Name: raw.RepoTags[0],
}
wsResp := response.WsResp{
Type: "docker",
Data: msg,
}
marshal, err := json.Marshal(wsResp)
if err != nil {
logger.Error(err.Error())
return
}
_, err = srv.dbus.GetWithTimeout(5*time.Second, ipc.ClientParam{
Dest: "com.ugreen.entry.wss",
Path: "/com/ugreen/entry/wss",
Method: "SendWssDbus",
}, string(marshal))
if err != nil {
logger.Error(err.Error())
return
}
return
}
msg := response.WsMsg{
Code: 2014,
Name: raw.RepoTags[0],
}
wsResp := response.WsResp{
Type: "docker",
Data: msg,
}
marshal, err := json.Marshal(wsResp)
if err != nil {
logger.Error(err.Error())
return
}
_, err = srv.dbus.GetWithTimeout(5*time.Second, ipc.ClientParam{
Dest: "com.ugreen.entry.wss",
Path: "/com/ugreen/entry/wss",
Method: "SendWssDbus",
}, string(marshal))
if err != nil {
logger.Error(err.Error())
return
}
c.Status(http.StatusOK)
}
这样修改后,save的内容将会被正确地写入到writer中,然后writer的内容将会被写入到c.Writer中,从而将文件流输出给前端。
原文地址: https://www.cveoy.top/t/topic/inC4 著作权归作者所有。请勿转载和采集!