mirror of
https://github.com/Xevion/go-ha.git
synced 2025-12-06 05:15:15 -06:00
feat: support secure connections
This commit is contained in:
28
app.go
28
app.go
@@ -77,6 +77,12 @@ type NewAppRequest struct {
|
|||||||
// Used to pull latitude/longitude from Home Assistant
|
// Used to pull latitude/longitude from Home Assistant
|
||||||
// to calculate sunset/sunrise times.
|
// to calculate sunset/sunrise times.
|
||||||
HomeZoneEntityId string
|
HomeZoneEntityId string
|
||||||
|
|
||||||
|
// Optional
|
||||||
|
// Whether to use secure connections for http and websockets.
|
||||||
|
// Setting this to `true` will use `https://` instead of `https://`
|
||||||
|
// and `wss://` instead of `ws://`.
|
||||||
|
Secure bool
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -92,13 +98,31 @@ func NewApp(request NewAppRequest) (*App, error) {
|
|||||||
if port == "" {
|
if port == "" {
|
||||||
port = "8123"
|
port = "8123"
|
||||||
}
|
}
|
||||||
conn, ctx, ctxCancel, err := ws.SetupConnection(request.IpAddress, port, request.HAAuthToken)
|
|
||||||
|
var (
|
||||||
|
conn *websocket.Conn
|
||||||
|
ctx context.Context
|
||||||
|
ctxCancel context.CancelFunc
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
if request.Secure {
|
||||||
|
conn, ctx, ctxCancel, err = ws.SetupSecureConnection(request.IpAddress, port, request.HAAuthToken)
|
||||||
|
} else {
|
||||||
|
conn, ctx, ctxCancel, err = ws.SetupConnection(request.IpAddress, port, request.HAAuthToken)
|
||||||
|
}
|
||||||
|
|
||||||
if conn == nil {
|
if conn == nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
httpClient := http.NewHttpClient(request.IpAddress, port, request.HAAuthToken)
|
var httpClient *http.HttpClient
|
||||||
|
|
||||||
|
if request.Secure {
|
||||||
|
httpClient = http.NewHttpsClient(request.IpAddress, port, request.HAAuthToken)
|
||||||
|
} else {
|
||||||
|
httpClient = http.NewHttpClient(request.IpAddress, port, request.HAAuthToken)
|
||||||
|
}
|
||||||
|
|
||||||
wsWriter := &ws.WebsocketWriter{Conn: conn}
|
wsWriter := &ws.WebsocketWriter{Conn: conn}
|
||||||
service := newService(wsWriter, ctx, httpClient)
|
service := newService(wsWriter, ctx, httpClient)
|
||||||
|
|||||||
@@ -16,8 +16,24 @@ type HttpClient struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewHttpClient(ip, port, token string) *HttpClient {
|
func NewHttpClient(ip, port, token string) *HttpClient {
|
||||||
url := fmt.Sprintf("http://%s:%s/api", ip, port)
|
return ClientFromUri(
|
||||||
return &HttpClient{url, token}
|
fmt.Sprintf("http://%s:%s/api", ip, port),
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewHttpsClient(ip, port, token string) *HttpClient {
|
||||||
|
return ClientFromUri(
|
||||||
|
fmt.Sprintf("https://%s:%s/api", ip, port),
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ClientFromUri(uri, token string) *HttpClient {
|
||||||
|
return &HttpClient{
|
||||||
|
uri,
|
||||||
|
token,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *HttpClient) GetState(entityId string) ([]byte, error) {
|
func (c *HttpClient) GetState(entityId string) ([]byte, error) {
|
||||||
|
|||||||
@@ -50,14 +50,24 @@ func ReadMessage(conn *websocket.Conn, ctx context.Context) ([]byte, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func SetupConnection(ip, port, authToken string) (*websocket.Conn, context.Context, context.CancelFunc, error) {
|
func SetupConnection(ip, port, authToken string) (*websocket.Conn, context.Context, context.CancelFunc, error) {
|
||||||
|
uri := fmt.Sprintf("ws:///%s:%s/api/websocket", ip, port)
|
||||||
|
return ConnectionFromUri(uri, authToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetupSecureConnection(ip, port, authToken string) (*websocket.Conn, context.Context, context.CancelFunc, error) {
|
||||||
|
uri := fmt.Sprintf("wss://%s:%s/api/websocket", ip, port)
|
||||||
|
return ConnectionFromUri(uri, authToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConnectionFromUri(uri, authToken string) (*websocket.Conn, context.Context, context.CancelFunc, error) {
|
||||||
ctx, ctxCancel := context.WithTimeout(context.Background(), time.Second*3)
|
ctx, ctxCancel := context.WithTimeout(context.Background(), time.Second*3)
|
||||||
|
|
||||||
// Init websocket connection
|
// Init websocket connection
|
||||||
dialer := websocket.DefaultDialer
|
dialer := websocket.DefaultDialer
|
||||||
conn, _, err := dialer.DialContext(ctx, fmt.Sprintf("ws://%s:%s/api/websocket", ip, port), nil)
|
conn, _, err := dialer.DialContext(ctx, uri, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctxCancel()
|
ctxCancel()
|
||||||
slog.Error("Failed to connect to websocket at ws://%s:%s/api/websocket. Check IP address and port\n", ip, port)
|
slog.Error("Failed to connect to websocket. Check URI\n", "uri", uri)
|
||||||
return nil, nil, nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user