Skip to content

Instantly share code, notes, and snippets.

@fffonion
Last active August 7, 2019 06:02
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save fffonion/9048776 to your computer and use it in GitHub Desktop.
Save fffonion/9048776 to your computer and use it in GitHub Desktop.
Wiki Mirror 维基百科镜像,B64加密超链接防止撞墙 https://wc.yooooo.us ,附apache和nginx配置
  1. 下载base64.js和index.php到同一目录/path/to/code
  2. 下载Apache Config,更名为.htaccess放入第一步的文件夹中;如果使用nginx,修改配置中的root为第一步的文件夹
#Redirect 301 ^/$ /search.htm
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
<FilesMatch ".(gif|jpg|jpeg|png|ico|css|js)$">
Header unset Pragma
Header unset ETag
FileETag None
Header set Cache-Control "max-age=604800"
</FilesMatch>
<ifmodule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/css text/plain text/xml application/x-httpd-php application/x-javascript
</ifmodule>
(function(global){"use strict";var _Base64=global.Base64;var version="2.1.9";var buffer;if(typeof module!=="undefined"&&module.exports){try{buffer=require("buffer").Buffer}catch(err){}}var b64chars="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";var b64tab=function(bin){var t={};for(var i=0,l=bin.length;i<l;i++)t[bin.charAt(i)]=i;return t}(b64chars);var fromCharCode=String.fromCharCode;var cb_utob=function(c){if(c.length<2){var cc=c.charCodeAt(0);return cc<128?c:cc<2048?fromCharCode(192|cc>>>6)+fromCharCode(128|cc&63):fromCharCode(224|cc>>>12&15)+fromCharCode(128|cc>>>6&63)+fromCharCode(128|cc&63)}else{var cc=65536+(c.charCodeAt(0)-55296)*1024+(c.charCodeAt(1)-56320);return fromCharCode(240|cc>>>18&7)+fromCharCode(128|cc>>>12&63)+fromCharCode(128|cc>>>6&63)+fromCharCode(128|cc&63)}};var re_utob=/[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g;var utob=function(u){return u.replace(re_utob,cb_utob)};var cb_encode=function(ccc){var padlen=[0,2,1][ccc.length%3],ord=ccc.charCodeAt(0)<<16|(ccc.length>1?ccc.charCodeAt(1):0)<<8|(ccc.length>2?ccc.charCodeAt(2):0),chars=[b64chars.charAt(ord>>>18),b64chars.charAt(ord>>>12&63),padlen>=2?"=":b64chars.charAt(ord>>>6&63),padlen>=1?"=":b64chars.charAt(ord&63)];return chars.join("")};var btoa=global.btoa?function(b){return global.btoa(b)}:function(b){return b.replace(/[\s\S]{1,3}/g,cb_encode)};var _encode=buffer?function(u){return(u.constructor===buffer.constructor?u:new buffer(u)).toString("base64")}:function(u){return btoa(utob(u))};var encode=function(u,urisafe){return!urisafe?_encode(String(u)):_encode(String(u)).replace(/[+\/]/g,function(m0){return m0=="+"?"-":"_"}).replace(/=/g,"")};var encodeURI=function(u){return encode(u,true)};var re_btou=new RegExp(["[À-ß][-¿]","[à-ï][-¿]{2}","[ð-÷][-¿]{3}"].join("|"),"g");var cb_btou=function(cccc){switch(cccc.length){case 4:var cp=(7&cccc.charCodeAt(0))<<18|(63&cccc.charCodeAt(1))<<12|(63&cccc.charCodeAt(2))<<6|63&cccc.charCodeAt(3),offset=cp-65536;return fromCharCode((offset>>>10)+55296)+fromCharCode((offset&1023)+56320);case 3:return fromCharCode((15&cccc.charCodeAt(0))<<12|(63&cccc.charCodeAt(1))<<6|63&cccc.charCodeAt(2));default:return fromCharCode((31&cccc.charCodeAt(0))<<6|63&cccc.charCodeAt(1))}};var btou=function(b){return b.replace(re_btou,cb_btou)};var cb_decode=function(cccc){var len=cccc.length,padlen=len%4,n=(len>0?b64tab[cccc.charAt(0)]<<18:0)|(len>1?b64tab[cccc.charAt(1)]<<12:0)|(len>2?b64tab[cccc.charAt(2)]<<6:0)|(len>3?b64tab[cccc.charAt(3)]:0),chars=[fromCharCode(n>>>16),fromCharCode(n>>>8&255),fromCharCode(n&255)];chars.length-=[0,0,2,1][padlen];return chars.join("")};var atob=global.atob?function(a){return global.atob(a)}:function(a){return a.replace(/[\s\S]{1,4}/g,cb_decode)};var _decode=buffer?function(a){return(a.constructor===buffer.constructor?a:new buffer(a,"base64")).toString()}:function(a){return btou(atob(a))};var decode=function(a){return _decode(String(a).replace(/[-_]/g,function(m0){return m0=="-"?"+":"/"}).replace(/[^A-Za-z0-9\+\/]/g,""))};var noConflict=function(){var Base64=global.Base64;global.Base64=_Base64;return Base64};global.Base64={VERSION:version,atob:atob,btoa:btoa,fromBase64:decode,toBase64:encode,utob:utob,encode:encode,encodeURI:encodeURI,btou:btou,decode:decode,noConflict:noConflict};if(typeof Object.defineProperty==="function"){var noEnum=function(v){return{value:v,enumerable:false,writable:true,configurable:true}};global.Base64.extendString=function(){Object.defineProperty(String.prototype,"fromBase64",noEnum(function(){return decode(this)}));Object.defineProperty(String.prototype,"toBase64",noEnum(function(urisafe){return encode(this,urisafe)}));Object.defineProperty(String.prototype,"toBase64URI",noEnum(function(){return encode(this,true)}))}}if(global["Meteor"]){Base64=global.Base64}})(this);
<?php
function mobile_check(){
$mobile_browser = false;
$user_agent = $_SERVER['HTTP_USER_AGENT'];
$accept = $_SERVER['HTTP_ACCEPT'];
if(
preg_match('/(acs|alav|alca|amoi|audi|aste|avan|benq|bird|blac|blaz|brew|cell|cldc|cmd-|dang|doco|erics|hipt|inno|ipaq|java|jigs|kddi|keji|leno|lg-c|lg-d|lg-g|lge-|maui|maxo|midp|mits|mmef|mobi|mot-|moto|mwbp|nec-|newt|noki|opwv|palm|pana|pant|pdxg|phil|play|pluc|port|prox|qtek|qwap|sage|sams|sany|sch-|sec-|send|seri|sgh-|shar|sie-|siem|smal|smar|sony|sph-|symb|t-mo|teli|tim-|tosh|tsm-|upg1|upsi|vk-v|voda|w3cs|wap-|wapa|wapi|wapp|wapr|webc|winw|winw|xda|xda-|up.browser|up.link|windowssce|iemobile|mini|mmp|symbian|midp|wap|phone|pocket|mobile|pda|psp)/i',$user_agent) ||
((strpos($accept,'text/vnd.wap.wml')>0)||(strpos($accept,'application/vnd.wap.xhtml+xml')>0))
){
$mobile_browser = true;
}
return $mobile_browser;
}
if(substr($_SERVER['REQUEST_URI'],1,4)!="wiki" and substr($_SERVER['REQUEST_URI'],0,3)!="/w/")
$req_uri = "/".base64_decode(substr($_SERVER['REQUEST_URI'],1));
else
$req_uri = $_SERVER['REQUEST_URI'];
if ($req_uri == "/"){
$req_uri = "/wiki/Wikipedia:%E9%A6%96%E9%A1%B5";
$loc = "zh";
}else{
if(preg_match("/\!([\w\-]+)/", $req_uri, $matches)){
$loc = $matches[1];
$req_uri=str_replace("!".$loc,"",$req_uri);
}else
$loc = "zh";
}
$host = ".wikipedia.org";
if(mobile_check()){
$host = ".m" . $host;
}
$host = $loc. $host;
$real_http_req_url = "https://".$host.$req_uri;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $real_http_req_url);
if($_SERVER['REQUEST_METHOD'] == 'POST'){
curl_setopt($ch, CURLOPT_POST, 1);
$body = @file_get_contents('php://input');
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
}
$headers = array();
foreach ($_SERVER as $k => $v) {
if (substr($k, 0, 5) == "HTTP_") {
$k = str_replace('_', ' ', substr($k, 5));
$k = str_replace(' ', '-', ucwords(strtolower($k)));
if (strtolower($k) == "host")
$v = $host;
else if (strtolower($k) == "referer")
$v = $real_http_req_url;
else if (strtolower($k) == "accept-encoding")
continue;
array_push($headers, $k.": ".$v);
}
}
array_push($headers, "Accept-Encoding: gzip,deflate");
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
//curl_setopt($ch, CURLOPT_VERBOSE, true);
$response = curl_exec($ch);
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$resp_header = substr($response, 0, $header_size);
$body = substr($response, $header_size);
$resp_compress = 0;
$is_html_content = true;
$is_image_content = false;
foreach(explode("\r\n", $resp_header) as $_){
if (strtolower(substr($_, 0, 10)) == "set-cookie") {
header(str_replace(".wikipedia.org",".".$_SERVER['HTTP_HOST'],$_));
} else if(strtolower(substr($_,0,8))=="location"){
preg_match("/([\w\-]+).[m.]*wikipedia.org\/(.+)/i",$_,$_m);
if($_m[1])
header("Location: /".base64_encode($_m[2]."!".$_m[1]), false);
}else if(strtolower(substr($_,0,16))=="content-encoding"){
if(strpos($_, 'gzip'))
$resp_compress = 1;
else if(strpos($_, 'deflate'))
$resp_compress = 2;
}else if(strtolower(substr($_,0,12))=="content-type"){
if(strpos($_, 'text/html') === FALSE){
$is_html_content = false;
if(strpos($_, 'image'))
$is_image_content = true;
}
header($_, false);
}else{
header($_, false);
}
}
curl_close($ch); //get data after login
if($resp_compress >0)
$body = gzdecode($body);
if (!$is_image_content){
//$pattern = "@zh.wikipedia.org/w/load.php\?([^\"]+)@i";
//$body = preg_replace($pattern, $_SERVER['HTTP_HOST'].'/w/load.php?\\1', $body);
$pattern = "@zh.wikipedia.org/([^\"]+)@i";
$body = preg_replace($pattern, $_SERVER['HTTP_HOST'].'/\\1', $body);
}
if (strpos($req_uri, "load.php") === FALSE){
echo $body;
if ($is_html_content){
?>
<script type="text/javascript" src="http://v3.jiathis.com/code/jiathis_r.js?move=0&amp;btn=r3.gif" charset="utf-8"></script>
<script src="/base64.js"></script>
<script type="text/javascript">
var is_http = location.protocol=="http:";
var uri = Base64.decode(document.location.pathname.substr(1));
if(uri.indexOf('!')!=-1){
var loc="!"+uri.substr(uri.indexOf('!')+1);}
else{
var loc="";
}
if(is_http){
var objs=document.getElementsByTagName("a");
for(var i=0;i<objs.length;i++){
if(objs[i].lang=="" && objs[i].href.indexOf(window.location.host)!=-1 && objs[i].href.indexOf('#')==-1){
objs[i].href="/"+Base64.encode(objs[i].href.substring(objs[i].href.indexOf("/wiki/")+1)+loc)
}
};
}
function encode_langlink(n){
return Base64.encode(n.href.substring(n.href.indexOf('wikipedia.org')+14)+'!'+n.hreflang);
}
<?php if(mobile_check()) echo "
var _footer=document.getElementsByClassName('footer-info');
if(_footer)_footer=_footer[0];
if(is_http){
var f=document.forms[1];
var f1=document.forms[2];
var other_lang=$('#mw-mf-language-selection').children();
var zhconv=$('#mw-mf-language-variant-selection').children();
$('#mw-mf-display-toggle').href=
'/'+Base64.encode('/w/index.php?title='+encodeURIComponent($('#section_0').innerHTML)+'&mobileaction=toggle_view_desktop');
}
"; else echo "
var _footer=$('#footer-info-copyright');
if(_footer)_footer=_footer[0];
if(is_http){
var f=$('#searchform');
var f1=$('#search');
var other_lang=$('.interlanguage-link');
var zhconv = $('#p-variants').children('div').find('a');
};
"; ?>
/*var other_lang=document.getElementsByClassName('page-list');other_lang=other_lang[other_lang.length-1].children;if(other_lang){other_lang=other_lang.children;for(var i=0;i<other_lang.length;i++){var n=other_lang[i].children[0];n.href=Base64.encode(n.href.substring(n.href.indexOf('wikipedia.org')+14)+'!'+n.hreflang);}}*/
document.title = document.title.replace('Wikipedia', 'Wikimirror').replace('维基百科,自由的百科全书', '维基百科镜像,不撞墙的百科全书');
if(other_lang){
for(var i=0;i<other_lang.length;i++){
var n=other_lang[i].children[0];
n.href=Base64.encode(n.href.substr(n.href.indexOf('wikipedia.org')+14)+'!'+n.hreflang);
}
}
if(zhconv){
console.log(zhconv);
for(var i=0;i<zhconv.length;i++){
zhconv[i].href = "/"+Base64.encode(zhconv[i].href.replace(location.protocol+"//"+location.host+"/", ""));
}
}
if(_footer) _footer.innerHTML+="<hr><br><b>维基镜像(其实是个反代)的内容完全来自维基百科,在HTTP明文传输时对链接进行了简单加密。</b><br>相关源代码可以从<a href='https://gist.github.com/fffonion/9048776' target='_blank'>这里获得</a> 登陆注册编辑功能目前不可用。";
if(is_http){
f.setAttribute("onsubmit","return b64redirect(true);");
if(f1) f1.setAttribute("onsubmit","return b64redirect(false);");
function b64redirect(isSimple){
if(f.search.value){
if(isSimple)
window.location="/"+Base64.encode("/w/index.php?search="+f.search.value+"&title="+f.title.value+"&go="+f.go.value);
else
window.location="/"+Base64.encode("/w/index.php?search="+f1.search.value+"&profile=default&fulltext=search&title="+f1.title.value);
}
return false;
};//mobile:other-lang-list, search not encoded; goto desktop not functioning
}
</script>
<?php
}
} else {
header("Cache-Control: max-age=3600, must-revalidate");
header("Expires: " . gmdate("D, d M Y H:i:s", time() + 3600) . " GMT");
echo $body;
};?>
server {
include cdn-range.conf;
listen 80;
listen [::]:80;
#if ($time_iso8601 ~ "^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})") {}
access_log /var/log/nginx/wiki_mirror-access.log combined;
error_log /var/log/nginx/wiki_mirror-error.log warn;
root /var/www/wiki-mirror;
index index.php;
server_name wiki.yooooo.us wc.yooooo.us;
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
#gzip_http_version 1.0;
gzip_comp_level 2;
gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
gzip_vary off;
gzip_disable "MSIE [1-6]\.";
rewrite /w/.* /index.php last;
location / {
if ( !-e $request_filename ) {
rewrite . /index.php last;
}
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
#error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
# NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
# With php5-cgi alone:
#fastcgi_pass 127.0.0.1:9000;
# With php5-fpm:
fastcgi_pass phpbackend;
fastcgi_index index.php;
include fastcgi_params;
if ($http_user_agent ~* "bot|spider|Bot") {
access_log /var/log/nginx/wiki_mirror-spider.log;
}
}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
location ~ /\.ht {
deny all;
}
}
@zodiac1111
Copy link

这个很不错,能不能介绍一下怎么用呢.我也想搭建一个类似的网站自己使用.

Copy link

ghost commented Oct 14, 2015

wjbk.org 這個鏡像很棒。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment