pocketbase-signer/handlers/upload.go

172 lines
5.9 KiB
Go

package handlers
import (
"bytes"
"encoding/json"
"io"
"log"
"mime/multipart"
"net/http"
"pocketbaseSigner/config"
"pocketbaseSigner/models"
)
func UploadHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "Метод не поддерживается", http.StatusMethodNotAllowed)
return
}
// Получаем токен из cookie
cookie, err := r.Cookie("pb_auth")
if err != nil {
http.Redirect(w, r, "/login", http.StatusSeeOther)
return
}
// Получаем ID пользователя из cookie
userIdCookie, err := r.Cookie("user_id")
if err != nil {
log.Printf("Ошибка при получении ID пользователя: %v", err)
http.Redirect(w, r, "/login", http.StatusSeeOther)
return
}
// Получаем текущие данные пользователя
url := config.PocketBaseURL + "/api/collections/users/records/" + userIdCookie.Value
req, err := http.NewRequest("GET", url, nil)
if err != nil {
log.Printf("Ошибка при создании запроса: %v", err)
http.Error(w, "Внутренняя ошибка сервера", http.StatusInternalServerError)
return
}
req.Header.Set("Authorization", cookie.Value)
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
log.Printf("Ошибка при получении данных пользователя: %v", err)
http.Error(w, "Ошибка при получении данных", http.StatusInternalServerError)
return
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
log.Printf("Ошибка при чтении ответа: %v", err)
http.Error(w, "Ошибка при обработке данных", http.StatusInternalServerError)
return
}
var userData models.UserData
if err := json.Unmarshal(body, &userData); err != nil {
log.Printf("Ошибка при разборе JSON: %v", err)
http.Error(w, "Ошибка при обработке данных", http.StatusInternalServerError)
return
}
// Получаем файл из формы
file, header, err := r.FormFile("files")
if err != nil {
log.Printf("Ошибка при получении файла: %v", err)
http.Error(w, "Ошибка при загрузке файла", http.StatusBadRequest)
return
}
defer file.Close()
// Создаем multipart writer для отправки файла
requestBody := &bytes.Buffer{}
writer := multipart.NewWriter(requestBody)
// Добавляем файл
part, err := writer.CreateFormFile("files", header.Filename)
if err != nil {
log.Printf("Ошибка при создании формы: %v", err)
http.Error(w, "Ошибка при подготовке файла", http.StatusInternalServerError)
return
}
// Копируем содержимое файла
_, err = io.Copy(part, file)
if err != nil {
log.Printf("Ошибка при копировании файла: %v", err)
http.Error(w, "Ошибка при обработке файла", http.StatusInternalServerError)
return
}
// Добавляем существующие файлы
for _, existingFile := range userData.Files {
part, err := writer.CreateFormFile("files", existingFile)
if err != nil {
log.Printf("Ошибка при добавлении существующего файла: %v", err)
continue
}
// Получаем содержимое существующего файла
fileUrl := config.PocketBaseURL + "/api/files/_pb_users_auth_/" + userIdCookie.Value + "/" + existingFile
fileReq, err := http.NewRequest("GET", fileUrl, nil)
if err != nil {
log.Printf("Ошибка при создании запроса для существующего файла: %v", err)
continue
}
fileReq.Header.Set("Authorization", cookie.Value)
fileResp, err := client.Do(fileReq)
if err != nil {
log.Printf("Ошибка при получении существующего файла: %v", err)
continue
}
_, err = io.Copy(part, fileResp.Body)
fileResp.Body.Close()
if err != nil {
log.Printf("Ошибка при копировании существующего файла: %v", err)
continue
}
}
// Закрываем writer
err = writer.Close()
if err != nil {
log.Printf("Ошибка при закрытии writer: %v", err)
http.Error(w, "Ошибка при подготовке запроса", http.StatusInternalServerError)
return
}
// Создаем запрос к PocketBase
url = config.PocketBaseURL + "/api/collections/users/records/" + userIdCookie.Value
log.Printf("Отправка запроса на URL: %s", url)
log.Printf("Content-Type: %s", writer.FormDataContentType())
req, err = http.NewRequest("PATCH", url, requestBody)
if err != nil {
log.Printf("Ошибка при создании запроса: %v", err)
http.Error(w, "Ошибка при отправке файла", http.StatusInternalServerError)
return
}
// Устанавливаем заголовки
req.Header.Set("Content-Type", writer.FormDataContentType())
req.Header.Set("Authorization", cookie.Value)
// Отправляем запрос
resp, err = client.Do(req)
if err != nil {
log.Printf("Ошибка при отправке запроса: %v", err)
http.Error(w, "Ошибка при загрузке файла", http.StatusInternalServerError)
return
}
defer resp.Body.Close()
// Читаем ответ
respBody, _ := io.ReadAll(resp.Body)
log.Printf("Ответ сервера (статус %d): %s", resp.StatusCode, string(respBody))
// Проверяем ответ
if resp.StatusCode != http.StatusOK {
log.Printf("Ошибка при загрузке файла (статус %d): %s", resp.StatusCode, string(respBody))
http.Error(w, "Ошибка при загрузке файла", resp.StatusCode)
return
}
// Перенаправляем обратно на дашборд
http.Redirect(w, r, "/dashboard", http.StatusSeeOther)
}