hap-nodejs 1.1.1-beta.4 → 1.1.1-beta.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/@types/bonjour-hap.d.ts +53 -50
- package/@types/simple-plist.d.ts +4 -0
- package/README.md +19 -16
- package/dist/accessories/AirConditioner_accessory.js +30 -28
- package/dist/accessories/AirConditioner_accessory.js.map +1 -1
- package/dist/accessories/AppleTVRemote_accessory.js +81 -69
- package/dist/accessories/AppleTVRemote_accessory.js.map +1 -1
- package/dist/accessories/Camera_accessory.js +136 -141
- package/dist/accessories/Camera_accessory.js.map +1 -1
- package/dist/accessories/Fan_accessory.js +22 -18
- package/dist/accessories/Fan_accessory.js.map +1 -1
- package/dist/accessories/GarageDoorOpener_accessory.js +35 -33
- package/dist/accessories/GarageDoorOpener_accessory.js.map +1 -1
- package/dist/accessories/Light-AdaptiveLighting_accessory.js +44 -42
- package/dist/accessories/Light-AdaptiveLighting_accessory.js.map +1 -1
- package/dist/accessories/Light_accessory.js +34 -32
- package/dist/accessories/Light_accessory.js.map +1 -1
- package/dist/accessories/Lock_accessory.js +26 -25
- package/dist/accessories/Lock_accessory.js.map +1 -1
- package/dist/accessories/MotionSensor_accessory.js +16 -13
- package/dist/accessories/MotionSensor_accessory.js.map +1 -1
- package/dist/accessories/Outlet_accessory.js +22 -20
- package/dist/accessories/Outlet_accessory.js.map +1 -1
- package/dist/accessories/SmartSpeaker_accessory.js +20 -18
- package/dist/accessories/SmartSpeaker_accessory.js.map +1 -1
- package/dist/accessories/Sprinkler_accessory.js +37 -34
- package/dist/accessories/Sprinkler_accessory.js.map +1 -1
- package/dist/accessories/TV_accessory.js +45 -43
- package/dist/accessories/TV_accessory.js.map +1 -1
- package/dist/accessories/TemperatureSensor_accessory.js +15 -12
- package/dist/accessories/TemperatureSensor_accessory.js.map +1 -1
- package/dist/accessories/Wi-FiRouter_accessory.d.ts +1 -1
- package/dist/accessories/Wi-FiRouter_accessory.d.ts.map +1 -1
- package/dist/accessories/Wi-FiRouter_accessory.js +12 -9
- package/dist/accessories/Wi-FiRouter_accessory.js.map +1 -1
- package/dist/accessories/Wi-FiSatellite_accessory.d.ts +1 -1
- package/dist/accessories/Wi-FiSatellite_accessory.d.ts.map +1 -1
- package/dist/accessories/Wi-FiSatellite_accessory.js +14 -11
- package/dist/accessories/Wi-FiSatellite_accessory.js.map +1 -1
- package/dist/accessories/gstreamer-audioProducer.d.ts +3 -3
- package/dist/accessories/gstreamer-audioProducer.d.ts.map +1 -1
- package/dist/accessories/gstreamer-audioProducer.js +38 -37
- package/dist/accessories/gstreamer-audioProducer.js.map +1 -1
- package/dist/accessories/types.d.ts +63 -63
- package/dist/accessories/types.d.ts.map +1 -1
- package/dist/accessories/types.js +87 -83
- package/dist/accessories/types.js.map +1 -1
- package/dist/index.d.ts +28 -26
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +34 -40
- package/dist/index.js.map +1 -1
- package/dist/internal-types.d.ts +1 -1
- package/dist/internal-types.d.ts.map +1 -1
- package/dist/internal-types.js +21 -19
- package/dist/internal-types.js.map +1 -1
- package/dist/lib/Accessory.d.ts +37 -38
- package/dist/lib/Accessory.d.ts.map +1 -1
- package/dist/lib/Accessory.js +296 -286
- package/dist/lib/Accessory.js.map +1 -1
- package/dist/lib/Advertiser.d.ts +7 -7
- package/dist/lib/Advertiser.d.ts.map +1 -1
- package/dist/lib/Advertiser.js +136 -128
- package/dist/lib/Advertiser.js.map +1 -1
- package/dist/lib/Bridge.d.ts +1 -1
- package/dist/lib/Bridge.d.ts.map +1 -1
- package/dist/lib/Bridge.js +6 -2
- package/dist/lib/Bridge.js.map +1 -1
- package/dist/lib/Characteristic.d.ts +41 -40
- package/dist/lib/Characteristic.d.ts.map +1 -1
- package/dist/lib/Characteristic.js +208 -204
- package/dist/lib/Characteristic.js.map +1 -1
- package/dist/lib/HAPServer.d.ts +30 -31
- package/dist/lib/HAPServer.d.ts.map +1 -1
- package/dist/lib/HAPServer.js +229 -220
- package/dist/lib/HAPServer.js.map +1 -1
- package/dist/lib/Service.d.ts +22 -22
- package/dist/lib/Service.d.ts.map +1 -1
- package/dist/lib/Service.js +67 -63
- package/dist/lib/Service.js.map +1 -1
- package/dist/lib/camera/RTPProxy.d.ts +1 -2
- package/dist/lib/camera/RTPProxy.d.ts.map +1 -1
- package/dist/lib/camera/RTPProxy.js +44 -28
- package/dist/lib/camera/RTPProxy.js.map +1 -1
- package/dist/lib/camera/RTPStreamManagement.d.ts +33 -34
- package/dist/lib/camera/RTPStreamManagement.d.ts.map +1 -1
- package/dist/lib/camera/RTPStreamManagement.js +149 -181
- package/dist/lib/camera/RTPStreamManagement.js.map +1 -1
- package/dist/lib/camera/RecordingManagement.d.ts +17 -19
- package/dist/lib/camera/RecordingManagement.d.ts.map +1 -1
- package/dist/lib/camera/RecordingManagement.js +151 -160
- package/dist/lib/camera/RecordingManagement.js.map +1 -1
- package/dist/lib/camera/index.d.ts +3 -3
- package/dist/lib/camera/index.d.ts.map +1 -1
- package/dist/lib/camera/index.js +6 -3
- package/dist/lib/camera/index.js.map +1 -1
- package/dist/lib/controller/AdaptiveLightingController.d.ts +33 -33
- package/dist/lib/controller/AdaptiveLightingController.d.ts.map +1 -1
- package/dist/lib/controller/AdaptiveLightingController.js +144 -152
- package/dist/lib/controller/AdaptiveLightingController.js.map +1 -1
- package/dist/lib/controller/CameraController.d.ts +20 -22
- package/dist/lib/controller/CameraController.d.ts.map +1 -1
- package/dist/lib/controller/CameraController.js +78 -74
- package/dist/lib/controller/CameraController.js.map +1 -1
- package/dist/lib/controller/Controller.d.ts +4 -4
- package/dist/lib/controller/Controller.d.ts.map +1 -1
- package/dist/lib/controller/Controller.js +8 -5
- package/dist/lib/controller/Controller.js.map +1 -1
- package/dist/lib/controller/DoorbellController.d.ts +4 -5
- package/dist/lib/controller/DoorbellController.d.ts.map +1 -1
- package/dist/lib/controller/DoorbellController.js +13 -9
- package/dist/lib/controller/DoorbellController.js.map +1 -1
- package/dist/lib/controller/RemoteController.d.ts +37 -39
- package/dist/lib/controller/RemoteController.d.ts.map +1 -1
- package/dist/lib/controller/RemoteController.js +197 -208
- package/dist/lib/controller/RemoteController.js.map +1 -1
- package/dist/lib/controller/index.d.ts +5 -5
- package/dist/lib/controller/index.d.ts.map +1 -1
- package/dist/lib/controller/index.js +8 -5
- package/dist/lib/controller/index.js.map +1 -1
- package/dist/lib/datastream/DataStreamManagement.d.ts +2 -2
- package/dist/lib/datastream/DataStreamManagement.d.ts.map +1 -1
- package/dist/lib/datastream/DataStreamManagement.js +39 -39
- package/dist/lib/datastream/DataStreamManagement.js.map +1 -1
- package/dist/lib/datastream/DataStreamParser.d.ts +0 -1
- package/dist/lib/datastream/DataStreamParser.d.ts.map +1 -1
- package/dist/lib/datastream/DataStreamParser.js +77 -57
- package/dist/lib/datastream/DataStreamParser.js.map +1 -1
- package/dist/lib/datastream/DataStreamServer.d.ts +22 -23
- package/dist/lib/datastream/DataStreamServer.d.ts.map +1 -1
- package/dist/lib/datastream/DataStreamServer.js +164 -154
- package/dist/lib/datastream/DataStreamServer.js.map +1 -1
- package/dist/lib/datastream/index.d.ts +3 -3
- package/dist/lib/datastream/index.d.ts.map +1 -1
- package/dist/lib/datastream/index.js +6 -3
- package/dist/lib/datastream/index.js.map +1 -1
- package/dist/lib/definitions/CharacteristicDefinitions.d.ts +11 -1
- package/dist/lib/definitions/CharacteristicDefinitions.d.ts.map +1 -1
- package/dist/lib/definitions/CharacteristicDefinitions.js +1218 -957
- package/dist/lib/definitions/CharacteristicDefinitions.js.map +1 -1
- package/dist/lib/definitions/ServiceDefinitions.d.ts +1 -1
- package/dist/lib/definitions/ServiceDefinitions.d.ts.map +1 -1
- package/dist/lib/definitions/ServiceDefinitions.js +695 -620
- package/dist/lib/definitions/ServiceDefinitions.js.map +1 -1
- package/dist/lib/definitions/generate-definitions.d.ts +3 -3
- package/dist/lib/definitions/generate-definitions.d.ts.map +1 -1
- package/dist/lib/definitions/generate-definitions.js +256 -244
- package/dist/lib/definitions/generate-definitions.js.map +1 -1
- package/dist/lib/definitions/generator-configuration.d.ts +1 -1
- package/dist/lib/definitions/generator-configuration.d.ts.map +1 -1
- package/dist/lib/definitions/generator-configuration.js +170 -160
- package/dist/lib/definitions/generator-configuration.js.map +1 -1
- package/dist/lib/definitions/index.d.ts +2 -2
- package/dist/lib/definitions/index.d.ts.map +1 -1
- package/dist/lib/definitions/index.js +5 -2
- package/dist/lib/definitions/index.js.map +1 -1
- package/dist/lib/gen/HomeKit.d.ts +7 -0
- package/dist/lib/gen/HomeKit.d.ts.map +1 -0
- package/dist/lib/gen/HomeKit.js +8 -0
- package/dist/lib/gen/HomeKit.js.map +1 -0
- package/dist/lib/model/AccessoryInfo.d.ts +3 -4
- package/dist/lib/model/AccessoryInfo.d.ts.map +1 -1
- package/dist/lib/model/AccessoryInfo.js +53 -50
- package/dist/lib/model/AccessoryInfo.js.map +1 -1
- package/dist/lib/model/ControllerStorage.d.ts +3 -3
- package/dist/lib/model/ControllerStorage.d.ts.map +1 -1
- package/dist/lib/model/ControllerStorage.js +23 -18
- package/dist/lib/model/ControllerStorage.js.map +1 -1
- package/dist/lib/model/HAPStorage.d.ts +2 -2
- package/dist/lib/model/HAPStorage.d.ts.map +1 -1
- package/dist/lib/model/HAPStorage.js +11 -4
- package/dist/lib/model/HAPStorage.js.map +1 -1
- package/dist/lib/model/IdentifierCache.d.ts +1 -1
- package/dist/lib/model/IdentifierCache.d.ts.map +1 -1
- package/dist/lib/model/IdentifierCache.js +27 -19
- package/dist/lib/model/IdentifierCache.js.map +1 -1
- package/dist/lib/tv/AccessControlManagement.d.ts +9 -9
- package/dist/lib/tv/AccessControlManagement.d.ts.map +1 -1
- package/dist/lib/tv/AccessControlManagement.js +29 -27
- package/dist/lib/tv/AccessControlManagement.js.map +1 -1
- package/dist/lib/util/checkName.d.ts +2 -2
- package/dist/lib/util/checkName.d.ts.map +1 -1
- package/dist/lib/util/checkName.js +9 -6
- package/dist/lib/util/checkName.js.map +1 -1
- package/dist/lib/util/clone.d.ts.map +1 -1
- package/dist/lib/util/clone.js +5 -1
- package/dist/lib/util/clone.js.map +1 -1
- package/dist/lib/util/color-utils.d.ts +1 -1
- package/dist/lib/util/color-utils.d.ts.map +1 -1
- package/dist/lib/util/color-utils.js +9 -4
- package/dist/lib/util/color-utils.js.map +1 -1
- package/dist/lib/util/eventedhttp.d.ts +22 -23
- package/dist/lib/util/eventedhttp.d.ts.map +1 -1
- package/dist/lib/util/eventedhttp.js +116 -109
- package/dist/lib/util/eventedhttp.js.map +1 -1
- package/dist/lib/util/hapCrypto.d.ts +2 -3
- package/dist/lib/util/hapCrypto.d.ts.map +1 -1
- package/dist/lib/util/hapCrypto.js +40 -31
- package/dist/lib/util/hapCrypto.js.map +1 -1
- package/dist/lib/util/hapStatusError.d.ts +1 -1
- package/dist/lib/util/hapStatusError.d.ts.map +1 -1
- package/dist/lib/util/hapStatusError.js +8 -4
- package/dist/lib/util/hapStatusError.js.map +1 -1
- package/dist/lib/util/net-utils.d.ts +1 -1
- package/dist/lib/util/net-utils.js +23 -17
- package/dist/lib/util/net-utils.js.map +1 -1
- package/dist/lib/util/once.d.ts.map +1 -1
- package/dist/lib/util/once.js +6 -2
- package/dist/lib/util/once.js.map +1 -1
- package/dist/lib/util/promise-utils.d.ts +1 -1
- package/dist/lib/util/promise-utils.d.ts.map +1 -1
- package/dist/lib/util/promise-utils.js +10 -3
- package/dist/lib/util/promise-utils.js.map +1 -1
- package/dist/lib/util/request-util.d.ts +2 -3
- package/dist/lib/util/request-util.d.ts.map +1 -1
- package/dist/lib/util/request-util.js +19 -11
- package/dist/lib/util/request-util.js.map +1 -1
- package/dist/lib/util/time.d.ts +0 -1
- package/dist/lib/util/time.d.ts.map +1 -1
- package/dist/lib/util/time.js +11 -6
- package/dist/lib/util/time.js.map +1 -1
- package/dist/lib/util/tlv.d.ts +0 -1
- package/dist/lib/util/tlv.d.ts.map +1 -1
- package/dist/lib/util/tlv.js +43 -28
- package/dist/lib/util/tlv.js.map +1 -1
- package/dist/lib/util/uuid.d.ts +0 -1
- package/dist/lib/util/uuid.d.ts.map +1 -1
- package/dist/lib/util/uuid.js +38 -26
- package/dist/lib/util/uuid.js.map +1 -1
- package/dist/types.d.ts +24 -24
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +5 -3
- package/dist/types.js.map +1 -1
- package/package.json +45 -50
- package/dist/lib/dbus/align.d.ts +0 -2
- package/dist/lib/dbus/align.d.ts.map +0 -1
- package/dist/lib/dbus/align.js +0 -12
- package/dist/lib/dbus/align.js.map +0 -1
- package/dist/lib/dbus/bus.d.ts +0 -38
- package/dist/lib/dbus/bus.d.ts.map +0 -1
- package/dist/lib/dbus/bus.js +0 -222
- package/dist/lib/dbus/bus.js.map +0 -1
- package/dist/lib/dbus/constants.d.ts +0 -43
- package/dist/lib/dbus/constants.d.ts.map +0 -1
- package/dist/lib/dbus/constants.js +0 -53
- package/dist/lib/dbus/constants.js.map +0 -1
- package/dist/lib/dbus/dbus-buffer.d.ts +0 -30
- package/dist/lib/dbus/dbus-buffer.d.ts.map +0 -1
- package/dist/lib/dbus/dbus-buffer.js +0 -175
- package/dist/lib/dbus/dbus-buffer.js.map +0 -1
- package/dist/lib/dbus/handshake.d.ts +0 -2
- package/dist/lib/dbus/handshake.d.ts.map +0 -1
- package/dist/lib/dbus/handshake.js +0 -130
- package/dist/lib/dbus/handshake.js.map +0 -1
- package/dist/lib/dbus/index.d.ts +0 -3
- package/dist/lib/dbus/index.d.ts.map +0 -1
- package/dist/lib/dbus/index.js +0 -123
- package/dist/lib/dbus/index.js.map +0 -1
- package/dist/lib/dbus/introspect.d.ts +0 -30
- package/dist/lib/dbus/introspect.d.ts.map +0 -1
- package/dist/lib/dbus/introspect.js +0 -208
- package/dist/lib/dbus/introspect.js.map +0 -1
- package/dist/lib/dbus/marshall.d.ts +0 -2
- package/dist/lib/dbus/marshall.d.ts.map +0 -1
- package/dist/lib/dbus/marshall.js +0 -97
- package/dist/lib/dbus/marshall.js.map +0 -1
- package/dist/lib/dbus/marshallers.d.ts +0 -10
- package/dist/lib/dbus/marshallers.d.ts.map +0 -1
- package/dist/lib/dbus/marshallers.js +0 -329
- package/dist/lib/dbus/marshallers.js.map +0 -1
- package/dist/lib/dbus/message.d.ts +0 -4
- package/dist/lib/dbus/message.d.ts.map +0 -1
- package/dist/lib/dbus/message.js +0 -116
- package/dist/lib/dbus/message.js.map +0 -1
- package/dist/lib/dbus/put.d.ts +0 -21
- package/dist/lib/dbus/put.d.ts.map +0 -1
- package/dist/lib/dbus/put.js +0 -120
- package/dist/lib/dbus/put.js.map +0 -1
- package/dist/lib/dbus/readline.d.ts +0 -2
- package/dist/lib/dbus/readline.d.ts.map +0 -1
- package/dist/lib/dbus/readline.js +0 -27
- package/dist/lib/dbus/readline.js.map +0 -1
- package/dist/lib/dbus/signature.d.ts +0 -2
- package/dist/lib/dbus/signature.d.ts.map +0 -1
- package/dist/lib/dbus/signature.js +0 -59
- package/dist/lib/dbus/signature.js.map +0 -1
- package/dist/lib/dbus/stdifaces.d.ts +0 -3
- package/dist/lib/dbus/stdifaces.d.ts.map +0 -1
- package/dist/lib/dbus/stdifaces.js +0 -206
- package/dist/lib/dbus/stdifaces.js.map +0 -1
|
@@ -1,23 +1,26 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
const
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.HAPConnection = exports.HAPConnectionEvent = exports.HAPConnectionState = exports.EventedHTTPServer = exports.EventedHTTPServerEvent = exports.HAPEncryption = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const domain_formatter_1 = require("@homebridge/ciao/lib/util/domain-formatter");
|
|
6
|
+
const assert_1 = tslib_1.__importDefault(require("assert"));
|
|
7
|
+
const debug_1 = tslib_1.__importDefault(require("debug"));
|
|
8
|
+
const events_1 = require("events");
|
|
9
|
+
const http_1 = tslib_1.__importDefault(require("http"));
|
|
10
|
+
const net_1 = tslib_1.__importDefault(require("net"));
|
|
11
|
+
const os_1 = tslib_1.__importDefault(require("os"));
|
|
12
|
+
const hapCrypto = tslib_1.__importStar(require("./hapCrypto"));
|
|
13
|
+
const net_utils_1 = require("./net-utils");
|
|
14
|
+
const uuid = tslib_1.__importStar(require("./uuid"));
|
|
15
|
+
const debug = (0, debug_1.default)("HAP-NodeJS:EventedHTTPServer");
|
|
16
|
+
const debugCon = (0, debug_1.default)("HAP-NodeJS:EventedHTTPServer:Connection");
|
|
17
|
+
const debugEvents = (0, debug_1.default)("HAP-NodeJS:EventEmitter");
|
|
15
18
|
/**
|
|
16
19
|
* Simple struct to hold vars needed to support HAP encryption.
|
|
17
20
|
*
|
|
18
21
|
* @group Cryptography
|
|
19
22
|
*/
|
|
20
|
-
|
|
23
|
+
class HAPEncryption {
|
|
21
24
|
clientPublicKey;
|
|
22
25
|
secretKey;
|
|
23
26
|
publicKey;
|
|
@@ -38,17 +41,17 @@ export class HAPEncryption {
|
|
|
38
41
|
this.controllerToAccessoryKey = Buffer.alloc(0);
|
|
39
42
|
}
|
|
40
43
|
}
|
|
44
|
+
exports.HAPEncryption = HAPEncryption;
|
|
41
45
|
/**
|
|
42
46
|
* @group HAP Accessory Server
|
|
43
47
|
*/
|
|
44
|
-
|
|
45
|
-
export var EventedHTTPServerEvent;
|
|
48
|
+
var EventedHTTPServerEvent;
|
|
46
49
|
(function (EventedHTTPServerEvent) {
|
|
47
50
|
EventedHTTPServerEvent["LISTENING"] = "listening";
|
|
48
51
|
EventedHTTPServerEvent["CONNECTION_OPENED"] = "connection-opened";
|
|
49
52
|
EventedHTTPServerEvent["REQUEST"] = "request";
|
|
50
53
|
EventedHTTPServerEvent["CONNECTION_CLOSED"] = "connection-closed";
|
|
51
|
-
})(EventedHTTPServerEvent || (EventedHTTPServerEvent = {}));
|
|
54
|
+
})(EventedHTTPServerEvent || (exports.EventedHTTPServerEvent = EventedHTTPServerEvent = {}));
|
|
52
55
|
/**
|
|
53
56
|
* EventedHTTPServer provides an HTTP-like server that supports HAP "extensions" for security and events.
|
|
54
57
|
*
|
|
@@ -68,8 +71,8 @@ export var EventedHTTPServerEvent;
|
|
|
68
71
|
*
|
|
69
72
|
* @group HAP Accessory Server
|
|
70
73
|
*/
|
|
71
|
-
// eslint-disable-next-line
|
|
72
|
-
|
|
74
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
|
|
75
|
+
class EventedHTTPServer extends events_1.EventEmitter {
|
|
73
76
|
static CONNECTION_TIMEOUT_LIMIT = 16; // if we have more (or equal) # connections we start the timeout
|
|
74
77
|
static MAX_CONNECTION_IDLE_TIME = 60 * 60 * 1000; // 1h
|
|
75
78
|
tcpServer;
|
|
@@ -86,20 +89,20 @@ export class EventedHTTPServer extends EventEmitter {
|
|
|
86
89
|
connectionLoggingInterval;
|
|
87
90
|
constructor() {
|
|
88
91
|
super();
|
|
89
|
-
this.tcpServer = createServer();
|
|
92
|
+
this.tcpServer = net_1.default.createServer();
|
|
90
93
|
}
|
|
91
94
|
scheduleNextConnectionIdleTimeout() {
|
|
92
95
|
this.connectionIdleTimeout = undefined;
|
|
93
96
|
if (!this.tcpServer.listening) {
|
|
94
97
|
return;
|
|
95
98
|
}
|
|
96
|
-
debug(
|
|
99
|
+
debug("Running idle timeout timer...");
|
|
97
100
|
const currentTime = new Date().getTime();
|
|
98
101
|
let nextTimeout = -1;
|
|
99
102
|
for (const connection of this.connections) {
|
|
100
103
|
const timeDelta = currentTime - connection.lastSocketOperation;
|
|
101
104
|
if (timeDelta >= EventedHTTPServer.MAX_CONNECTION_IDLE_TIME) {
|
|
102
|
-
debug(
|
|
105
|
+
debug("[%s] Closing connection as it was inactive for " + timeDelta + "ms");
|
|
103
106
|
connection.close();
|
|
104
107
|
}
|
|
105
108
|
else {
|
|
@@ -116,17 +119,17 @@ export class EventedHTTPServer extends EventEmitter {
|
|
|
116
119
|
listen(targetPort, hostname) {
|
|
117
120
|
this.tcpServer.listen(targetPort, hostname, () => {
|
|
118
121
|
const address = this.tcpServer.address(); // address() is only a string when listening to unix domain sockets
|
|
119
|
-
debug(
|
|
122
|
+
debug("Server listening on %s:%s", address.family === "IPv6" ? `[${address.address}]` : address.address, address.port);
|
|
120
123
|
this.connectionLoggingInterval = setInterval(() => {
|
|
121
124
|
const connectionInformation = [...this.connections]
|
|
122
125
|
.map(connection => `${connection.remoteAddress}:${connection.remotePort}`)
|
|
123
|
-
.join(
|
|
124
|
-
debug(
|
|
126
|
+
.join(", ");
|
|
127
|
+
debug("Currently %d hap connections open: %s", this.connections.size, connectionInformation);
|
|
125
128
|
}, 60_000);
|
|
126
129
|
this.connectionLoggingInterval.unref();
|
|
127
130
|
this.emit("listening" /* EventedHTTPServerEvent.LISTENING */, address.port, address.address);
|
|
128
131
|
});
|
|
129
|
-
this.tcpServer.on(
|
|
132
|
+
this.tcpServer.on("connection", this.onConnection.bind(this));
|
|
130
133
|
}
|
|
131
134
|
stop() {
|
|
132
135
|
if (this.connectionLoggingInterval != null) {
|
|
@@ -155,28 +158,27 @@ export class EventedHTTPServer extends EventEmitter {
|
|
|
155
158
|
* @param value - The newly set value of the characteristic.
|
|
156
159
|
* @param originator - If specified, the connection will not get an event message.
|
|
157
160
|
* @param immediateDelivery - The HAP spec requires some characteristics to be delivery immediately.
|
|
158
|
-
*
|
|
161
|
+
* Namely, for the {@link Characteristic.ButtonEvent} and the {@link Characteristic.ProgrammableSwitchEvent} characteristics.
|
|
159
162
|
*/
|
|
160
163
|
broadcastEvent(aid, iid, value, originator, immediateDelivery) {
|
|
161
164
|
for (const connection of this.connections) {
|
|
162
165
|
if (connection === originator) {
|
|
163
|
-
debug(
|
|
166
|
+
debug("[%s] Muting event '%s' notification for this connection since it originated here.", connection.remoteAddress, aid + "." + iid);
|
|
164
167
|
continue;
|
|
165
168
|
}
|
|
166
169
|
connection.sendEvent(aid, iid, value, immediateDelivery);
|
|
167
170
|
}
|
|
168
171
|
}
|
|
169
172
|
onConnection(socket) {
|
|
170
|
-
|
|
173
|
+
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
171
174
|
const connection = new HAPConnection(this, socket);
|
|
172
175
|
connection.on("request" /* HAPConnectionEvent.REQUEST */, (request, response) => {
|
|
173
176
|
this.emit("request" /* EventedHTTPServerEvent.REQUEST */, connection, request, response);
|
|
174
177
|
});
|
|
175
178
|
connection.on("authenticated" /* HAPConnectionEvent.AUTHENTICATED */, this.handleConnectionAuthenticated.bind(this, connection));
|
|
176
179
|
connection.on("closed" /* HAPConnectionEvent.CLOSED */, this.handleConnectionClose.bind(this, connection));
|
|
177
|
-
/* eslint-enable ts/no-use-before-define */
|
|
178
180
|
this.connections.add(connection);
|
|
179
|
-
debug(
|
|
181
|
+
debug("[%s] New connection from client on interface %s (%s)", connection.remoteAddress, connection.networkInterface, connection.localAddress);
|
|
180
182
|
this.emit("connection-opened" /* EventedHTTPServerEvent.CONNECTION_OPENED */, connection);
|
|
181
183
|
if (this.connections.size >= EventedHTTPServer.CONNECTION_TIMEOUT_LIMIT && !this.connectionIdleTimeout) {
|
|
182
184
|
this.scheduleNextConnectionIdleTimeout();
|
|
@@ -226,12 +228,12 @@ export class EventedHTTPServer extends EventEmitter {
|
|
|
226
228
|
}
|
|
227
229
|
}
|
|
228
230
|
}
|
|
231
|
+
exports.EventedHTTPServer = EventedHTTPServer;
|
|
229
232
|
/**
|
|
230
233
|
* @private
|
|
231
234
|
* @group HAP Accessory Server
|
|
232
235
|
*/
|
|
233
|
-
|
|
234
|
-
export var HAPConnectionState;
|
|
236
|
+
var HAPConnectionState;
|
|
235
237
|
(function (HAPConnectionState) {
|
|
236
238
|
HAPConnectionState[HAPConnectionState["CONNECTING"] = 0] = "CONNECTING";
|
|
237
239
|
HAPConnectionState[HAPConnectionState["FULLY_SET_UP"] = 1] = "FULLY_SET_UP";
|
|
@@ -241,25 +243,24 @@ export var HAPConnectionState;
|
|
|
241
243
|
HAPConnectionState[HAPConnectionState["TO_BE_TEARED_DOWN"] = 3] = "TO_BE_TEARED_DOWN";
|
|
242
244
|
HAPConnectionState[HAPConnectionState["CLOSING"] = 4] = "CLOSING";
|
|
243
245
|
HAPConnectionState[HAPConnectionState["CLOSED"] = 5] = "CLOSED";
|
|
244
|
-
})(HAPConnectionState || (HAPConnectionState = {}));
|
|
246
|
+
})(HAPConnectionState || (exports.HAPConnectionState = HAPConnectionState = {}));
|
|
245
247
|
/**
|
|
246
248
|
* @group HAP Accessory Server
|
|
247
249
|
*/
|
|
248
|
-
|
|
249
|
-
export var HAPConnectionEvent;
|
|
250
|
+
var HAPConnectionEvent;
|
|
250
251
|
(function (HAPConnectionEvent) {
|
|
251
252
|
HAPConnectionEvent["REQUEST"] = "request";
|
|
252
253
|
HAPConnectionEvent["AUTHENTICATED"] = "authenticated";
|
|
253
254
|
HAPConnectionEvent["CLOSED"] = "closed";
|
|
254
|
-
})(HAPConnectionEvent || (HAPConnectionEvent = {}));
|
|
255
|
+
})(HAPConnectionEvent || (exports.HAPConnectionEvent = HAPConnectionEvent = {}));
|
|
255
256
|
/**
|
|
256
257
|
* Manages a single iOS-initiated HTTP connection during its lifetime.
|
|
257
258
|
* @group HAP Accessory Server
|
|
258
259
|
*/
|
|
259
|
-
// eslint-disable-next-line
|
|
260
|
-
|
|
260
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
|
|
261
|
+
class HAPConnection extends events_1.EventEmitter {
|
|
261
262
|
/**
|
|
262
|
-
* @private
|
|
263
|
+
* @private file-private API
|
|
263
264
|
*/
|
|
264
265
|
server;
|
|
265
266
|
sessionID; // uuid unique to every HAP connection
|
|
@@ -293,53 +294,58 @@ export class HAPConnection extends EventEmitter {
|
|
|
293
294
|
constructor(server, clientSocket) {
|
|
294
295
|
super();
|
|
295
296
|
this.server = server;
|
|
296
|
-
this.sessionID = generate(
|
|
297
|
+
this.sessionID = uuid.generate(clientSocket.remoteAddress + ":" + clientSocket.remotePort);
|
|
297
298
|
this.localAddress = clientSocket.localAddress;
|
|
298
299
|
this.remoteAddress = clientSocket.remoteAddress; // cache because it becomes undefined in 'onClientSocketClose'
|
|
299
300
|
this.remotePort = clientSocket.remotePort;
|
|
300
301
|
this.networkInterface = HAPConnection.getLocalNetworkInterface(clientSocket);
|
|
301
302
|
// clientSocket is the socket connected to the actual iOS device
|
|
302
303
|
this.tcpSocket = clientSocket;
|
|
303
|
-
this.tcpSocket.on(
|
|
304
|
-
this.tcpSocket.on(
|
|
304
|
+
this.tcpSocket.on("data", this.onTCPSocketData.bind(this));
|
|
305
|
+
this.tcpSocket.on("close", this.onTCPSocketClose.bind(this));
|
|
305
306
|
// we MUST register for this event, otherwise the error will bubble up to the top and crash the node process entirely.
|
|
306
|
-
this.tcpSocket.on(
|
|
307
|
+
this.tcpSocket.on("error", this.onTCPSocketError.bind(this));
|
|
307
308
|
this.tcpSocket.setNoDelay(true); // disable Nagle algorithm
|
|
308
309
|
// "HAP accessory servers must not use keepalive messages, which periodically wake up iOS devices".
|
|
309
310
|
// Thus, we don't configure any tcp keepalive
|
|
310
311
|
// create our internal HTTP server for this connection that we will proxy data to and from
|
|
311
|
-
this.internalHttpServer =
|
|
312
|
+
this.internalHttpServer = http_1.default.createServer();
|
|
312
313
|
this.internalHttpServer.timeout = 0; // clients expect to hold connections open as long as they want
|
|
313
314
|
this.internalHttpServer.keepAliveTimeout = 0; // workaround for https://github.com/nodejs/node/issues/13391
|
|
314
|
-
this.internalHttpServer.on(
|
|
315
|
-
this.internalHttpServer.on(
|
|
316
|
-
this.internalHttpServer.on(
|
|
315
|
+
this.internalHttpServer.on("listening", this.onHttpServerListening.bind(this));
|
|
316
|
+
this.internalHttpServer.on("request", this.handleHttpServerRequest.bind(this));
|
|
317
|
+
this.internalHttpServer.on("error", this.onHttpServerError.bind(this));
|
|
317
318
|
// close event is added later on the "connect" event as possible listen retries would throw unnecessary close events
|
|
318
|
-
this.internalHttpServer.listen(0, this.internalHttpServerAddress = getOSLoopbackAddressIfAvailable());
|
|
319
|
+
this.internalHttpServer.listen(0, this.internalHttpServerAddress = (0, net_utils_1.getOSLoopbackAddressIfAvailable)());
|
|
319
320
|
}
|
|
320
321
|
debugListenerRegistration(event, registration = true, beforeCount = -1) {
|
|
321
|
-
const stackTrace = new Error().stack.split(
|
|
322
|
+
const stackTrace = new Error().stack.split("\n")[3];
|
|
322
323
|
const eventCount = this.listeners(event).length;
|
|
323
|
-
const tabs1 = event === "authenticated" /* HAPConnectionEvent.AUTHENTICATED */ ?
|
|
324
|
-
const tabs2 = !registration ?
|
|
325
|
-
|
|
324
|
+
const tabs1 = event === "authenticated" /* HAPConnectionEvent.AUTHENTICATED */ ? "\t" : "\t\t";
|
|
325
|
+
const tabs2 = !registration ? "\t" : "\t\t";
|
|
326
|
+
// eslint-disable-next-line max-len
|
|
327
|
+
debugEvents(`[${this.remoteAddress}] ${registration ? "Registered" : "Unregistered"} event '${String(event).toUpperCase()}' ${tabs1}(total: ${eventCount}${!registration ? " Before: " + beforeCount : ""}) ${tabs2}${stackTrace}`);
|
|
326
328
|
}
|
|
329
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
327
330
|
on(event, listener) {
|
|
328
331
|
const result = super.on(event, listener);
|
|
329
332
|
this.debugListenerRegistration(event);
|
|
330
333
|
return result;
|
|
331
334
|
}
|
|
335
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
332
336
|
addListener(event, listener) {
|
|
333
337
|
const result = super.addListener(event, listener);
|
|
334
338
|
this.debugListenerRegistration(event);
|
|
335
339
|
return result;
|
|
336
340
|
}
|
|
341
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
337
342
|
removeListener(event, listener) {
|
|
338
343
|
const beforeCount = this.listeners(event).length;
|
|
339
344
|
const result = super.removeListener(event, listener);
|
|
340
345
|
this.debugListenerRegistration(event, false, beforeCount);
|
|
341
346
|
return result;
|
|
342
347
|
}
|
|
348
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
343
349
|
off(event, listener) {
|
|
344
350
|
const result = super.off(event, listener);
|
|
345
351
|
const beforeCount = this.listeners(event).length;
|
|
@@ -380,17 +386,17 @@ export class HAPConnection extends EventEmitter {
|
|
|
380
386
|
}
|
|
381
387
|
}
|
|
382
388
|
sendEvent(aid, iid, value, immediateDelivery) {
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
const eventName =
|
|
389
|
+
(0, assert_1.default)(aid != null, "HAPConnection.sendEvent: aid must be defined!");
|
|
390
|
+
(0, assert_1.default)(iid != null, "HAPConnection.sendEvent: iid must be defined!");
|
|
391
|
+
const eventName = aid + "." + iid;
|
|
386
392
|
if (!this.registeredEvents.has(eventName)) {
|
|
387
393
|
// non verified connections can't register events, so this case is covered!
|
|
388
394
|
return;
|
|
389
395
|
}
|
|
390
396
|
const event = {
|
|
391
|
-
aid,
|
|
392
|
-
iid,
|
|
393
|
-
value,
|
|
397
|
+
aid: aid,
|
|
398
|
+
iid: iid,
|
|
399
|
+
value: value,
|
|
394
400
|
};
|
|
395
401
|
if (immediateDelivery) {
|
|
396
402
|
// some characteristics are required to deliver notifications immediately
|
|
@@ -444,7 +450,7 @@ export class HAPConnection extends EventEmitter {
|
|
|
444
450
|
characteristics: [],
|
|
445
451
|
};
|
|
446
452
|
for (const queuedEvent of this.queuedEvents) {
|
|
447
|
-
if (!this.registeredEvents.has(
|
|
453
|
+
if (!this.registeredEvents.has(queuedEvent.aid + "." + queuedEvent.iid)) {
|
|
448
454
|
continue; // client unregistered that event in the meantime
|
|
449
455
|
}
|
|
450
456
|
eventData.characteristics.push(queuedEvent);
|
|
@@ -461,27 +467,27 @@ export class HAPConnection extends EventEmitter {
|
|
|
461
467
|
* @param notification - The event which should be sent out
|
|
462
468
|
*/
|
|
463
469
|
writeEventNotification(notification) {
|
|
464
|
-
debugCon(
|
|
465
|
-
|
|
470
|
+
debugCon("[%s] Sending HAP event notifications %o", this.remoteAddress, notification.characteristics);
|
|
471
|
+
(0, assert_1.default)(!this.handlingRequest, "Can't write event notifications while handling a request!");
|
|
466
472
|
// Apple backend processes events in reverse order, so we need to reverse the array
|
|
467
473
|
// so that events are processed in chronological order.
|
|
468
474
|
notification.characteristics.reverse();
|
|
469
|
-
const dataBuffer = Buffer.from(JSON.stringify(notification),
|
|
470
|
-
const header = Buffer.from(
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
475
|
+
const dataBuffer = Buffer.from(JSON.stringify(notification), "utf8");
|
|
476
|
+
const header = Buffer.from("EVENT/1.0 200 OK\r\n" +
|
|
477
|
+
"Content-Type: application/hap+json\r\n" +
|
|
478
|
+
"Content-Length: " + dataBuffer.length + "\r\n" +
|
|
479
|
+
"\r\n", "utf8");
|
|
474
480
|
const buffer = Buffer.concat([header, dataBuffer]);
|
|
475
481
|
this.tcpSocket.write(this.encrypt(buffer), this.handleTCPSocketWriteFulfilled.bind(this));
|
|
476
482
|
}
|
|
477
483
|
enableEventNotifications(aid, iid) {
|
|
478
|
-
this.registeredEvents.add(
|
|
484
|
+
this.registeredEvents.add(aid + "." + iid);
|
|
479
485
|
}
|
|
480
486
|
disableEventNotifications(aid, iid) {
|
|
481
|
-
this.registeredEvents.delete(
|
|
487
|
+
this.registeredEvents.delete(aid + "." + iid);
|
|
482
488
|
}
|
|
483
489
|
hasEventNotifications(aid, iid) {
|
|
484
|
-
return this.registeredEvents.has(
|
|
490
|
+
return this.registeredEvents.has(aid + "." + iid);
|
|
485
491
|
}
|
|
486
492
|
getRegisteredEvents() {
|
|
487
493
|
return this.registeredEvents;
|
|
@@ -495,37 +501,37 @@ export class HAPConnection extends EventEmitter {
|
|
|
495
501
|
// Since all communication calls are asynchronous, we could easily receive this 'encrypt' event for those bytes.
|
|
496
502
|
// So we want to make sure that we aren't encrypting data until we have *received* some encrypted data from the client first.
|
|
497
503
|
if (this.encryption && this.encryption.accessoryToControllerKey.length > 0 && this.encryption.controllerToAccessoryCount > 0) {
|
|
498
|
-
return layerEncrypt(data, this.encryption);
|
|
504
|
+
return hapCrypto.layerEncrypt(data, this.encryption);
|
|
499
505
|
}
|
|
500
506
|
return data; // otherwise, we don't encrypt and return plaintext
|
|
501
507
|
}
|
|
502
508
|
decrypt(data) {
|
|
503
509
|
if (this.encryption && this.encryption.controllerToAccessoryKey.length > 0) {
|
|
504
510
|
// below call may throw an error if decryption failed
|
|
505
|
-
return layerDecrypt(data, this.encryption);
|
|
511
|
+
return hapCrypto.layerDecrypt(data, this.encryption);
|
|
506
512
|
}
|
|
507
513
|
return data; // otherwise, we don't decrypt and return plaintext
|
|
508
514
|
}
|
|
509
515
|
onHttpServerListening() {
|
|
510
516
|
const addressInfo = this.internalHttpServer.address(); // address() is only a string when listening to unix domain sockets
|
|
511
|
-
const addressString = addressInfo.family ===
|
|
517
|
+
const addressString = addressInfo.family === "IPv6" ? `[${addressInfo.address}]` : addressInfo.address;
|
|
512
518
|
this.internalHttpServerPort = addressInfo.port;
|
|
513
|
-
debugCon(
|
|
514
|
-
this.internalHttpServer.on(
|
|
519
|
+
debugCon("[%s] Internal HTTP server listening on %s:%s", this.remoteAddress, addressString, addressInfo.port);
|
|
520
|
+
this.internalHttpServer.on("close", this.onHttpServerClose.bind(this));
|
|
515
521
|
// now we can establish a connection to this running HTTP server for proxying data
|
|
516
|
-
this.httpSocket = createConnection(this.internalHttpServerPort, this.internalHttpServerAddress); // previously we used addressInfo.address
|
|
522
|
+
this.httpSocket = net_1.default.createConnection(this.internalHttpServerPort, this.internalHttpServerAddress); // previously we used addressInfo.address
|
|
517
523
|
this.httpSocket.setNoDelay(true); // disable Nagle algorithm
|
|
518
|
-
this.httpSocket.on(
|
|
524
|
+
this.httpSocket.on("data", this.handleHttpServerResponse.bind(this));
|
|
519
525
|
// we MUST register for this event, otherwise the error will bubble up to the top and crash the node process entirely.
|
|
520
|
-
this.httpSocket.on(
|
|
521
|
-
this.httpSocket.on(
|
|
522
|
-
this.httpSocket.on(
|
|
526
|
+
this.httpSocket.on("error", this.onHttpSocketError.bind(this));
|
|
527
|
+
this.httpSocket.on("close", this.onHttpSocketClose.bind(this));
|
|
528
|
+
this.httpSocket.on("connect", () => {
|
|
523
529
|
// we are now fully set up:
|
|
524
530
|
// - clientSocket is connected to the iOS device
|
|
525
531
|
// - serverSocket is connected to the httpServer
|
|
526
532
|
// - ready to proxy data!
|
|
527
533
|
this.state = 1 /* HAPConnectionState.FULLY_SET_UP */;
|
|
528
|
-
debugCon(
|
|
534
|
+
debugCon("[%s] Internal HTTP socket connected. HAPConnection now fully set up!", this.remoteAddress);
|
|
529
535
|
// start by flushing any pending buffered data received from the client while we were setting up
|
|
530
536
|
if (this.pendingClientSocketData && this.pendingClientSocketData.length > 0) {
|
|
531
537
|
this.httpSocket.write(this.pendingClientSocketData);
|
|
@@ -548,7 +554,7 @@ export class HAPConnection extends EventEmitter {
|
|
|
548
554
|
data = this.decrypt(data);
|
|
549
555
|
}
|
|
550
556
|
catch (error) { // decryption and/or verification failed, disconnect the client
|
|
551
|
-
debugCon(
|
|
557
|
+
debugCon("[%s] Error occurred trying to decrypt incoming packet: %s", this.remoteAddress, error.message);
|
|
552
558
|
this.close();
|
|
553
559
|
return;
|
|
554
560
|
}
|
|
@@ -569,7 +575,7 @@ export class HAPConnection extends EventEmitter {
|
|
|
569
575
|
// don't accept data of a connection which is about to be closed or already closed
|
|
570
576
|
return;
|
|
571
577
|
}
|
|
572
|
-
debugCon(
|
|
578
|
+
debugCon("[%s] HTTP request: %s", this.remoteAddress, request.url);
|
|
573
579
|
request.socket.setNoDelay(true);
|
|
574
580
|
this.emit("request" /* HAPConnectionEvent.REQUEST */, request, response);
|
|
575
581
|
}
|
|
@@ -581,7 +587,7 @@ export class HAPConnection extends EventEmitter {
|
|
|
581
587
|
handleHttpServerResponse(data) {
|
|
582
588
|
data = this.encrypt(data);
|
|
583
589
|
this.tcpSocket.write(data, this.handleTCPSocketWriteFulfilled.bind(this));
|
|
584
|
-
debugCon(
|
|
590
|
+
debugCon("[%s] HTTP Response is finished", this.remoteAddress);
|
|
585
591
|
this.handlingRequest = false;
|
|
586
592
|
if (this.state === 3 /* HAPConnectionState.TO_BE_TEARED_DOWN */) {
|
|
587
593
|
setTimeout(() => this.close(), 10);
|
|
@@ -598,12 +604,12 @@ export class HAPConnection extends EventEmitter {
|
|
|
598
604
|
this.lastSocketOperation = new Date().getTime();
|
|
599
605
|
}
|
|
600
606
|
onTCPSocketError(err) {
|
|
601
|
-
debugCon(
|
|
607
|
+
debugCon("[%s] Client connection error: %s", this.remoteAddress, err.message);
|
|
602
608
|
// onTCPSocketClose will be called next
|
|
603
609
|
}
|
|
604
610
|
onTCPSocketClose() {
|
|
605
611
|
this.state = 5 /* HAPConnectionState.CLOSED */;
|
|
606
|
-
debugCon(
|
|
612
|
+
debugCon("[%s] Client connection closed", this.remoteAddress);
|
|
607
613
|
if (this.httpSocket) {
|
|
608
614
|
this.httpSocket.destroy();
|
|
609
615
|
}
|
|
@@ -612,43 +618,43 @@ export class HAPConnection extends EventEmitter {
|
|
|
612
618
|
this.removeAllListeners(); // cleanup listeners, we are officially dead now
|
|
613
619
|
}
|
|
614
620
|
onHttpServerError(err) {
|
|
615
|
-
debugCon(
|
|
616
|
-
if (err.code ===
|
|
621
|
+
debugCon("[%s] HTTP server error: %s", this.remoteAddress, err.message);
|
|
622
|
+
if (err.code === "EADDRINUSE") {
|
|
617
623
|
this.internalHttpServerPort = undefined;
|
|
618
624
|
this.internalHttpServer.close();
|
|
619
|
-
this.internalHttpServer.listen(0, this.internalHttpServerAddress = getOSLoopbackAddressIfAvailable());
|
|
625
|
+
this.internalHttpServer.listen(0, this.internalHttpServerAddress = (0, net_utils_1.getOSLoopbackAddressIfAvailable)());
|
|
620
626
|
}
|
|
621
627
|
}
|
|
622
628
|
onHttpServerClose() {
|
|
623
|
-
debugCon(
|
|
629
|
+
debugCon("[%s] HTTP server was closed", this.remoteAddress);
|
|
624
630
|
// make sure the iOS side is closed as well
|
|
625
631
|
this.close();
|
|
626
632
|
}
|
|
627
633
|
onHttpSocketError(err) {
|
|
628
|
-
debugCon(
|
|
634
|
+
debugCon("[%s] HTTP connection error: ", this.remoteAddress, err.message);
|
|
629
635
|
// onHttpSocketClose will be called next
|
|
630
636
|
}
|
|
631
637
|
onHttpSocketClose() {
|
|
632
|
-
debugCon(
|
|
638
|
+
debugCon("[%s] HTTP connection was closed", this.remoteAddress);
|
|
633
639
|
// we only support a single long-lived connection to our internal HTTP server. Since it's closed,
|
|
634
640
|
// we'll need to shut it down entirely.
|
|
635
641
|
this.internalHttpServer.close();
|
|
636
642
|
}
|
|
637
643
|
getLocalAddress(ipVersion) {
|
|
638
|
-
const interfaceDetails = networkInterfaces()[this.networkInterface];
|
|
644
|
+
const interfaceDetails = os_1.default.networkInterfaces()[this.networkInterface];
|
|
639
645
|
if (!interfaceDetails) {
|
|
640
|
-
throw new Error(
|
|
646
|
+
throw new Error("Could not find " + ipVersion + " address for interface " + this.networkInterface);
|
|
641
647
|
}
|
|
642
648
|
// Find our first local IPv4 address.
|
|
643
|
-
if (ipVersion ===
|
|
644
|
-
const ipv4Info = interfaceDetails.find(info => info.family ===
|
|
649
|
+
if (ipVersion === "ipv4") {
|
|
650
|
+
const ipv4Info = interfaceDetails.find(info => info.family === "IPv4");
|
|
645
651
|
if (ipv4Info) {
|
|
646
652
|
return ipv4Info.address;
|
|
647
653
|
}
|
|
648
|
-
throw new Error(
|
|
654
|
+
throw new Error("Could not find " + ipVersion + " address for interface " + this.networkInterface + ".");
|
|
649
655
|
}
|
|
650
656
|
let localUniqueAddress;
|
|
651
|
-
for (const v6entry of interfaceDetails.filter(entry => entry.family ===
|
|
657
|
+
for (const v6entry of interfaceDetails.filter(entry => entry.family === "IPv6")) {
|
|
652
658
|
if (!v6entry.scopeid) {
|
|
653
659
|
return v6entry.address;
|
|
654
660
|
}
|
|
@@ -657,26 +663,26 @@ export class HAPConnection extends EventEmitter {
|
|
|
657
663
|
if (localUniqueAddress) {
|
|
658
664
|
return localUniqueAddress;
|
|
659
665
|
}
|
|
660
|
-
throw new Error(
|
|
666
|
+
throw new Error("Could not find " + ipVersion + " address for interface " + this.networkInterface);
|
|
661
667
|
}
|
|
662
668
|
static getLocalNetworkInterface(socket) {
|
|
663
669
|
let localAddress = socket.localAddress;
|
|
664
670
|
// Grab the list of network interfaces.
|
|
665
|
-
const interfaces = networkInterfaces();
|
|
671
|
+
const interfaces = os_1.default.networkInterfaces();
|
|
666
672
|
// Default to the first non-loopback interface we see.
|
|
667
|
-
const defaultInterface = () => Object.entries(interfaces).find(([, addresses]) => addresses?.some(address => !address.internal))?.[0] ??
|
|
673
|
+
const defaultInterface = () => Object.entries(interfaces).find(([, addresses]) => addresses?.some(address => !address.internal))?.[0] ?? "unknown";
|
|
668
674
|
// No local address return our default.
|
|
669
675
|
if (!localAddress) {
|
|
670
676
|
return defaultInterface();
|
|
671
677
|
}
|
|
672
678
|
// Handle IPv4-mapped IPv6 addresses.
|
|
673
|
-
localAddress = localAddress.replace(/^::ffff:/i,
|
|
679
|
+
localAddress = localAddress.replace(/^::ffff:/i, "");
|
|
674
680
|
// Handle edge cases where we have an IPv4-mapped IPv6 address without the requisite prefix.
|
|
675
681
|
if (/^::(?:\d{1,3}\.){3}\d{1,3}$/.test(localAddress)) {
|
|
676
|
-
localAddress = localAddress.replace(/^::/,
|
|
682
|
+
localAddress = localAddress.replace(/^::/, "");
|
|
677
683
|
}
|
|
678
684
|
// Handle link-local IPv6 addresses.
|
|
679
|
-
localAddress = localAddress.split(
|
|
685
|
+
localAddress = localAddress.split("%")[0];
|
|
680
686
|
// Let's find an exact match using the IP.
|
|
681
687
|
for (const [name, addresses] of Object.entries(interfaces)) {
|
|
682
688
|
if (addresses?.some(({ address }) => address === localAddress)) {
|
|
@@ -684,16 +690,17 @@ export class HAPConnection extends EventEmitter {
|
|
|
684
690
|
}
|
|
685
691
|
}
|
|
686
692
|
// We couldn't find an interface to match the address from above, so we attempt to match subnets (see https://github.com/homebridge/HAP-NodeJS/issues/847).
|
|
687
|
-
const family = isIPv4(localAddress) ?
|
|
693
|
+
const family = net_1.default.isIPv4(localAddress) ? "IPv4" : "IPv6";
|
|
688
694
|
// Let's find a match based on the subnet.
|
|
689
695
|
for (const [name, addresses] of Object.entries(interfaces)) {
|
|
690
|
-
if (addresses?.some(entry => entry.family === family && getNetAddress(localAddress, entry.netmask) === getNetAddress(entry.address, entry.netmask))) {
|
|
696
|
+
if (addresses?.some(entry => entry.family === family && (0, domain_formatter_1.getNetAddress)(localAddress, entry.netmask) === (0, domain_formatter_1.getNetAddress)(entry.address, entry.netmask))) {
|
|
691
697
|
return name;
|
|
692
698
|
}
|
|
693
699
|
}
|
|
694
|
-
|
|
695
|
-
|
|
700
|
+
console.log("WARNING: unable to determine which interface to use for socket coming from " + socket.remoteAddress + ":" + socket.remotePort + " to " +
|
|
701
|
+
socket.localAddress + ".");
|
|
696
702
|
return defaultInterface();
|
|
697
703
|
}
|
|
698
704
|
}
|
|
705
|
+
exports.HAPConnection = HAPConnection;
|
|
699
706
|
//# sourceMappingURL=eventedhttp.js.map
|