You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					80 lines
				
				1.8 KiB
			
		
		
			
		
	
	
					80 lines
				
				1.8 KiB
			| 
											3 years ago
										 | 'use strict' | ||
|  | 
 | ||
|  | function negotiate (header, supportedEncodings) { | ||
|  |   if (!header) { | ||
|  |     return undefined | ||
|  |   } | ||
|  |   const supportedEncodingMap = createMap(supportedEncodings) | ||
|  |   const acceptedEncodings = parse(header) | ||
|  |     .sort((a, b) => comparator(a, b, supportedEncodingMap)) | ||
|  |     .filter(isNonZeroQuality) | ||
|  |   return determinePreffered(acceptedEncodings, supportedEncodingMap) | ||
|  | } | ||
|  | 
 | ||
|  | function determinePreffered (acceptedEncodings, supportedEncodings) { | ||
|  |   for (const encoding of acceptedEncodings) { | ||
|  |     const selected = supportedEncodings[encoding.name] | ||
|  |     if (selected) { | ||
|  |       return selected.encoding | ||
|  |     } | ||
|  |   } | ||
|  |   return null | ||
|  | } | ||
|  | 
 | ||
|  | function createMap (supported) { | ||
|  |   const supportedEncodings = {} | ||
|  |   let priority = 0 | ||
|  |   if (supported.length > 0) { | ||
|  |     supportedEncodings['*'] = { encoding: supported[0], priority } | ||
|  |     priority++ | ||
|  |   } | ||
|  |   for (const encoding of supported) { | ||
|  |     supportedEncodings[encoding] = { encoding, priority } | ||
|  |     priority++ | ||
|  |   } | ||
|  |   return supportedEncodings | ||
|  | } | ||
|  | 
 | ||
|  | function parse (header) { | ||
|  |   const split = header.split(',') | ||
|  |   return split.map(parseEncoding) | ||
|  | } | ||
|  | 
 | ||
|  | function isNonZeroQuality (encoding) { | ||
|  |   return encoding.quality !== 0 | ||
|  | } | ||
|  | 
 | ||
|  | function parseEncoding (encoding) { | ||
|  |   const [name, second] = encoding.trim().split(';') | ||
|  |   const quality = getQuality(second) | ||
|  |   return { | ||
|  |     name, | ||
|  |     quality | ||
|  |   } | ||
|  | } | ||
|  | 
 | ||
|  | function getQuality (second) { | ||
|  |   if (!second) { | ||
|  |     return 1 | ||
|  |   } | ||
|  |   const [, quality] = second.trim().split('=') | ||
|  |   return parseFloat(quality) | ||
|  | } | ||
|  | 
 | ||
|  | function comparator (a, b, supportedEncodingMap) { | ||
|  |   if (a.quality === b.quality) { | ||
|  |     if (supportedEncodingMap[a.name] && | ||
|  |       supportedEncodingMap[b.name] && | ||
|  |       supportedEncodingMap[a.name].priority < supportedEncodingMap[b.name].priority) { | ||
|  |       return -1 | ||
|  |     } else { | ||
|  |       return 1 | ||
|  |     } | ||
|  |   } | ||
|  |   return b.quality - a.quality | ||
|  | } | ||
|  | 
 | ||
|  | module.exports = { | ||
|  |   negotiate | ||
|  | } |