request.js 7.1 KB
Newer Older
N
Nzix 已提交
1
const encrypt = require('./crypto')
N
Nzix 已提交
2 3
const request = require('request')
const queryString = require('querystring')
T
trazyn 已提交
4
const PacProxyAgent = require('pac-proxy-agent')
L
lizhenyuls 已提交
5
const zlib = require('zlib')
N
Nzix 已提交
6

7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
// request.debug = true // 开启可看到更详细信息

const chooseUserAgent = ua => {
  const userAgentList = [
    'Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1',
    'Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1',
    'Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Mobile Safari/537.36',
    'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Mobile Safari/537.36',
    'Mozilla/5.0 (Linux; Android 5.1.1; Nexus 6 Build/LYZ28E) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Mobile Safari/537.36',
    'Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_2 like Mac OS X) AppleWebKit/603.2.4 (KHTML, like Gecko) Mobile/14F89;GameHelper',
    'Mozilla/5.0 (iPhone; CPU iPhone OS 10_0 like Mac OS X) AppleWebKit/602.1.38 (KHTML, like Gecko) Version/10.0 Mobile/14A300 Safari/602.1',
    'Mozilla/5.0 (iPad; CPU OS 10_0 like Mac OS X) AppleWebKit/602.1.38 (KHTML, like Gecko) Version/10.0 Mobile/14A300 Safari/602.1',
    'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:46.0) Gecko/20100101 Firefox/46.0',
    'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36',
    'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/603.2.4 (KHTML, like Gecko) Version/10.1.1 Safari/603.2.4',
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:46.0) Gecko/20100101 Firefox/46.0',
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36',
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/13.10586'
  ]
  let index = 0
  if (typeof ua == 'undefined')
    index = Math.floor(Math.random() * userAgentList.length)
L
lizhenyuls 已提交
29 30
  else if (ua === 'mobile') index = Math.floor(Math.random() * 7)
  else if (ua === 'pc') index = Math.floor(Math.random() * 5) + 8
31 32
  else return ua
  return userAgentList[index]
N
Nzix 已提交
33 34
}

N
Nzix 已提交
35
const createRequest = (method, url, data, options) => {
36 37
  return new Promise((resolve, reject) => {
    let headers = { 'User-Agent': chooseUserAgent(options.ua) }
L
lizhenyuls 已提交
38
    if (method.toUpperCase() === 'POST')
39 40
      headers['Content-Type'] = 'application/x-www-form-urlencoded'
    if (url.includes('music.163.com'))
41
      headers['Referer'] = 'https://music.163.com'
42
    // headers['X-Real-IP'] = '118.88.88.88'
N
Nzix 已提交
43

44 45 46 47 48 49 50 51 52 53
    if (typeof options.cookie === 'object')
      headers['Cookie'] = Object.keys(options.cookie)
        .map(
          key =>
            encodeURIComponent(key) +
            '=' +
            encodeURIComponent(options.cookie[key])
        )
        .join('; ')
    else if (options.cookie) headers['Cookie'] = options.cookie
N
Nzix 已提交
54

L
lizhenyuls 已提交
55
    if (options.crypto === 'weapi') {
56 57 58 59
      let csrfToken = (headers['Cookie'] || '').match(/_csrf=([^(;|$)]+)/)
      data.csrf_token = csrfToken ? csrfToken[1] : ''
      data = encrypt.weapi(data)
      url = url.replace(/\w*api/, 'weapi')
L
lizhenyuls 已提交
60
    } else if (options.crypto === 'linuxapi') {
61 62 63 64 65 66 67
      data = encrypt.linuxapi({
        method: method,
        url: url.replace(/\w*api/, 'api'),
        params: data
      })
      headers['User-Agent'] =
        'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36'
68
      url = 'https://music.163.com/api/linux/forward'
L
lizhenyuls 已提交
69 70 71 72
    } else if (options.crypto === 'eapi') {
      const cookie = options.cookie || {};
      const csrfToken = cookie['__csrf'] || ''
      const header = {
B
binaryify 已提交
73 74 75 76 77 78 79 80 81 82 83
        'osver': cookie.osver, //系统版本
        'deviceId': cookie.deviceId, //encrypt.base64.encode(imei + '\t02:00:00:00:00:00\t5106025eb79a5247\t70ffbaac7')
        'appver': cookie.appver || '6.1.1', // app版本
        'versioncode': cookie.versioncode || '140', //版本号
        'mobilename': cookie.mobilename, //设备model
        'buildver': cookie.buildver || Date.now().toString().substr(0, 10),
        'resolution': cookie.resolution || '1920x1080', //设备分辨率
        '__csrf': csrfToken,
        'os': cookie.os || 'android',
        'channel': cookie.channel,
        'requestId': `${Date.now()}_${Math.floor(Math.random() * 1000).toString().padStart(4, '0')}`
L
lizhenyuls 已提交
84
      }
B
binaryify 已提交
85 86
      if (cookie.MUSIC_U) header['MUSIC_U'] = cookie.MUSIC_U
      if (cookie.MUSIC_A) header['MUSIC_A'] = cookie.MUSIC_A
L
lizhenyuls 已提交
87 88 89 90 91 92 93 94 95 96
      headers['Cookie'] = Object.keys(header)
        .map(
          key =>
            encodeURIComponent(key) +
            '=' +
            encodeURIComponent(header[key])
        )
        .join('; ')
      data.header = header
      data = encrypt.eapi(options.url, data)
B
binaryify 已提交
97
      url = url.replace(/\w*api/, 'eapi')
98
    }
N
Nzix 已提交
99

100
    const answer = { status: 500, body: {}, cookie: [] }
T
trazyn 已提交
101 102 103 104 105 106 107
    const settings = {
      method: method,
      url: url,
      headers: headers,
      body: queryString.stringify(data)
    }

L
lizhenyuls 已提交
108 109
    if (options.crypto === 'eapi') settings.encoding = null

T
trazyn 已提交
110 111 112 113 114 115
    if (/\.pac$/i.test(options.proxy)) {
      settings.agent = new PacProxyAgent(options.proxy)
    } else {
      settings.proxy = options.proxy
    }

116
    request(
T
trazyn 已提交
117
      settings,
118 119 120 121 122 123 124 125 126 127
      (err, res, body) => {
        if (err) {
          answer.status = 502
          answer.body = { code: 502, msg: err.stack }
          reject(answer)
        } else {
          answer.cookie = (res.headers['set-cookie'] || []).map(x =>
            x.replace(/\s*Domain=[^(;|$)]+;*/, '')
          )
          try {
L
lizhenyuls 已提交
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
            if (options.crypto === 'eapi') {

              zlib.unzip(body, function (err, buffer) {
                const _buffer = err ? body : buffer
                try {
                  try{
                    answer.body = JSON.parse(encrypt.decrypt(_buffer).toString())
                    answer.status = answer.body.code || res.statusCode
                  } catch(e){
                    answer.body = JSON.parse(_buffer.toString())
                    answer.status = res.statusCode
                  }
                } catch (e) {
                  answer.body = _buffer.toString()
                  answer.status = res.statusCode
                }
                answer.status =
                  100 < answer.status && answer.status < 600 ? answer.status : 400
                if (answer.status === 200) resolve(answer)
                else reject(answer)
              });
              return false

            } else {

              answer.body = JSON.parse(body)
              answer.status = answer.body.code || res.statusCode

            }

158 159 160 161
          } catch (e) {
            answer.body = body
            answer.status = res.statusCode
          }
L
lizhenyuls 已提交
162

163 164 165 166
          answer.status =
            100 < answer.status && answer.status < 600 ? answer.status : 400
          if (answer.status == 200) resolve(answer)
          else reject(answer)
N
Nzix 已提交
167
        }
168 169 170
      }
    )
  })
N
Nzix 已提交
171 172 173
}

module.exports = createRequest