feat: support monitoring WebSocket endpoints (#511)
* feat: support monitoring WebSocket endpoints WebSocket endpoints are automatically identified by the URL protocol specification: `wss://` or `ws://`. The request body is used as the "message" written to the server, and the answer is stored in the `[BODY]`. Optionally, the user can set the `jsonrpc` flag to automatically wrap the request body in a JSON RPC 2.0 method call. * core:websocket: close connection after using it * test: add tests related to WebSocket support - test we can identify the endpoint type for WebSockets based on the URL supplied: `wss://` (with SSL/TLS) and `ws://` (plain text). - test we can generate a JsonRPC 2.0 message via the new endpoint flag `JsonRPC`. * core:endpoint: fix name of jsonrpc parameter See https://en.wikipedia.org/wiki/JSON-RPC#Version_2.0 * core:websocket: fix dangling open connection on error Move the `defer ws.Close()` to after opening the connection, so the socket is closed also in case of errors. * remove jsonrpc flag * core:websocket: fix nil pointer dereference The connection should only be closed if successfully opened. * Move websocket function to client * update go.mod * Fix build errors * Fix errors * Update client/client.go --------- Co-authored-by: TwiN <twin@linux.com>
This commit is contained in:
@ -5,6 +5,7 @@ import (
|
||||
"crypto/x509"
|
||||
"errors"
|
||||
"fmt"
|
||||
"golang.org/x/net/websocket"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/smtp"
|
||||
@ -184,6 +185,37 @@ func Ping(address string, config *Config) (bool, time.Duration) {
|
||||
return true, 0
|
||||
}
|
||||
|
||||
// Open a websocket connection, write `body` and return a message from the server
|
||||
func QueryWebSocket(address string, config *Config, body string) (bool, []byte, error) {
|
||||
const (
|
||||
Origin = "http://localhost/"
|
||||
MaximumMessageSize = 1024 // in bytes
|
||||
)
|
||||
|
||||
wsConfig, err := websocket.NewConfig(address, Origin)
|
||||
if err != nil {
|
||||
return false, nil, fmt.Errorf("error configuring websocket connection: %w", err)
|
||||
}
|
||||
// Dial URL
|
||||
ws, err := websocket.DialConfig(wsConfig)
|
||||
if err != nil {
|
||||
return false, nil, fmt.Errorf("error dialing websocket: %w", err)
|
||||
}
|
||||
defer ws.Close()
|
||||
connected := true
|
||||
// Write message
|
||||
if _, err := ws.Write([]byte(body)); err != nil {
|
||||
return false, nil, fmt.Errorf("error writing websocket body: %w", err)
|
||||
}
|
||||
// Read message
|
||||
var n int
|
||||
msg := make([]byte, MaximumMessageSize)
|
||||
if n, err = ws.Read(msg); err != nil {
|
||||
return false, nil, fmt.Errorf("error reading websocket message: %w", err)
|
||||
}
|
||||
return connected, msg[:n], nil
|
||||
}
|
||||
|
||||
// InjectHTTPClient is used to inject a custom HTTP client for testing purposes
|
||||
func InjectHTTPClient(httpClient *http.Client) {
|
||||
injectedHTTPClient = httpClient
|
||||
|
Reference in New Issue
Block a user