2015年10月

将cow的stat文件自动转为pac文件

cow是一个简化穿墙的 HTTP 代理服务器。它能自动检测被墙网站,它的检测结果会保存在stat文件中。该文件为一个json文件,里面记录了特定的网址直接访问和被block的次数,通过分析该文件即可创建一个包含黑白名单的pac文件,使用黑白名单加cow的本地代理方案是比较省心省流量的。

以下代码可以自动将stat文件转为pac文件:

<?php
$src = 'R:\stat.txt';
$dest = 'R:\my.pac';
$common = <<<EOF
var proxy = 'PROXY 127.0.0.1:7777; DIRECT';

var direct = 'DIRECT';

var IsMatch = function(host, domain) {
    return host.indexOf(domain, host.length - domain.length) !== -1 && 
    (domain.length === host.length || host.indexOf("." + domain, host.length - ("." + domain).length) !== -1);
}

function FindProxyForURL(url, host) {
    host = host.toLowerCase();

    for (i = 0; i < blackList.length; i++) {
        if (IsMatch(host, blackList[i])) {
            return proxy;
        }
    }

    for (i = 0; i < whiteList.length; i++) {
        if (IsMatch(host, whiteList[i])) {
            return direct;
        }
    }

    return proxy;
}
EOF;

$stat = file_get_contents($src);
$sites = json_decode($stat, true)['site_info'];
$black = [];
$white = [];
foreach ($sites as $url => $stat) {
    if (filter_var($url, FILTER_VALIDATE_IP)) continue;
    preg_match('/(?:.+\.)?(\w+\.\w+)/', $url, $matches);
    if (! isset($matches[1])) continue;
    if ($stat['block'] > 0) {
        $black[$matches[1]] = '"' . $matches[1] . '"';
    } else {
        $white[$matches[1]] = '"' . $matches[1] . '"';
    }
}
var_dump($black);
var_dump($white);
$blackList = 'var blackList = [' . PHP_EOL . '    ' . implode(',' . PHP_EOL . '    ', $black) . PHP_EOL . '];';
$whiteList = 'var whiteList = [' . PHP_EOL . '    ' . implode(',' . PHP_EOL . '    ', $white) . PHP_EOL . '];';
file_put_contents($dest, $blackList . PHP_EOL . PHP_EOL . $whiteList . PHP_EOL . PHP_EOL . $common);

通过curl每天自动在coding上创建task和push代码

Coding.net每天可以通过push代码和创建task赚取码币,码币可以用来换实物或coding的开发版服务。码币现在虽然汇率一直没有变过,但是获取码币是越来越难了,趁着还能每天获取保底0.03码币可多屯一点。

首先是创建task:

<?php
$url = 'xxx';
$referer = 'xxx';
$cookie = 'xxx';
$userAgent = 'xxx';
$data = [
    'priority' => 1,
    'content' => 'xxx',
    'owner_id' => xxx,
    'deadline' => '',
    'description' => '',
]; 

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_TIMEOUT, 50);
curl_setopt($ch, CURLOPT_REFERER, $referer);
curl_setopt($ch, CURLOPT_USERAGENT, $userAgent);
curl_setopt($ch, CURLOPT_COOKIE, $cookie);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
var_dump(curl_exec($ch));
var_dump(curl_error($ch));
curl_close($ch);

,代码内的xxx都换为各自的数据就行了,在手动创建task时在chrome的开发者工具的network下可以看到,或者用其他抓包工具也可获取。

然后是自动push代码的:

<?php
require 'Curl.php';

use Curl\Curl;

$url = [
    'create' => 'https://ide.coding.net/backend/ws/create',
    'write' => 'https://ide.coding.net/backend/ws/xxx/write',
    'status' => 'https://ide.coding.net/backend/git/xxx/status?__t=',
    'commit' => 'https://ide.coding.net/backend/git/xxx/commit',
    'push' => 'https://ide.coding.net/backend/git/xxx/push',
];
$referrer = 'https://ide.coding.net/ws/xxx';
$cookie = 'xxx';
$userAgent = 'xxx';
$data = [
    'create' => [
        'ownerName' => '',
        'projectName' => '',
        'host' => '',
        'spaceKey' => 'xxx',
    ],
    'write' => [
        'path' => '/README.md',
        'content' => 'xxx',
    ],
    'commit' => [
        'files[]' => 'README.md',
        'message' => 'xxx',
    ],
    'push' => [],
]; 

$get = getCurl($userAgent, $referrer);
$post = getCurl($userAgent, $referrer);
$put = getCurl($userAgent, $referrer);

var_dump($post->post($url['create'], $data['create']));
var_dump($put->put($url['write'], $data['write']));
var_dump($get->get($url['status'] . substr(str_replace('.', '', microtime(true)), 0, 13)));
var_dump($post->post($url['commit'], $data['commit']));
var_dump($post->post($url['push'], $data['push']));

function getCurl($userAgent, $referrer)
{
    $curl = new Curl();
    $curl->setUserAgent($userAgent);
    $curl->setReferrer($referrer);
    $curl->setCookie('sid', 'xxx');
    $curl->setCookie('_gat', 1);
    $curl->setCookie('_ga', 'xxx');
    $curl->setCookie('JSESSIONID', 'xxx');
    $curl->setHeader('X-Requested-With', 'XMLHttpRequest');
    $curl->setOpt(CURLOPT_SSL_VERIFYPEER, false);
    return $curl;
}

这段代码中用到了一个开源项目:php-curl-class,原因是我自己构造的curl请求不知道为什么会获得401的返回。同样的代码内的所有xxx都要替换为各自对应的数据,其中create、write、commit、push四个步骤是必须的,status是为了观察执行情况。

至于如何实现定时执行计划任务,有条件的自然是在服务器上使用crontab,如果没有自己的服务器的,我比较推荐使用第三方的cron服务,比如sae和ace就有提供cron服务,sae目前有一定免费配额,虽然很少,不过用作执行计划任务绰绰有余,个人十分推荐。