记一次Tiny Tiny RSS魔改过程
01 前言
习惯于用Inoreader
订阅RSS
的童鞋都知道,一段时间以来已无法正常使用(当然有特殊手段的除外)了,从而严重影响了正常的阅读计划,原因可能大家都知道。正所谓“自己动手,丰衣足食”,好了,大不了自己搭个服务嘛,正好前段时间整了个自用服务器。
经过查阅资料,确定了Tiny Tiny RSS
(以下简称TTRSS
)和FreshRSS
两款。具体怎么搭不在本文讨论范围内。最后笔者选择了TTRSS
,用docker-compose
搭建好以后,在添加某论坛网站的订阅源时,弹出403
错误,甚是郁闷,而又不想放弃此源,怎么办。一顿苦思——想来只有自己改码源了,于是开始了一波魔改操作。
02 正文
注意:本文测试环境为:CentOS Linux release 8.1.1911 (Core)
整个过程下来,可以分为几步:
(1)测试是否能正常下载
众所周知,一般一个RSS源的链接,可以直接在浏览器中打开看到内容,因而一般也是可以下载的。那么先试一下能不能下载(测试时请将https://XXXXXX?mod=rss
换成具体链接):
curl https://XXXXXX?mod=rss
结果无意外的也是403
错误:
但是呢,在本地Win 10
下也试了一下,却是完全OK的:
又查了一波资料,联想到由于服务器是某云的,是不是IP被目标网址屏蔽了?
(2)使用代理,再测试是否能正常下载
随手找了代理IP,那么再来试一下(测试时请将https://XXXXXX?mod=rss
换成具体链接,将123.123.123.123:8000
换成实际代理的IP和端口号):
curl https://XXXXXX?mod=rss -x 123.123.123.123:8000
结果是,可以下载(乱码不用管):
那么可以确定,通过代理,还是有可能在TTRSS
中将此RSS源订阅成功的。
(3)修改码源
经过一番查阅,得知TTRSS
是用PHP
语言写的,不慌,先找到码源clone
一份下来到本地Win 10
。
git clone https://git.tt-rss.org/fox/tt-rss.git
二话不说,VS Code
开启:
好多文件,看着头大,毕竟不是专业PHP程序员。正考虑从哪入手——嗯,先抓包看一眼:
哦,请求了addfeed
方法。好的,去VS Code
搜索这个字符串,看看在哪出现了……
在 /classes/rpc.php
里面发现了这个方法:
function addfeed() {
$feed = clean($_REQUEST['feed']);
$cat = clean($_REQUEST['cat']);
$need_auth = isset($_REQUEST['need_auth']);
$login = $need_auth ? clean($_REQUEST['login']) : '';
$pass = $need_auth ? trim(clean($_REQUEST['pass'])) : '';
$rc = Feeds::subscribe_to_feed($feed, $cat, $login, $pass);
print json_encode(array("result" => $rc));
}
前面几行看起来是处理参数,然后跟进Feeds::subscribe_to_feed
方法,嗯,这个方法写得有点长:
接下来呢,再回头看一下前面抓包的返回信息,错误码是5
,那么找一下有没有返回5
的地方,果然有:
这里返回错误码5
了,所以往前看看都做了什么,$conten
t是从@fetch_file_contents
方法得到的,那么再跟进@fetch_file_contents
(文件/include/functions.php
中)方法,这个方法写得也挺长:
看下来,需要注意的地方是这个if
:
if (!defined('NO_CURL') && function_exists('curl_init') && !ini_get("open_basedir")) {
//....
}else{
//...
}
这里面应该就是PHP中使用curl
下载指定链接(也就是订阅源的链接)的过程。之所以订阅失败,应该是这里出问题了。前面分析了通过代理是可以进行下载的,那么就是加上代理了。可以看到,这个if
里面是一路下来的,只尝试下载一次,失败就整体失败了,所以的话,给它套一个循环,让它多试一次——第一次失败,再试一次(使用自定义代理)。
所以改成这样了:
//...原来的代码
if (!defined('NO_CURL') && function_exists('curl_init') && !ini_get("open_basedir")) {
$tryTime = 0 ;
while(true){
//...原来的代码
//if (defined('_HTTP_PROXY')) {
// curl_setopt($ch, CURLOPT_PROXY, _HTTP_PROXY);
//} 改成以下:
if($tryTime < 1){
if (defined('_HTTP_PROXY')) {
curl_setopt($ch, CURLOPT_PROXY, _HTTP_PROXY);
}
}else{
//try to set proxy one time
curl_setopt($ch, CURLOPT_PROXY, '123.123.123.123');
curl_setopt($ch, CURLOPT_PROXYPORT, 8000);
curl_setopt($ch, CURLOPT_PROXYTYPE, 0);
}
//...原来的代码
if ($http_code != 200 || $type && strpos($fetch_last_content_type, "$type") === false) {
//...原来的代码
//return false; 改成以下:
if($tryTime < 1){
$tryTime++;
continue;
}else{
return false;
}
}
if (!$contents) {
$fetch_last_error = curl_errno($ch) . " " . curl_error($ch);
curl_close($ch);
//return false; 改成以下:
if($tryTime < 1){
$tryTime++;
continue;
}else{
return false;
}
}
//...原来的代码
}
}else{
//... 原来的代码
}
修改后:
下面这里将前面测试的代理服务器IP和端口号分别填入即可:
curl_setopt($ch, CURLOPT_PROXY, '123.123.123.123');
curl_setopt($ch, CURLOPT_PROXYPORT, 8000);
curl_setopt($ch, CURLOPT_PROXYTYPE, 0); //0表示http代理,一般可以不改
好了,将此修改后的functions.php
文件传到服务器将ttrss
容器里面原来的替换掉,然后重启一下即可。
考虑到可能有些人对Linux
或者docker
不太熟悉的话,还是截个图作为参考(请从第三个ll
命令之后开始看):
注意:使用
docker cp
和docker restart
命令时,容器ID可能是不一样的,请先进行docker ps
后再将ID复制过来用
重启TTRSS容器后,在浏览器重新登录,发现可以正常订阅这个特别的RSS源了,原来的源也不受影响。
03 后记
水平有限,虽然这种改法一时解决了问题,但是万一代理服务器失效,也可能再次订阅不了。有条件的话,可能将其改成代理IP池,应该可以解决这问题。
安卓端APP可以考虑FeedMe
。
安装TTRSS可以参考:
Awesome TTRSS
如果想用笔者搭的服务,可以留言留下用户名和邮箱,虽然服务器配置不高,应该可以用用。
----------END----------