@hqoss/http-client
Advanced tools
Comparing version 0.1.16-0 to 0.1.17-0
/// <reference types="node" /> | ||
import { EventEmitter } from "events"; | ||
import { RequestOptions, IncomingMessage } from "http"; | ||
import { RequestOptions } from "http"; | ||
import { Readable } from "stream"; | ||
@@ -13,3 +13,3 @@ import { Method, ConsumedResponse } from "./types"; | ||
delete: (pathOrUrl: string | URL, reqOpts?: RequestOptions | undefined, telemetry?: EventEmitter | undefined) => Promise<ConsumedResponse<Buffer>>; | ||
request: (pathOrUrl: string | URL, method: Method, reqOpts?: RequestOptions | undefined, data?: string | Readable | Buffer | undefined, telemetry?: EventEmitter | undefined) => Promise<IncomingMessage>; | ||
request: (pathOrUrl: string | URL, method: Method, reqOpts?: RequestOptions | undefined, data?: string | Readable | Buffer | undefined, telemetry?: EventEmitter | undefined) => Promise<ConsumedResponse<Buffer>>; | ||
private buildUrl; | ||
@@ -16,0 +16,0 @@ private combineOpts; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const events_1 = require("events"); | ||
const http_1 = require("http"); | ||
@@ -11,9 +12,9 @@ const stream_1 = require("stream"); | ||
this.get = (pathOrUrl, reqOpts, telemetry) => { | ||
return this.request(pathOrUrl, types_1.Method.Get, reqOpts, undefined, telemetry).then(transform_1.toBufferResponse); | ||
return this.request(pathOrUrl, types_1.Method.Get, reqOpts, undefined, telemetry); | ||
}; | ||
this.post = (pathOrUrl, reqOpts, data, telemetry) => { | ||
return this.request(pathOrUrl, types_1.Method.Post, reqOpts, data, telemetry).then(transform_1.toBufferResponse); | ||
return this.request(pathOrUrl, types_1.Method.Post, reqOpts, data, telemetry); | ||
}; | ||
this.delete = (pathOrUrl, reqOpts, telemetry) => { | ||
return this.request(pathOrUrl, types_1.Method.Delete, reqOpts, undefined, telemetry).then(transform_1.toBufferResponse); | ||
return this.request(pathOrUrl, types_1.Method.Delete, reqOpts, undefined, telemetry); | ||
}; | ||
@@ -24,2 +25,3 @@ this.request = (pathOrUrl, method, reqOpts, data, telemetry) => { | ||
} | ||
const resolver = new events_1.EventEmitter(); | ||
const url = this.buildUrl(pathOrUrl); | ||
@@ -38,14 +40,31 @@ const contentLength = getContentLength(data); | ||
telemetry === null || telemetry === void 0 ? void 0 : telemetry.emit(telemetry_1.EventType.RequestStreamInitialised, new telemetry_1.TelemetryEvent(telemetry_1.EventType.RequestStreamInitialised, { url, opts })); | ||
return new Promise((resolve, reject) => { | ||
req.once("socket", (socket) => { | ||
telemetry === null || telemetry === void 0 ? void 0 : telemetry.emit(telemetry_1.EventType.SocketObtained, new telemetry_1.TelemetryEvent(telemetry_1.EventType.SocketObtained)); | ||
socket.once("connect", () => { | ||
telemetry === null || telemetry === void 0 ? void 0 : telemetry.emit(telemetry_1.EventType.ConnectionEstablished, new telemetry_1.TelemetryEvent(telemetry_1.EventType.ConnectionEstablished)); | ||
}); | ||
req.once("socket", (socket) => { | ||
telemetry === null || telemetry === void 0 ? void 0 : telemetry.emit(telemetry_1.EventType.SocketObtained, new telemetry_1.TelemetryEvent(telemetry_1.EventType.SocketObtained)); | ||
socket.once("connect", () => { | ||
telemetry === null || telemetry === void 0 ? void 0 : telemetry.emit(telemetry_1.EventType.ConnectionEstablished, new telemetry_1.TelemetryEvent(telemetry_1.EventType.ConnectionEstablished)); | ||
}); | ||
req.once("response", (res) => { | ||
telemetry === null || telemetry === void 0 ? void 0 : telemetry.emit(telemetry_1.EventType.ResponseStreamReceived, new telemetry_1.TelemetryEvent(telemetry_1.EventType.ResponseStreamReceived)); | ||
resolve(res); | ||
}); | ||
req.once("response", (res) => { | ||
telemetry === null || telemetry === void 0 ? void 0 : telemetry.emit(telemetry_1.EventType.ResponseStreamReceived, new telemetry_1.TelemetryEvent(telemetry_1.EventType.ResponseStreamReceived)); | ||
transform_1.toBufferResponse(res) | ||
.then((bufferResponse) => { | ||
resolver.emit("resolve", bufferResponse); | ||
}) | ||
.catch((error) => { | ||
resolver.emit("reject", error); | ||
}); | ||
req.once("error", (error) => { | ||
}); | ||
req.once("error", (error) => { | ||
// See https://nodejs.org/api/http.html#http_request_destroy_error | ||
// | ||
// No further events will be emitted. | ||
// All listeners will be removed once the request is garbage collected. | ||
// Remaining data in the response will be dropped and the socket will be destroyed. | ||
req.destroy(); | ||
telemetry === null || telemetry === void 0 ? void 0 : telemetry.emit(telemetry_1.EventType.RequestError, new telemetry_1.TelemetryEvent(telemetry_1.EventType.RequestError, undefined, error)); | ||
resolver.emit("reject", error); | ||
}); | ||
if (data instanceof stream_1.Readable) { | ||
// If there is an error reading data, destroy the request and pass the error. | ||
data.once("error", (error) => { | ||
// See https://nodejs.org/api/http.html#http_request_destroy_error | ||
@@ -56,24 +75,15 @@ // | ||
// Remaining data in the response will be dropped and the socket will be destroyed. | ||
req.destroy(); | ||
telemetry === null || telemetry === void 0 ? void 0 : telemetry.emit(telemetry_1.EventType.RequestError, new telemetry_1.TelemetryEvent(telemetry_1.EventType.RequestError, undefined, error)); | ||
reject(error); | ||
req.destroy(error); | ||
}); | ||
if (data instanceof stream_1.Readable) { | ||
// If there is an error reading data, destroy the request and pass the error. | ||
data.once("error", (error) => { | ||
// See https://nodejs.org/api/http.html#http_request_destroy_error | ||
// | ||
// No further events will be emitted. | ||
// All listeners will be removed once the request is garbage collected. | ||
// Remaining data in the response will be dropped and the socket will be destroyed. | ||
req.destroy(error); | ||
}); | ||
// Pipe ends the writable stream (req) implicitly. | ||
// See https://nodejs.org/api/stream.html#stream_readable_pipe_destination_options. | ||
data.pipe(req); | ||
} | ||
else { | ||
req.end(data); | ||
} | ||
telemetry === null || telemetry === void 0 ? void 0 : telemetry.emit(telemetry_1.EventType.RequestStreamEnded, new telemetry_1.TelemetryEvent(telemetry_1.EventType.RequestStreamEnded)); | ||
// Pipe ends the writable stream (req) implicitly. | ||
// See https://nodejs.org/api/stream.html#stream_readable_pipe_destination_options. | ||
data.pipe(req); | ||
} | ||
else { | ||
req.end(data); | ||
} | ||
telemetry === null || telemetry === void 0 ? void 0 : telemetry.emit(telemetry_1.EventType.RequestStreamEnded, new telemetry_1.TelemetryEvent(telemetry_1.EventType.RequestStreamEnded)); | ||
return new Promise((resolve, reject) => { | ||
resolver.once("resolve", (response) => resolve(response)); | ||
resolver.once("reject", (error) => reject(error)); | ||
}); | ||
@@ -80,0 +90,0 @@ }; |
@@ -10,3 +10,2 @@ "use strict"; | ||
const telemetry_1 = require("../../lib/httpClient/telemetry"); | ||
const transform_1 = require("../../lib/httpClient/transform"); | ||
const types_1 = require("../../lib/httpClient/types"); | ||
@@ -86,3 +85,7 @@ const noop = () => { }; | ||
const data = Buffer.from("Hello, world!"); | ||
const server = http_1.createServer((_req, res) => res.end(data)).listen(port, () => { | ||
const date = new Date().toISOString(); | ||
const server = http_1.createServer((_req, res) => { | ||
res.setHeader("date", date); | ||
res.end(data); | ||
}).listen(port, () => { | ||
runner.emit("init"); | ||
@@ -104,6 +107,14 @@ }); | ||
try { | ||
const response = await client | ||
.request("/", types_1.Method.Get, undefined, undefined, telemetry) | ||
.then(transform_1.readableToBuffer); | ||
assert_1.default.deepStrictEqual(response, data); | ||
const response = await client.request("/", types_1.Method.Get, undefined, undefined, telemetry); | ||
assert_1.default.deepStrictEqual(response, { | ||
data, | ||
headers: { | ||
"content-length": `${Buffer.byteLength(data)}`, | ||
connection: "close", | ||
date, | ||
}, | ||
statusClass: types_1.StatusClass.Successful, | ||
statusCode: 200, | ||
statusMessage: "OK", | ||
}); | ||
assert_1.default.deepStrictEqual(telemetry.eventNames(), [telemetry_1.EventType.RequestError]); | ||
@@ -192,6 +203,13 @@ runner.emit("end"); | ||
try { | ||
const response = await client | ||
.request("/", types_1.Method.Post, undefined, data, telemetry) | ||
.then(transform_1.readableToBuffer); | ||
assert_1.default.deepStrictEqual(response, data); | ||
const { headers: { date: _date, ...headers }, ...response } = await client.request("/", types_1.Method.Post, undefined, data, telemetry); | ||
assert_1.default.deepStrictEqual(headers, { | ||
connection: "close", | ||
"transfer-encoding": "chunked", | ||
}); | ||
assert_1.default.deepStrictEqual(response, { | ||
data, | ||
statusClass: types_1.StatusClass.Successful, | ||
statusCode: 200, | ||
statusMessage: "OK", | ||
}); | ||
assert_1.default.deepStrictEqual(telemetry.eventNames(), [telemetry_1.EventType.RequestError]); | ||
@@ -230,5 +248,3 @@ runner.emit("end"); | ||
const tasks = [...Array(numberOfRequests).keys()].map(() => { | ||
return client | ||
.request("/", types_1.Method.Get, undefined, undefined, telemetry) | ||
.then(transform_1.toBufferResponse); | ||
return client.request("/", types_1.Method.Get, undefined, undefined, telemetry); | ||
}); | ||
@@ -235,0 +251,0 @@ const res = await Promise.all(tasks); |
import { EventEmitter } from "events"; | ||
import { request, RequestOptions, IncomingMessage } from "http"; | ||
import { request, RequestOptions } from "http"; | ||
import { Readable } from "stream"; | ||
@@ -32,9 +32,3 @@ | ||
): Promise<ConsumedResponse<Buffer>> => { | ||
return this.request( | ||
pathOrUrl, | ||
Method.Get, | ||
reqOpts, | ||
undefined, | ||
telemetry, | ||
).then(toBufferResponse); | ||
return this.request(pathOrUrl, Method.Get, reqOpts, undefined, telemetry); | ||
}; | ||
@@ -48,5 +42,3 @@ | ||
): Promise<ConsumedResponse<Buffer>> => { | ||
return this.request(pathOrUrl, Method.Post, reqOpts, data, telemetry).then( | ||
toBufferResponse, | ||
); | ||
return this.request(pathOrUrl, Method.Post, reqOpts, data, telemetry); | ||
}; | ||
@@ -65,3 +57,3 @@ | ||
telemetry, | ||
).then(toBufferResponse); | ||
); | ||
}; | ||
@@ -75,3 +67,3 @@ | ||
telemetry?: EventEmitter, | ||
): Promise<IncomingMessage> => { | ||
): Promise<ConsumedResponse<Buffer>> => { | ||
if (data && !isConsumable(data)) { | ||
@@ -83,2 +75,3 @@ return Promise.reject( | ||
const resolver = new EventEmitter(); | ||
const url = this.buildUrl(pathOrUrl); | ||
@@ -105,27 +98,50 @@ const contentLength = getContentLength(data); | ||
return new Promise((resolve, reject) => { | ||
req.once("socket", (socket) => { | ||
req.once("socket", (socket) => { | ||
telemetry?.emit( | ||
EventType.SocketObtained, | ||
new TelemetryEvent(EventType.SocketObtained), | ||
); | ||
socket.once("connect", () => { | ||
telemetry?.emit( | ||
EventType.SocketObtained, | ||
new TelemetryEvent(EventType.SocketObtained), | ||
EventType.ConnectionEstablished, | ||
new TelemetryEvent(EventType.ConnectionEstablished), | ||
); | ||
}); | ||
}); | ||
socket.once("connect", () => { | ||
telemetry?.emit( | ||
EventType.ConnectionEstablished, | ||
new TelemetryEvent(EventType.ConnectionEstablished), | ||
); | ||
req.once("response", (res) => { | ||
telemetry?.emit( | ||
EventType.ResponseStreamReceived, | ||
new TelemetryEvent(EventType.ResponseStreamReceived), | ||
); | ||
toBufferResponse(res) | ||
.then((bufferResponse) => { | ||
resolver.emit("resolve", bufferResponse); | ||
}) | ||
.catch((error) => { | ||
resolver.emit("reject", error); | ||
}); | ||
}); | ||
}); | ||
req.once("response", (res) => { | ||
telemetry?.emit( | ||
EventType.ResponseStreamReceived, | ||
new TelemetryEvent(EventType.ResponseStreamReceived), | ||
); | ||
req.once("error", (error) => { | ||
// See https://nodejs.org/api/http.html#http_request_destroy_error | ||
// | ||
// No further events will be emitted. | ||
// All listeners will be removed once the request is garbage collected. | ||
// Remaining data in the response will be dropped and the socket will be destroyed. | ||
req.destroy(); | ||
resolve(res); | ||
}); | ||
telemetry?.emit( | ||
EventType.RequestError, | ||
new TelemetryEvent(EventType.RequestError, undefined, error), | ||
); | ||
req.once("error", (error) => { | ||
resolver.emit("reject", error); | ||
}); | ||
if (data instanceof Readable) { | ||
// If there is an error reading data, destroy the request and pass the error. | ||
data.once("error", (error) => { | ||
// See https://nodejs.org/api/http.html#http_request_destroy_error | ||
@@ -136,34 +152,20 @@ // | ||
// Remaining data in the response will be dropped and the socket will be destroyed. | ||
req.destroy(); | ||
telemetry?.emit( | ||
EventType.RequestError, | ||
new TelemetryEvent(EventType.RequestError, undefined, error), | ||
); | ||
reject(error); | ||
req.destroy(error); | ||
}); | ||
if (data instanceof Readable) { | ||
// If there is an error reading data, destroy the request and pass the error. | ||
data.once("error", (error) => { | ||
// See https://nodejs.org/api/http.html#http_request_destroy_error | ||
// | ||
// No further events will be emitted. | ||
// All listeners will be removed once the request is garbage collected. | ||
// Remaining data in the response will be dropped and the socket will be destroyed. | ||
req.destroy(error); | ||
}); | ||
// Pipe ends the writable stream (req) implicitly. | ||
// See https://nodejs.org/api/stream.html#stream_readable_pipe_destination_options. | ||
data.pipe(req); | ||
} else { | ||
req.end(data); | ||
} | ||
// Pipe ends the writable stream (req) implicitly. | ||
// See https://nodejs.org/api/stream.html#stream_readable_pipe_destination_options. | ||
data.pipe(req); | ||
} else { | ||
req.end(data); | ||
} | ||
telemetry?.emit( | ||
EventType.RequestStreamEnded, | ||
new TelemetryEvent(EventType.RequestStreamEnded), | ||
); | ||
telemetry?.emit( | ||
EventType.RequestStreamEnded, | ||
new TelemetryEvent(EventType.RequestStreamEnded), | ||
); | ||
return new Promise((resolve, reject) => { | ||
resolver.once("resolve", (response) => resolve(response)); | ||
resolver.once("reject", (error) => reject(error)); | ||
}); | ||
@@ -170,0 +172,0 @@ }; |
{ | ||
"name": "@hqoss/http-client", | ||
"version": "0.1.16-0", | ||
"version": "0.1.17-0", | ||
"description": "A light-weight, performant, composable blueprint for writing consistent and re-usable Node.js HTTP clients", | ||
@@ -5,0 +5,0 @@ "main": "./dist/lib/index.js", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
180942
1135