fix: handle zero size (#1888)
This commit is contained in:
parent
724ec918c9
commit
8c7c0f53c1
3 changed files with 24 additions and 11 deletions
|
@ -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 {
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Reference in a new issue