fix: ensure that the HTTP receiver sanitizes headers in accept() (#239)

Even though the underlying structured and binary receivers already sanitize
the headers, this needs to be done at the receiver.accept() level since
the headers are inspected there to determine what mode the event is being
sent as.

Signed-off-by: Lance Ball <lball@redhat.com>
This commit is contained in:
Lance Ball 2020-07-06 17:33:13 -04:00 committed by GitHub
parent d65b0135e0
commit 51035dc65b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 33 additions and 3 deletions

View File

@ -1,4 +1,4 @@
import { Headers } from "./http/headers"; import { Headers, sanitize } from "./http/headers";
import { CloudEvent, Version, ValidationError } from ".."; import { CloudEvent, Version, ValidationError } from "..";
import { BinaryHTTPReceiver as BinaryReceiver } from "./http/binary_receiver"; import { BinaryHTTPReceiver as BinaryReceiver } from "./http/binary_receiver";
import { StructuredHTTPReceiver as StructuredReceiver } from "./http/structured_receiver"; import { StructuredHTTPReceiver as StructuredReceiver } from "./http/structured_receiver";
@ -60,8 +60,9 @@ export class Receiver {
* @return {CloudEvent} A new {CloudEvent} instance * @return {CloudEvent} A new {CloudEvent} instance
*/ */
accept(headers: Headers, body: string | Record<string, unknown> | CloudEventV1 | CloudEventV03): CloudEvent { accept(headers: Headers, body: string | Record<string, unknown> | CloudEventV1 | CloudEventV03): CloudEvent {
const mode: Mode = getMode(headers); const cleanHeaders: Headers = sanitize(headers);
const version = getVersion(mode, headers, body); const mode: Mode = getMode(cleanHeaders);
const version = getVersion(mode, cleanHeaders, body);
switch (version) { switch (version) {
case Version.V1: case Version.V1:
return this.receivers.v1[mode].parse(body, headers); return this.receivers.v1[mode].parse(body, headers);

View File

@ -52,6 +52,35 @@ describe("HTTP Transport Binding Receiver for CloudEvents", () => {
expect(typeof event.data).to.equal("object"); expect(typeof event.data).to.equal("object");
expect((event.data as Record<string, string>).lunch).to.equal("sushi"); expect((event.data as Record<string, string>).lunch).to.equal("sushi");
}); });
it("Recognizes headers in title case for binary events", () => {
const binaryHeaders = {
"Content-Type": "application/json; charset=utf-8",
"ce-specversion": specversion,
"ce-id": id,
"ce-type": type,
"ce-source": source,
};
const event: CloudEvent = receiver.accept(binaryHeaders, data);
expect(event.validate()).to.be.true;
expect((event.data as Record<string, string>).lunch).to.equal("sushi");
});
it("Recognizes headers in title case for structured events", () => {
const structuredHeaders = { "Content-Type": "application/cloudevents+json" };
const payload = {
id,
type,
source,
data,
specversion,
};
const event: CloudEvent = receiver.accept(structuredHeaders, payload);
expect(event.validate()).to.be.true;
expect((event.data as Record<string, string>).lunch).to.equal("sushi");
});
}); });
describe("V1", () => { describe("V1", () => {