source: trip-planner-front/node_modules/content-type/index.js@ 188ee53

Last change on this file since 188ee53 was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 4.7 KB
Line 
1/*!
2 * content-type
3 * Copyright(c) 2015 Douglas Christopher Wilson
4 * MIT Licensed
5 */
6
7'use strict'
8
9/**
10 * RegExp to match *( ";" parameter ) in RFC 7231 sec 3.1.1.1
11 *
12 * parameter = token "=" ( token / quoted-string )
13 * token = 1*tchar
14 * tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*"
15 * / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~"
16 * / DIGIT / ALPHA
17 * ; any VCHAR, except delimiters
18 * quoted-string = DQUOTE *( qdtext / quoted-pair ) DQUOTE
19 * qdtext = HTAB / SP / %x21 / %x23-5B / %x5D-7E / obs-text
20 * obs-text = %x80-FF
21 * quoted-pair = "\" ( HTAB / SP / VCHAR / obs-text )
22 */
23var PARAM_REGEXP = /; *([!#$%&'*+.^_`|~0-9A-Za-z-]+) *= *("(?:[\u000b\u0020\u0021\u0023-\u005b\u005d-\u007e\u0080-\u00ff]|\\[\u000b\u0020-\u00ff])*"|[!#$%&'*+.^_`|~0-9A-Za-z-]+) */g
24var TEXT_REGEXP = /^[\u000b\u0020-\u007e\u0080-\u00ff]+$/
25var TOKEN_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/
26
27/**
28 * RegExp to match quoted-pair in RFC 7230 sec 3.2.6
29 *
30 * quoted-pair = "\" ( HTAB / SP / VCHAR / obs-text )
31 * obs-text = %x80-FF
32 */
33var QESC_REGEXP = /\\([\u000b\u0020-\u00ff])/g
34
35/**
36 * RegExp to match chars that must be quoted-pair in RFC 7230 sec 3.2.6
37 */
38var QUOTE_REGEXP = /([\\"])/g
39
40/**
41 * RegExp to match type in RFC 7231 sec 3.1.1.1
42 *
43 * media-type = type "/" subtype
44 * type = token
45 * subtype = token
46 */
47var TYPE_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+\/[!#$%&'*+.^_`|~0-9A-Za-z-]+$/
48
49/**
50 * Module exports.
51 * @public
52 */
53
54exports.format = format
55exports.parse = parse
56
57/**
58 * Format object to media type.
59 *
60 * @param {object} obj
61 * @return {string}
62 * @public
63 */
64
65function format (obj) {
66 if (!obj || typeof obj !== 'object') {
67 throw new TypeError('argument obj is required')
68 }
69
70 var parameters = obj.parameters
71 var type = obj.type
72
73 if (!type || !TYPE_REGEXP.test(type)) {
74 throw new TypeError('invalid type')
75 }
76
77 var string = type
78
79 // append parameters
80 if (parameters && typeof parameters === 'object') {
81 var param
82 var params = Object.keys(parameters).sort()
83
84 for (var i = 0; i < params.length; i++) {
85 param = params[i]
86
87 if (!TOKEN_REGEXP.test(param)) {
88 throw new TypeError('invalid parameter name')
89 }
90
91 string += '; ' + param + '=' + qstring(parameters[param])
92 }
93 }
94
95 return string
96}
97
98/**
99 * Parse media type to object.
100 *
101 * @param {string|object} string
102 * @return {Object}
103 * @public
104 */
105
106function parse (string) {
107 if (!string) {
108 throw new TypeError('argument string is required')
109 }
110
111 // support req/res-like objects as argument
112 var header = typeof string === 'object'
113 ? getcontenttype(string)
114 : string
115
116 if (typeof header !== 'string') {
117 throw new TypeError('argument string is required to be a string')
118 }
119
120 var index = header.indexOf(';')
121 var type = index !== -1
122 ? header.substr(0, index).trim()
123 : header.trim()
124
125 if (!TYPE_REGEXP.test(type)) {
126 throw new TypeError('invalid media type')
127 }
128
129 var obj = new ContentType(type.toLowerCase())
130
131 // parse parameters
132 if (index !== -1) {
133 var key
134 var match
135 var value
136
137 PARAM_REGEXP.lastIndex = index
138
139 while ((match = PARAM_REGEXP.exec(header))) {
140 if (match.index !== index) {
141 throw new TypeError('invalid parameter format')
142 }
143
144 index += match[0].length
145 key = match[1].toLowerCase()
146 value = match[2]
147
148 if (value[0] === '"') {
149 // remove quotes and escapes
150 value = value
151 .substr(1, value.length - 2)
152 .replace(QESC_REGEXP, '$1')
153 }
154
155 obj.parameters[key] = value
156 }
157
158 if (index !== header.length) {
159 throw new TypeError('invalid parameter format')
160 }
161 }
162
163 return obj
164}
165
166/**
167 * Get content-type from req/res objects.
168 *
169 * @param {object}
170 * @return {Object}
171 * @private
172 */
173
174function getcontenttype (obj) {
175 var header
176
177 if (typeof obj.getHeader === 'function') {
178 // res-like
179 header = obj.getHeader('content-type')
180 } else if (typeof obj.headers === 'object') {
181 // req-like
182 header = obj.headers && obj.headers['content-type']
183 }
184
185 if (typeof header !== 'string') {
186 throw new TypeError('content-type header is missing from object')
187 }
188
189 return header
190}
191
192/**
193 * Quote a string if necessary.
194 *
195 * @param {string} val
196 * @return {string}
197 * @private
198 */
199
200function qstring (val) {
201 var str = String(val)
202
203 // no need to quote tokens
204 if (TOKEN_REGEXP.test(str)) {
205 return str
206 }
207
208 if (str.length > 0 && !TEXT_REGEXP.test(str)) {
209 throw new TypeError('invalid parameter value')
210 }
211
212 return '"' + str.replace(QUOTE_REGEXP, '\\$1') + '"'
213}
214
215/**
216 * Class to represent a content type.
217 * @private
218 */
219function ContentType (type) {
220 this.parameters = Object.create(null)
221 this.type = type
222}
Note: See TracBrowser for help on using the repository browser.