mirror of
https://github.com/pomerium/pomerium.git
synced 2025-04-29 10:26:29 +02:00
85 lines
2.1 KiB
Go
85 lines
2.1 KiB
Go
// Package fileutil provides file utility functions, complementing the
|
|
// lower level abstractions found in the standard library.
|
|
package fileutil
|
|
|
|
import (
|
|
"bytes"
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
)
|
|
|
|
// IsReadableFile reports whether the file exists and is readable.
|
|
// If the error is non-nil, it means there might be a file or directory
|
|
// with that name but we cannot read it.
|
|
//
|
|
// Adapted from the upspin.io source code.
|
|
func IsReadableFile(path string) (bool, error) {
|
|
// Is it stattable and is it a plain file?
|
|
info, err := os.Stat(path)
|
|
if err != nil {
|
|
if os.IsNotExist(err) {
|
|
return false, nil // Item does not exist.
|
|
}
|
|
return false, err // Item is problematic.
|
|
}
|
|
if info.IsDir() {
|
|
return false, errors.New("is directory")
|
|
}
|
|
// Is it readable?
|
|
fd, err := os.Open(path)
|
|
if err != nil {
|
|
return false, errors.New("permission denied")
|
|
}
|
|
fd.Close()
|
|
return true, nil // Item exists and is readable.
|
|
}
|
|
|
|
// Getwd returns a rooted path name corresponding to the
|
|
// current directory. If the current directory can be
|
|
// reached via multiple paths (due to symbolic links),
|
|
// Getwd may return any one of them.
|
|
//
|
|
// On failure, will return "."
|
|
func Getwd() string {
|
|
p, err := os.Getwd()
|
|
if err != nil {
|
|
return "."
|
|
}
|
|
return p
|
|
}
|
|
|
|
// ReadFileUpTo reads file up to given size
|
|
// it returns an error if file is larger than allowed maximum
|
|
func ReadFileUpTo(fname string, maxSize int64) ([]byte, error) {
|
|
var buf bytes.Buffer
|
|
if err := CopyFileUpTo(&buf, fname, maxSize); err != nil {
|
|
return nil, err
|
|
}
|
|
return buf.Bytes(), nil
|
|
}
|
|
|
|
// CopyFileUpTo copies content of the file up to maxBytes
|
|
// it returns an error if file is larger than allowed maximum
|
|
func CopyFileUpTo(dst io.Writer, fname string, maxBytes int64) error {
|
|
fd, err := os.Open(fname)
|
|
if err != nil {
|
|
return fmt.Errorf("open %s: %w", fname, err)
|
|
}
|
|
defer func() { _ = fd.Close() }()
|
|
|
|
fi, err := fd.Stat()
|
|
if err != nil {
|
|
return fmt.Errorf("stat %s: %w", fname, err)
|
|
}
|
|
if fi.Size() > maxBytes {
|
|
return fmt.Errorf("file %s size %d > max %d", fname, fi.Size(), maxBytes)
|
|
}
|
|
|
|
if _, err := io.Copy(dst, fd); err != nil {
|
|
return fmt.Errorf("read %s: %w", fname, err)
|
|
}
|
|
|
|
return nil
|
|
}
|