Fix license issues
[sdnc/oam.git] / dgbuilder / dgeflows / node_modules / serve-index / node_modules / accepts / node_modules / negotiator / lib / mediaType.js
1 module.exports = preferredMediaTypes;
2 preferredMediaTypes.preferredMediaTypes = preferredMediaTypes;
3
4 function parseAccept(accept) {
5   var accepts = accept.split(',');
6
7   for (var i = 0, j = 0; i < accepts.length; i++) {
8     var mediaType = parseMediaType(accepts[i].trim(), i);
9
10     if (mediaType) {
11       accepts[j++] = mediaType;
12     }
13   }
14
15   // trim accepts
16   accepts.length = j;
17
18   return accepts;
19 };
20
21 function parseMediaType(s, i) {
22   var match = s.match(/\s*(\S+?)\/([^;\s]+)\s*(?:;(.*))?/);
23   if (!match) return null;
24
25   var type = match[1],
26       subtype = match[2],
27       full = "" + type + "/" + subtype,
28       params = {},
29       q = 1;
30
31   if (match[3]) {
32     params = match[3].split(';').map(function(s) {
33       return s.trim().split('=');
34     }).reduce(function (set, p) {
35       set[p[0]] = p[1];
36       return set
37     }, params);
38
39     if (params.q != null) {
40       q = parseFloat(params.q);
41       delete params.q;
42     }
43   }
44
45   return {
46     type: type,
47     subtype: subtype,
48     params: params,
49     q: q,
50     i: i,
51     full: full
52   };
53 }
54
55 function getMediaTypePriority(type, accepted, index) {
56   var priority = {o: -1, q: 0, s: 0};
57
58   for (var i = 0; i < accepted.length; i++) {
59     var spec = specify(type, accepted[i], index);
60
61     if (spec && (priority.s - spec.s || priority.q - spec.q || priority.o - spec.o) < 0) {
62       priority = spec;
63     }
64   }
65
66   return priority;
67 }
68
69 function specify(type, spec, index) {
70   var p = parseMediaType(type);
71   var s = 0;
72
73   if (!p) {
74     return null;
75   }
76
77   if(spec.type.toLowerCase() == p.type.toLowerCase()) {
78     s |= 4
79   } else if(spec.type != '*') {
80     return null;
81   }
82
83   if(spec.subtype.toLowerCase() == p.subtype.toLowerCase()) {
84     s |= 2
85   } else if(spec.subtype != '*') {
86     return null;
87   }
88
89   var keys = Object.keys(spec.params);
90   if (keys.length > 0) {
91     if (keys.every(function (k) {
92       return spec.params[k] == '*' || (spec.params[k] || '').toLowerCase() == (p.params[k] || '').toLowerCase();
93     })) {
94       s |= 1
95     } else {
96       return null
97     }
98   }
99
100   return {
101     i: index,
102     o: spec.i,
103     q: spec.q,
104     s: s,
105   }
106
107 }
108
109 function preferredMediaTypes(accept, provided) {
110   // RFC 2616 sec 14.2: no header = */*
111   var accepts = parseAccept(accept === undefined ? '*/*' : accept || '');
112
113   if (!provided) {
114     // sorted list of all types
115     return accepts.filter(isQuality).sort(compareSpecs).map(function getType(spec) {
116       return spec.full;
117     });
118   }
119
120   var priorities = provided.map(function getPriority(type, index) {
121     return getMediaTypePriority(type, accepts, index);
122   });
123
124   // sorted list of accepted types
125   return priorities.filter(isQuality).sort(compareSpecs).map(function getType(priority) {
126     return provided[priorities.indexOf(priority)];
127   });
128 }
129
130 function compareSpecs(a, b) {
131   return (b.q - a.q) || (b.s - a.s) || (a.o - b.o) || (a.i - b.i) || 0;
132 }
133
134 function isQuality(spec) {
135   return spec.q > 0;
136 }