mirror of
				https://github.com/cderche/greenlock-storage-s3
				synced 2025-10-30 20:12:46 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			90 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			90 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| var util =  require('../util');
 | |
| var AWS = require('../core');
 | |
| 
 | |
| /**
 | |
|  * Prepend prefix defined by API model to endpoint that's already
 | |
|  * constructed. This feature does not apply to operations using
 | |
|  * endpoint discovery and can be disabled.
 | |
|  * @api private
 | |
|  */
 | |
| function populateHostPrefix(request)  {
 | |
|   var enabled = request.service.config.hostPrefixEnabled;
 | |
|   if (!enabled) return request;
 | |
|   var operationModel = request.service.api.operations[request.operation];
 | |
|   //don't marshal host prefix when operation has endpoint discovery traits
 | |
|   if (hasEndpointDiscover(request)) return request;
 | |
|   if (operationModel.endpoint && operationModel.endpoint.hostPrefix) {
 | |
|     var hostPrefixNotation = operationModel.endpoint.hostPrefix;
 | |
|     var hostPrefix = expandHostPrefix(hostPrefixNotation, request.params, operationModel.input);
 | |
|     prependEndpointPrefix(request.httpRequest.endpoint, hostPrefix);
 | |
|     validateHostname(request.httpRequest.endpoint.hostname);
 | |
|   }
 | |
|   return request;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @api private
 | |
|  */
 | |
| function hasEndpointDiscover(request) {
 | |
|   var api = request.service.api;
 | |
|   var operationModel = api.operations[request.operation];
 | |
|   var isEndpointOperation = api.endpointOperation && (api.endpointOperation === util.string.lowerFirst(operationModel.name));
 | |
|   return (operationModel.endpointDiscoveryRequired !== 'NULL' || isEndpointOperation === true);
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @api private
 | |
|  */
 | |
| function expandHostPrefix(hostPrefixNotation, params, shape) {
 | |
|   util.each(shape.members, function(name, member) {
 | |
|     if (member.hostLabel === true) {
 | |
|       if (typeof params[name] !== 'string' || params[name] === '') {
 | |
|         throw util.error(new Error(), {
 | |
|           message: 'Parameter ' + name + ' should be a non-empty string.',
 | |
|           code: 'InvalidParameter'
 | |
|         });
 | |
|       }
 | |
|       var regex = new RegExp('\\{' + name + '\\}', 'g');
 | |
|       hostPrefixNotation = hostPrefixNotation.replace(regex, params[name]);
 | |
|     }
 | |
|   });
 | |
|   return hostPrefixNotation;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @api private
 | |
|  */
 | |
| function prependEndpointPrefix(endpoint, prefix) {
 | |
|   if (endpoint.host) {
 | |
|     endpoint.host = prefix + endpoint.host;
 | |
|   }
 | |
|   if (endpoint.hostname) {
 | |
|     endpoint.hostname = prefix + endpoint.hostname;
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @api private
 | |
|  */
 | |
| function validateHostname(hostname) {
 | |
|   var labels = hostname.split('.');
 | |
|   //Reference: https://tools.ietf.org/html/rfc1123#section-2
 | |
|   var hostPattern = /^[a-zA-Z0-9]{1}$|^[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9]$/;
 | |
|   util.arrayEach(labels, function(label) {
 | |
|     if (!label.length || label.length < 1 || label.length > 63) {
 | |
|       throw util.error(new Error(), {
 | |
|         code: 'ValidationError',
 | |
|         message: 'Hostname label length should be between 1 to 63 characters, inclusive.'
 | |
|       });
 | |
|     }
 | |
|     if (!hostPattern.test(label)) {
 | |
|       throw AWS.util.error(new Error(),
 | |
|         {code: 'ValidationError', message: label + ' is not hostname compatible.'});
 | |
|     }
 | |
|   });
 | |
| }
 | |
| 
 | |
| module.exports = {
 | |
|   populateHostPrefix: populateHostPrefix
 | |
| };
 |