feat: bypass Pixiv Cloudflare by directly accessing Pixiv gateway server IP (#5952)

This commit is contained in:
Bao, Huang-Huang
2020-10-20 18:18:05 +08:00
committed by GitHub
parent cc1f892254
commit 45347d2b9c
13 changed files with 62 additions and 8 deletions

View File

@@ -446,6 +446,10 @@ RSSHub 支持使用访问密钥 / 码,白名单和黑名单三种方式进行
- `PIXIV_PASSWORD`: Pixiv 密码
- `PIXIV_BYPASS_CDN`: 绕过 Pixiv 前置的 Cloudflare CDN, 使用`PIXIV_BYPASS_HOSTNAME`指示的 IP 地址访问 Pixiv API, 可以解决因 Cloudflare 机器人验证导致的登录失败问题,默认关闭,设置 true 或 1 开启
- `PIXIV_BYPASS_HOSTNAME`: Pixiv 源站的主机名或 IP 地址,主机名会被解析为 IPv4 地址,默认为`public-api.secure.pixiv.net`;仅在`PIXIV_BYPASS_CDN`开启时生效
- pixiv fanbox 用于获取付费内容
- `FANBOX_SESSION_ID`: 对应 cookies 中的`FANBOXSESSID`

View File

@@ -55,6 +55,8 @@ const calculateValue = () => {
pixiv: {
username: envs.PIXIV_USERNAME,
password: envs.PIXIV_PASSWORD,
bypassCdn: envs.PIXIV_BYPASS_CDN !== '0' && envs.PIXIV_BYPASS_CDN !== 'false',
bypassCdnHostname: envs.PIXIV_BYPASS_HOSTNAME || 'public-api.secure.pixiv.net',
},
fanbox: {
session: envs.FANBOX_SESSION_ID,

View File

@@ -1,4 +1,4 @@
const got = require('@/utils/got');
const got = require('../pixiv-got');
const maskHeader = require('../constants').maskHeader;
const queryString = require('query-string');

View File

@@ -1,4 +1,4 @@
const got = require('@/utils/got');
const got = require('../pixiv-got');
const maskHeader = require('../constants').maskHeader;
const queryString = require('query-string');

View File

@@ -1,4 +1,4 @@
const got = require('@/utils/got');
const got = require('../pixiv-got');
const maskHeader = require('../constants').maskHeader;
const queryString = require('query-string');

View File

@@ -1,4 +1,4 @@
const got = require('@/utils/got');
const got = require('../pixiv-got');
const maskHeader = require('../constants').maskHeader;
const assert = require('assert');
const queryString = require('query-string');

View File

@@ -1,4 +1,4 @@
const got = require('@/utils/got');
const got = require('../pixiv-got');
const maskHeader = require('../constants').maskHeader;
const queryString = require('query-string');

View File

@@ -1,4 +1,4 @@
const got = require('@/utils/got');
const got = require('../pixiv-got');
const maskHeader = require('../constants').maskHeader;
const queryString = require('query-string');

View File

@@ -1,4 +1,4 @@
const got = require('@/utils/got');
const got = require('../pixiv-got');
const maskHeader = require('../constants').maskHeader;
const queryString = require('query-string');

View File

@@ -0,0 +1,42 @@
const dnsPromises = require('dns').promises;
const ipRegex = require('ip-regex');
const got = require('@/utils/got');
const logger = require('@/utils/logger');
const pixivConfig = require('@/config').value.pixiv;
const pixivGot = got.extend({
hooks: {
beforeRequest: [
async (options) => {
if (!pixivConfig.bypassCdn) {
return;
}
let hostname = null;
const isIP = ipRegex({ exact: true }).test(pixivConfig.bypassCdnHostname);
if (isIP) {
hostname = pixivConfig.bypassCdnHostname;
} else {
try {
const addresses = await dnsPromises.resolve4(pixivConfig.bypassCdnHostname);
if (addresses.length) {
hostname = addresses[Math.floor(addresses.length * Math.random())];
} else {
logger.warn(`No IPv4 address resolved from ${pixivConfig.bypassCdnHostname}`);
}
} catch (e) {
logger.error(`Failed to resolve ${pixivConfig.bypassCdnHostname}`);
}
}
if (hostname) {
options.headers = {
...options.headers,
host: options.url.hostname,
};
options.url.hostname = hostname;
}
},
],
},
});
module.exports = pixivGot;

View File

@@ -1,7 +1,7 @@
const config = require('@/config').value;
const logger = require('@/utils/logger');
const wait = require('@/utils/wait');
const got = require('@/utils/got');
const got = require('./pixiv-got');
const maskHeader = require('./constants').maskHeader;
const md5 = require('@/utils/md5');

View File

@@ -86,6 +86,7 @@
"hooman": "1.2.6",
"https-proxy-agent": "5.0.0",
"iconv-lite": "0.6.2",
"ip-regex": "4.2.0",
"is-localhost-ip": "1.4.0",
"jsdom": "16.4.0",
"json-bigint": "1.0.0",

View File

@@ -6525,6 +6525,11 @@ invert-kv@^2.0.0:
resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02"
integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==
ip-regex@4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-4.2.0.tgz#a03f5eb661d9a154e3973a03de8b23dd0ad6892e"
integrity sha512-n5cDDeTWWRwK1EBoWwRti+8nP4NbytBBY0pldmnIkq6Z55KNFmWofh4rl9dPZpj+U/nVq7gweR3ylrvMt4YZ5A==
ip-regex@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9"