270 lines
6.8 KiB
Go
270 lines
6.8 KiB
Go
package command
|
||
|
||
import (
|
||
"encoding/json"
|
||
"net/http"
|
||
"os"
|
||
"regexp"
|
||
"strings"
|
||
"vServer/Backend/config"
|
||
"vServer/Backend/tools"
|
||
)
|
||
|
||
var entries []os.DirEntry
|
||
|
||
func path_www() {
|
||
|
||
wwwPath, err := tools.AbsPath("WebServer/www")
|
||
tools.Error_check(err, "Ошибка получения пути")
|
||
|
||
entries, err = os.ReadDir(wwwPath)
|
||
tools.Error_check(err, "Ошибка чтения директории")
|
||
|
||
}
|
||
|
||
func site_type(entry os.DirEntry) string {
|
||
|
||
certPath, err := tools.AbsPath("WebServer/cert/" + entry.Name())
|
||
if err == nil {
|
||
if _, err := os.Stat(certPath); err == nil {
|
||
return "https"
|
||
}
|
||
}
|
||
return "http"
|
||
}
|
||
|
||
func site_alliace(siteName string) []string {
|
||
// Получаем абсолютный путь к config.json
|
||
configPath, err := tools.AbsPath("WebServer/config.json")
|
||
tools.Error_check(err, "Ошибка получения пути к config.json")
|
||
|
||
// Читаем содержимое config.json
|
||
configData, err := os.ReadFile(configPath)
|
||
tools.Error_check(err, "Ошибка чтения config.json")
|
||
|
||
// Структура для парсинга Site_www
|
||
type SiteConfig struct {
|
||
Name string `json:"name"`
|
||
Host string `json:"host"`
|
||
Alias []string `json:"alias"`
|
||
Status string `json:"status"`
|
||
}
|
||
type Config struct {
|
||
SiteWWW []SiteConfig `json:"Site_www"`
|
||
}
|
||
|
||
var config Config
|
||
err = json.Unmarshal(configData, &config)
|
||
tools.Error_check(err, "Ошибка парсинга config.json")
|
||
|
||
// Ищем алиасы для конкретного сайта
|
||
for _, site := range config.SiteWWW {
|
||
if site.Host == siteName {
|
||
return site.Alias
|
||
}
|
||
}
|
||
|
||
// Возвращаем пустой массив если сайт не найден
|
||
return []string{}
|
||
}
|
||
|
||
func site_status(siteName string) string {
|
||
configPath := "WebServer/config.json"
|
||
|
||
// Читаем конфигурационный файл
|
||
data, err := os.ReadFile(configPath)
|
||
if err != nil {
|
||
return "error"
|
||
}
|
||
|
||
// Парсим JSON
|
||
var config map[string]interface{}
|
||
if err := json.Unmarshal(data, &config); err != nil {
|
||
return "error"
|
||
}
|
||
|
||
// Получаем список сайтов
|
||
siteWww, ok := config["Site_www"].([]interface{})
|
||
if !ok {
|
||
return "error"
|
||
}
|
||
|
||
// Ищем сайт по host
|
||
for _, siteInterface := range siteWww {
|
||
site, ok := siteInterface.(map[string]interface{})
|
||
if !ok {
|
||
continue
|
||
}
|
||
|
||
// Проверяем только по host (имя папки)
|
||
if host, ok := site["host"].(string); ok && host == siteName {
|
||
if status, ok := site["status"].(string); ok {
|
||
return status
|
||
}
|
||
}
|
||
}
|
||
|
||
return "inactive"
|
||
}
|
||
|
||
func SiteList(w http.ResponseWriter, r *http.Request, path string) bool {
|
||
|
||
switch path {
|
||
|
||
case "/service/Site_List":
|
||
sites := []map[string]interface{}{}
|
||
|
||
path_www()
|
||
|
||
for _, entry := range entries {
|
||
if entry.IsDir() {
|
||
site := map[string]interface{}{
|
||
"host": entry.Name(),
|
||
"type": site_type(entry),
|
||
"aliases": site_alliace(entry.Name()),
|
||
"status": site_status(entry.Name()),
|
||
}
|
||
sites = append(sites, site)
|
||
}
|
||
}
|
||
|
||
metrics := map[string]interface{}{
|
||
"sites": sites,
|
||
}
|
||
|
||
data, _ := json.MarshalIndent(metrics, "", " ")
|
||
w.Write(data)
|
||
|
||
return true
|
||
|
||
}
|
||
|
||
return false
|
||
|
||
}
|
||
|
||
func addSiteToConfig(siteName string) error {
|
||
// Получаем абсолютный путь к config.json
|
||
configPath, err := tools.AbsPath("WebServer/config.json")
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
// Читаем содержимое config.json
|
||
configData, err := os.ReadFile(configPath)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
// Парсим как общий JSON объект
|
||
var config map[string]interface{}
|
||
err = json.Unmarshal(configData, &config)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
// Получаем массив сайтов
|
||
siteWWW, ok := config["Site_www"].([]interface{})
|
||
if !ok {
|
||
siteWWW = []interface{}{}
|
||
}
|
||
|
||
// Создаем новый сайт в том же формате что уже есть
|
||
newSite := map[string]interface{}{
|
||
"name": siteName,
|
||
"host": siteName,
|
||
"alias": []string{""},
|
||
"status": "active",
|
||
}
|
||
|
||
// Добавляем новый сайт в массив
|
||
config["Site_www"] = append(siteWWW, newSite)
|
||
|
||
// Сохраняем обновленный конфиг
|
||
updatedData, err := json.MarshalIndent(config, "", " ")
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
// Делаем массивы алиасов в одну строку
|
||
re := regexp.MustCompile(`"alias": \[\s+"([^"]*?)"\s+\]`)
|
||
compactData := re.ReplaceAll(updatedData, []byte(`"alias": ["$1"]`))
|
||
|
||
// Исправляем отступы после Site_www
|
||
dataStr := string(compactData)
|
||
dataStr = strings.ReplaceAll(dataStr, ` ],
|
||
"Soft_Settings"`, ` ],
|
||
|
||
"Soft_Settings"`)
|
||
compactData = []byte(dataStr)
|
||
|
||
err = os.WriteFile(configPath, compactData, 0644)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
func site_add(w http.ResponseWriter, path string) bool {
|
||
|
||
// URL параметры: /service/Site_Add/sitename
|
||
if strings.HasPrefix(path, "/service/Site_Add/") {
|
||
siteName := strings.TrimPrefix(path, "/service/Site_Add/")
|
||
|
||
if siteName == "" {
|
||
w.WriteHeader(400)
|
||
w.Write([]byte(`{"status":"error","message":"Не указано имя сайта в URL"}`))
|
||
return true
|
||
}
|
||
|
||
wwwPath := "WebServer/www/" + siteName
|
||
|
||
// Проверяем существует ли уже такой сайт
|
||
if _, err := os.Stat(wwwPath); err == nil {
|
||
w.WriteHeader(409) // Conflict
|
||
w.Write([]byte(`{"status":"error","message":"Сайт ` + siteName + ` уже существует"}`))
|
||
return true
|
||
}
|
||
|
||
err := os.MkdirAll(wwwPath, 0755)
|
||
if err != nil {
|
||
w.WriteHeader(500)
|
||
w.Write([]byte(`{"status":"error","message":"Ошибка создания папки сайта"}`))
|
||
return true
|
||
}
|
||
|
||
// Добавляем сайт в config.json
|
||
err = addSiteToConfig(siteName)
|
||
if err != nil {
|
||
w.WriteHeader(500)
|
||
w.Write([]byte(`{"status":"error","message":"Ошибка добавления в конфигурацию: ` + err.Error() + `"}`))
|
||
return true
|
||
}
|
||
|
||
// Создаем папку public_www
|
||
publicWwwPath := wwwPath + "/public_www"
|
||
err = os.MkdirAll(publicWwwPath, 0755)
|
||
if err != nil {
|
||
w.WriteHeader(500)
|
||
w.Write([]byte(`{"status":"error","message":"Ошибка создания папки public_www"}`))
|
||
return true
|
||
}
|
||
|
||
indexFilePath := wwwPath + "/public_www/index.html"
|
||
indexContent := "Привет друг! Твой сайт создан!"
|
||
err = os.WriteFile(indexFilePath, []byte(indexContent), 0644)
|
||
if err != nil {
|
||
w.WriteHeader(500)
|
||
w.Write([]byte(`{"status":"error","message":"Ошибка создания index.html: ` + err.Error() + `"}`))
|
||
return true
|
||
}
|
||
|
||
w.Write([]byte(`{"status":"ok","message":"Сайт ` + siteName + ` успешно создан и добавлен в конфигурацию"}`))
|
||
config.LoadConfig()
|
||
return true
|
||
}
|
||
|
||
return false
|
||
}
|