More cleanup

This commit is contained in:
watsonb8 2019-09-08 12:25:09 -04:00
parent 423be484b2
commit dabdfc56a5
8 changed files with 49 additions and 39 deletions

View File

@ -1,3 +1,5 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
/**
* The contents in this file were taken from NorthernMan54/Hap-Node-Client
* https://raw.githubusercontent.com/NorthernMan54/Hap-Node-Client/master/lib/httpParser.js
@ -16,26 +18,21 @@ interface IHttpResult {
method?: string;
url?: string;
headers?: Dictionary<string | number>;
//eslint-disable-next-line
body?: any;
//eslint-disable-next-line
boundary?: any;
//eslint-disable-next-line
multipart?: any;
//eslint-disable-next-line
additional?: any;
//eslint-disable-next-line
meta?: any;
}
export default class HttpMessageParser {
private static requestLineRegex = /(HTTP|EVENT)\/(1\.0|1\.1|2\.0)\s+(\d+)\s+([\w\s-_]+)/i;
private static responseLineRegex = /(GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD|TRACE|CONNECT)\s+(.*)\s+HTTP\/(1\.0|1\.1|2\.0)/i;
private static headerNewlineRegex = /^[\r\n]+/gim;
private static boundaryRegex = /(\n|\r\n)+--[\w-]+(\n|\r\n)+/g;
private requestLineRegex = /(HTTP|EVENT)\/(1\.0|1\.1|2\.0)\s+(\d+)\s+([\w\s-_]+)/i;
private responseLineRegex = /(GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD|TRACE|CONNECT)\s+(.*)\s+HTTP\/(1\.0|1\.1|2\.0)/i;
private headerNewlineRegex = /^[\r\n]+/gim;
private boundaryRegex = /(\n|\r\n)+--[\w-]+(\n|\r\n)+/g;
//eslint-disable-next-line
public static parse(message: any): IHttpResult {
public parse(message: any): IHttpResult {
const result: IHttpResult = {};
let messageString = '';
@ -119,7 +116,11 @@ export default class HttpMessageParser {
/* Parse body
*/
let start = headerNewlineIndex;
const contentLength: number = result.headers!['Content-Length'] as number;
let contentLength = 0;
if (result.headers) {
contentLength = result.headers['Content-Length'] as number;
}
let end = (result.headers && result.headers['Content-Length'] && contentLength ? contentLength + start : messageString.length);
@ -163,7 +164,7 @@ export default class HttpMessageParser {
const splitRegex = new RegExp('^' + fullBoundary + '.*[\n\r]?$', 'gm');
const parts = multipartBody.split(splitRegex);
result.multipart = parts.filter(this.isTruthy).map(function (part, i) {
result.multipart = parts.filter(this.isTruthy).map((part, index) => {
// tslint:disable-next-line: no-shadowed-variable
const result: IHttpResult = {};
@ -188,7 +189,7 @@ export default class HttpMessageParser {
let endOffset = null;
if (newlineIndex > -1) {
const headers = HttpMessageParser.parseHeaders(possibleHeadersString);
const headers = this.parseHeaders(possibleHeadersString);
if (Object.keys(headers).length > 0) {
result.headers = headers;
@ -211,8 +212,8 @@ export default class HttpMessageParser {
boundaryNewlineIndexes.push(headerNewlineIndex);
});
startOffset = boundaryNewlineIndexes[i];
endOffset = boundaryIndexes[i + 1];
startOffset = boundaryNewlineIndexes[index];
endOffset = boundaryIndexes[index + 1];
body = message.slice(startOffset, endOffset);
} else {
body = part;
@ -233,7 +234,7 @@ export default class HttpMessageParser {
}
private static trim(str: string): string {
private trim(str: string): string {
const firstNonWhitespaceRegex = /[\w-]+/gim;
const firstNonWhitespaceIndex = str.search(firstNonWhitespaceRegex);
let tmpStr = "";
@ -245,11 +246,11 @@ export default class HttpMessageParser {
return str;
}
private static isTruthy = function _isTruthy(value: any): boolean {
private isTruthy = function _isTruthy(value: any): boolean {
return !!value;
};
private static isNumeric = function _isNumeric(value: any): boolean {
private isNumeric = function _isNumeric(value: any): boolean {
if (typeof value === 'number' && !isNaN(value)) {
return true;
}
@ -263,35 +264,35 @@ export default class HttpMessageParser {
return !isNaN(value);
};
private static isBuffer = (item: any): boolean => {
return ((HttpMessageParser.isNodeBufferSupported() &&
private isBuffer = (item: any): boolean => {
return ((this.isNodeBufferSupported() &&
typeof global === 'object' &&
global.Buffer.isBuffer(item)) ||
(item instanceof Object &&
item._isBuffer));
};
private static isNodeBufferSupported = (): boolean => {
private isNodeBufferSupported = (): boolean => {
return (typeof global === 'object' &&
typeof global.Buffer === 'function' &&
typeof global.Buffer.isBuffer === 'function');
};
private static parseHeaders = (body: any): Dictionary<string | number> => {
private parseHeaders = (body: any): Dictionary<string | number> => {
const headers: Dictionary<string | number> = {};
if (typeof body !== 'string') {
return headers;
}
body.split(/[\r\n]/).forEach(function (string) {
const match = string.match(/([\w-]+):\s*(.*)/i);
body.split(/[\r\n]/).forEach((str: string) => {
const match = str.match(/([\w-]+):\s*(.*)/i);
if (Array.isArray(match) && match.length === 3) {
const key = match[1];
const value = match[2];
headers[key] = HttpMessageParser.isNumeric(value) ? Number(value) : value;
headers[key] = this.isNumeric(value) ? Number(value) : value;
}
});

View File

@ -5,8 +5,8 @@
import * as net from 'net';
import * as url from 'url';
import HttpMessageParser from './httpParser';
import { Dictionary } from '../../Types/types';
import HttpMessageParser from './httpParser';
interface IRequest {
method: 'PUT' | 'POST' | 'GET' | 'DELETE' | 'PATCH';
@ -16,7 +16,6 @@ interface IRequest {
body: string;
}
export const parseMessage = HttpMessageParser.parse;
function _headersToString(headers: Dictionary<string>): string {
let response = '';
@ -71,3 +70,5 @@ export function createConnection(instance: { ipAddress: string; port: number },
return client;
}
export { HttpMessageParser };

View File

@ -1,6 +1,6 @@
import { EventEmitter } from 'events';
import { IServiceType, IHapEvInstance } from './interfaces';
import { createConnection, parseMessage } from './eventedHttpClient';
import { createConnection, HttpMessageParser } from './eventedHttpClient';
import { CharacteristicType } from './hapClient';
import { log } from '../Types/types';
@ -10,6 +10,7 @@ export class HapMonitor extends EventEmitter {
private services: IServiceType[];
private logger: log;
private debug: log;
private parser: HttpMessageParser
constructor(logger: log, debug: log, pin: string, services: IServiceType[]) {
super();
@ -18,6 +19,7 @@ export class HapMonitor extends EventEmitter {
this.pin = pin;
this.services = services;
this.evInstances = [];
this.parser = new HttpMessageParser();
// get a list of characteristics we can watch for each instance
this.parseServices();
@ -36,7 +38,7 @@ export class HapMonitor extends EventEmitter {
this.debug(`[HapClient] [${instance.ipAddress}:${instance.port} (${instance.username})] Connected`);
instance.socket.on('data', (data) => {
const message = parseMessage(data);
const message = this.parser.parse(data);
if (message.statusCode === 401) {

5
src/HapClient/index.ts Normal file
View File

@ -0,0 +1,5 @@
import { HapClient } from './hapClient';
import { HapMonitor } from './hapMonitor';
export { HapClient };
export { HapMonitor };

View File

@ -1,7 +1,7 @@
import { Socket } from 'net';
export interface IHapInstance {
displayName: string
displayName: string;
name: string;
ipAddress: string;
port: number;
@ -13,7 +13,7 @@ export interface IHapEvInstance {
ipAddress: string;
port: number;
username: string;
evCharacteristics?: { aid: number, iid: number, ev: boolean }[];
evCharacteristics?: { aid: number; iid: number; ev: boolean }[];
socket?: Socket;
}
@ -47,7 +47,7 @@ export interface IServiceResp {
}
export interface IAccessoryResp {
instance: IInstanceResp
instance: IInstanceResp;
aid: number;
services: Array<IServiceResp>;
}
@ -121,4 +121,4 @@ export const createDefaultCharacteristicType = (): ICharacteristicType => {
canWrite: false,
ev: false,
};
}
};

View File

@ -1,10 +1,11 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
/**
* Helper function to convert callbacks into promises
* @param func
*/
export default function callbackify(func: (...args: any[]) => Promise<any>): Function {
return (...args: any[]) => {
return (...args: any[]): void => {
const onlyArgs: any[] = [];
let maybeCallback: Function | null = null;
@ -25,6 +26,6 @@ export default function callbackify(func: (...args: any[]) => Promise<any>): Fun
func(...onlyArgs)
.then((data: any) => callback(null, data))
.catch((err: any) => callback(err))
}
.catch((err: any) => callback(err));
};
}

View File

@ -1,3 +1,3 @@
export function sleep(ms: number) {
return new Promise(resolve => setTimeout(resolve, ms));
export function sleep(ms: number): Promise<number> {
return new Promise((resolve): number => setTimeout(resolve, ms));
}

View File

@ -1,4 +1,4 @@
import { HapClient } from "../HapClient/hapClient";
import { HapClient } from "../HapClient";
import { log } from '../Types/types';
import { singleton } from 'tsyringe';