Basic http gateway

This commit is contained in:
2024-10-20 17:42:51 +08:00
parent ff24a43580
commit 9ac6370ecb
6 changed files with 85 additions and 52 deletions

48
pkg/http/api/command.go Normal file
View File

@ -0,0 +1,48 @@
package api
import (
"context"
"git.solsynth.dev/hypernet/nexus/pkg/directory"
"git.solsynth.dev/hypernet/nexus/pkg/proto"
"github.com/gofiber/fiber/v2"
"github.com/rs/zerolog/log"
"google.golang.org/grpc/metadata"
"strings"
"time"
)
func invokeCommand(c *fiber.Ctx) error {
command := c.Params("command")
method := strings.ToLower(c.Method())
handler := directory.GetCommandHandler(command, method)
if handler == nil {
return fiber.NewError(fiber.StatusNotFound, "command not found")
}
conn, err := handler.GetGrpcConn()
if err != nil {
return fiber.NewError(fiber.StatusServiceUnavailable, "service unavailable")
}
log.Debug().Str("id", command).Str("method", method).Msg("Invoking command from HTTP Gateway...")
ctx := metadata.AppendToOutgoingContext(c.Context(), "client_id", "http-gateway", "ip", c.IP(), "user_agent", c.Get(fiber.HeaderUserAgent))
ctx, cancel := context.WithTimeout(ctx, time.Second*10)
defer cancel()
out, err := proto.NewCommandControllerClient(conn).SendCommand(ctx, &proto.CommandArgument{
Command: command,
Method: method,
Payload: c.Body(),
})
if err != nil {
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
} else {
if !out.IsDelivered {
log.Debug().Str("id", command).Str("method", method).Msg("Invoking command from HTTP Gateway... failed, delivery not confirmed")
}
return c.Status(int(out.Status)).Send(out.Payload)
}
}

View File

@ -1,13 +1,8 @@
package api
import (
"github.com/spf13/viper"
"strings"
"git.solsynth.dev/hypernet/nexus/pkg/directory"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/proxy"
"github.com/rs/zerolog/log"
"github.com/samber/lo"
)
@ -22,33 +17,3 @@ func listExistsService(c *fiber.Ctx) error {
}
}))
}
func forwardServiceRequest(c *fiber.Ctx) error {
serviceType := c.Params("service")
ogKeyword := serviceType
aliasingMap := viper.GetStringMapString("services.aliases")
if val, ok := aliasingMap[serviceType]; ok {
serviceType = val
}
service := directory.GetServiceInstanceByType(serviceType)
if service == nil || service.HttpAddr == nil {
return fiber.NewError(fiber.StatusNotFound, "service not found")
}
ogUrl := c.Request().URI().String()
url := c.OriginalURL()
url = strings.Replace(url, "/cgi/"+ogKeyword, "/api", 1)
url = "http://" + *service.HttpAddr + url
log.Debug().
Str("from", ogUrl).
Str("to", url).
Str("service", serviceType).
Str("id", service.ID).
Msg("Forwarding request for service...")
return proxy.Do(c, url)
}

View File

@ -24,5 +24,5 @@ func MapAPIs(app *fiber.App) {
return c.Next()
}).Get("/ws", websocket.New(listenWebsocket))
app.All("/cgi/:service/*", forwardServiceRequest)
app.All("/cgi/:command", invokeCommand)
}