Bug:Fix file validation issue
[vnfsdk/refrepo.git] / vnfmarket / src / main / webapp / vnfmarket / node_modules / negotiator / lib / mediaType.js
1 /**
2  * negotiator
3  * Copyright(c) 2012 Isaac Z. Schlueter
4  * Copyright(c) 2014 Federico Romero
5  * Copyright(c) 2014-2015 Douglas Christopher Wilson
6  * MIT Licensed
7  */
8
9 module.exports = preferredMediaTypes;
10 preferredMediaTypes.preferredMediaTypes = preferredMediaTypes;
11
12 function parseAccept(accept) {
13   var accepts = splitMediaTypes(accept);
14
15   for (var i = 0, j = 0; i < accepts.length; i++) {
16     var mediaType = parseMediaType(accepts[i].trim(), i);
17
18     if (mediaType) {
19       accepts[j++] = mediaType;
20     }
21   }
22
23   // trim accepts
24   accepts.length = j;
25
26   return accepts;
27 };
28
29 function parseMediaType(s, i) {
30   var match = s.match(/\s*(\S+?)\/([^;\s]+)\s*(?:;(.*))?/);
31   if (!match) return null;
32
33   var type = match[1],
34       subtype = match[2],
35       full = "" + type + "/" + subtype,
36       params = {},
37       q = 1;
38
39   if (match[3]) {
40     params = match[3].split(';').map(function(s) {
41       return s.trim().split('=');
42     }).reduce(function (set, p) {
43       var name = p[0].toLowerCase();
44       var value = p[1];
45
46       set[name] = value && value[0] === '"' && value[value.length - 1] === '"'
47         ? value.substr(1, value.length - 2)
48         : value;
49
50       return set;
51     }, params);
52
53     if (params.q != null) {
54       q = parseFloat(params.q);
55       delete params.q;
56     }
57   }
58
59   return {
60     type: type,
61     subtype: subtype,
62     params: params,
63     q: q,
64     i: i,
65     full: full
66   };
67 }
68
69 function getMediaTypePriority(type, accepted, index) {
70   var priority = {o: -1, q: 0, s: 0};
71
72   for (var i = 0; i < accepted.length; i++) {
73     var spec = specify(type, accepted[i], index);
74
75     if (spec && (priority.s - spec.s || priority.q - spec.q || priority.o - spec.o) < 0) {
76       priority = spec;
77     }
78   }
79
80   return priority;
81 }
82
83 function specify(type, spec, index) {
84   var p = parseMediaType(type);
85   var s = 0;
86
87   if (!p) {
88     return null;
89   }
90
91   if(spec.type.toLowerCase() == p.type.toLowerCase()) {
92     s |= 4
93   } else if(spec.type != '*') {
94     return null;
95   }
96
97   if(spec.subtype.toLowerCase() == p.subtype.toLowerCase()) {
98     s |= 2
99   } else if(spec.subtype != '*') {
100     return null;
101   }
102
103   var keys = Object.keys(spec.params);
104   if (keys.length > 0) {
105     if (keys.every(function (k) {
106       return spec.params[k] == '*' || (spec.params[k] || '').toLowerCase() == (p.params[k] || '').toLowerCase();
107     })) {
108       s |= 1
109     } else {
110       return null
111     }
112   }
113
114   return {
115     i: index,
116     o: spec.i,
117     q: spec.q,
118     s: s,
119   }
120
121 }
122
123 function preferredMediaTypes(accept, provided) {
124   // RFC 2616 sec 14.2: no header = */*
125   var accepts = parseAccept(accept === undefined ? '*/*' : accept || '');
126
127   if (!provided) {
128     // sorted list of all types
129     return accepts.filter(isQuality).sort(compareSpecs).map(function getType(spec) {
130       return spec.full;
131     });
132   }
133
134   var priorities = provided.map(function getPriority(type, index) {
135     return getMediaTypePriority(type, accepts, index);
136   });
137
138   // sorted list of accepted types
139   return priorities.filter(isQuality).sort(compareSpecs).map(function getType(priority) {
140     return provided[priorities.indexOf(priority)];
141   });
142 }
143
144 function compareSpecs(a, b) {
145   return (b.q - a.q) || (b.s - a.s) || (a.o - b.o) || (a.i - b.i) || 0;
146 }
147
148 function isQuality(spec) {
149   return spec.q > 0;
150 }
151
152 function quoteCount(string) {
153   var count = 0;
154   var index = 0;
155
156   while ((index = string.indexOf('"', index)) !== -1) {
157     count++;
158     index++;
159   }
160
161   return count;
162 }
163
164 function splitMediaTypes(accept) {
165   var accepts = accept.split(',');
166
167   for (var i = 1, j = 0; i < accepts.length; i++) {
168     if (quoteCount(accepts[j]) % 2 == 0) {
169       accepts[++j] = accepts[i];
170     } else {
171       accepts[j] += ',' + accepts[i];
172     }
173   }
174
175   // trim accepts
176   accepts.length = j + 1;
177
178   return accepts;
179 }