modified: serv_nginx/api_bb/internal/handlers/avatar.go
modified: serv_nginx/api_bb/internal/handlers/handlers.go modified: serv_nginx/api_bb/internal/handlers/user.go modified: serv_nginx/api_bb/internal/routes/routes.go modified: serv_nginx/api_bb/internal/service/avatar_service.go modified: serv_nginx/nginx/nginx-ssl.conf try to serve file name throught path
This commit is contained in:
@@ -19,6 +19,8 @@ type AvatarService interface {
|
||||
UploadAvatar(userID uint, file multipart.File, header *multipart.FileHeader) (string, error)
|
||||
DeleteAvatar(userID uint) error
|
||||
GetAvatarPath(userID uint) (string, error)
|
||||
GetAvatarFile(filename string) ([]byte, string, error) // НОВЫЙ МЕТОД
|
||||
ServeAvatarFile(w io.Writer, filename string) (string, error)
|
||||
}
|
||||
|
||||
type avatarService struct {
|
||||
@@ -111,3 +113,103 @@ func (s *avatarService) GetAvatarPath(userID uint) (string, error) {
|
||||
}
|
||||
return user.Avatar, nil
|
||||
}
|
||||
|
||||
func (s *avatarService) GetAvatarFile(filename string) ([]byte, string, error) {
|
||||
// Валидация имени файла
|
||||
if filename == "" || strings.Contains(filename, "..") || strings.Contains(filename, "/") {
|
||||
return nil, "", fmt.Errorf("invalid filename")
|
||||
}
|
||||
|
||||
// Проверяем допустимые расширения
|
||||
allowedExts := map[string]string{
|
||||
".png": "image/png",
|
||||
".jpg": "image/jpeg",
|
||||
".jpeg": "image/jpeg",
|
||||
".gif": "image/gif",
|
||||
".webp": "image/webp",
|
||||
}
|
||||
|
||||
fileExt := strings.ToLower(filepath.Ext(filename))
|
||||
contentType, exists := allowedExts[fileExt]
|
||||
if !exists {
|
||||
return nil, "", fmt.Errorf("unsupported file format")
|
||||
}
|
||||
|
||||
// Формируем путь к файлу
|
||||
filePath := filepath.Join("./uploads/avatars", filename)
|
||||
|
||||
// Проверяем существование файла
|
||||
fileInfo, err := os.Stat(filePath)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil, "", fmt.Errorf("avatar file not found")
|
||||
}
|
||||
return nil, "", fmt.Errorf("failed to access file: %v", err)
|
||||
}
|
||||
|
||||
// Проверяем размер файла (максимум 10MB)
|
||||
if fileInfo.Size() > 10*1024*1024 {
|
||||
return nil, "", fmt.Errorf("file too large")
|
||||
}
|
||||
|
||||
// Читаем файл
|
||||
fileData, err := os.ReadFile(filePath)
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("failed to read file: %v", err)
|
||||
}
|
||||
|
||||
return fileData, contentType, nil
|
||||
}
|
||||
|
||||
func (s *avatarService) ServeAvatarFile(w io.Writer, filename string) (string, error) {
|
||||
// Валидация имени файла
|
||||
if filename == "" || strings.Contains(filename, "..") || strings.Contains(filename, "/") {
|
||||
return "", fmt.Errorf("invalid filename")
|
||||
}
|
||||
|
||||
// Проверяем допустимые расширения
|
||||
allowedExts := map[string]string{
|
||||
".png": "image/png",
|
||||
".jpg": "image/jpeg",
|
||||
".jpeg": "image/jpeg",
|
||||
".gif": "image/gif",
|
||||
".webp": "image/webp",
|
||||
}
|
||||
|
||||
fileExt := strings.ToLower(filepath.Ext(filename))
|
||||
contentType, exists := allowedExts[fileExt]
|
||||
if !exists {
|
||||
return "", fmt.Errorf("unsupported file format")
|
||||
}
|
||||
|
||||
// Формируем путь к файлу
|
||||
filePath := filepath.Join("./uploads/avatars", filename)
|
||||
|
||||
// Проверяем существование файла
|
||||
fileInfo, err := os.Stat(filePath)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return "", fmt.Errorf("avatar file not found")
|
||||
}
|
||||
return "", fmt.Errorf("failed to access file: %v", err)
|
||||
}
|
||||
|
||||
// Проверяем размер файла
|
||||
if fileInfo.Size() > 10*1024*1024 {
|
||||
return "", fmt.Errorf("file too large")
|
||||
}
|
||||
|
||||
// Открываем и копируем файл
|
||||
file, err := os.Open(filePath)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to open file: %v", err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
_, err = io.Copy(w, file)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to serve file: %v", err)
|
||||
}
|
||||
|
||||
return contentType, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user