fdx-proxy is a Go library that provides a full-duplex proxy solution to handle scenarios where an HTTP node is not directly accessible by external services but can initiate outbound connections. The library establishes a WebSocket-based full-duplex communication channel between a proxy (fdx-proxy client) running on the HTTP node and an external service (fdx-proxy server). This allows seamless proxying of requests from the external service to the HTTP node through the established WebSocket connection.
The fdx-proxy library consists of the following core components:
- FullDuplexServer: Manages WebSocket connections and forwards HTTP requests from external clients to the target HTTP service.
- FullDuplexProxy: Acts as a client that establishes a full-duplex WebSocket channel with the
FullDuplexServer, enabling bidirectional communication. - Proxy Controller (
tools/main.go): Provides a command-line interface to start thefdx-proxyclient.
To use fdx-proxy as a Go library in your own project, add it as a dependency:
go get github.com/yuuavwa/fdx-proxyThe primary use case for fdx-proxy is to integrate it with an external service that requires access to an HTTP node which is not directly accessible. Here’s how to use fdx-proxy:
-
Implement the Full Duplex Server in Your External Service: In your external service, use
fdx-proxyto implement a full-duplex server that listens for WebSocket connections from the proxy client. Here is an example:import ( "fmt" proxy "github.com/yuuavwa/fdx-proxy" ) var serverCtrl *proxy.FullDuplexServerController serverCtrl, _ = proxy.NewFullDuplexServerController() // in your gin router handler func ProxyHandler(c *gin.Context) { targetID := c.Param("target_id") err := serverCtrl.AddFullDuplexConnController(c, targetID) if err != nil { panic(err) } // ... } func MyTask(target_id string) { if ctrl, err := serverCtrl.GetFullDuplexConnController(target_id); ctrl != nil && err == nil { ReqMethod := "GET" ReqHeaders := map[string]string{} ReqBody := "" ReqURL := "https://www.this-is-just-a-test.com/" // here to use CallAPI to proxy the request through the websocket connection status, res_body, err := serverCtrl.CallAPI(target_id, ReqMethod, ReqURL, ReqHeaders, ReqBody) if err != nil { panic(err) } fmt.Println(status, res_body) // ... } } func main() { router := gin.Default() router.GET("/api/EstablishFullDuplexChannel/:target_id", ProxyHandler) go MyTask("192.168.0.100:5000") router.Run(":8080") // Start server on port 8080 }
This example sets up a server that listens for WebSocket connections at the endpoint
/api/EstablishFullDuplexChannel/:target_idand handles incoming requests using theCallAPIfunction. -
Deploy the Full Duplex Proxy on the HTTP Node: On the HTTP node that cannot be accessed directly but can access the external service, deploy the proxy client by running the following command:
go run tools/main.go -m proxy -s <external_service_address> -t <target_address>
<external_service_address>: The address of the external service that runs thefdx-proxyserver.<target_address>: The identifier or address of the target HTTP service that the proxy client will forward requests to. This command starts thefdx-proxyclient, which connects to the external service and establishes a WebSocket channel for full-duplex communication.
-
fdx-server:
- Listens for WebSocket connections at the specified endpoint.
- Creates a
FullDuplexServerControllerto manage incoming and outgoing requests over the WebSocket channel.
-
fdx-proxy:
- Actively connects to the proxy server using WebSocket and establishes a communication channel.
- Uses
FullDuplexProxyControllerto handle bidirectional communication, including reading requests from the WebSocket and forwarding them to the target HTTP service.
The fdx-proxy library supports logging. Modify the SetLogger function in util.go to set the desired log file path.