package admin
import (
"computer-network/logger"
"encoding/json"
"fmt"
"html"
"net"
"strings"
"sync"
)
type AdminHandler struct {
mu sync.RWMutex
}
func NewAdminHandler() *AdminHandler {
return &AdminHandler{}
}
func (h *AdminHandler) ClearLogs() *HTTPResponse {
h.mu.Lock()
defer h.mu.Unlock()
logger.ClearLogs()
jsonData, _ := json.Marshal(map[string]interface{}{
"success": true,
"message": "Logs cleared successfully",
})
return &HTTPResponse{
StatusCode: "200 OK",
ContentType: "application/json",
Body: string(jsonData),
}
}
func (h *AdminHandler) GetIndexPage() *HTTPResponse {
html := `
Web Server Admin Console
`
return &HTTPResponse{
StatusCode: "200 OK",
ContentType: "text/html; charset=utf-8",
Body: html,
}
}
func (h *AdminHandler) GetLogsPage() *HTTPResponse {
logs := logger.GetLogs()
var logEntries []string
if len(logs) == 0 {
logEntries = append(logEntries, `暂无访问日志
`)
} else {
for i := len(logs) - 1; i >= 0; i-- {
log := logs[i]
date := log.Timestamp.Format("2006-01-02 15:04:05")
duration := log.Duration.Milliseconds()
statusClass := fmt.Sprintf("status-%d", log.StatusCode)
logEntry := fmt.Sprintf(`
[%s]
%s
%s
%s
%d
%dms
`,
date, log.ClientIP, log.Method, html.EscapeString(log.URL), statusClass, log.StatusCode, duration)
logEntries = append(logEntries, logEntry)
}
}
html := fmt.Sprintf(`
访问日志 - Web服务器管理
`, len(logs), strings.Join(logEntries, ""))
return &HTTPResponse{
StatusCode: "200 OK",
ContentType: "text/html; charset=utf-8",
Body: html,
}
}
type LogEntryJSON struct {
ClientIP string `json:"client_ip"`
Method string `json:"method"`
URL string `json:"url"`
HTTPVersion string `json:"http_version"`
StatusCode int `json:"status_code"`
Duration int64 `json:"duration"`
Timestamp string `json:"timestamp"`
}
func (h *AdminHandler) GetLogsJSON() *HTTPResponse {
h.mu.RLock()
defer h.mu.RUnlock()
logs := logger.GetLogs()
jsonLogs := make([]LogEntryJSON, len(logs))
for i, log := range logs {
jsonLogs[i] = LogEntryJSON{
ClientIP: log.ClientIP,
Method: log.Method,
URL: log.URL,
HTTPVersion: log.HTTPVersion,
StatusCode: log.StatusCode,
Duration: log.Duration.Nanoseconds(),
Timestamp: log.Timestamp.Format("2006-01-02T15:04:05Z07:00"),
}
}
jsonData, _ := json.Marshal(map[string]interface{}{
"logs": jsonLogs,
"count": len(logs),
})
return &HTTPResponse{
StatusCode: "200 OK",
ContentType: "application/json",
Body: string(jsonData),
}
}
func (h *AdminHandler) GetStatusJSON() *HTTPResponse {
h.mu.RLock()
defer h.mu.RUnlock()
jsonData, _ := json.Marshal(map[string]interface{}{
"running": true,
"port": 8080,
})
return &HTTPResponse{
StatusCode: "200 OK",
ContentType: "application/json",
Body: string(jsonData),
}
}
type HTTPResponse struct {
StatusCode string
ContentType string
Body string
}
func (r *HTTPResponse) Build() []byte {
var builder strings.Builder
builder.WriteString(fmt.Sprintf("HTTP/1.1 %s\r\n", r.StatusCode))
builder.WriteString(fmt.Sprintf("Content-Type: %s\r\n", r.ContentType))
builder.WriteString(fmt.Sprintf("Content-Length: %d\r\n", len(r.Body)))
builder.WriteString("\r\n")
builder.WriteString(r.Body)
return []byte(builder.String())
}
func SendResponse(conn net.Conn, response *HTTPResponse) error {
data := response.Build()
_, err := conn.Write(data)
return err
}