✨ Broadcast event
This commit is contained in:
7
pkg/internal/http/api/check_ip.go
Normal file
7
pkg/internal/http/api/check_ip.go
Normal file
@ -0,0 +1,7 @@
|
||||
package api
|
||||
|
||||
import "github.com/gofiber/fiber/v2"
|
||||
|
||||
func getClientIP(c *fiber.Ctx) error {
|
||||
return c.SendString(c.IP())
|
||||
}
|
67
pkg/internal/http/api/command.go
Normal file
67
pkg/internal/http/api/command.go
Normal file
@ -0,0 +1,67 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"git.solsynth.dev/hypernet/nexus/pkg/internal/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...")
|
||||
|
||||
var meta []string
|
||||
meta = append(meta, "client_id", "http-gateway")
|
||||
meta = append(meta, "net.ip", c.IP())
|
||||
meta = append(meta, "http.user_agent", c.Get(fiber.HeaderUserAgent))
|
||||
for k, v := range c.GetReqHeaders() {
|
||||
meta = append(
|
||||
meta,
|
||||
strings.ToLower(fmt.Sprintf("header.%s", strings.ReplaceAll(k, "-", "_"))),
|
||||
strings.Join(v, "\n"),
|
||||
)
|
||||
}
|
||||
|
||||
for k, v := range c.Queries() {
|
||||
meta = append(
|
||||
meta,
|
||||
strings.ToLower(fmt.Sprintf("query.%s", strings.ReplaceAll(k, "-", "_"))),
|
||||
v,
|
||||
)
|
||||
}
|
||||
|
||||
ctx := metadata.AppendToOutgoingContext(c.Context(), meta...)
|
||||
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 {
|
||||
c.Set(fiber.HeaderContentType, out.ContentType)
|
||||
return c.Status(int(out.Status)).Send(out.Payload)
|
||||
}
|
||||
}
|
19
pkg/internal/http/api/directory.go
Normal file
19
pkg/internal/http/api/directory.go
Normal file
@ -0,0 +1,19 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
directory2 "git.solsynth.dev/hypernet/nexus/pkg/internal/directory"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/samber/lo"
|
||||
)
|
||||
|
||||
func listExistsService(c *fiber.Ctx) error {
|
||||
services := directory2.ListServiceInstance()
|
||||
|
||||
return c.JSON(lo.Map(services, func(item *directory2.ServiceInstance, index int) map[string]any {
|
||||
return map[string]any{
|
||||
"id": item.ID,
|
||||
"type": item.Type,
|
||||
"label": item.Label,
|
||||
}
|
||||
}))
|
||||
}
|
41
pkg/internal/http/api/forward.go
Normal file
41
pkg/internal/http/api/forward.go
Normal file
@ -0,0 +1,41 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"git.solsynth.dev/hypernet/nexus/pkg/internal/directory"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/middleware/proxy"
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/viper"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func forwardService(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, "", 1)
|
||||
url = *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)
|
||||
|
||||
}
|
30
pkg/internal/http/api/index.go
Normal file
30
pkg/internal/http/api/index.go
Normal file
@ -0,0 +1,30 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"git.solsynth.dev/hypernet/nexus/pkg/internal/http/ws"
|
||||
"github.com/gofiber/contrib/websocket"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
func MapAPIs(app *fiber.App) {
|
||||
// Some built-in public-accessible APIs
|
||||
wellKnown := app.Group("/.well-known").Name("Well Known")
|
||||
{
|
||||
wellKnown.Get("/", func(c *fiber.Ctx) error {
|
||||
return c.SendStatus(fiber.StatusOK)
|
||||
})
|
||||
wellKnown.Get("/check-ip", getClientIP)
|
||||
wellKnown.Get("/directory/services", listExistsService)
|
||||
}
|
||||
|
||||
// Common websocket gateway
|
||||
app.Use(func(c *fiber.Ctx) error {
|
||||
/*if err := exts.EnsureAuthenticated(c); err != nil {
|
||||
return err
|
||||
}*/
|
||||
return c.Next()
|
||||
}).Get("/ws", websocket.New(ws.Listen))
|
||||
|
||||
app.All("/inv/:command", invokeCommand)
|
||||
app.All("/cgi/:service/*", forwardService)
|
||||
}
|
Reference in New Issue
Block a user