mirror of
https://github.com/wgh136/nysoure.git
synced 2025-09-27 12:17:24 +00:00
Implement file download function with retry logic and cleanup for existing files
This commit is contained in:
@@ -489,6 +489,34 @@ func testFileUrl(url string) (int64, error) {
|
|||||||
return contentLength, nil
|
return contentLength, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func downloadFile(url string, path string) error {
|
||||||
|
if _, err := os.Stat(path); err == nil {
|
||||||
|
_ = os.Remove(path) // Remove the file if it already exists
|
||||||
|
}
|
||||||
|
client := http.Client{}
|
||||||
|
req, err := http.NewRequest("GET", url, nil)
|
||||||
|
if err != nil {
|
||||||
|
return model.NewRequestError("failed to create HTTP request")
|
||||||
|
}
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return model.NewRequestError("failed to send HTTP request")
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
return model.NewRequestError("URL is not accessible, status code: " + resp.Status)
|
||||||
|
}
|
||||||
|
file, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY, os.ModePerm)
|
||||||
|
if err != nil {
|
||||||
|
return model.NewInternalServerError("failed to open file for writing")
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
if _, err := io.Copy(file, resp.Body); err != nil {
|
||||||
|
return model.NewInternalServerError("failed to copy response body to file")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func CreateServerDownloadTask(uid uint, url, filename, description string, resourceID, storageID uint) (*model.FileView, error) {
|
func CreateServerDownloadTask(uid uint, url, filename, description string, resourceID, storageID uint) (*model.FileView, error) {
|
||||||
canUpload, err := checkUserCanUpload(uid)
|
canUpload, err := checkUserCanUpload(uid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -522,48 +550,28 @@ func CreateServerDownloadTask(uid uint, url, filename, description string, resou
|
|||||||
defer func() {
|
defer func() {
|
||||||
updateUploadingSize(-contentLength)
|
updateUploadingSize(-contentLength)
|
||||||
}()
|
}()
|
||||||
client := http.Client{}
|
|
||||||
req, err := http.NewRequest("GET", url, nil)
|
|
||||||
if err != nil {
|
|
||||||
log.Error("failed to create HTTP request: ", err)
|
|
||||||
_ = dao.DeleteFile(file.UUID)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
resp, err := client.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
log.Error("failed to send HTTP request: ", err)
|
|
||||||
_ = dao.DeleteFile(file.UUID)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
log.Error("failed to parse Content-Length header: ", err)
|
|
||||||
_ = dao.DeleteFile(file.UUID)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
tempPath := filepath.Join(utils.GetStoragePath(), uuid.NewString())
|
tempPath := filepath.Join(utils.GetStoragePath(), uuid.NewString())
|
||||||
tempFile, err := os.OpenFile(tempPath, os.O_CREATE|os.O_WRONLY, os.ModePerm)
|
|
||||||
if err != nil {
|
|
||||||
log.Error("failed to open temp file: ", err)
|
|
||||||
_ = dao.DeleteFile(file.UUID)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer func() {
|
defer func() {
|
||||||
_ = tempFile.Close()
|
|
||||||
if err := os.Remove(tempPath); err != nil {
|
if err := os.Remove(tempPath); err != nil {
|
||||||
log.Error("failed to remove temp file: ", err)
|
log.Error("failed to remove temp file: ", err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
if _, err := io.Copy(tempFile, resp.Body); err != nil {
|
|
||||||
log.Error("failed to copy and hash response body: ", err)
|
for i := 0; i < 3; i++ {
|
||||||
_ = dao.DeleteFile(file.UUID)
|
if err := downloadFile(url, tempPath); err != nil {
|
||||||
return
|
log.Error("failed to download file: ", err)
|
||||||
}
|
if i == 2 {
|
||||||
_ = resp.Body.Close()
|
_ = dao.DeleteFile(file.UUID)
|
||||||
if err := tempFile.Close(); err != nil {
|
log.Error("Failed to download file after retries, deleting file record: ", file.UUID)
|
||||||
log.Error("failed to close temp file: ", err)
|
return
|
||||||
_ = dao.DeleteFile(file.UUID)
|
}
|
||||||
return
|
log.Info("Retrying download... Attempt: ", i+1)
|
||||||
|
time.Sleep(2 * time.Second) // Wait before retrying
|
||||||
|
continue
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stat, err := os.Stat(tempPath)
|
stat, err := os.Stat(tempPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("failed to get temp file info: ", err)
|
log.Error("failed to get temp file info: ", err)
|
||||||
|
Reference in New Issue
Block a user