UNPKG

@webscale-networks/cloudedge-handlers

Version:

Webscale Networks CloudEDGE Handlers for cloud-agnostic edge function execution

189 lines (177 loc) 5.63 kB
'use strict'; // A generic header class for retrieving, iterating, adding and removing // headers. // // Use cases: // // Iterating over all headers: // for (const [header_name, values] of headers) { // for (const value in values) { // ... // } // } // // Retrieving a header: // headers.get('header_name') // returns header values or undefined. // // Adding the header 'Webscale': 'is cool' while preserving any existing // 'Webscale' headers: // headers.add('Webscale', 'is cool'); // returns header values. // // Adding the header 'Webscale': 'is cool' without preserving any existing // header values: // headers.set('Webscale', 'is cool'); // returns header values. // // Removing the 'Webscale' completely: // headers.remove('Webscale'); class Headers { #headers = {}; #toGeneric = null; #toCloudProvider = null; constructor(incomingHeaders, toGeneric, toCloudProvider) { this.#toGeneric = toGeneric || this.#toWebscaleHeaders; this.#toCloudProvider = toCloudProvider || this.#fromWebscaleHeaders; this.#headers = this.#toGeneric(incomingHeaders); } // Allows iteration over an instance of the class. See the example above // for syntax. [Symbol.iterator]() { let index = 0; const entries = Object.entries(this.#headers); return { next: () => { if (index < entries.length) { return { value: entries[index++], done: false, }; } else { return { done: true, }; } } } } // Returns the header values of a particular header as an array. get(name) { return this.#headers[name.toLowerCase()]; } // Adds a string value to a header. Header names are case insensitive. // Existing header values are preserved. Returns the updated header values // as an array. add(name, value) { if (this.#headers[name.toLowerCase()]) { this.#headers[name.toLowerCase()].push(value); } else { this.#headers[name.toLowerCase()] = [value]; } return this.get(name); } // Sets a header to the given value. Header names are case insensitive. // The given value can be a string or an array for duplicate headers. // Existing header values are removed. Returns the updated header values as // an array. set(name, value) { if (Array.isArray(value)) { this.#headers[name.toLowerCase()] = value; } else { this.#headers[name.toLowerCase()] = [value]; } return this.get(name); } // Removes the given header completely. Returns all headers. remove(name) { delete this.#headers[name.toLowerCase()]; } // Converts Webscale's representation of headers to a cloud provider's // representation. toCloudProvider() { return this.#toCloudProvider(this.#headers); } // Default. // // Converts Lambda@Edge header format to Webscale's format. // // Lambda@Edge format: // headers: { // 'header name in lowercase': [{ // key: 'header name in standard case', // value: 'header value' // }], // ... // }, // // Webscale format: // headers: { // 'header name in standard case': // ['header value 1', ... 'header value N'], // } #toWebscaleHeaders = (headerTypes) => { let result = {}; for (const headerType in headerTypes) { headerTypes[headerType].forEach((header) => { if (result[header['key'].toLowerCase()]) { result[header['key'].toLowerCase()].push( header['value'], ); } else { result[header['key'].toLowerCase()] = [header['value']]; } }); } return result; }; // Default. // // Converts Webscale's header format to Lambda@Edge's header format. // // Webscale format: // headers: { // 'header name in standard case': // ['header value 1', ... 'header value N'], // } // // Lambda@Edge format: // headers: { // 'header name in lowercase': [ // { // key: 'header name in standard case', // value: 'header value 1', // }, ... // { // key: 'header name in standard case', // value: 'header value N', // }, // ], // ... // }, #fromWebscaleHeaders = (headerTypes) => { let result = {}; for (const headerType in headerTypes) { headerTypes[headerType].forEach((headerValue) => { if (!headerValue) return; if (result[headerType.toLowerCase()]) { result[headerType.toLowerCase()].push( { key: headerType, value: headerValue, } ); } else { result[headerType.toLowerCase()] = [ { key: headerType, value: headerValue, } ]; } }); } return result; }; }; module.exports = { Headers, }