helpers.js
2.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
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
};