fix: handle zero size (#1888)

This commit is contained in:
Jason Song 2023-07-11 11:35:27 +08:00 committed by GitHub
parent 724ec918c9
commit 8c7c0f53c1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 24 additions and 11 deletions

View file

@ -311,10 +311,13 @@ func (h *Handler) commit(w http.ResponseWriter, r *http.Request, params httprout
db.Close() db.Close()
if err := h.storage.Commit(cache.ID, cache.Size); err != nil { size, err := h.storage.Commit(cache.ID, cache.Size)
if err != nil {
h.responseJSON(w, r, 500, err) h.responseJSON(w, r, 500, err)
return return
} }
// write real size back to cache, it may be different from the current value when the request doesn't specify it.
cache.Size = size
db, err = h.openDB() db, err = h.openDB()
if err != nil { if err != nil {

View file

@ -15,11 +15,17 @@ func (c *Request) ToCache() *Cache {
if c == nil { if c == nil {
return nil return nil
} }
return &Cache{ ret := &Cache{
Key: c.Key, Key: c.Key,
Version: c.Version, Version: c.Version,
Size: c.Size, Size: c.Size,
} }
if c.Size == 0 {
// So the request comes from old versions of actions, like `actions/cache@v2`.
// It doesn't send cache size. Set it to -1 to indicate that.
ret.Size = -1
}
return ret
} }
type Cache struct { type Cache struct {

View file

@ -46,7 +46,7 @@ func (s *Storage) Write(id uint64, offset int64, reader io.Reader) error {
return err return err
} }
func (s *Storage) Commit(id uint64, size int64) error { func (s *Storage) Commit(id uint64, size int64) (int64, error) {
defer func() { defer func() {
_ = os.RemoveAll(s.tempDir(id)) _ = os.RemoveAll(s.tempDir(id))
}() }()
@ -54,15 +54,15 @@ func (s *Storage) Commit(id uint64, size int64) error {
name := s.filename(id) name := s.filename(id)
tempNames, err := s.tempNames(id) tempNames, err := s.tempNames(id)
if err != nil { if err != nil {
return err return 0, err
} }
if err := os.MkdirAll(filepath.Dir(name), 0o755); err != nil { if err := os.MkdirAll(filepath.Dir(name), 0o755); err != nil {
return err return 0, err
} }
file, err := os.Create(name) file, err := os.Create(name)
if err != nil { if err != nil {
return err return 0, err
} }
defer file.Close() defer file.Close()
@ -70,22 +70,26 @@ func (s *Storage) Commit(id uint64, size int64) error {
for _, v := range tempNames { for _, v := range tempNames {
f, err := os.Open(v) f, err := os.Open(v)
if err != nil { if err != nil {
return err return 0, err
} }
n, err := io.Copy(file, f) n, err := io.Copy(file, f)
_ = f.Close() _ = f.Close()
if err != nil { if err != nil {
return err return 0, err
} }
written += n written += n
} }
if written != size { // If size is less than 0, it means the size is unknown.
// We can't check the size of the file, just skip the check.
// It happens when the request comes from old versions of actions, like `actions/cache@v2`.
if size >= 0 && written != size {
_ = file.Close() _ = file.Close()
_ = os.Remove(name) _ = os.Remove(name)
return fmt.Errorf("broken file: %v != %v", written, size) return 0, fmt.Errorf("broken file: %v != %v", written, size)
} }
return nil
return written, nil
} }
func (s *Storage) Serve(w http.ResponseWriter, r *http.Request, id uint64) { func (s *Storage) Serve(w http.ResponseWriter, r *http.Request, id uint64) {