feat: support secure connections

This commit is contained in:
Dominik Siebel
2024-02-22 11:28:05 +01:00
parent a9aad16cf3
commit 8b436ce4ee
3 changed files with 56 additions and 6 deletions

28
app.go
View File

@@ -77,6 +77,12 @@ type NewAppRequest struct {
// Used to pull latitude/longitude from Home Assistant
// to calculate sunset/sunrise times.
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 == "" {
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 {
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}
service := newService(wsWriter, ctx, httpClient)

View File

@@ -16,8 +16,24 @@ type HttpClient struct {
}
func NewHttpClient(ip, port, token string) *HttpClient {
url := fmt.Sprintf("http://%s:%s/api", ip, port)
return &HttpClient{url, token}
return ClientFromUri(
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) {

View File

@@ -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) {
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)
// Init websocket connection
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 {
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
}