From 56f53d15ffc2649a4d9ea9e4da14d8433c791408 Mon Sep 17 00:00:00 2001 From: Michael Reber Date: Tue, 12 Nov 2019 16:59:19 +0100 Subject: [PATCH] Initial commit --- config.php | 57 +++ favicon.ico | Bin 0 -> 106884 bytes index.php | 145 ++++++ language.php | 9 + login.php | 429 +++++++++++++++++ plugins/TestPlugin.php | 25 + plugins/UrlFormPlugin.php | 39 ++ templates/main.php | 84 ++++ templates/proxy.png | Bin 0 -> 12782 bytes templates/tos.php | 30 ++ templates/url_form.php | 80 ++++ vendor/athlon1600/php-proxy-plugin-bundle | 1 + vendor/athlon1600/php-proxy/.gitignore | 3 + vendor/athlon1600/php-proxy/LICENSE | 21 + vendor/athlon1600/php-proxy/README.md | 99 ++++ vendor/athlon1600/php-proxy/composer.json | 21 + vendor/athlon1600/php-proxy/src/Config.php | 39 ++ .../php-proxy/src/Event/ProxyEvent.php | 39 ++ vendor/athlon1600/php-proxy/src/Html.php | 182 ++++++++ .../php-proxy/src/Http/ParamStore.php | 84 ++++ .../athlon1600/php-proxy/src/Http/Request.php | 362 ++++++++++++++ .../php-proxy/src/Http/Response.php | 120 +++++ .../php-proxy/src/Plugin/AbstractPlugin.php | 80 ++++ .../php-proxy/src/Plugin/BlockListPlugin.php | 57 +++ .../php-proxy/src/Plugin/CookiePlugin.php | 132 ++++++ .../src/Plugin/HeaderRewritePlugin.php | 69 +++ .../php-proxy/src/Plugin/ProxifyPlugin.php | 185 ++++++++ .../php-proxy/src/Plugin/StreamPlugin.php | 57 +++ vendor/athlon1600/php-proxy/src/Proxy.php | 168 +++++++ vendor/athlon1600/php-proxy/src/Redis.php | 30 ++ vendor/athlon1600/php-proxy/src/helpers.php | 199 ++++++++ vendor/athlon1600/youtube-downloader/LICENSE | 21 + .../athlon1600/youtube-downloader/README.md | 81 ++++ .../youtube-downloader/composer.json | 14 + .../src/YouTubeDownloader.php | 388 +++++++++++++++ vendor/autoload.php | 7 + vendor/composer/ClassLoader.php | 413 ++++++++++++++++ vendor/composer/LICENSE | 21 + vendor/composer/autoload_classmap.php | 9 + vendor/composer/autoload_files.php | 12 + vendor/composer/autoload_namespaces.php | 9 + vendor/composer/autoload_psr4.php | 12 + vendor/composer/autoload_real.php | 59 +++ vendor/composer/installed.json | 182 ++++++++ vendor/symfony/event-dispatcher/.gitignore | 3 + vendor/symfony/event-dispatcher/CHANGELOG.md | 37 ++ .../ContainerAwareEventDispatcher.php | 211 +++++++++ .../Debug/TraceableEventDispatcher.php | 324 +++++++++++++ .../TraceableEventDispatcherInterface.php | 34 ++ .../Debug/WrappedListener.php | 116 +++++ .../RegisterListenersPass.php | 135 ++++++ vendor/symfony/event-dispatcher/Event.php | 58 +++ .../event-dispatcher/EventDispatcher.php | 236 ++++++++++ .../EventDispatcherInterface.php | 100 ++++ .../EventSubscriberInterface.php | 46 ++ .../symfony/event-dispatcher/GenericEvent.php | 186 ++++++++ .../ImmutableEventDispatcher.php | 101 ++++ vendor/symfony/event-dispatcher/LICENSE | 19 + vendor/symfony/event-dispatcher/README.md | 15 + .../Tests/AbstractEventDispatcherTest.php | 442 ++++++++++++++++++ .../ContainerAwareEventDispatcherTest.php | 210 +++++++++ .../Debug/TraceableEventDispatcherTest.php | 242 ++++++++++ .../RegisterListenersPassTest.php | 167 +++++++ .../Tests/EventDispatcherTest.php | 22 + .../event-dispatcher/Tests/EventTest.php | 55 +++ .../Tests/GenericEventTest.php | 140 ++++++ .../Tests/ImmutableEventDispatcherTest.php | 106 +++++ vendor/symfony/event-dispatcher/composer.json | 47 ++ .../symfony/event-dispatcher/phpunit.xml.dist | 31 ++ 69 files changed, 7157 insertions(+) create mode 100644 config.php create mode 100644 favicon.ico create mode 100644 index.php create mode 100644 language.php create mode 100644 login.php create mode 100644 plugins/TestPlugin.php create mode 100644 plugins/UrlFormPlugin.php create mode 100644 templates/main.php create mode 100644 templates/proxy.png create mode 100644 templates/tos.php create mode 100644 templates/url_form.php create mode 160000 vendor/athlon1600/php-proxy-plugin-bundle create mode 100644 vendor/athlon1600/php-proxy/.gitignore create mode 100644 vendor/athlon1600/php-proxy/LICENSE create mode 100644 vendor/athlon1600/php-proxy/README.md create mode 100644 vendor/athlon1600/php-proxy/composer.json create mode 100644 vendor/athlon1600/php-proxy/src/Config.php create mode 100644 vendor/athlon1600/php-proxy/src/Event/ProxyEvent.php create mode 100644 vendor/athlon1600/php-proxy/src/Html.php create mode 100644 vendor/athlon1600/php-proxy/src/Http/ParamStore.php create mode 100644 vendor/athlon1600/php-proxy/src/Http/Request.php create mode 100644 vendor/athlon1600/php-proxy/src/Http/Response.php create mode 100644 vendor/athlon1600/php-proxy/src/Plugin/AbstractPlugin.php create mode 100644 vendor/athlon1600/php-proxy/src/Plugin/BlockListPlugin.php create mode 100644 vendor/athlon1600/php-proxy/src/Plugin/CookiePlugin.php create mode 100644 vendor/athlon1600/php-proxy/src/Plugin/HeaderRewritePlugin.php create mode 100644 vendor/athlon1600/php-proxy/src/Plugin/ProxifyPlugin.php create mode 100644 vendor/athlon1600/php-proxy/src/Plugin/StreamPlugin.php create mode 100644 vendor/athlon1600/php-proxy/src/Proxy.php create mode 100644 vendor/athlon1600/php-proxy/src/Redis.php create mode 100644 vendor/athlon1600/php-proxy/src/helpers.php create mode 100644 vendor/athlon1600/youtube-downloader/LICENSE create mode 100644 vendor/athlon1600/youtube-downloader/README.md create mode 100644 vendor/athlon1600/youtube-downloader/composer.json create mode 100644 vendor/athlon1600/youtube-downloader/src/YouTubeDownloader.php create mode 100644 vendor/autoload.php create mode 100644 vendor/composer/ClassLoader.php create mode 100644 vendor/composer/LICENSE create mode 100644 vendor/composer/autoload_classmap.php create mode 100644 vendor/composer/autoload_files.php create mode 100644 vendor/composer/autoload_namespaces.php create mode 100644 vendor/composer/autoload_psr4.php create mode 100644 vendor/composer/autoload_real.php create mode 100644 vendor/composer/installed.json create mode 100644 vendor/symfony/event-dispatcher/.gitignore create mode 100644 vendor/symfony/event-dispatcher/CHANGELOG.md create mode 100644 vendor/symfony/event-dispatcher/ContainerAwareEventDispatcher.php create mode 100644 vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php create mode 100644 vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcherInterface.php create mode 100644 vendor/symfony/event-dispatcher/Debug/WrappedListener.php create mode 100644 vendor/symfony/event-dispatcher/DependencyInjection/RegisterListenersPass.php create mode 100644 vendor/symfony/event-dispatcher/Event.php create mode 100644 vendor/symfony/event-dispatcher/EventDispatcher.php create mode 100644 vendor/symfony/event-dispatcher/EventDispatcherInterface.php create mode 100644 vendor/symfony/event-dispatcher/EventSubscriberInterface.php create mode 100644 vendor/symfony/event-dispatcher/GenericEvent.php create mode 100644 vendor/symfony/event-dispatcher/ImmutableEventDispatcher.php create mode 100644 vendor/symfony/event-dispatcher/LICENSE create mode 100644 vendor/symfony/event-dispatcher/README.md create mode 100644 vendor/symfony/event-dispatcher/Tests/AbstractEventDispatcherTest.php create mode 100644 vendor/symfony/event-dispatcher/Tests/ContainerAwareEventDispatcherTest.php create mode 100644 vendor/symfony/event-dispatcher/Tests/Debug/TraceableEventDispatcherTest.php create mode 100644 vendor/symfony/event-dispatcher/Tests/DependencyInjection/RegisterListenersPassTest.php create mode 100644 vendor/symfony/event-dispatcher/Tests/EventDispatcherTest.php create mode 100644 vendor/symfony/event-dispatcher/Tests/EventTest.php create mode 100644 vendor/symfony/event-dispatcher/Tests/GenericEventTest.php create mode 100644 vendor/symfony/event-dispatcher/Tests/ImmutableEventDispatcherTest.php create mode 100644 vendor/symfony/event-dispatcher/composer.json create mode 100644 vendor/symfony/event-dispatcher/phpunit.xml.dist diff --git a/config.php b/config.php new file mode 100644 index 0000000..96c2718 --- /dev/null +++ b/config.php @@ -0,0 +1,57 @@ + '', + // CURLOPT_CONNECTTIMEOUT => 5 +); + +//$config['replace_title'] = 'Google Search'; + +//$config['error_redirect'] = "https://unblockvideos.com/#error={error_msg}"; +//$config['index_redirect'] = 'https://unblockvideos.com/'; + +// $config['replace_icon'] = 'icon_url'; + +// this better be here other Config::load fails +return $config; + +?> \ No newline at end of file diff --git a/favicon.ico b/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..990f029ee4dc0c2b1420c9526bdd6e72c7fef198 GIT binary patch literal 106884 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 kHOgMGCuV4<|v(}ZE^Orz=nuILRN=y9E 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 Proxy::VERSION + )); + } else { + echo render_template("./templates/main.php", array('version' => Proxy::VERSION)); + } + + } + + exit; +} + +// decode q parameter to get the real URL +$url = url_decrypt($_GET['q']); + +$proxy = new Proxy(); + +// load plugins +foreach (Config::get('plugins', array()) as $plugin) { + + $plugin_class = $plugin . 'Plugin'; + + if (file_exists('./plugins/' . $plugin_class . '.php')) { + + // use user plugin from /plugins/ + require_once('./plugins/' . $plugin_class . '.php'); + + } else if (class_exists('\\Proxy\\Plugin\\' . $plugin_class)) { + + // does the native plugin from php-proxy package with such name exist? + $plugin_class = '\\Proxy\\Plugin\\' . $plugin_class; + } + + // otherwise plugin_class better be loaded already through composer.json and match namespace exactly \\Vendor\\Plugin\\SuperPlugin + $proxy->getEventDispatcher()->addSubscriber(new $plugin_class()); +} + +try { + + // request sent to index.php + $request = Request::createFromGlobals(); + + // remove all GET parameters such as ?q= + $request->get->clear(); + + // forward it to some other URL + $response = $proxy->forward($request, $url); + + // if that was a streaming response, then everything was already sent and script will be killed before it even reaches this line + $response->send(); + +} catch (Exception $ex) { + + // if the site is on server2.proxy.com then you may wish to redirect it back to proxy.com + if (Config::get("error_redirect")) { + + $url = render_string(Config::get("error_redirect"), array( + 'error_msg' => rawurlencode($ex->getMessage()) + )); + + // Cannot modify header information - headers already sent + header("HTTP/1.1 302 Found"); + header("Location: {$url}"); + + } else { + + echo render_template("./templates/main.php", array( + 'url' => $url, + 'error_msg' => $ex->getMessage(), + 'version' => Proxy::VERSION + )); + + } +} + +?> \ No newline at end of file diff --git a/language.php b/language.php new file mode 100644 index 0000000..70a0a36 --- /dev/null +++ b/language.php @@ -0,0 +1,9 @@ + + + + + + Please authenticate! + + + + + + + + + + + +
+ + +
+ + + + + + + +$val) { + $lp = (USE_USERNAME ? $key : '') .'%'.$val; + if ($_COOKIE['verify'] == md5($lp)) { + $found = true; + // prolong timeout + if (TIMEOUT_CHECK_ACTIVITY) { + setcookie("verify", md5($lp), $timeout, '/'); + } + break; + } + } + if (!$found) { + showLoginPasswordProtect(""); + } +} +?> \ No newline at end of file diff --git a/plugins/TestPlugin.php b/plugins/TestPlugin.php new file mode 100644 index 0000000..5259bf1 --- /dev/null +++ b/plugins/TestPlugin.php @@ -0,0 +1,25 @@ + \ No newline at end of file diff --git a/plugins/UrlFormPlugin.php b/plugins/UrlFormPlugin.php new file mode 100644 index 0000000..800fc88 --- /dev/null +++ b/plugins/UrlFormPlugin.php @@ -0,0 +1,39 @@ +getUri(); + + // we attach url_form only if this is a html response + if(!is_html($response->headers->get('content-type'))){ + return; + } + + // this path would be relative to index.php that included it? + $url_form = render_template("./templates/url_form.php", array( + 'url' => $url + )); + + $output = $response->getContent(); + + // does the html page contain tag, if so insert our form right after tag starts + $output = preg_replace('@@is', '$0'.PHP_EOL.$url_form, $output, 1, $count); + + // tag was not found, just put the form at the top of the page + if($count == 0){ + $output = $url_form.$output; + } + + $response->setContent($output); + } +} + +?> \ No newline at end of file diff --git a/templates/main.php b/templates/main.php new file mode 100644 index 0000000..50d759d --- /dev/null +++ b/templates/main.php @@ -0,0 +1,84 @@ + + + + + <?php echo $config['website-name']; ?> + + "> + + + + + + +
+
+
+ + + +
+

+

+ +
+
+
+ + Google +
+

+

+ +
+ "/> +
+
+
+

+ + +

+
+
+
+ + +
+ + \ No newline at end of file diff --git a/templates/proxy.png b/templates/proxy.png new file mode 100644 index 0000000000000000000000000000000000000000..6619d925cf51beb6d18fe52bc5dcb4bafe089dd2 GIT binary patch literal 12782 zcmeHt_cvT$)c%{V4Ivmp)aae)y+@ZQqlFNO-plBsccP9&5WPn?L<_=* znh0K>_lNI4@qO=Fcb&cWIrpq}_I>Wz`=0&0)lgF)A*3e+0FWpt%4q=ry%C`RA9mAx zDZbl()4)7sm2~j&@fTLrF*hoKyP}~d09qgayCLq~+Lkv)Ixl$xFKstlFJB7}8{q5f z%je+g#@Gyeas|MS5ApB^A$Z(hAw`L&mpnl^wy zVK}&OJbVH|B4QF!GI9z^s$0~zX=v%_8SXGLF|)9;vERLSpM&!O7dHtEX>ZXk={i!qm*%!qUpx#@5c> z!O_Xt#nsLIrH7}Nw~w!%|Et#lfkDB@kkGL3h&Pc@Z=+-0#lHU#7oU)rl$?^9mY$KB zm7SA|%F8b(EGjN3{a99BQCU@8Q(ITx(Ad=6@~O40y`!@W-TnDX&)43*{%-?=L&GDZ zW8)K(Q`0lwXXoY@7MGS+Fso}n);Bh{wtw#I?)}<7z#jfSIzBl)JOA_d;@{=fF8-Vd z0KB?Naxyx8^S`o*OmuZ;&}SVqd@T6Cu^}jEu>o9aQirE;YATCIWVmi@$kb|Hf6l77 zA;b2!z?_bnjct*3ev01hVm)z!HE!mpjN&(JocN*btDhyA#cc@}+h&%xvI0k~s{j7s zKIqu3=$N^#xLjV4Rb_|dS>$o^>Sk|h>cllDPi=_+mxl6bBF#78@ z?y(~kH6t~(A$#GDjI*<-!M5&vkK7C5j^`;Ubt`-WwSo|2P>(d9l$2Ce zdIDFG)lY8^6G~v;E-c`kcR*R7m!~XrT2yi%{Sb^5;+*_S9b-p+2@`BCD%|rW1Pymx zs3`xwaN9UXuQenkF>XKsNtB3Go|$YRN6y}CVnRX&2f!9Kw7bm4nSU^ftL1w<%?hyn zAh{^TU;P`_W1KZ?5dYa{1VMgY6aAah zz1(`}xLl?_i313gw?0yZz3sgFBg`g3E{bwZLO_0^K!<1dp&&Bglk3i9cdN}=Dp|@V z5m;~kXH{~4TOv@m(y+mh64WTQ{e0UkckOY!M5Zh!ul7(f<+~z0KK~O1TTaqjhw~2! z@r8dA#VB;zXE_+-h&fi4xaNTvL6Egk3+tz4iD3Cy01_UlOVXOpPNke|=4(Na5)PN2 zpZYxg?rOKi%R>WN5>iGb*PPDbYWrDdTsRj>32a3r`6Uo3Za22x{o=cpO2g> zUO5|n6Sz`{SqwJyO3LMx)J~YEs8`wjkp1tO)rYR-*gfy-j;QqYll=)LR$72x8+(zS>Ci^0N`J*< z{OQm6MR#g$Gz_H%4;~$EPj*qI4Z0Tft2`@xG5#ZZD<4wI?j_I5L8W3lJ9PWnBE8+T zdaB$vK@%Vpzw4Ol?eE!^VVey`25bEjcN%L;0ZWRKe-?3N`hi={xw=#z_r*hJcRgB0 z5H4)oU(VEj$29@#yV$dPvNF@LI_UsmDZF@OdV0T6Q0Bbj+UVQvNpNFr3biEYIpwOp zt06Xx4TB#3TzqB#7je9a=i$Tyt2QUWv68%&{?Xre9|nF8<-`LHhl~%~M%9Jg|FH*S zHlFpV>VHZi0hZ}MF*X;3U({khBz`|HQT*~)v{g8i0?4`!X?~r0wm!xCCX1BRB;_v5 zWs4>Z%dkg!GFRMwx$yUnY;d#n7>(daLhS6hI`fZ?tIG}IOI^MlL`r_wWunAbnh;>^ zmd<-_pe)XlFuABCIp5Zu45l$}eZ)_-~ak-EA112KpiRc@d-qoS1BYA0UL71oL5 zcjRc}R+DDXDPg_c;f^6W%SnWR+V+sfeBq}3U767w+lOawHhbS*yPwXi#7FXVj&{C| zU-2CQ&hfZ_Rj7t2?bLK}ZS81`Vl&@v$vzHiY-VA4(&#x<^lV4g`CkdSH-tsICc@C~ z7vus_cM-<~=XyCV$2^kv@T`^L+jlM1HuAs`gqL6`b{`tGH` z)8#7iKLvDhfuNsw4}Ha~64Z82pepF`n9{*vaC>y+`nTHPZLIRsEBpJa5Rm>>m}7YN z!%EM6p(<+n@?Gpj@WAXb!^@(S$Ngp{Mei8(62$NrW#>{pqY=aoo4~wOUl`Ux=cIKmuneSG8kHtl!vA9UNjWx8h`?}_& z|1@z`dP)7qkTG83h<{C1Pvz@1x+>5s?D@Aqp*rqBgCR-q+@UdiD`2&xU8W8gcv+@+UZZA@#|w?yV%zu0&*^~BP~ckKaC^qs1!CgBSTTrxFM*IlW+ zJRi;HP4et4|6)O<*%h4RM+$y(4)n;;bTy5ZFw#|ISDc)Wmc(}Lij2wF33REm<=`Oi zS~x#h7@8h+dn|v^sygX)UU@Ly8>}0pVspgbCA~OR4}>M()p~Reu0&SkpUe``zwe^? zg*AJb?_?v8)+s0dH4XT z)dc6#Y16aFh)d4Y&gmf^(U9+C1(qa-PXJED<@5dG+jiP~v=@qr9E5)~dau(K4qp@5 zE;pc(Zv*=Xy0gWN)5>3-?-BsXCOD{mFo@|q@p<^H4<{cN^y9p%Bx`X~36k6Dh{%ZP za>3Pw5cYxTZ%W==Ko=l%p>t>(S}Vejcf{1K4x0mHZLT!!8;{I%%D@x^=n@RUlf1;0 zH$KnJLy=Y2*V?qGDx0^;)JSoF;tCPmJ{=p&EzLTAm$G&ZPyU&UqzMZ|>EWU%L8&r^ zs)pfGAen)AQtjXMGm$g`GMlf{Wx9}3Tu@Bueu^{wL|sS}qdKMh&kXf8__1ZVO5L8G zh#TmK;U@-%Pru_UNT;JOi9MH=Y1})58?2JxOFp>m0x?&Tp^X)z=~Q?$Y-#blf~+Oc z_OefEsCzq#A|j(o&KSg1MUA(g;7i80Jy;1K#)PEQ?;43jKnN5x=ZDH+sjmYeJZ6i{t<3YM4}O%HRV^ z$Ml0e!Jq+60X?u5{EXLOY&gwmq8PEtVZ6^2p&fFVtK{bvNj}wg}Sl z#bx9Tj4TO%%r=T8XJa1OxcKJF-#~NL%g!#VjP#a-!jl%cZTa?O<1caIsoky1_vUes z?L-S#bXvOD;6s?~4@v6l*N2Dd-OC^RNES22nagy6>}n#blLVW$$XvLOYfC@hdI8OF{Y*L*?^!R)?LxcO69UET>^$#w;lZO|%s0_2=~yaLzrEcFeC_gIO|9 zjA8;TiRjR*!o8t47H%d?AA|nAX06s3evi_5La&p)QAq~c>(Tk|inIM>_->DAUkZN% z>vX7%sa;*sFmXHbK!6lmb{DD~$mx%7cAJKq6O52@ocPQhUe*!hOROB847Si~@T%#=>>zxk0;d2ExH>7I*%p%SrnF(b+Gmynh zjFr^i%{uTcZ&96%HYsihyR!H6^Pe-8lfHpJdTmjma+2&ZFShj+coI|360@38a5C^c zBL@e#jyt3D>2o4Hf`1J=ew8L|Hp_cwG3_JPa$7idn*jKkmOlzLb?{wWUZoO_+2rh< zsff{Rj1hh*8aRF*$csR_Q5%PHT6JUK^K3!Z=8)?Mc~P+$!@cTiVhmZ% zb$WOH>BAOfR4VO&qW`b+`EPdCM2SvyZi6>kLx`lL3ZaU$$h= z#uxy04PK0Ur?W*jbd;O<`ei9zt~Gs3Qz-jV+uLQpg5e3`n{=9|^k#S+v1TkEs<{P{ zd@Qu2aCH8aUIFAm0&RC;GtmxHHgggj^K^i|*(QPBbZPeE=nl~^joA0@(}V@~F1-}s zH=Rx$v!O_&m0G+wO_{2IbE*6{E5m8LP~*>dJJg`&VBLJg#Y#ZH-#Fd!$vgiU!IL+% z!HwJ0fT$(ZhppbV$HFM#Y5azTOcWJ=QQ{uE$RO*|C}jr}RHOc6N%C+^JEy*QaNR=; zsk3vC@T$}ER=I?ZQ5wl=?+jMFX0b(RgjAU;3<;t{XHUo?ynqA->O2nv)Uf zKrW4GjGro8q7S)kWM*Rw?9MD$VyW=dW>$zzNZyl&R|op`mE_mAcM!D5)0r}?f4 z9TPon;3{{%6J)sS>6_o5j429wDLjUnS#2RImg`Se$x$8mbylOWl~6^_hULqeJHG^? zyff-t)3d|vAy4jZL2BbphvilPIx|P&+xQjvo!qjfJzb=zrL^t5Riq5qr2X`mHVq`P>yc9n5IXz@l>Lxq;E&kF|lJ2rPZOvz!fQ zR%CHN4b`IZ>7AB`qA|};grbxX(*7eM6IM;~hkowWP@cIRJ7kbcf=Rhgvi*;7J?x-&*~CRr_m)Al(|_+4~zfb)Gsf(+i0td zPKR~di13*o>#Y?8h_&cLdhqD0jMIObK`a*VbTFq>z1)#v1+ABYD5fA-B z2JZywMHGN>F$`C2s}9L=&lLbIWLzbSmF*PRXYsfVE=cLGWlOl>7t$hS%&)&GbXICM zvPbO@syRF(Ku@9uD*WYaK+`RH81geO7Ywm!BeR0NfTjHZ=C zg%T%7EQV|os?}>dnBeMh8QXjq_X=a8D0;^KWDL%tsiD;NEie=}OE>ZUq&4ysGks?w zv98Y^)svdzkVG7pUgg7x#P8F-O$c&uQn`X!vr9>k7LGUnlXVc51?h;+mrK}QPX()B zx>uC#0k+yX&Y9OZs&}2gX|msbx@2Z;&|n%H*|bkKwQ4pPBuC`#HWG}7g7_U$v-S8* zl-H_!r_YQ#Gi73Fw?Q15#X7?l$F;-;qXflo5ukNext~Ul!df07js;@eQ&>0LIdtG@ zY-?^BZ#(EF@sEw}XCR+ZUpUIaY3G#12IPhj<@V5wHo935&X9l~;lb}7{&=AesjU0T zk2>7gS;dsINj>XX!I}6NqXOiZ(E;A*WL-oil_hT+-Cd!1d3cL)&&n-I?*bywi@%cg zwD*xIZusWgN2ou4A^JT5QBhrne<7N&P<~avULL^;0l@P#!fJ@^3xgBvc#+`WPV$Fa zuL6e1_NCP`QI>OwODo0x_ASw)R}~*FZnEmCv9S9P8p)&xz00dy({p;32imMh;?UfK zQ5^yNX>^~X)N5&gOw}S&hXQPugVh%<&}#j=`Kj_BNGlpc^QEcNMjXx?$&&C!)EO3z z*y_B`y%|Xh0hv}3AUz?`l9%CQ$wZe$W>J#LQ2CJ;@Sh z9%lR!Y$n8)gSYx{0Gl~;1SlMhtN{|FwoNZCYVVdP(27|KW}10Rh$JC(1+*=2Kvcp4 z-jkqd{=UFPNC!O!2Z|6R_uJ#mW&Cqy5QL7!oewg(3`T&SP9&v5MsLr6DPGQ}slLBBK8R`Rh4iw(UL;7F#dypn0 zWK>YVyyV7;7r&|a42~Fx-?+my7cmN4kgxMS)em8qTLKMPYj_B~s*BM!zZYETC8;X$L{=L77A%~>3B;C^#} zwsbNR15BJ&Z**Ot4v=GizM9~$MBC$oc!-!Spp1o}KPf0B?sY?fFQv2oZ;Q4NmlRD} zP)Gfun1sY9_mMb2K=M9Pia!|a1%O9R$EV&$2y^853=fl~iZ}j^09O!M2XJI1X$oK( zcPC|{q2$BTFtEX0ee>k>20avG3CDLRV+F*y0L|usi%NE51e$WdTo3TLG{O;ihY-#w za^M{cxTkQ)>Ck98)c!9#A@m%fJTD<7==UHm(#c9DL4LMtddr1$q6WUOim`1WGav`Y z5FvKOfh;cA#AQ)+0#RJZhaj)Vk%*EG-A;!hMViL|bUX0FHO!k-5|XDj$8aITWx*}( z3pJyRXkyIOkK%#lWkdYz+jx+;BIlnl9w@+26KI^iG}M6OLj;kZ0mx0IXGUtJ^W`U5 zrt2a<_xZ?fVIIFDLq08z;Ve?MrPdgs22?%FJcXY@(k>SaADr7E$$4#%jzU1AvXXdA z&Kd~WA@A$8rGV1gz#Wbzg|N_v^j1Ol<_ADNAto0RAjdv7M2A+e2IFw@SOmKr7{?d( zhjY@11pMN2p{tKpv9sHg+6t%62ZY{^lZZ*sA$7_kT< z(}fTrO#my{9SSm2tANHin$kYjA?^@@pYW4SnE+V^P$cAe6_4+sw}#)5A%y;OCVn~{ zi`Ja>pyMD8*q7!j*FAPfQA`K3$sGff;tgE0=KyEWgS@h#Zg3Abu4#bY%hVbelIBx$ z2H?*8=Bfg>h(L=iU0UHd9i@JI90poCfHwKI|BjAv~k>FyQ zc!*+qSXwhloFN|Ys*KC+2Y-h_kOeJF;u^tvBWhIfJ_0mB4nQ=^HVTS^N^9|` zVE8twRNf!GwfYQ?#iTfFyD*HBjzvc)rYwY7u`-qvXrMi#U5W5@* z=>v`JD?GF&1ZfC4KMAHo=>T&zphj(qgAiu{{2butIvcqAy}8hR>NE0z`zUytVyxmvrZr0I|rsQK|NaTAu1A#!-*VmKvhvOqT5d7ZG;oJ1)BH>jqYuW#uMlUbf;Jsr&sidMTdU^GLLV&PPAc&r3M(y?EJY>hg{l!SK*W;M26rG$_-DG>O(YYQ_UFNhc5egFJl>kuT$zw3S>!crg^dp@Q*luK*{A>YyhYE$0R`9 z;0Z&cE77#BU=~jcilyRbUe86PxyVNpyWjwMZXH)Ud#Fad?X?jZQb>ax(JhWi>j!0` z5R`i*`w3uKaVVy^iJk6?iJ$@&G=49O25b(40SGzi(297c8$i%|34bMzha4wDQ06YY zt^hH7wzvaOWk+rnQ|Hatt!X$iG&$f;*Hv2Xm21Pr3NaJPAP6eO>@D||1sr8SU^)Rl z3jG4nk^%fp1c<9y$=m7j;c0Sp*DZ>h9@Gdm8~naB`6~NEV}?s(R$Cm5#42rK)Q^j2 z5XA@7RRWRDyso#9JF%ZdHscx#H9^1f>don0!%p<|r{Clh*X{Q|OW2k|{(kBQHY@mB zX)*~>M4+E=^$t~(XR-=NPziti?qTL=3l8cx_bOB3G|-2!>;S5$A4HHMOyk?IOL7cgt-pVjIr(I-P@=zf;(O&Q&}48A-nY`f+Ou(tl@ z^20q7((ejE=574=yMSiM`6i;}_pOEP-fgHZaLAxy`DbnLr?cB*^{*~?V92*aCTiY$I03N*bxt4LlQcI9-f%!fJowAK!?8(*8OT^&$X)(Ev-5$t-(M-uYh5suqoDtg5X{Lz9(IFR`iFKNuUDfs`X0~4c%d~Rz zTV3XFX5I=e>wUVgvVV1yaIcPe{8Vk5VS4548Y3n}FU%s%?1uxqPq})`Q=k8zQ2e_h^w-wW?kVT`kHDqGBvM(_HaV59r z9`!x_5XG+yk9wm_|L}t1fjK&XKnfPOCXb=ISbFe%^Aa7~Xx*Yo3C5r-c4vcupR+H~ z)k6hZw1y;<-m@xI)7&8(6#~leS#V3|w92IVi+PI=MFufK?Oq7kuk)JuSfuf#l(1K6;=VO5JdGLnPV3M`4>FEH)nU?CHiHXKKw8euJ*LZ9$+EsUBm0RiWDU z!8)^m;wJB^+hB@0bN0k?yUk2+F%p*`1wRcR7olPAY1v=~d1sy-A;+$KlO%EN(A?caSGtb*w$)o23>>4so5of!CT9b>^ds6o0<#=k8B-;^B*&}FxD{E`&!iG3RaVmR{=amrJSA))YKuen9y{4v+-iEQo21kHRdKa@sZqaK1~-OIvNB%4d zk>@=Il?$O6EDF~VHS5f^dqqe+xkwUL@sx}8+bgj>SB!^6C64R2S@~(Y=N_GYZ@?8! zZB*`~LwgW&W+h(Anl3z&Gf$xA?0Fis)&J9}7+O{?dqRX}>35Tu^_KpCAM?Wqm(XG< z#!rj-VgQ*QK!fX!ixDby4z|%_jC9EAC{la?x70#2xowsaYjvnM104O*Cib4!WNe&U zvPlp69El-&gI~}hza)<_pha}AEvFYJ zL-4;nTvn#GCWSY{q~6U_u?$Ca{>8z-r*G^0xr3II`?S;;V#hz4*;l%hLE_MPcv!K{h6z=cwh% zvzZ`@IE*tf&ug!%)9l*|?YABj6CbJ0yr`m!TQhux0~YIo(=-p2Re4Cc+UrjphMpSs ziR8fARBm5F#t4pQVw|I|qu++t=hhu^G%c0()eXBgdzZCeqp1Lzq>=W1M?qGaV!J|8 z%Dzb2R*K1J;hn76D;;0p7nW%69Jyy=7W($7THG4Iv@%V+EdH4JAZ|X|_7w~~xrKNY zF7LAaQit{#H*@d=&e`^Jp1=j$u{HmnnjH|ZKU;1|S9&%dP8ce#56EOBGhHyJp43~< zC7}q0n(`4Z=!C2eel)u-1UwmCO{mFY#Br00oumN|KPD70_sW}Rh#zuTd@AkJUy-Yx z4-8t$bO#$+3Qq#>Z=Hb^rmn8X3ah6=%!-J22_#}}NS@J|U)Dm)0QD*BO0_JD_M5(bn|R=n# z%zG=tff;#?9xVCzUWZ^g%*)3{{qytN<^;3y)B=A0)R%X`N%uUw z>e=O}&|QE%m|BLDJ!}{g2h3ljKE>X|8=s1jRPvk&Ek6e;gq$|OrIK=N%b*Z29o*TnDS~-p9o_kG5VrL6#Lr#G6>OjZgX|W zadk1iS*h?{y%H@XQh1jHHU`h(t+tO~qBZ{DgB35w11!Hr^GQ^njcT^z+O<{9sk(5B0$g=ICj8k`1SQ+@b$WY1k>)qg~oPr>NG>;gr$bbf^UQ(2Z++4qSn zP>~Hp`aucfB?6>FbS0~mKs$M&Pyh3(=38r*e;YV{sJDx*@p`Mue0(Rr7)F~X4{{Lg zmD!pZ#bQ{~z*IlIP*RLb@@D=kZl&lBMH7hqdp{?At6PR!S}nqJn-)N^P3YEURWC7N zFKb51Wg{NQKjHH3BfhRIcHdqGYcGHPSMK8*lI?zIA^Ez(2!@haTjv{^TUu@7T=eG( zwMSgZX<8{6zA%rFq2@G4a%H%YWL5biGBfoQXxyC?1c$0##k~& zU-IYQ26b@uBHzdPX=;^IYQT`2Y5wE-c~{3l^kg&3PlfLveZ=R)q4Z1CcGQJB0wir~ zf*MTn^e{sB%2SOsBQaQ;f`!++%j6uQRHTf+1OnQAu2!HMPIx=_f}TNJk9ixqE_c=C=6e_7{S_~#@5hoaq+cWzce*Ts<#?DE^%i4)~9OmY&b=R1y! z6bH2ds11o%5myEN(S>FXE+&_jA;yF+>Q0*c&#D1wirB%s1MpZKi9TKWU}BMc@(m^M z4CNO*^tJkzr{jZc-A8Hmru$XJm2jW7QdZv5?3W82l6VLlN2i|KG;J~xzlu+${@~=p z=rm=Fs|0C$IePRggD&6nfttM2ecj$iSGx)W_Ln+iiQBU9TN5d&MhoXbZ)r57J14aP ziVy28;5g~S+nA{4b6-5(>4P>+Re+wAgkp!r7JI7C88NWZAVGG-lKB1^<|^?SA6=Cb zov>u^J}exnjpf`4an!O^cm+i=mD0`#`*i-CReg0G@Jrq6ZczEQ3a5+Xx}V`9r9<@B z+Gxm_ID?H5J4fhOH%s>sW4(Ot+93;0>*3FEg%=ljRZ7X7jfZeFS@Wy2?{E?0{?GKU zMyJ#`S`$B#!f^v8XV z=)$YpthspfI zqDD66!<_G>&Rh$qFXqu2`Vy}}5W(xTK`$c*rRiF7#t9ta<<2N;LTj-TO`2VHT?DiH z6T>?&clLy54xbMsdo>pfB(Y7R0-;0hHR2fawR>bd&#q7nUGw0WQ#Qlnr=s?O+{`V` zWHlCeeE1zbW<`z?vpdkUFQyrq0?%FmxaE)Bm$e)}q%ZG!j+2?G6SMP*3be@#!pyfuw0fRKBZf~ri>OTA#-V(j>dr0GkOkr@i(0u(=ocCjjrg^i(eJ`#cw?X%) zbrZ>L{=b85#^n&?3VpzdqIE+7#+%JyDd{t93>TFV!cnb z(xrRk;ku(pLeFB2vzRWl9-l1pSHgkyC{Oz&QosDdJjt8o}r0<9rUi9DQaDF3~7 z&S5jK^m)6$`7+50y-FRS;AfP${zp>Us9&0W%UAf`-!|JqM{|2q*n5N5mx*@6G*?4- zuN+veZ+^s!m3Wl! zA9*r1y|DXbKSrTAf#gciR#|e(TrY%RR)B9gK99U5{Z&C;zS*Tx7Cu+ev4N>o z5|(Codf(EGcT~P9GsixBwY%UTNaLntsJbTMQ#PWnqVpfkbHdA}+?&i)^d#uAIK)iK zAmbsI=bVGNWi+4DRkY2eH|9lPg~HAg@BHNnL@(YT;ah+ZIAjPMHNVVCPifwn6z=e9 zIXO~`c+V7E&y+GsQ>pg1R!^FpuXUh&)vC|w-|@S;>eTA$nM4)u=KGHw7tgCQejVN8 z2-L0;3f_6C`D(9)Lb6ex=GOo6T`wPNm$Xr4kTFW#)p>flr*4{BHkvMV>8etD%Jitc z?e@^aD^~v(O|DC&2Z2hwZVZol>R~u^y9wHiuYB_MMT-r8Q2o83Vk$!yefRUI8K9i77e$0sgm z{f6z+_G|nUC1YS;O7^_&VZZe2-?Hl@T`qHSTZuT~Gn(XjXX?nMeXA}OnyaL;vfcFw m=B*>5-$Z=>jBV(v|4BPYP)%9w%pd*7vR9H + + + + <?php echo $config['website-name']; ?> + + "> + + + + + +
+
+
+
+

+

+

+ +
+
+
+
+ + \ No newline at end of file diff --git a/templates/url_form.php b/templates/url_form.php new file mode 100644 index 0000000..2bb09f4 --- /dev/null +++ b/templates/url_form.php @@ -0,0 +1,80 @@ + + + + + +
+ +
+ +
+ " onclick=" window.location.href='index.php'"> + + + "> +
+ +
+ +
+ + diff --git a/vendor/athlon1600/php-proxy-plugin-bundle b/vendor/athlon1600/php-proxy-plugin-bundle new file mode 160000 index 0000000..172202c --- /dev/null +++ b/vendor/athlon1600/php-proxy-plugin-bundle @@ -0,0 +1 @@ +Subproject commit 172202c9b7913dc397b0a2eeacb68984a73f5c6e diff --git a/vendor/athlon1600/php-proxy/.gitignore b/vendor/athlon1600/php-proxy/.gitignore new file mode 100644 index 0000000..fd24be7 --- /dev/null +++ b/vendor/athlon1600/php-proxy/.gitignore @@ -0,0 +1,3 @@ +/vendor/* +composer.lock +.htaccess \ No newline at end of file diff --git a/vendor/athlon1600/php-proxy/LICENSE b/vendor/athlon1600/php-proxy/LICENSE new file mode 100644 index 0000000..a8fc851 --- /dev/null +++ b/vendor/athlon1600/php-proxy/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2016 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/athlon1600/php-proxy/README.md b/vendor/athlon1600/php-proxy/README.md new file mode 100644 index 0000000..4c25f84 --- /dev/null +++ b/vendor/athlon1600/php-proxy/README.md @@ -0,0 +1,99 @@ +php-proxy +========= + +Proxy script built on PHP, Symfony and cURL. +This library borrows ideas from Glype, Jenssegers proxy, and Guzzle. + +PHP-Proxy Web Application +------- + +If you're looking for a **project** version of this script that functions as a Web Application similar to Glype, then visit +[**php-proxy-app**](https://github.com/Athlon1600/php-proxy-app) + +See this php-proxy in action: +UnblockVideos.com + +Installation +------- + +Install it using [Composer](http://getcomposer.org): + +```bash +composer require athlon1600/php-proxy +``` + +Example +-------- + +```php +require('vendor/autoload.php'); + +use Proxy\Http\Request; +use Proxy\Proxy; + +$request = Request::createFromGlobals(); + +$proxy = new Proxy(); + +$proxy->getEventDispatcher()->addListener('request.before_send', function($event){ + + $event['request']->headers->set('X-Forwarded-For', 'php-proxy'); + +}); + +$proxy->getEventDispatcher()->addListener('request.sent', function($event){ + + if($event['response']->getStatusCode() != 200){ + die("Bad status code!"); + } + +}); + +$proxy->getEventDispatcher()->addListener('request.complete', function($event){ + + $content = $event['response']->getContent(); + $content .= ''; + + $event['response']->setContent($content); + +}); + +$response = $proxy->forward($request, "https://www.yahoo.com"); + +// send the response back to the client +$response->send(); + +``` + +Plugin Example +-------- + +```php +namespace Proxy\Plugin; + +use Proxy\Plugin\AbstractPlugin; +use Proxy\Event\ProxyEvent; + +use Proxy\Html; + +class MultiSiteMatchPlugin extends AbstractPlugin { + + // Matches multiple domain names (abc.com, abc.de, abc.pl) using regex (you MUST use / character) + protected $url_pattern = '/^abc\.(com|de|pl)$/is'; + // Matches a single domain name + //protected $url_pattern = 'abc.com'; + + public function onCompleted(ProxyEvent $event){ + + $response = $event['response']; + + $html = $response->getContent(); + + // do your stuff here... + + $response->setContent($html); + } +} +``` + +Notice that you must use the **/** character for regexes on ```$url_pattern``` diff --git a/vendor/athlon1600/php-proxy/composer.json b/vendor/athlon1600/php-proxy/composer.json new file mode 100644 index 0000000..2bf58ab --- /dev/null +++ b/vendor/athlon1600/php-proxy/composer.json @@ -0,0 +1,21 @@ +{ + "name": "athlon1600/php-proxy", + "type": "library", + "keywords": ["php proxy", "proxy script", "php web proxy", "web proxy", "php proxy script"], + "homepage": "https://www.php-proxy.com/", + "require": { + "ext-curl": "*", + "symfony/event-dispatcher": "~3.2" + }, + "suggest": { + "predis/predis": "For caching purposes" + }, + "autoload": { + "psr-4": { + "Proxy\\": "src/" + }, + "files": [ + "src/helpers.php" + ] + } +} \ No newline at end of file diff --git a/vendor/athlon1600/php-proxy/src/Config.php b/vendor/athlon1600/php-proxy/src/Config.php new file mode 100644 index 0000000..8708b24 --- /dev/null +++ b/vendor/athlon1600/php-proxy/src/Config.php @@ -0,0 +1,39 @@ + \ No newline at end of file diff --git a/vendor/athlon1600/php-proxy/src/Event/ProxyEvent.php b/vendor/athlon1600/php-proxy/src/Event/ProxyEvent.php new file mode 100644 index 0000000..1cfddec --- /dev/null +++ b/vendor/athlon1600/php-proxy/src/Event/ProxyEvent.php @@ -0,0 +1,39 @@ +data = $data; + } + + public function offsetSet($offset, $value){ + + if(is_null($offset)) { + $this->data[] = $value; + } else { + $this->data[$offset] = $value; + } + } + + public function offsetExists($offset){ + return isset($this->data[$offset]); + } + + public function offsetUnset($offset){ + unset($this->data[$offset]); + } + + public function offsetGet($offset){ + return isset($this->data[$offset]) ? $this->data[$offset] : null; + } + +} + +?> \ No newline at end of file diff --git a/vendor/athlon1600/php-proxy/src/Html.php b/vendor/athlon1600/php-proxy/src/Html.php new file mode 100644 index 0000000..08c4c40 --- /dev/null +++ b/vendor/athlon1600/php-proxy/src/Html.php @@ -0,0 +1,182 @@ +]*>(.*?)<\s*\/\s*script\s*>/is', '', $html); + return $html; + } + + public static function remove_styles($html){ + $html = preg_replace('/<\s*style[^>]*>(.*?)<\s*\/\s*style\s*>/is', '', $html); + return $html; + } + + public static function remove_comments($html){ + return preg_replace('//s', '', $html); + } + + private static function find($selector, $html, $start_from = 0){ + + $html = substr($html, $start_from); + + $inner_start = 0; + $inner_end = 0; + + $pattern = '//'; + + if(substr($selector, 0, 1) == '#'){ + $pattern = '/<(\w+)[^>]+id="'.substr($selector, 1).'"[^>]*>/is'; + } else if(substr($selector, 0, 1) == '.'){ + $pattern = '/<(\w+)[^>]+class="'.substr($selector, 1).'"[^>]*>/is'; + } else { + return false; + } + + if(preg_match($pattern, $html, $matches, PREG_OFFSET_CAPTURE)){ + + $outer_start = $matches[0][1]; + $inner_start = $matches[0][1] + strlen($matches[0][0]); + + // tag stuff + $tag_name = $matches[1][0]; + $tag_len = strlen($tag_name); + + $run_count = 300; + + // "open" 0){ + + $open_tag = strpos($html, "<{$tag_name}", $start); + $close_tag = strpos($html, " $outer_start + $start_from, + 'inner_start' => $inner_start + $start_from, + 'inner_end' => $inner_end + $start_from, + 'outer_end' => $outer_end + $start_from + ); + } + + return false; + } + + public static function extract_inner($selector, $html){ + return self::extract($selector, $html, true); + } + + public static function extract_outer($selector, $html){ + return self::extract($selector, $html, false); + } + + private static function extract($selector, $html, $inner = false){ + + $pos = 0; + $limit = 300; + + $result = array(); + $data = false; + + do { + + $data = self::find($selector, $html, $pos); + + if($data){ + + $code = substr($html, $inner ? $data['inner_start'] : $data['outer_start'], + $inner ? $data['inner_end'] - $data['inner_start'] : $data['outer_end'] - $data['outer_start']); + + $result[] = $code; + $pos = $data['outer_end']; + } + + } while ($data && --$limit > 0); + + return $result; + } + + public static function remove($selector, $html){ + return self::replace($selector, '', $html, false); + } + + public static function replace_outer($selector, $replace, $html, &$matches = NULL){ + return self::replace($selector, $replace, $html, false, $matches); + } + + public static function replace_inner($selector, $replace, $html, &$matches = NULL){ + return self::replace($selector, $replace, $html, true, $matches); + } + + private static function replace($selector, $replace, $html, $replace_inner = false, &$matches = NULL){ + + $start_from = 0; + $limit = 300; + + $data = false; + $replace = (array)$replace; + + do { + + $data = self::find($selector, $html, $start_from); + + if($data){ + + $r = array_shift($replace); + + // from where to where will we be replacing? + $replace_space = $replace_inner ? $data['inner_end'] - $data['inner_start'] : $data['outer_end'] - $data['outer_start']; + $replace_len = strlen($r); + + if($matches !== NULL){ + $matches[] = substr($html, $replace_inner ? $data['inner_start'] : $data['outer_start'], $replace_space); + } + + $html = substr_replace($html, $r, $replace_inner ? $data['inner_start'] : $data['outer_start'], $replace_space); + + // next time we resume search at position right at the end of this element + $start_from = $data['outer_end'] + ($replace_len - $replace_space); + } + + } while ($data && --$limit > 0); + + return $html; + } +} + +?> \ No newline at end of file diff --git a/vendor/athlon1600/php-proxy/src/Http/ParamStore.php b/vendor/athlon1600/php-proxy/src/Http/ParamStore.php new file mode 100644 index 0000000..6485d79 --- /dev/null +++ b/vendor/athlon1600/php-proxy/src/Http/ParamStore.php @@ -0,0 +1,84 @@ +data = $parameters; + $this->case_sensitive = $case_sensitive; + } + + private function normalizeKey($key){ + return $this->case_sensitive ? $key : strtolower($key); + } + + public function set($key, $value, $replace = true){ + + $key = $this->normalizeKey($key); + + // replacing or does not have existing key filled yet + if($replace || !$this->has($key)){ + $this->data[$key] = $value; + } else { + + if(is_array($this->data[$key])){ + $this->data[$key][] = $value; + } else { + $this->data[$key] = array($this->data[$key], $value); + } + } + } + + public function replace(array $data){ + + // remove all existing items first + $this->clear(); + + foreach($data as $key => $value){ + $this->set($key, $value); + } + } + + public function remove($key){ + unset($this->data[$this->normalizeKey($key)]); + } + + public function clear(){ + $this->data = array(); + } + + public function has($key){ + return isset($this->data[$this->normalizeKey($key)]); + } + + public function get($key, $default = null){ + + $key = $this->normalizeKey($key); + + return $this->has($key) ? $this->data[$key] : $default; + } + + // Returns an array of all values currently stored + public function all(){ + return $this->data; + } + + public function __toString(){ + return json_encode($this->data, true); + } +} + +?> \ No newline at end of file diff --git a/vendor/athlon1600/php-proxy/src/Http/Request.php b/vendor/athlon1600/php-proxy/src/Http/Request.php new file mode 100644 index 0000000..a51561b --- /dev/null +++ b/vendor/athlon1600/php-proxy/src/Http/Request.php @@ -0,0 +1,362 @@ +params = new ParamStore(); + $this->headers = new ParamStore(); + + // http params + $this->post = new ParamStore(null, true); + $this->get = new ParamStore(null, true); + + $this->files = new ParamStore(null, true); + + $this->setMethod($method); + $this->setUrl($url); + $this->setBody($body); + + // make the request ready to be sent right from the start - prepare must be called manually from this point on if you ever add post or file parameters + $this->prepare(); + } + + /* + Does multiple things + - regenerate content body based on $post and $files parameters + - set content-type, content-length headers + - set transfer-encoding, expect headers + */ + public function prepare(){ + + /* + Any HTTP/1.1 message containing an entity-body SHOULD include a Content-Type header field defining the media type of that body. + http://www.w3.org/Protocols/rfc2616/rfc2616-sec7.html#sec7.2.1 + */ + + // Must be a multipart request + if($this->files->all()){ + + $boundary = self::generateBoundary(); + + $this->prepared_body = Request::buildPostBody($this->post->all(), $this->files->all(), $boundary); + $this->headers->set('content-type', 'multipart/form-data; boundary='.$boundary); + + } else if($this->post->all()){ + + $this->prepared_body = http_build_query($this->post->all()); + $this->headers->set('content-type', 'application/x-www-form-urlencoded'); + + } else { + + $this->headers->set('content-type', $this->detectContentType($this->body)); + $this->prepared_body = $this->body; + } + + /* + The transfer-length of a message is the length of the message-body as it appears in the message; that is, after any transfer-codings have been applied. + http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.4 + */ + + $len = strlen($this->prepared_body); + + if($len > 0){ + $this->headers->set('content-length', $len); + } else { + $this->headers->remove('content-length'); + $this->headers->remove('content-type'); + } + } + + public function __toString(){ + $str = $this->getMethod().' '.$this->getUrl().' HTTP/'.$this->getProtocolVersion()."\r\n"; + return $str.$this->getRawHeaders()."\r\n\r\n".$this->getRawBody(); + } + + public function setMethod($method){ + $this->method = strtoupper($method); + } + + public function getMethod(){ + return $this->method; + } + + // this was no longer working --- https://github.com/guzzle/psr7/blob/master/src/functions.php + public static function parseQuery($query){ + $result = array(); + parse_str($query, $result); + + return $result; + } + + public function setUrl($url){ + // remove hashtag - preg_replace so we don't have to check for its existence first - is it possible preserving hashtag? + $url = preg_replace('/#.*/', '', $url); + + // check if url has any query parameters + $query = parse_url($url, PHP_URL_QUERY); + + // remove it and add the query params to get collection + if($query){ + //$url = str_replace('?'.$query, '', $url); + $url = preg_replace('/\?.*/', '', $url); + + $result = self::parseQuery($query); + $this->get->replace($result); + } + + // url without query params - those will be appended later + $this->url = $url; + $this->headers->set('host', parse_url($url, PHP_URL_HOST)); + } + + public function getRawHeaders(){ + + $result = array(); + + $headers = $this->headers->all(); + + // Sort headers by name + //ksort($headers); + + // Turn this into name=value pairs + foreach($headers as $name => $values){ + + // could be an array if multiple headers are sent with the same name? + foreach( (array)$values as $value){ + $name = implode('-', array_map('ucfirst', explode('-', $name))); + $result[] = sprintf("%s: %s", $name, $value); + } + } + + return implode("\r\n", $result); + } + + public function getUrl(){ + + // does this URL have any query parameters? + if($this->get->all()){ + return $this->url.'?'.http_build_query($this->get->all()); + } + + return $this->url; + } + + public function getUri(){ + return call_user_func_array(array($this, "getUrl"), func_get_args()); + } + + public function setProtocolVersion($version){ + $this->protocol_version = $version; + } + + public function getProtocolVersion(){ + return $this->protocol_version; + } + + // Set raw contents of the body + // this will clear all the values currently stored in POST and FILES + // will be ignored during PREPARE if post or files contain any values + public function setBody($body, $content_type = false){ + + // clear old body data + $this->post->clear(); + $this->files->clear(); + + // is this form data? + if(is_array($body)){ + $body = http_build_query($body); + } + + $this->body = (string)$body; + + // plain text should be: text/plain; charset=UTF-8 + if($content_type){ + $this->headers->set('content-type', $content_type); + } + + // do it! + $this->prepare(); + } + + private static function generateBoundary(){ + return '-----'.md5(microtime().rand()); + } + + // can be $_POST and $_FILES + public static function buildPostBody($fields, $files, $boundary = null){ + + // the reason BODY part is not included in sprintf pattern is because of limits + $part_field = "--%s\r\nContent-Disposition: form-data; name=\"%s\"\r\n\r\n"; + $part_file = "--%s\r\nContent-Disposition: form-data; name=\"%s\"; filename=\"%s\"\r\nContent-Type: %s\r\n\r\n"; + + // each part should be preceeded by this line + if(!$boundary){ + $boundary = self::generateBoundary(); + } + + $body = ''; + + foreach($fields as $name => $value){ + $body .= sprintf($part_field, $boundary, $name, $value); + $body .= "{$value}\r\n"; + } + + // data better have [name, tmp_name, and optional type] + foreach($files as $name => $values) { + // Multiple files can be uploaded using different name for input. + // See http://php.net/manual/en/features.file-upload.multiple.php + if (!is_array($values['tmp_name'])) { + $multiValues = array_map(function ($a) { + return (array)$a; + }, $values); + $fieldName = $name; + } else { + $multiValues = $values; + $fieldName = "{$name}[]"; + } + + foreach (array_keys($multiValues['tmp_name']) as $key) { + + // There must be no error http://php.net/manual/en/features.file-upload.errors.php + if (!$multiValues['tmp_name'][$key] || $multiValues['error'][$key] !== 0 || !is_readable($multiValues['tmp_name'][$key])) { + continue; + } + + $body .= sprintf($part_file, $boundary, $fieldName, $multiValues['name'][$key], $multiValues['type'][$key]); + $body .= file_get_contents($multiValues['tmp_name'][$key]); + $body .= "\r\n"; + } + } + $body .= "--{$boundary}--\r\n\r\n"; + + return $body; + } + + private function detectContentType($data){ + + // http://www.w3.org/Protocols/rfc1341/4_Content-Type.html + + // If the media type remains unknown, the recipient SHOULD treat it as type "application/octet-stream". + $content_type = 'application/octet-stream'; + + if(preg_match('/^{\s*"[^"]+"\s*:/', $data)){ + $content_type = 'application/json'; + } else if(preg_match('/^(?:<\?xml[^?>]+\?>)\s*<[^>]+>/i', $data)){ + $content_type = 'application/xml'; + } else if(preg_match('/^[a-zA-Z0-9_.~-]+=[^&]*&/', $data)){ + $content_type = 'application/x-www-form-urlencoded'; + } + + return $content_type; + } + + // Returns a parsed version of the body + /* + public function getBody(){ + + // what is the content type? + $content_type = $this->headers->get('content-type', ''); + + switch($content_type){ + case 'application/x-www-form-urlencoded': + $result = array(); + mb_parse_str($this->body, $result); + return $result; + case 'application/json': + return json_decode($this->body); + case 'text/xml': + case 'application/xml': + case 'application/x-xml': + return simplexml_load_string($this->body); + } + + return null; + } + */ + + // Returns raw body string exactly as it appears in the HTTP request + public function getRawBody(){ + return $this->prepared_body; + } + + public static function createFromGlobals(){ + + $method = $_SERVER['REQUEST_METHOD']; + $scheme = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS']) ? 'https' : 'http'; + + $url = $scheme.'://'. $_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']; + + $request = new Request($method, $url); + + // fill in headers + foreach($_SERVER as $name => $value){ + + if(strpos($name, 'HTTP_') === 0){ + + $name = substr($name, 5); + $name = str_replace('_', ' ', $name); + $name = ucwords(strtolower($name)); + $name = str_replace(' ', '-', $name); + + $request->headers->set($name, $value); + } + } + + // for extra convenience + //$request->params->set('user-ip', $_SERVER['REMOTE_ADDR']); + + // will be empty if content-type is multipart + $input = file_get_contents("php://input"); + + if(count($_FILES) > 0){ + $request->post->replace($_POST); + $request->files->replace($_FILES); + } else if(count($_POST) > 0){ + $request->post->replace($_POST); + } else { + $request->setBody($input); + } + + // for extra convenience + $request->prepare(); + + return $request; + } +} + + +?> \ No newline at end of file diff --git a/vendor/athlon1600/php-proxy/src/Http/Response.php b/vendor/athlon1600/php-proxy/src/Http/Response.php new file mode 100644 index 0000000..e5075ea --- /dev/null +++ b/vendor/athlon1600/php-proxy/src/Http/Response.php @@ -0,0 +1,120 @@ + 'Continue', + 101 => 'Switching Protocols', + 200 => 'OK', + 201 => 'Created', + 202 => 'Accepted', + 203 => 'Non-Authoritative Information', + 204 => 'No Content', + 205 => 'Reset Content', + 206 => 'Partial Content', + 300 => 'Multiple Choices', + 301 => 'Moved Permanently', + 302 => 'Found', + 303 => 'See Other', + 304 => 'Not Modified', + 305 => 'Use Proxy', + 307 => 'Temporary Redirect', + 400 => 'Bad Request', + 401 => 'Unauthorized', + 402 => 'Payment Required', + 403 => 'Forbidden', + 404 => 'Not Found', + 405 => 'Method Not Allowed', + 406 => 'Not Acceptable', + 407 => 'Proxy Authentication Required', + 408 => 'Request Time-out', + 409 => 'Conflict', + 410 => 'Gone', + 411 => 'Length Required', + 412 => 'Precondition Failed', + 413 => 'Request Entity Too Large', + 414 => 'Request-URI Too Large', + 415 => 'Unsupported Media Type', + 416 => 'Requested range not satisfiable', + 417 => 'Expectation Failed', + 429 => 'Too Many Requests', + 500 => 'Internal Server Error', + 501 => 'Not Implemented', + 502 => 'Bad Gateway', + 503 => 'Service Unavailable', + 504 => 'Gateway Time-out', + 505 => 'Unsupported Version' + ); + + public $status; + + public $headers; + + private $content; + + // getHeaderLines + public function __construct($content = '', $status = 200, $headers = array()){ + + $this->headers = new ParamStore($headers); + + $this->setContent($content); + $this->setStatusCode($status); + } + + public function setStatusCode($code){ + $this->status = $code; + } + + public function getStatusCode(){ + return $this->status; + } + + public function getStatusText(){ + return $this->statusCodes[$this->getStatusCode()]; + } + + public function setContent($content){ + $this->content = (string)$content; + } + + public function getContent(){ + return $this->content; + } + + public function sendHeaders(){ + + if(headers_sent()){ + return; + } + + header(sprintf('HTTP/1.1 %s %s', $this->status, $this->getStatusText()), true, $this->status); + + foreach($this->headers->all() as $name => $value){ + + /* + Multiple message-header fields with the same field-name MAY be present in a message + if and only if the entire field-value for that header field is defined as a comma-separated list + http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2 + */ + + $values = is_array($value) ? $value : array($value); + + // false = do not replace previous identical header + foreach($values as $value){ + header("{$name}: {$value}", false); + } + } + } + + public function send(){ + $this->sendHeaders(); + echo $this->content; + } + +} + +?> \ No newline at end of file diff --git a/vendor/athlon1600/php-proxy/src/Plugin/AbstractPlugin.php b/vendor/athlon1600/php-proxy/src/Plugin/AbstractPlugin.php new file mode 100644 index 0000000..405c33b --- /dev/null +++ b/vendor/athlon1600/php-proxy/src/Plugin/AbstractPlugin.php @@ -0,0 +1,80 @@ +getUri(); + + // url filter provided and current request url does not match it + if($this->url_pattern){ + if(strpos($this->url_pattern, '/') === 0){ + if(!preg_match($this->url_pattern, $url)) + return; + } + else + { + if(stripos($url, $this->url_pattern) === false) + return; + } + } + + switch($event_name){ + + case 'request.before_send': + $this->onBeforeRequest($event); + break; + + case 'request.sent': + $this->onHeadersReceived($event); + break; + + case 'curl.callback.write': + $this->onCurlWrite($event); + break; + + case 'request.complete': + $this->onCompleted($event); + break; + } + } + + // This method returns an array indexed by event names and whose values are either the method name to call + // or an array composed of the method name to call and a priority. + final public static function getSubscribedEvents(){ + return array( + 'request.before_send' => 'route', + 'request.sent' => 'route', + 'curl.callback.write' => 'route', + 'request.complete' => 'route' + ); + } +} + +?> diff --git a/vendor/athlon1600/php-proxy/src/Plugin/BlockListPlugin.php b/vendor/athlon1600/php-proxy/src/Plugin/BlockListPlugin.php new file mode 100644 index 0000000..f64669b --- /dev/null +++ b/vendor/athlon1600/php-proxy/src/Plugin/BlockListPlugin.php @@ -0,0 +1,57 @@ +getUrl(); + $url_host = parse_url($url, PHP_URL_HOST); + + $fnc_custom = Config::get('blocklist.custom'); + if(is_callable($fnc_custom)){ + + $ret = call_user_func($fnc_custom, compact('user_ip', 'user_ip_long', 'url', 'url_host') ); + if(!$ret){ + throw new \Exception("Error: Access Denied!"); + } + + return; + } + + /* + 1. Wildcard format: 1.2.3.* + 2. CIDR format: 1.2.3/24 OR 1.2.3.4/255.255.255.0 + 3. Start-End IP format: 1.2.3.0-1.2.3.255 + */ + $ip_match = false; + $action_block = true; + + if(Config::has('blocklist.ip_allow')){ + $ip_match = Config::get('blocklist.ip_allow'); + $action_block = false; + } else if(Config::has('blocklist.ip_block')){ + $ip_match = Config::get('blocklist.ip_block'); + } + + if($ip_match){ + $m = re_match($ip_match, $user_ip); + + // ip matched and we are in block_mode + // ip NOT matched and we are in allow mode + if( ($m && $action_block) || (!$m && !$action_block)){ + throw new \Exception("Error: Access denied!"); + } + } + } +} + +?> \ No newline at end of file diff --git a/vendor/athlon1600/php-proxy/src/Plugin/CookiePlugin.php b/vendor/athlon1600/php-proxy/src/Plugin/CookiePlugin.php new file mode 100644 index 0000000..0d69eff --- /dev/null +++ b/vendor/athlon1600/php-proxy/src/Plugin/CookiePlugin.php @@ -0,0 +1,132 @@ +headers->get("cookie"); + + // remove old cookie header and rewrite it + $request->headers->remove("cookie"); + + /* + When the user agent generates an HTTP request, the user agent MUST NOT attach more than one Cookie header field. + http://tools.ietf.org/html/rfc6265#section-5.4 + */ + $send_cookies = array(); + + // extract "proxy cookies" only + // A Proxy Cookie would have the following name: COOKIE_PREFIX_domain-it-belongs-to__cookie-name + if(preg_match_all('@pc_(.+?)__(.+?)=([^;]+)@', $http_cookie, $matches, PREG_SET_ORDER)){ + + foreach($matches as $match){ + + $cookie_name = $match[2]; + $cookie_value = $match[3]; + $cookie_domain = str_replace("_", ".", $match[1]); + + // what is the domain or our current URL? + $host = parse_url($request->getUri(), PHP_URL_HOST); + + // does this cookie belong to this domain? + // sometimes domain begins with a DOT indicating all subdomains - deprecated but still in use on some servers... + if(strpos($host, $cookie_domain) !== false){ + $send_cookies[] = $cookie_name.'='.$cookie_value; + } + } + } + + // do we have any cookies to send? + if($send_cookies){ + $request->headers->set('cookie', implode("; ", $send_cookies)); + } + } + + // cookies received from a target server via set-cookie should be rewritten + public function onHeadersReceived(ProxyEvent $event){ + + $request = $event['request']; + $response = $event['response']; + + // does the response send any cookies? + $set_cookie = $response->headers->get('set-cookie'); + + if($set_cookie){ + + // remove set-cookie header and reconstruct it differently + $response->headers->remove('set-cookie'); + + // loop through each set-cookie line + foreach( (array)$set_cookie as $line){ + + // parse cookie data as array from header line + $cookie = $this->parse_cookie($line, $request->getUri()); + + // construct a "proxy cookie" whose name includes the domain to which this cookie belongs to + // replace dots with underscores as cookie name can only contain alphanumeric and underscore + $cookie_name = sprintf("%s_%s__%s", self::COOKIE_PREFIX, str_replace('.', '_', $cookie['domain']), $cookie['name']); + + // append a simple name=value cookie to the header - no expiration date means that the cookie will be a session cookie + $event['response']->headers->set('set-cookie', $cookie_name.'='.$cookie['value'], false); + } + } + } + + // adapted from browserkit + private function parse_cookie($line, $url){ + + $host = parse_url($url, PHP_URL_HOST); + + $data = array( + 'name' => '', + 'value' => '', + 'domain' => $host, + 'path' => '/', + 'expires' => 0, + 'secure' => false, + 'httpOnly' => true + ); + + $line = preg_replace('/^Set-Cookie2?: /i', '', trim($line)); + + // there should be at least one name=value pair + $pairs = array_filter(array_map('trim', explode(';', $line))); + + foreach($pairs as $index => $comp){ + + $parts = explode('=', $comp, 2); + $key = trim($parts[0]); + + if(count($parts) == 1){ + + // secure; HttpOnly; == 1 + $data[$key] = true; + + } else { + + $value = trim($parts[1]); + + if($index == 0){ + $data['name'] = $key; + $data['value'] = $value; + } else { + $data[$key] = $value; + } + } + } + + return $data; + } +} + +?> \ No newline at end of file diff --git a/vendor/athlon1600/php-proxy/src/Plugin/HeaderRewritePlugin.php b/vendor/athlon1600/php-proxy/src/Plugin/HeaderRewritePlugin.php new file mode 100644 index 0000000..9eccdf3 --- /dev/null +++ b/vendor/athlon1600/php-proxy/src/Plugin/HeaderRewritePlugin.php @@ -0,0 +1,69 @@ +headers->set('accept-encoding', 'identity'); + + // mask proxy referer + $event['request']->headers->remove('referer'); + } + + function onHeadersReceived(ProxyEvent $event){ + + // so stupid... onCompleted won't be called on "streaming" responses + $response = $event['response']; + $request_url = $event['request']->getUri(); + + // proxify header location value + if($response->headers->has('location')){ + + $location = $response->headers->get('location'); + + // just in case this is a relative url like: /en + $response->headers->set('location', proxify_url($location, $request_url)); + } + + $code = $response->getStatusCode(); + $text = $response->getStatusText(); + + if($code >= 400 && $code <= 600){ + throw new \Exception("Error accessing resource: {$code} - {$text}"); + } + + // we need content-encoding (in case server refuses to serve it in plain text) + // content-length: final size of content sent to user may change via plugins, so it makes no sense to send old content-length + $forward_headers = array('content-type', 'zzzcontent-length', 'accept-ranges', 'content-range', 'content-disposition', 'location', 'set-cookie'); + + foreach($response->headers->all() as $name => $value){ + + // is this one of the headers we wish to forward back to the client? + if(!in_array($name, $forward_headers)){ + $response->headers->remove($name); + } + } + + if(!$response->headers->has('content-disposition')){ + + $url_path = parse_url($request_url, PHP_URL_PATH); + $filename = basename($url_path); + + $response->headers->set('Content-Disposition', 'filename="'.$filename.'"'); + } + + // do not ever cache our proxy pages! + $response->headers->set("cache-control", "no-cache, no-store, must-revalidate"); + $response->headers->set("pragma", "no-cache"); + $response->headers->set("expires", 0); + } + +} + +?> \ No newline at end of file diff --git a/vendor/athlon1600/php-proxy/src/Plugin/ProxifyPlugin.php b/vendor/athlon1600/php-proxy/src/Plugin/ProxifyPlugin.php new file mode 100644 index 0000000..0d29cdf --- /dev/null +++ b/vendor/athlon1600/php-proxy/src/Plugin/ProxifyPlugin.php @@ -0,0 +1,185 @@ +base_url), $matches[0]); + } + + // this.params.logoImg&&(e="background-image: url("+this.params.logoImg+")") + private function css_import($matches){ + return str_replace($matches[2], proxify_url($matches[2], $this->base_url), $matches[0]); + } + + // replace src= and href= + private function html_attr($matches){ + + // could be empty? + $url = trim($matches[2]); + + if(stripos($url, 'data:') === 0 || stripos($url, 'magnet:') === 0 ){ + return $matches[0]; + } + + return str_replace($url, proxify_url($url, $this->base_url), $matches[0]); + } + + private function form_action($matches){ + + // sometimes form action is empty - which means a postback to the current page + // $matches[1] holds single or double quote - whichever was used by webmaster + + // $matches[2] holds form submit URL - can be empty which in that case should be replaced with current URL + if(!$matches[2]){ + $matches[2] = $this->base_url; + } + + $new_action = proxify_url($matches[2], $this->base_url); + + // what is form method? + $form_post = preg_match('@method=(["\'])post\1@i', $matches[0]) == 1; + + // take entire form string - find real url and replace it with proxified url + $result = str_replace($matches[2], $new_action, $matches[0]); + + // must be converted to POST otherwise GET form would just start appending name=value pairs to your proxy url + if(!$form_post){ + + // may throw Duplicate Attribute warning but only first method matters + $result = str_replace("post->has('convertGET')){ + + // we don't need this parameter anymore + $request->post->remove('convertGET'); + + // replace all GET parameters with POST data + $request->get->replace($request->post->all()); + + // remove POST data + $request->post->clear(); + + // This is now a GET request + $request->setMethod('GET'); + + $request->prepare(); + } + } + + private function meta_refresh($matches){ + $url = $matches[2]; + return str_replace($url, proxify_url($url, $this->base_url), $matches[0]); + } + + // , <base>, <link>, <style>, <meta>, <script>, <noscript> + private function proxify_head($str){ + + // let's replace page titles with something custom + if(Config::get('replace_title')){ + $str = preg_replace('/<title[^>]*>(.*?)<\/title>/is', '<title>'.Config::get('replace_title').'', $str); + } + + + // base - update base_url contained in href - remove tag entirely + //$str = preg_replace_callback('/]*href= + + // link - replace href with proxified + // link rel="shortcut icon" - replace or remove + + // meta - only interested in http-equiv - replace url refresh + // + $str = preg_replace_callback('/content=(["\'])\d+\s*;\s*url=(.*?)\1/is', array($this, 'meta_refresh'), $str); + + return $str; + } + + // The background attribute is not supported in HTML5. Use CSS instead. + private function proxify_css($str){ + + // The HTML5 standard does not require quotes around attribute values. + + // if {1} is not there then youtube breaks for some reason + $str = preg_replace_callback('@[^a-z]{1}url\s*\((?:\'|"|)(.*?)(?:\'|"|)\)@im', array($this, 'css_url'), $str); + + // https://developer.mozilla.org/en-US/docs/Web/CSS/@import + // TODO: what about @import directives that are outside