fix: support mTLS in 1.0 Binary and Structured emitters
This commit modifies both of the 1.0 emitters so that they may accept typed objects as a part of the configuration. When using mTLS in Node, you need to provide an `Agent` to the underlying HTTP handler. In this case, Axios will pass this object along to Node.js when it is provided. Fixes: https://github.com/cloudevents/sdk-javascript/issues/48 Signed-off-by: Lance Ball <lball@redhat.com>
This commit is contained in:
parent
4a199d4623
commit
3a063d7245
|
@ -2,58 +2,48 @@ var axios = require("axios");
|
||||||
var empty = require("is-empty");
|
var empty = require("is-empty");
|
||||||
|
|
||||||
const Constants = require("./constants.js");
|
const Constants = require("./constants.js");
|
||||||
|
const defaults = {};
|
||||||
|
defaults[Constants.HEADERS] = {};
|
||||||
|
defaults[Constants.HEADERS][Constants.HEADER_CONTENT_TYPE] = Constants.DEFAULT_CONTENT_TYPE;
|
||||||
|
|
||||||
function BinaryHTTPEmitter(config, headerByGetter, extensionPrefix){
|
function BinaryHTTPEmitter(config, headerByGetter, extensionPrefix){
|
||||||
this.config = JSON.parse(JSON.stringify(config));
|
this.config = Object.assign({}, defaults, config);
|
||||||
this.headerByGetter = headerByGetter;
|
this.headerByGetter = headerByGetter;
|
||||||
this.extensionPrefix = extensionPrefix;
|
this.extensionPrefix = extensionPrefix;
|
||||||
|
|
||||||
this.config[Constants.HEADERS] =
|
|
||||||
(!this.config[Constants.HEADERS]
|
|
||||||
? {}
|
|
||||||
: this.config[Constants.HEADERS]);
|
|
||||||
|
|
||||||
// default is json
|
|
||||||
if(!this.config[Constants.HEADERS][Constants.HEADER_CONTENT_TYPE]){
|
|
||||||
this.config[Constants.HEADERS][Constants.HEADER_CONTENT_TYPE] =
|
|
||||||
Constants.DEFAULT_CONTENT_TYPE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BinaryHTTPEmitter.prototype.emit = function(cloudevent) {
|
BinaryHTTPEmitter.prototype.emit = function (cloudevent) {
|
||||||
// Create new request object
|
const config = Object.assign({}, this.config);
|
||||||
var _config = JSON.parse(JSON.stringify(this.config));
|
const headers = Object.assign({}, this.config[Constants.HEADERS]);
|
||||||
|
|
||||||
// Always set stuff in _config
|
|
||||||
var _headers = _config[Constants.HEADERS];
|
|
||||||
|
|
||||||
Object.keys(this.headerByGetter)
|
Object.keys(this.headerByGetter)
|
||||||
.filter((getter) => cloudevent[getter]())
|
.filter((getter) => cloudevent[getter]())
|
||||||
.forEach((getter) => {
|
.forEach((getter) => {
|
||||||
let header = this.headerByGetter[getter];
|
const header = this.headerByGetter[getter];
|
||||||
_headers[header.name] =
|
headers[header.name] =
|
||||||
header.parser(
|
header.parser(
|
||||||
cloudevent[getter]()
|
cloudevent[getter]()
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Set the cloudevent payload
|
// Set the cloudevent payload
|
||||||
let formatted = cloudevent.format();
|
const formatted = cloudevent.format();
|
||||||
let data = formatted.data;
|
let data = formatted.data;
|
||||||
data = (formatted.data_base64 ? formatted.data_base64: data);
|
data = (formatted.data_base64 ? formatted.data_base64: data);
|
||||||
|
|
||||||
_config[Constants.DATA_ATTRIBUTE] = data;
|
|
||||||
|
|
||||||
// Have extensions?
|
// Have extensions?
|
||||||
var exts = cloudevent.getExtensions();
|
const exts = cloudevent.getExtensions();
|
||||||
Object.keys(exts)
|
Object.keys(exts)
|
||||||
.filter((ext) => Object.hasOwnProperty.call(exts, ext))
|
.filter((ext) => Object.hasOwnProperty.call(exts, ext))
|
||||||
.forEach((ext) => {
|
.forEach((ext) => {
|
||||||
_headers[this.extensionPrefix + ext] = exts[ext];
|
headers[this.extensionPrefix + ext] = exts[ext];
|
||||||
});
|
});
|
||||||
|
|
||||||
// Return the Promise
|
config[Constants.DATA_ATTRIBUTE] = data;
|
||||||
return axios.request(_config);
|
config.headers = headers;
|
||||||
};
|
|
||||||
|
// Return the Promise
|
||||||
|
return axios.request(config);
|
||||||
|
};
|
||||||
|
|
||||||
module.exports = BinaryHTTPEmitter;
|
module.exports = BinaryHTTPEmitter;
|
||||||
|
|
|
@ -1,30 +1,23 @@
|
||||||
var axios = require("axios");
|
var axios = require("axios");
|
||||||
|
|
||||||
const Constants = require("./constants.js");
|
const Constants = require("./constants.js");
|
||||||
|
const defaults = {};
|
||||||
|
defaults[Constants.HEADERS] = {};
|
||||||
|
defaults[Constants.HEADERS][Constants.HEADER_CONTENT_TYPE] = Constants.DEFAULT_CE_CONTENT_TYPE;
|
||||||
|
|
||||||
function StructuredHTTPEmitter(configuration){
|
function StructuredHTTPEmitter(configuration){
|
||||||
this.config = JSON.parse(JSON.stringify(configuration));
|
this.config = Object.assign({}, defaults, configuration);
|
||||||
|
|
||||||
this.config[Constants.HEADERS] =
|
|
||||||
(!this.config[Constants.HEADERS]
|
|
||||||
? {}
|
|
||||||
: this.config[Constants.HEADERS]);
|
|
||||||
|
|
||||||
if(!this.config[Constants.HEADERS][Constants.HEADER_CONTENT_TYPE]){
|
|
||||||
this.config[Constants.HEADERS][Constants.HEADER_CONTENT_TYPE] =
|
|
||||||
Constants.DEFAULT_CE_CONTENT_TYPE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StructuredHTTPEmitter.prototype.emit = function(cloudevent) {
|
StructuredHTTPEmitter.prototype.emit = function (cloudevent) {
|
||||||
// Create new request object
|
|
||||||
var _config = JSON.parse(JSON.stringify(this.config));
|
|
||||||
|
|
||||||
// Set the cloudevent payload
|
// Set the cloudevent payload
|
||||||
_config[Constants.DATA_ATTRIBUTE] = cloudevent.format();
|
this.config[Constants.DATA_ATTRIBUTE] = cloudevent.format();
|
||||||
|
|
||||||
// Return the Promise
|
// Return the Promise
|
||||||
return axios.request(_config);
|
return axios.request(this.config).then(response => {
|
||||||
|
delete this.config[Constants.DATA_ATTRIBUTE];
|
||||||
|
return response;
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = StructuredHTTPEmitter;
|
module.exports = StructuredHTTPEmitter;
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
const expect = require("chai").expect;
|
const expect = require("chai").expect;
|
||||||
const nock = require("nock");
|
const nock = require("nock");
|
||||||
const http = require("http");
|
const https = require("https");
|
||||||
const request = require("request");
|
|
||||||
const {asBase64} = require("../lib/utils/fun.js");
|
const {asBase64} = require("../lib/utils/fun.js");
|
||||||
|
|
||||||
const BinaryHTTPEmitter =
|
const {
|
||||||
require("../lib/bindings/http/emitter_binary_1.js");
|
Spec,
|
||||||
const Cloudevent = require("../lib/cloudevent.js");
|
BinaryHTTPEmitter,
|
||||||
|
StructuredHTTPEmitter,
|
||||||
const v1 = require("../v1/index.js");
|
Cloudevent
|
||||||
|
} = require("../v1/index.js");
|
||||||
|
|
||||||
const type = "com.github.pull.create";
|
const type = "com.github.pull.create";
|
||||||
const source = "urn:event:from:myapi/resourse/123";
|
const source = "urn:event:from:myapi/resourse/123";
|
||||||
|
@ -28,7 +28,7 @@ const ext2Name = "extension2";
|
||||||
const ext2Value = "acme";
|
const ext2Value = "acme";
|
||||||
|
|
||||||
const cloudevent =
|
const cloudevent =
|
||||||
new Cloudevent(v1.Spec)
|
new Cloudevent(Spec)
|
||||||
.type(type)
|
.type(type)
|
||||||
.source(source)
|
.source(source)
|
||||||
.dataContentType(ceContentType)
|
.dataContentType(ceContentType)
|
||||||
|
@ -48,7 +48,7 @@ const httpcfg = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const binary = new BinaryHTTPEmitter(httpcfg);
|
const binary = new BinaryHTTPEmitter(httpcfg);
|
||||||
const structured = new v1.StructuredHTTPEmitter(httpcfg);
|
const structured = new StructuredHTTPEmitter(httpcfg);
|
||||||
|
|
||||||
describe("HTTP Transport Binding - Version 1.0", () => {
|
describe("HTTP Transport Binding - Version 1.0", () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
@ -59,6 +59,21 @@ describe("HTTP Transport Binding - Version 1.0", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("Structured", () => {
|
describe("Structured", () => {
|
||||||
|
it('works with mTLS authentication', () => {
|
||||||
|
const event = new StructuredHTTPEmitter({
|
||||||
|
method: 'POST',
|
||||||
|
url: `${webhook}/json`,
|
||||||
|
httpsAgent: new https.Agent({
|
||||||
|
cert: 'some value',
|
||||||
|
key: 'other value'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
return event.emit(cloudevent).then(response => {
|
||||||
|
expect(response.config.headers['Content-Type'])
|
||||||
|
.to.equal(contentType);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe("JSON Format", () => {
|
describe("JSON Format", () => {
|
||||||
it("requires '" + contentType + "' Content-Type in the header", () => {
|
it("requires '" + contentType + "' Content-Type in the header", () => {
|
||||||
return structured.emit(cloudevent)
|
return structured.emit(cloudevent)
|
||||||
|
@ -81,7 +96,7 @@ describe("HTTP Transport Binding - Version 1.0", () => {
|
||||||
let bindata = Uint32Array.from(dataString, (c) => c.codePointAt(0));
|
let bindata = Uint32Array.from(dataString, (c) => c.codePointAt(0));
|
||||||
let expected = asBase64(bindata);
|
let expected = asBase64(bindata);
|
||||||
let binevent =
|
let binevent =
|
||||||
new Cloudevent(v1.Spec)
|
new Cloudevent(Spec)
|
||||||
.type(type)
|
.type(type)
|
||||||
.source(source)
|
.source(source)
|
||||||
.dataContentType("text/plain")
|
.dataContentType("text/plain")
|
||||||
|
@ -98,7 +113,7 @@ describe("HTTP Transport Binding - Version 1.0", () => {
|
||||||
|
|
||||||
it("the payload must have 'data_base64' when data is binary", () => {
|
it("the payload must have 'data_base64' when data is binary", () => {
|
||||||
let binevent =
|
let binevent =
|
||||||
new Cloudevent(v1.Spec)
|
new Cloudevent(Spec)
|
||||||
.type(type)
|
.type(type)
|
||||||
.source(source)
|
.source(source)
|
||||||
.dataContentType("text/plain")
|
.dataContentType("text/plain")
|
||||||
|
@ -117,6 +132,21 @@ describe("HTTP Transport Binding - Version 1.0", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("Binary", () => {
|
describe("Binary", () => {
|
||||||
|
it('works with mTLS authentication', () => {
|
||||||
|
const event = new BinaryHTTPEmitter({
|
||||||
|
method: 'POST',
|
||||||
|
url: `${webhook}/json`,
|
||||||
|
httpsAgent: new https.Agent({
|
||||||
|
cert: 'some value',
|
||||||
|
key: 'other value'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
return event.emit(cloudevent).then(response => {
|
||||||
|
expect(response.config.headers['Content-Type'])
|
||||||
|
.to.equal(cloudevent.getDataContentType());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe("JSON Format", () => {
|
describe("JSON Format", () => {
|
||||||
it("requires '" + cloudevent.getDataContentType() + "' Content-Type in the header", () => {
|
it("requires '" + cloudevent.getDataContentType() + "' Content-Type in the header", () => {
|
||||||
return binary.emit(cloudevent)
|
return binary.emit(cloudevent)
|
||||||
|
@ -138,7 +168,7 @@ describe("HTTP Transport Binding - Version 1.0", () => {
|
||||||
let bindata = Uint32Array.from(dataString, (c) => c.codePointAt(0));
|
let bindata = Uint32Array.from(dataString, (c) => c.codePointAt(0));
|
||||||
let expected = asBase64(bindata);
|
let expected = asBase64(bindata);
|
||||||
let binevent =
|
let binevent =
|
||||||
new Cloudevent(v1.Spec)
|
new Cloudevent(Spec)
|
||||||
.type(type)
|
.type(type)
|
||||||
.source(source)
|
.source(source)
|
||||||
.dataContentType("text/plain")
|
.dataContentType("text/plain")
|
||||||
|
|
|
@ -22,5 +22,7 @@ module.exports = {
|
||||||
BinaryHTTPEmitter,
|
BinaryHTTPEmitter,
|
||||||
StructuredHTTPReceiver,
|
StructuredHTTPReceiver,
|
||||||
BinaryHTTPReceiver,
|
BinaryHTTPReceiver,
|
||||||
|
Cloudevent: event,
|
||||||
|
CloudEvent: event,
|
||||||
event
|
event
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue