initial commit
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"syscall"
|
||||
"up/utils"
|
||||
)
|
||||
|
||||
func ExtlinuxWrite(w http.ResponseWriter, r *http.Request) {
|
||||
var MOUNT_POINT = os.Getenv("MOUNT_POINT")
|
||||
var EXTLINUX_FILE = os.Getenv("EXTLINUX_FILE")
|
||||
// Ограничиваем размер тела, чтобы избежать слишком больших запросов (аналог 4096 в C)
|
||||
r.Body = http.MaxBytesReader(w, r.Body, 4096)
|
||||
body, err := io.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
http.Error(w, `{"error":"Failed to read body"}`, http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// Парсим JSON
|
||||
var requestData struct {
|
||||
Content string `json:"content"`
|
||||
}
|
||||
if err := json.Unmarshal(body, &requestData); err != nil {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte(`{"error":"Invalid JSON"}`))
|
||||
return
|
||||
}
|
||||
|
||||
// Проверяем наличие поля content
|
||||
if requestData.Content == "" {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte(`{"error":"Missing content field"}`))
|
||||
return
|
||||
}
|
||||
|
||||
timestamp := r.URL.Query().Get("timestamp")
|
||||
if timestamp != "" {
|
||||
// Полное URL-декодирование (в C декодировался только %3A, но здесь используем стандартный способ)
|
||||
decoded, err := url.QueryUnescape(timestamp)
|
||||
if err == nil {
|
||||
timestamp = decoded
|
||||
}
|
||||
}
|
||||
|
||||
// Монтируем устройство
|
||||
if utils.MountDevice() < 0 {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(`{"error":"Failed to mount device"}`))
|
||||
return
|
||||
}
|
||||
|
||||
// Формируем полный путь к файлу
|
||||
filePath := filepath.Join(MOUNT_POINT, EXTLINUX_FILE)
|
||||
fmt.Println(filePath)
|
||||
|
||||
// Открываем файл на запись (создаём/перезаписываем)
|
||||
f, err := os.Create(filePath)
|
||||
if err != nil {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(`{"error":"Failed to open file"}`))
|
||||
return
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
// Записываем содержимое
|
||||
if _, err := f.WriteString(requestData.Content); err != nil {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(`{"error":"Failed to write file"}`))
|
||||
return
|
||||
}
|
||||
|
||||
if timestamp != "" {
|
||||
versionPath := filepath.Join(MOUNT_POINT, EXTLINUX_FILE+".version")
|
||||
vf, err := os.Create(versionPath)
|
||||
if err == nil {
|
||||
// Форматируем ISO 8601 в человекочитаемый вид (как в C)
|
||||
var readableDate string
|
||||
if len(timestamp) >= 19 {
|
||||
readableDate = timestamp[:10] + " " + timestamp[11:19] // "YYYY-MM-DD HH:MM:SS"
|
||||
} else {
|
||||
readableDate = timestamp
|
||||
}
|
||||
vf.WriteString(readableDate + "\n")
|
||||
vf.Close()
|
||||
log.Printf("Written extlinux.conf version: %s\n", readableDate)
|
||||
}
|
||||
}
|
||||
|
||||
// Принудительно сбрасываем файловые буферы на диск (аналог sync())
|
||||
syscall.Sync()
|
||||
|
||||
// Успешный ответ
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write([]byte(`{"status":"success","message":"extlinux.conf updated"}`))
|
||||
}
|
||||
Reference in New Issue
Block a user