| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394 |
- package inbound
- import (
- "encoding/json"
- "io"
- "net/http"
- C "github.com/sagernet/sing-box/constant"
- "github.com/sagernet/sing-box/option"
- "github.com/sagernet/sing/common"
- E "github.com/sagernet/sing/common/exceptions"
- F "github.com/sagernet/sing/common/format"
- "github.com/go-chi/chi/v5"
- "github.com/go-chi/render"
- )
- func (h *ShadowsocksMulti) createHandler() http.Handler {
- router := chi.NewRouter()
- router.Get("/", h.handleHello)
- router.Put("/users", h.handleUpdateUsers)
- router.Get("/traffics", h.handleReadTraffics)
- return router
- }
- func (h *ShadowsocksMulti) handleHello(writer http.ResponseWriter, request *http.Request) {
- render.JSON(writer, request, render.M{
- "server": "sing-box",
- "version": C.Version,
- })
- }
- func (h *ShadowsocksMulti) handleUpdateUsers(writer http.ResponseWriter, request *http.Request) {
- var users []option.ShadowsocksUser
- err := readRequest(request, &users)
- if err != nil {
- h.newError(E.Cause(err, "controller: update users: parse request"))
- writer.WriteHeader(http.StatusBadRequest)
- writer.Write([]byte(F.ToString(err)))
- return
- }
- users = append([]option.ShadowsocksUser{{
- Name: "control",
- Password: h.users[0].Password,
- }}, users...)
- err = h.service.UpdateUsersWithPasswords(common.MapIndexed(users, func(index int, user option.ShadowsocksUser) int {
- return index
- }), common.Map(users, func(user option.ShadowsocksUser) string {
- return user.Password
- }))
- if err != nil {
- h.newError(E.Cause(err, "controller: update users"))
- writer.WriteHeader(http.StatusBadRequest)
- writer.Write([]byte(F.ToString(err)))
- return
- }
- h.users = users
- h.trafficManager.Reset()
- writer.WriteHeader(http.StatusNoContent)
- h.logger.Info("controller: updated ", len(users)-1, " users")
- }
- type ShadowsocksUserTraffic struct {
- Name string `json:"name,omitempty"`
- Upload uint64 `json:"upload,omitempty"`
- Download uint64 `json:"download,omitempty"`
- }
- func (h *ShadowsocksMulti) handleReadTraffics(writer http.ResponseWriter, request *http.Request) {
- h.logger.Debug("controller: traffics sent")
- trafficMap := h.trafficManager.ReadTraffics()
- if len(trafficMap) == 0 {
- writer.WriteHeader(http.StatusNoContent)
- return
- }
- traffics := make([]ShadowsocksUserTraffic, 0, len(trafficMap))
- for user, traffic := range trafficMap {
- traffics = append(traffics, ShadowsocksUserTraffic{
- Name: h.users[user].Name,
- Upload: traffic.Upload,
- Download: traffic.Download,
- })
- }
- render.JSON(writer, request, traffics)
- }
- func readRequest(request *http.Request, v any) error {
- defer request.Body.Close()
- content, err := io.ReadAll(request.Body)
- if err != nil {
- return err
- }
- return json.Unmarshal(content, v)
- }
|