mirror of
https://github.com/Buriburizaem0n/nezha_domains.git
synced 2026-09-19 17:50:12 +00:00
65 lines
2.4 KiB
Go
65 lines
2.4 KiB
Go
//go:build agentcompat
|
|
|
|
package controller
|
|
|
|
import (
|
|
"github.com/gin-gonic/gin"
|
|
|
|
"github.com/nezhahq/nezha/pkg/agentcompatcontract"
|
|
"github.com/nezhahq/nezha/service/rpc"
|
|
)
|
|
|
|
type agentcompatCapabilityHeaderContextKey struct{}
|
|
|
|
func prepareAgentcompatCapabilityHeader(c *gin.Context) {
|
|
values := c.Request.Header.Values(agentcompatcontract.IOStreamCapabilityHeader)
|
|
if len(values) == 0 {
|
|
return
|
|
}
|
|
c.Request.Header.Del(agentcompatcontract.IOStreamCapabilityHeader)
|
|
c.Set(agentcompatCapabilityHeaderContextKey{}, values)
|
|
}
|
|
|
|
func createIOStreamWithAgentcompatCapability(c *gin.Context, streamID string, creatorUserID, serverID uint64, purpose rpc.AgentCompatCapabilityPurpose) (func(), error) {
|
|
identity := agentcompatCapabilityIdentity{purpose: purpose, serverID: serverID}
|
|
rawValues, _ := c.Get(agentcompatCapabilityHeaderContextKey{})
|
|
values, _ := rawValues.([]string)
|
|
if len(values) == 0 {
|
|
if err := rpc.NezhaHandlerSingleton.CreateStream(streamID, creatorUserID, serverID); err != nil {
|
|
return nil, err
|
|
}
|
|
return func() { _ = rpc.NezhaHandlerSingleton.CloseStream(streamID) }, nil
|
|
}
|
|
if len(values) != 1 || values[0] == "" {
|
|
return nil, errAgentcompatCapabilityUnavailable
|
|
}
|
|
capability, err := rpc.ParseAgentCompatIOStreamCapability(values[0])
|
|
if err != nil {
|
|
return nil, errAgentcompatCapabilityUnavailable
|
|
}
|
|
proof, err := currentAgentcompatCapabilityProof(c, identity)
|
|
if err != nil {
|
|
return nil, errAgentcompatCapabilityUnavailable
|
|
}
|
|
access := proof.access(capability)
|
|
if err := rpc.NezhaHandlerSingleton.CreateStreamWithPurpose(streamID, creatorUserID, serverID, agentcompatStreamPurpose(purpose)); err != nil {
|
|
_ = rpc.NezhaHandlerSingleton.UnregisterAgentCompatIOStreamCapability(access)
|
|
return nil, err
|
|
}
|
|
// Bind before dispatch preserves exact cancellation when the create response is lost.
|
|
if err := rpc.NezhaHandlerSingleton.BindAgentCompatIOStreamCapability(rpc.AgentCompatCapabilityBinding{AgentCompatCapabilityAccess: access, StreamID: streamID}); err != nil {
|
|
_ = rpc.NezhaHandlerSingleton.CloseStream(streamID)
|
|
return nil, errAgentcompatCapabilityUnavailable
|
|
}
|
|
return func() {
|
|
_ = rpc.NezhaHandlerSingleton.CancelAgentCompatIOStreamCapability(access)
|
|
}, nil
|
|
}
|
|
|
|
func agentcompatStreamPurpose(purpose rpc.AgentCompatCapabilityPurpose) rpc.StreamPurpose {
|
|
if purpose == rpc.AgentCompatCapabilityTerminal {
|
|
return rpc.PurposeTerminal
|
|
}
|
|
return rpc.PurposeFileManager
|
|
}
|