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
						
					
					
				| '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
 | |
| }
 |