Skip to content

Instantly share code, notes, and snippets.

@fffonion
Last active August 7, 2019 06:02
Show Gist options
  • 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;
}
}
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