Skip to content

server/plugin: add CloseUserConn operation to server plugin system#5228

Open
xb-bxy wants to merge 2 commits intofatedier:devfrom
xb-bxy:feat/close-user-conn
Open

server/plugin: add CloseUserConn operation to server plugin system#5228
xb-bxy wants to merge 2 commits intofatedier:devfrom
xb-bxy:feat/close-user-conn

Conversation

@xb-bxy
Copy link

@xb-bxy xb-bxy commented Mar 10, 2026

WHY --> Feature Request

When a user connection is accepted, the NewUserConn plugin operation is triggered. However, there is no corresponding lifecycle hook when the user connection is closed. This makes it impossible for plugins to track connection duration, perform cleanup, emit metrics per connection, or audit user session end-events.

Without CloseUserConn, plugins have no way to know when a proxied user connection has terminated.


Changes

  • Add OpCloseUserConn = "CloseUserConn" operation constant to the plugin op set
  • Add CloseUserConnContent struct (mirrors NewUserConnContent) with user, proxy_name, proxy_type, and remote_addr fields
  • Add closeUserConnPlugins []Plugin field to Manager and register plugins that support OpCloseUserConn
  • Add Manager.CloseUserConn() method that fans out the event to all registered plugins (errors are collected and logged as warnings, not blocking)
  • In handleUserTCPConnection, add a defer that calls CloseUserConn after the user connection closes, passing the same content as NewUserConn
  • Minor fix: remove redundant workConn = nil after workConn.Close() in GetWorkConnFromPool, and improve the closing log with userConn.RemoteAddr

Server Plugin Config Example

[[httpPlugins]]
name    = "my-plugin"
addr    = "https://plugin.example.com"
path    = "/handler"
ops     = ["NewUserConn", "CloseUserConn"]

Plugin handler receives CloseUserConn POST request with body:

{
  "version": "0.1.0",
  "op": "CloseUserConn",
  "content": {
    "user": { "user": "alice", "metas": {}, "run_id": "xxx" },
    "proxy_name": "my-proxy",
    "proxy_type": "tcp",
    "remote_addr": "1.2.3.4:12345"
  }
}

Test plan

  • Plugin registered with CloseUserConn op receives the event after each user connection closes
  • Plugin not registered with CloseUserConn is not called (zero-cost fast path when closeUserConnPlugins is empty)
  • CloseUserConn errors are logged as warnings and do not affect the data transfer result
  • NewUserConn → data transfer → CloseUserConn lifecycle is correct end-to-end
  • go vet plugin. clean
  • go build compiles cleanly
  • All existing server plugin tests pass (go test plugin.)

Copilot AI review requested due to automatic review settings March 10, 2026 04:05
@kilo-code-bot
Copy link

kilo-code-bot bot commented Mar 10, 2026

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Files Reviewed (7 files)
  • pkg/config/v1/validation/validation.go
  • pkg/plugin/server/manager.go
  • pkg/plugin/server/plugin.go
  • pkg/plugin/server/types.go
  • server/proxy/proxy.go
  • test/e2e/legacy/plugin/server.go
  • test/e2e/v1/plugin/server.go

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a CloseUserConn lifecycle hook to the frp server plugin system, allowing plugins to be notified when a proxied user TCP connection terminates. This mirrors the existing NewUserConn hook and enables plugins to track connection duration, emit per-connection metrics, and perform cleanup.

Changes:

  • Adds OpCloseUserConn constant, CloseUserConnContent struct, closeUserConnPlugins slice, and Manager.CloseUserConn() method to the server plugin package
  • Registers OpCloseUserConn in the supported plugin ops validation list
  • Adds a defer CloseUserConn(...) call in handleUserTCPConnection and includes a minor improvement to the debug log for closed connections

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
pkg/plugin/server/plugin.go Adds OpCloseUserConn = "CloseUserConn" operation constant
pkg/plugin/server/types.go Adds CloseUserConnContent struct (identical fields to NewUserConnContent)
pkg/plugin/server/manager.go Adds closeUserConnPlugins slice, registers plugins for the new op, and implements CloseUserConn() fan-out method
pkg/config/v1/validation/validation.go Adds OpCloseUserConn to SupportedHTTPPluginOps validation list
server/proxy/proxy.go Adds defer CloseUserConn(...) after successful NewUserConn; also changes err = … to err := … (shadowing bug) and removes workConn = nil

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Author

@xb-bxy xb-bxy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add CloseUserConn test cases for plugin server

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants