Skip to content

Commit efe466a

Browse files
authored
fix: ensure loose validation for isEvent and toEvent (cloudevents#394)
The `HTTP.isEvent()` and `HTTP.toEvent()` functions both had some validation code that violated the principle of loose validation when receiving an event over HTTP. As discussed, the validation should be managed by the receiver in this case with `event.validate()` Signed-off-by: Lance Ball <[email protected]>
1 parent 93f0213 commit efe466a

File tree

2 files changed

+35
-21
lines changed

2 files changed

+35
-21
lines changed

src/message/http/index.ts

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
import { CloudEvent, CloudEventV03, CloudEventV1, CONSTANTS, Mode, Version } from "../..";
22
import { Message, Headers } from "..";
33

4-
import { headersFor, sanitize, v03structuredParsers, v1binaryParsers, v1structuredParsers } from "./headers";
4+
import {
5+
headersFor,
6+
sanitize,
7+
v03binaryParsers,
8+
v03structuredParsers,
9+
v1binaryParsers,
10+
v1structuredParsers,
11+
} from "./headers";
512
import { isStringOrObjectOrThrow, ValidationError } from "../../event/validation";
613
import { JSONParser, MappedParser, Parser, parserByContentType } from "../../parsers";
714

@@ -122,23 +129,12 @@ function parseBinary(message: Message, version: Version): CloudEvent {
122129
let body = message.body;
123130

124131
if (!headers) throw new ValidationError("headers is null or undefined");
125-
if (body) {
126-
isStringOrObjectOrThrow(body, new ValidationError("payload must be an object or a string"));
127-
}
128-
129-
if (
130-
headers[CONSTANTS.CE_HEADERS.SPEC_VERSION] &&
131-
headers[CONSTANTS.CE_HEADERS.SPEC_VERSION] !== Version.V03 &&
132-
headers[CONSTANTS.CE_HEADERS.SPEC_VERSION] !== Version.V1
133-
) {
134-
throw new ValidationError(`invalid spec version ${headers[CONSTANTS.CE_HEADERS.SPEC_VERSION]}`);
135-
}
136132

137133
// Clone and low case all headers names
138134
const sanitizedHeaders = sanitize(headers);
139135

140136
const eventObj: { [key: string]: unknown | string | Record<string, unknown> } = {};
141-
const parserMap: Record<string, MappedParser> = version === Version.V1 ? v1binaryParsers : v1binaryParsers;
137+
const parserMap: Record<string, MappedParser> = version === Version.V1 ? v1binaryParsers : v03binaryParsers;
142138

143139
for (const header in parserMap) {
144140
if (sanitizedHeaders[header]) {
@@ -186,14 +182,6 @@ function parseStructured(message: Message, version: Version): CloudEvent {
186182
if (!headers) throw new ValidationError("headers is null or undefined");
187183
isStringOrObjectOrThrow(payload, new ValidationError("payload must be an object or a string"));
188184

189-
if (
190-
headers[CONSTANTS.CE_HEADERS.SPEC_VERSION] &&
191-
headers[CONSTANTS.CE_HEADERS.SPEC_VERSION] != Version.V03 &&
192-
headers[CONSTANTS.CE_HEADERS.SPEC_VERSION] != Version.V1
193-
) {
194-
throw new ValidationError(`invalid spec version ${headers[CONSTANTS.CE_HEADERS.SPEC_VERSION]}`);
195-
}
196-
197185
// Clone and low case all headers names
198186
const sanitizedHeaders = sanitize(headers);
199187

test/integration/message_test.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,32 @@ describe("HTTP transport", () => {
5959
expect(HTTP.isEvent(message)).to.be.true;
6060
});
6161

62+
it("Can detect CloudEvent binary Messages with weird versions", () => {
63+
// Now create a message that is an event
64+
const message = {
65+
body: `{ "greeting": "hello" }`,
66+
headers: {
67+
[CONSTANTS.CE_HEADERS.ID]: "1234",
68+
[CONSTANTS.CE_HEADERS.SOURCE]: "test",
69+
[CONSTANTS.CE_HEADERS.TYPE]: "test.event",
70+
[CONSTANTS.CE_HEADERS.SPEC_VERSION]: "11.8",
71+
},
72+
};
73+
expect(HTTP.isEvent(message)).to.be.true;
74+
expect(HTTP.toEvent(message)).not.to.throw;
75+
});
76+
77+
it("Can detect CloudEvent structured Messages with weird versions", () => {
78+
// Now create a message that is an event
79+
const message = {
80+
body: `{ "source": "test", "type": "test.event", "specversion": "11.8"}`,
81+
headers: {
82+
[CONSTANTS.CE_HEADERS.ID]: "1234",
83+
},
84+
};
85+
expect(HTTP.isEvent(message)).to.be.true;
86+
expect(HTTP.toEvent(message)).not.to.throw;
87+
});
6288
// Allow for external systems to send bad events - do what we can
6389
// to accept them
6490
it("Does not throw an exception when converting an invalid Message to a CloudEvent", () => {

0 commit comments

Comments
 (0)