11import { CloudEvent , Version } from "../.." ;
22import { Headers , validate , sanitize } from "./headers" ;
3- import { Parser } from "../../parsers" ;
3+ import { Parser , JSONParser } from "../../parsers" ;
44import { parserByContentType } from "../../parsers" ;
55import { structuredParsers as v1Parsers } from "./v1/parsers" ;
66import { structuredParsers as v03Parsers } from "./v03/parsers" ;
7- import { isString , isBase64 } from "../../event/validation" ;
7+ import { isString , isBase64 , ValidationError , isStringOrObjectOrThrow , isBinary , asBase64 } from "../../event/validation" ;
88import { CloudEventV1 , validateV1 as validateV1 } from "../../event/v1" ;
99import { CloudEventV03 , validateV03 as validateV03 } from "../../event/v03" ;
1010import CONSTANTS from "../../constants" ;
@@ -33,18 +33,36 @@ export class StructuredHTTPReceiver {
3333 * @throws {ValidationError } if the payload and header combination do not conform to the spec
3434 */
3535 parse ( payload : any , headers : Headers ) {
36+ if ( ! payload ) throw new ValidationError ( "payload is null or undefined" ) ;
37+ if ( ! headers ) throw new ValidationError ( "headers is null or undefined" ) ;
38+ isStringOrObjectOrThrow ( payload , new ValidationError ( "payload must be an object or a string" ) ) ;
39+
40+ if ( headers [ CONSTANTS . CE_HEADERS . SPEC_VERSION ] &&
41+ headers [ CONSTANTS . CE_HEADERS . SPEC_VERSION ] != Version . V03 &&
42+ headers [ CONSTANTS . CE_HEADERS . SPEC_VERSION ] != Version . V1 ) {
43+ throw new ValidationError ( `invalid spec version ${ headers [ CONSTANTS . CE_HEADERS . SPEC_VERSION ] } ` ) ;
44+ }
45+
3646 payload = isString ( payload ) && isBase64 ( payload )
3747 ? Buffer . from ( payload , "base64" ) . toString ( )
3848 : payload ;
3949
40- // Clone and low case all headers names
50+ // Clone and low case all headers names
4151 const sanitizedHeaders = sanitize ( headers ) ;
4252
43- const parser : Parser = parserByContentType [ sanitizedHeaders [ CONSTANTS . HEADER_CONTENT_TYPE ] ] ;
53+ const contentType = sanitizedHeaders [ CONSTANTS . HEADER_CONTENT_TYPE ] ;
54+ const parser : Parser = contentType ? parserByContentType [ contentType ] : new JSONParser ( ) ;
55+ if ( ! parser ) throw new ValidationError ( `invalid content type ${ sanitizedHeaders [ CONSTANTS . HEADER_CONTENT_TYPE ] } ` ) ;
4456 const incoming = parser . parse ( payload ) ;
4557
4658 const eventObj : { [ key : string ] : any } = { } ;
4759 const parserMap = this . version === Version . V1 ? v1Parsers : v03Parsers ;
60+
61+ // if the incoming data is in binary form, encode to base64
62+ if ( isBinary ( incoming . data ) ) {
63+ eventObj . data_base64 = asBase64 ( incoming . data ) ;
64+ }
65+
4866 parserMap . forEach ( ( value , key ) => {
4967 if ( incoming [ key ] ) {
5068 eventObj [ value . name ] = value . parser . parse ( incoming [ key ] ) ;
@@ -55,6 +73,13 @@ export class StructuredHTTPReceiver {
5573 eventObj [ key ] = incoming [ key ] ;
5674 }
5775
76+ // ensure data content is correctly encoded
77+ if ( eventObj . data && eventObj . datacontentencoding ) {
78+ if ( eventObj . datacontentencoding === CONSTANTS . ENCODING_BASE64 && ! isBase64 ( eventObj . data ) ) {
79+ throw new ValidationError ( "invalid payload" ) ;
80+ }
81+ }
82+
5883 const cloudevent = CloudEvent . create ( eventObj as CloudEventV1 | CloudEventV03 ) ;
5984
6085 // Validates the event
0 commit comments