(body io.Reader, slug string, maxBytes int64)
| 953 | } |
| 954 | |
| 955 | func spoolDownloadResponse(body io.Reader, slug string, maxBytes int64) (_ io.ReadCloser, size int64, err error) { |
| 956 | file, err := os.CreateTemp("", "agh-github-download-*") |
| 957 | if err != nil { |
| 958 | return nil, 0, fmt.Errorf("create temp download file for %q: %w", slug, err) |
| 959 | } |
| 960 | defer func() { |
| 961 | if err != nil { |
| 962 | _ = os.Remove(file.Name()) |
| 963 | } |
| 964 | }() |
| 965 | |
| 966 | limit := normalizeArchiveSizeLimit(maxBytes) |
| 967 | written, err := io.Copy(file, io.LimitReader(body, limit+1)) |
| 968 | if err != nil { |
| 969 | closeErr := file.Close() |
| 970 | return nil, 0, joinErrors( |
| 971 | fmt.Errorf("write temp download file for %q: %w", slug, err), |
| 972 | closeErr, |
| 973 | ) |
| 974 | } |
| 975 | if written > limit { |
| 976 | closeErr := file.Close() |
| 977 | return nil, written, joinErrors( |
| 978 | fmt.Errorf( |
| 979 | "%w: github download for %q exceeds compressed archive limit %d", |
| 980 | registry.ErrArchiveTooLargeCompressed, |
| 981 | slug, |
| 982 | limit, |
| 983 | ), |
| 984 | closeErr, |
| 985 | ) |
| 986 | } |
| 987 | if _, err := file.Seek(0, io.SeekStart); err != nil { |
| 988 | closeErr := file.Close() |
| 989 | return nil, 0, joinErrors( |
| 990 | fmt.Errorf("rewind temp download file for %q: %w", slug, err), |
| 991 | closeErr, |
| 992 | ) |
| 993 | } |
| 994 | |
| 995 | return &tempFileReadCloser{File: file, path: file.Name()}, written, nil |
| 996 | } |
| 997 | |
| 998 | func normalizeArchiveSizeLimit(limit int64) int64 { |
| 999 | if limit > 0 { |
no test coverage detected