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
|
||||
}
|
||||
|
||||
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) {
|
||||
canUpload, err := checkUserCanUpload(uid)
|
||||
if err != nil {
|
||||
@@ -522,48 +550,28 @@ func CreateServerDownloadTask(uid uint, url, filename, description string, resou
|
||||
defer func() {
|
||||
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())
|
||||
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() {
|
||||
_ = tempFile.Close()
|
||||
if err := os.Remove(tempPath); err != nil {
|
||||
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++ {
|
||||
if err := downloadFile(url, tempPath); err != nil {
|
||||
log.Error("failed to download file: ", err)
|
||||
if i == 2 {
|
||||
_ = dao.DeleteFile(file.UUID)
|
||||
log.Error("Failed to download file after retries, deleting file record: ", file.UUID)
|
||||
return
|
||||
}
|
||||
_ = resp.Body.Close()
|
||||
if err := tempFile.Close(); err != nil {
|
||||
log.Error("failed to close temp file: ", err)
|
||||
_ = 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)
|
||||
if err != nil {
|
||||
log.Error("failed to get temp file info: ", err)
|
||||
|
Reference in New Issue
Block a user