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.
		
		
		
		
		
			
		
			
				
					189 lines
				
				4.6 KiB
			
		
		
			
		
	
	
					189 lines
				
				4.6 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								'use strict'
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const UUID_REG = /^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/
							 | 
						||
| 
								 | 
							
								const URN_REG = /([A-Za-z0-9][A-Za-z0-9-]{0,31}):(([A-Za-z0-9()+,\-.:=@;$_!*']|%[0-9A-Fa-f]{2})+)/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function isSecure (wsComponents) {
							 | 
						||
| 
								 | 
							
								  return typeof wsComponents.secure === 'boolean' ? wsComponents.secure : String(wsComponents.scheme).toLowerCase() === 'wss'
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function httpParse (components) {
							 | 
						||
| 
								 | 
							
								  if (!components.host) {
							 | 
						||
| 
								 | 
							
								    components.error = components.error || 'HTTP URIs must have a host.'
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return components
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function httpSerialize (components) {
							 | 
						||
| 
								 | 
							
								  const secure = String(components.scheme).toLowerCase() === 'https'
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // normalize the default port
							 | 
						||
| 
								 | 
							
								  if (components.port === (secure ? 443 : 80) || components.port === '') {
							 | 
						||
| 
								 | 
							
								    components.port = undefined
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // normalize the empty path
							 | 
						||
| 
								 | 
							
								  if (!components.path) {
							 | 
						||
| 
								 | 
							
								    components.path = '/'
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // NOTE: We do not parse query strings for HTTP URIs
							 | 
						||
| 
								 | 
							
								  // as WWW Form Url Encoded query strings are part of the HTML4+ spec,
							 | 
						||
| 
								 | 
							
								  // and not the HTTP spec.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return components
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function wsParse (wsComponents) {
							 | 
						||
| 
								 | 
							
								// indicate if the secure flag is set
							 | 
						||
| 
								 | 
							
								  wsComponents.secure = isSecure(wsComponents)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // construct resouce name
							 | 
						||
| 
								 | 
							
								  wsComponents.resourceName = (wsComponents.path || '/') + (wsComponents.query ? '?' + wsComponents.query : '')
							 | 
						||
| 
								 | 
							
								  wsComponents.path = undefined
							 | 
						||
| 
								 | 
							
								  wsComponents.query = undefined
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return wsComponents
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function wsSerialize (wsComponents) {
							 | 
						||
| 
								 | 
							
								// normalize the default port
							 | 
						||
| 
								 | 
							
								  if (wsComponents.port === (isSecure(wsComponents) ? 443 : 80) || wsComponents.port === '') {
							 | 
						||
| 
								 | 
							
								    wsComponents.port = undefined
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // ensure scheme matches secure flag
							 | 
						||
| 
								 | 
							
								  if (typeof wsComponents.secure === 'boolean') {
							 | 
						||
| 
								 | 
							
								    wsComponents.scheme = (wsComponents.secure ? 'wss' : 'ws')
							 | 
						||
| 
								 | 
							
								    wsComponents.secure = undefined
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // reconstruct path from resource name
							 | 
						||
| 
								 | 
							
								  if (wsComponents.resourceName) {
							 | 
						||
| 
								 | 
							
								    const [path, query] = wsComponents.resourceName.split('?')
							 | 
						||
| 
								 | 
							
								    wsComponents.path = (path && path !== '/' ? path : undefined)
							 | 
						||
| 
								 | 
							
								    wsComponents.query = query
							 | 
						||
| 
								 | 
							
								    wsComponents.resourceName = undefined
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // forbid fragment component
							 | 
						||
| 
								 | 
							
								  wsComponents.fragment = undefined
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return wsComponents
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function urnParse (urnComponents, options) {
							 | 
						||
| 
								 | 
							
								  if (!urnComponents.path) {
							 | 
						||
| 
								 | 
							
								    urnComponents.error = 'URN can not be parsed'
							 | 
						||
| 
								 | 
							
								    return urnComponents
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  const matches = urnComponents.path.match(URN_REG)
							 | 
						||
| 
								 | 
							
								  if (matches) {
							 | 
						||
| 
								 | 
							
								    const scheme = options.scheme || urnComponents.scheme || 'urn'
							 | 
						||
| 
								 | 
							
								    urnComponents.nid = matches[1].toLowerCase()
							 | 
						||
| 
								 | 
							
								    urnComponents.nss = matches[2]
							 | 
						||
| 
								 | 
							
								    const urnScheme = `${scheme}:${options.nid || urnComponents.nid}`
							 | 
						||
| 
								 | 
							
								    const schemeHandler = SCHEMES[urnScheme]
							 | 
						||
| 
								 | 
							
								    urnComponents.path = undefined
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (schemeHandler) {
							 | 
						||
| 
								 | 
							
								      urnComponents = schemeHandler.parse(urnComponents, options)
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  } else {
							 | 
						||
| 
								 | 
							
								    urnComponents.error = urnComponents.error || 'URN can not be parsed.'
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return urnComponents
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function urnSerialize (urnComponents, options) {
							 | 
						||
| 
								 | 
							
								  const scheme = options.scheme || urnComponents.scheme || 'urn'
							 | 
						||
| 
								 | 
							
								  const nid = urnComponents.nid.toLowerCase()
							 | 
						||
| 
								 | 
							
								  const urnScheme = `${scheme}:${options.nid || nid}`
							 | 
						||
| 
								 | 
							
								  const schemeHandler = SCHEMES[urnScheme]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (schemeHandler) {
							 | 
						||
| 
								 | 
							
								    urnComponents = schemeHandler.serialize(urnComponents, options)
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const uriComponents = urnComponents
							 | 
						||
| 
								 | 
							
								  const nss = urnComponents.nss
							 | 
						||
| 
								 | 
							
								  uriComponents.path = `${nid || options.nid}:${nss}`
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  options.skipEscape = true
							 | 
						||
| 
								 | 
							
								  return uriComponents
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function urnuuidParse (urnComponents, options) {
							 | 
						||
| 
								 | 
							
								  const uuidComponents = urnComponents
							 | 
						||
| 
								 | 
							
								  uuidComponents.uuid = uuidComponents.nss
							 | 
						||
| 
								 | 
							
								  uuidComponents.nss = undefined
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (!options.tolerant && (!uuidComponents.uuid || !UUID_REG.test(uuidComponents.uuid))) {
							 | 
						||
| 
								 | 
							
								    uuidComponents.error = uuidComponents.error || 'UUID is not valid.'
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return uuidComponents
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function urnuuidSerialize (uuidComponents) {
							 | 
						||
| 
								 | 
							
								  const urnComponents = uuidComponents
							 | 
						||
| 
								 | 
							
								  // normalize UUID
							 | 
						||
| 
								 | 
							
								  urnComponents.nss = (uuidComponents.uuid || '').toLowerCase()
							 | 
						||
| 
								 | 
							
								  return urnComponents
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const http = {
							 | 
						||
| 
								 | 
							
								  scheme: 'http',
							 | 
						||
| 
								 | 
							
								  domainHost: true,
							 | 
						||
| 
								 | 
							
								  parse: httpParse,
							 | 
						||
| 
								 | 
							
								  serialize: httpSerialize
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const https = {
							 | 
						||
| 
								 | 
							
								  scheme: 'https',
							 | 
						||
| 
								 | 
							
								  domainHost: http.domainHost,
							 | 
						||
| 
								 | 
							
								  parse: httpParse,
							 | 
						||
| 
								 | 
							
								  serialize: httpSerialize
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const ws = {
							 | 
						||
| 
								 | 
							
								  scheme: 'ws',
							 | 
						||
| 
								 | 
							
								  domainHost: true,
							 | 
						||
| 
								 | 
							
								  parse: wsParse,
							 | 
						||
| 
								 | 
							
								  serialize: wsSerialize
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const wss = {
							 | 
						||
| 
								 | 
							
								  scheme: 'wss',
							 | 
						||
| 
								 | 
							
								  domainHost: ws.domainHost,
							 | 
						||
| 
								 | 
							
								  parse: ws.parse,
							 | 
						||
| 
								 | 
							
								  serialize: ws.serialize
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const urn = {
							 | 
						||
| 
								 | 
							
								  scheme: 'urn',
							 | 
						||
| 
								 | 
							
								  parse: urnParse,
							 | 
						||
| 
								 | 
							
								  serialize: urnSerialize,
							 | 
						||
| 
								 | 
							
								  skipNormalize: true
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const urnuuid = {
							 | 
						||
| 
								 | 
							
								  scheme: 'urn:uuid',
							 | 
						||
| 
								 | 
							
								  parse: urnuuidParse,
							 | 
						||
| 
								 | 
							
								  serialize: urnuuidSerialize,
							 | 
						||
| 
								 | 
							
								  skipNormalize: true
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const SCHEMES = {
							 | 
						||
| 
								 | 
							
								  http,
							 | 
						||
| 
								 | 
							
								  https,
							 | 
						||
| 
								 | 
							
								  ws,
							 | 
						||
| 
								 | 
							
								  wss,
							 | 
						||
| 
								 | 
							
								  urn,
							 | 
						||
| 
								 | 
							
								  'urn:uuid': urnuuid
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								module.exports = SCHEMES
							 |