(cookieStr)
| 17 | } |
| 18 | |
| 19 | static parse(cookieStr) { |
| 20 | if (!cookieStr && typeof cookieStr !== 'string') return null |
| 21 | |
| 22 | cookieStr = cookieStr.trim().split(';') |
| 23 | |
| 24 | // key-value |
| 25 | const parseKeyValue = /^([^=;\x00-\x1F]+)=([^;\n\r\0\x00-\x1F]*).*/.exec(cookieStr.shift()) |
| 26 | if (!parseKeyValue) return null |
| 27 | |
| 28 | const key = (parseKeyValue[1] || '').trim() |
| 29 | const value = (parseKeyValue[2] || '').trim() |
| 30 | |
| 31 | // 其他字段 |
| 32 | let path = null |
| 33 | let domain = null |
| 34 | let expires = null |
| 35 | let maxAge = null |
| 36 | let secure = false |
| 37 | let httpOnly = false |
| 38 | |
| 39 | for (let item of cookieStr) { |
| 40 | item = item.trim() |
| 41 | if (!item) continue |
| 42 | |
| 43 | let [key, value] = item.split('=') |
| 44 | key = (key || '').trim().toLowerCase() |
| 45 | value = (value || '').trim() |
| 46 | |
| 47 | if (!key) continue |
| 48 | |
| 49 | switch (key) { |
| 50 | case 'path': |
| 51 | if (value[0] === '/') path = value |
| 52 | break |
| 53 | case 'domain': |
| 54 | value = value.replace(/^\./, '').toLowerCase() |
| 55 | if (value) domain = value |
| 56 | break |
| 57 | case 'expires': |
| 58 | if (value) { |
| 59 | const timeStamp = Date.parse(value) |
| 60 | if (timeStamp) expires = timeStamp |
| 61 | } |
| 62 | break |
| 63 | case 'max-age': |
| 64 | if (/^-?[0-9]+$/.test(value)) maxAge = +value * 1000 |
| 65 | break |
| 66 | case 'secure': |
| 67 | secure = true |
| 68 | break |
| 69 | case 'httponly': |
| 70 | httpOnly = true |
| 71 | break |
| 72 | default: |
| 73 | // ignore |
| 74 | break |
| 75 | } |
| 76 | } |
no test coverage detected