-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
09a42d1
commit 0ec79a2
Showing
6 changed files
with
79 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,34 @@ | ||
import { Hono } from 'hono' | ||
import fetch from 'isomorphic-unfetch' | ||
import { env } from 'hono/adapter' | ||
import { StatusCode } from 'hono/utils/http-status' | ||
import { Bindings } from '../types' | ||
import { parseNodeUrls, randomPick } from '@/utils/helper' | ||
|
||
const app = new Hono<{ Bindings: Bindings }>() | ||
|
||
app.get('*', async (c) => { | ||
const { RSSHUB_NODE_URLS } = env(c) | ||
const allNodeUrls = parseNodeUrls(RSSHUB_NODE_URLS) | ||
const path = c.req.path | ||
const query = c.req.query() | ||
// 由于 Cloudflare Workers 的限制,fetch 一次最多并发 6 个,所以最多随机选择 5 个节点。 | ||
// 添加默认节点,官方实例默认为第一个。 | ||
// 随机选择5个节点,不包括默认节点。 | ||
const nodeUrls = ['https://rsshub.app', ...randomPick(allNodeUrls, 5)].map((url) => { | ||
const _url = new URL(url) | ||
_url.pathname = path | ||
_url.search = new URLSearchParams(query).toString() | ||
return _url.toString() | ||
}) | ||
// 并发请求,有一个成功就返回值 | ||
const res = await Promise.any(nodeUrls.map((url) => fetch(url))) | ||
const data = await res.text() | ||
const contentType = res.headers.get('Content-Type') || 'application/xml' | ||
c.header('Content-Type', contentType) | ||
c.status(res.status as StatusCode) | ||
|
||
return c.body(data) | ||
}) | ||
|
||
export default app |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,4 +5,5 @@ export type Bindings = { | |
LOG_LEVEL: string | ||
TIMEOUT: string | ||
MAX_BODY_SIZE: string | ||
RSSHUB_NODE_URLS: string | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
|
||
/** | ||
* 将 RSSHUB_NODE_URLS 解析为数组 | ||
* | ||
* @author CaoMeiYouRen | ||
* @date 2024-10-24 | ||
* @export | ||
* @param value | ||
*/ | ||
export function parseNodeUrls(value: string) { | ||
return [...new Set(value.split(',') | ||
.map((url) => url.trim())), | ||
] // 去重 | ||
.map((url) => new URL(url).toString()) // 格式化 URL | ||
} | ||
|
||
/** | ||
* 从给定的数组中随机挑选五个不重复的项 | ||
* 采用洗牌算法,概率相同 | ||
* | ||
* @author CaoMeiYouRen | ||
* @date 2024-10-24 | ||
* @export | ||
* @template T | ||
* @param array | ||
* @param count | ||
*/ | ||
export function randomPick<T>(array: T[], count: number): T[] { | ||
const shuffled = [...array] | ||
for (let i = shuffled.length - 1; i > 0; i--) { | ||
const j = Math.floor(Math.random() * (i + 1)); | ||
[shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]] | ||
} | ||
return shuffled.slice(0, count) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters