| |
| |
| |
| |
|
|
|
|
| 'use strict'
|
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| var PARAM_REGEXP = /; *([!#$%&'*+.^_`|~0-9A-Za-z-]+) *= *("(?:[\u000b\u0020\u0021\u0023-\u005b\u005d-\u007e\u0080-\u00ff]|\\[\u000b\u0020-\u00ff])*"|[!#$%&'*+.^_`|~0-9A-Za-z-]+) */g
|
| var TEXT_REGEXP = /^[\u000b\u0020-\u007e\u0080-\u00ff]+$/
|
| var TOKEN_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/
|
|
|
| |
| |
| |
| |
| |
|
|
| var QESC_REGEXP = /\\([\u000b\u0020-\u00ff])/g
|
|
|
| |
| |
|
|
| var QUOTE_REGEXP = /([\\"])/g
|
|
|
| |
| |
| |
| |
| |
| |
|
|
| var TYPE_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+\/[!#$%&'*+.^_`|~0-9A-Za-z-]+$/
|
|
|
| |
| |
| |
|
|
|
|
| exports.format = format
|
| exports.parse = parse
|
|
|
| |
| |
| |
| |
| |
| |
|
|
|
|
| function format (obj) {
|
| if (!obj || typeof obj !== 'object') {
|
| throw new TypeError('argument obj is required')
|
| }
|
|
|
| var parameters = obj.parameters
|
| var type = obj.type
|
|
|
| if (!type || !TYPE_REGEXP.test(type)) {
|
| throw new TypeError('invalid type')
|
| }
|
|
|
| var string = type
|
|
|
|
|
| if (parameters && typeof parameters === 'object') {
|
| var param
|
| var params = Object.keys(parameters).sort()
|
|
|
| for (var i = 0; i < params.length; i++) {
|
| param = params[i]
|
|
|
| if (!TOKEN_REGEXP.test(param)) {
|
| throw new TypeError('invalid parameter name')
|
| }
|
|
|
| string += '; ' + param + '=' + qstring(parameters[param])
|
| }
|
| }
|
|
|
| return string
|
| }
|
|
|
| |
| |
| |
| |
| |
| |
|
|
|
|
| function parse (string) {
|
| if (!string) {
|
| throw new TypeError('argument string is required')
|
| }
|
|
|
|
|
| var header = typeof string === 'object'
|
| ? getcontenttype(string)
|
| : string
|
|
|
| if (typeof header !== 'string') {
|
| throw new TypeError('argument string is required to be a string')
|
| }
|
|
|
| var index = header.indexOf(';')
|
| var type = index !== -1
|
| ? header.slice(0, index).trim()
|
| : header.trim()
|
|
|
| if (!TYPE_REGEXP.test(type)) {
|
| throw new TypeError('invalid media type')
|
| }
|
|
|
| var obj = new ContentType(type.toLowerCase())
|
|
|
|
|
| if (index !== -1) {
|
| var key
|
| var match
|
| var value
|
|
|
| PARAM_REGEXP.lastIndex = index
|
|
|
| while ((match = PARAM_REGEXP.exec(header))) {
|
| if (match.index !== index) {
|
| throw new TypeError('invalid parameter format')
|
| }
|
|
|
| index += match[0].length
|
| key = match[1].toLowerCase()
|
| value = match[2]
|
|
|
| if (value.charCodeAt(0) === 0x22 ) {
|
|
|
| value = value.slice(1, -1)
|
|
|
|
|
| if (value.indexOf('\\') !== -1) {
|
| value = value.replace(QESC_REGEXP, '$1')
|
| }
|
| }
|
|
|
| obj.parameters[key] = value
|
| }
|
|
|
| if (index !== header.length) {
|
| throw new TypeError('invalid parameter format')
|
| }
|
| }
|
|
|
| return obj
|
| }
|
|
|
| |
| |
| |
| |
| |
| |
|
|
|
|
| function getcontenttype (obj) {
|
| var header
|
|
|
| if (typeof obj.getHeader === 'function') {
|
|
|
| header = obj.getHeader('content-type')
|
| } else if (typeof obj.headers === 'object') {
|
|
|
| header = obj.headers && obj.headers['content-type']
|
| }
|
|
|
| if (typeof header !== 'string') {
|
| throw new TypeError('content-type header is missing from object')
|
| }
|
|
|
| return header
|
| }
|
|
|
| |
| |
| |
| |
| |
| |
|
|
|
|
| function qstring (val) {
|
| var str = String(val)
|
|
|
|
|
| if (TOKEN_REGEXP.test(str)) {
|
| return str
|
| }
|
|
|
| if (str.length > 0 && !TEXT_REGEXP.test(str)) {
|
| throw new TypeError('invalid parameter value')
|
| }
|
|
|
| return '"' + str.replace(QUOTE_REGEXP, '\\$1') + '"'
|
| }
|
|
|
| |
| |
| |
|
|
| function ContentType (type) {
|
| this.parameters = Object.create(null)
|
| this.type = type
|
| }
|
|
|