Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
axeok committed Sep 27, 2018
0 parents commit 57bb078
Show file tree
Hide file tree
Showing 9 changed files with 544 additions and 0 deletions.
31 changes: 31 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
Yii2 Proxy Httpclient
=====================
Native httpclient with custom or autoparsed free proxy servers

Installation
------------

The preferred way to install this extension is through [composer](http://getcomposer.org/download/).

Either run

```
php composer.phar require --prefer-dist shintio/yii2-proxy-httpclient "*"
```

or add

```
"shintio/yii2-proxy-httpclient": "*"
```

to the require section of your `composer.json` file.


Usage
-----

Once the extension is installed, simply use it in your code by :

```php
<?= \shintio\yii2\proxy\AutoloadExample::widget(); ?>```
29 changes: 29 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "shintio/yii2-proxy-httpclient",
"description": "Native httpclient with custom or autoparsed free proxy servers",
"type": "yii2-extension",
"keywords": [
"yii2",
"extension",
"proxy",
"curl",
"httpclient"
],
"license": "BSD-3-Clause",
"authors": [
{
"name": "Aleksey Fedorenko",
"email": "shintio.afedorenko@gmail.com"
}
],
"require": {
"yiisoft/yii2": "~2.0.0",
"yiisoft/yii2-httpclient": "^2.0",
"electrolinux/phpquery": "^0.9.6"
},
"autoload": {
"psr-4": {
"shintio\\yii2\\proxy\\": "src/"
}
}
}
46 changes: 46 additions & 0 deletions src/components/Client.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

namespace shintio\yii2\proxy\components;

use shintio\yii2\proxy\models\ProxyServerInterface;
use yii\helpers\ArrayHelper;

/**
* Class Client
* @package shintio\yii2\proxy\components
*
* @property ProxyServerInterface $proxyServerClass
* @property ProxyManager $proxyManager
*/
class Client extends \yii\httpclient\Client
{
public $proxyServerClass;

public $proxyManager;

public function createRequest($rescan = true, $checkProxy = true, $checkTimeout = 5)
{
ArrayHelper::setValue($this->requestConfig, 'class', $this->requestConfig['class'] ?? Request::class);

$request = parent::createRequest();

$proxy = $this->getProxyManager()->getProxyString($checkProxy, $checkTimeout);

if (!$proxy && $rescan) {
$this->getProxyManager()->parseNewProxy();

$proxy = $this->getProxyManager()->getProxyString($checkProxy, $checkTimeout);
}

if ($proxy) {
$request->setOptions(['proxy' => $proxy]);
}

return $request;
}

public function getProxyManager()
{
return $this->proxyManager ?? new ProxyManager();
}
}
187 changes: 187 additions & 0 deletions src/components/ProxyManager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
<?php

namespace shintio\yii2\proxy\components;

use shintio\yii2\proxy\models\ProxyServer;
use shintio\yii2\proxy\models\ProxyServerInterface;
use yii\helpers\ArrayHelper;
use yii\httpclient\Response;

/**
* Class ProxyParser
* @package shintio\yii2\proxy\components
*
* @property ProxyServerInterface $proxyServerModel
*/
class ProxyManager
{
public $proxyServerModel = ProxyServer::class;

public $client;

public $checkerUrl = 'https://ipleak.net/json/';
public $proxyLists = [
[
'url' => 'https://free-proxy-list.net/',
'container' => 'table#proxylisttable',
'ip' => 0,
'port' => 1,
'country' => 3,
]
];

/**
* @return integer
*/
public function parseNewProxy()
{
$count = 0;

foreach ($this->proxyLists as $proxyList) {
$url = ArrayHelper::remove($proxyList, 'url');
$container = ArrayHelper::remove($proxyList, 'container');

$client = $this->getClient();

$request = $client->createRequest()->setMethod('get')->setUrl($url);

$response = $request->send();

if ($response->isOk) {
$document = \phpQuery::newDocumentHTML($response->content);

$proxies = [];

foreach ($proxyList as $key => $attribute) {
foreach ($document->find("$container tr") as $item) {
/** @var \DOMElement $item */
if ($item->childNodes[$proxyList['ip']]->tagName == 'td') {
($this->proxyServerModel)::saveNew($item->childNodes[$proxyList['ip']]->nodeValue,
$item->childNodes[$proxyList['port']]->nodeValue,
$item->childNodes[$proxyList['password']]->nodeValue ?? null,
$item->childNodes[$proxyList['country']]->nodeValue ?? null);

$count++;
}
}
}
}
}

return $count;
}

/**
* @param ProxyServerInterface|null $proxy
* @param integer $timeout
*
* @return ProxyServerInterface|boolean
*/
public function checkProxy($proxy = null, $timeout = 5)
{
if (isset($proxy)) {
return $this->sendCheckRequest($proxy, $timeout);
} else {
do {
$proxy = ($this->proxyServerModel)::findNew();

if (isset($proxy)) {
$proxy = $this->sendCheckRequest($proxy, $timeout);
} else {
return false;
}
} while (empty($proxy));

return $proxy;
}
}

public function getClient()
{
return $this->client ?? new \yii\httpclient\Client();
}

/**
* @param bool $check
* @param integer $timeout
*
* @return ProxyServerInterface
*/
public function getProxy($check = true, $timeout = 5)
{
$proxy = ($this->proxyServerModel)::findActive();

return $check ? $this->checkProxy($proxy, $timeout) : $proxy;
}

/**
* @param bool $check
* @param integer $timeout
*
* @return string|boolean
*/
public function getProxyString($check = true, $timeout = 5)
{
$proxy = $this->getProxy($check, $timeout);

return $proxy ? $this->formatProxyString($proxy) : false;
}

/**
* @param ProxyServerInterface $proxy
*
* @return string
*/
public function formatProxyString($proxy)
{
return 'tcp://' . $proxy->getIp() . ':' . $proxy->getPort();
}

/**
* @param ProxyServerInterface $proxy
* @param integer $timeout
*
* @return ProxyServerInterface|boolean
*/
protected function sendCheckRequest($proxy, $timeout = 5)
{
$client = $this->getClient();

$request = $client->createRequest()->setMethod('get')->setOptions([
'proxy' => $this->formatProxyString($proxy),
'timeout' => $timeout
])->setUrl($this->checkerUrl);

try {
$response = $request->send();

if ($response->isOk) {
$ip = $this->getCheckedIp($response);

if ($ip == $proxy->getIp()) {
$proxy->setActive();

return $proxy;
}
}
} catch (\Exception $exception) {

}

$proxy->setUnActive();

return false;
}

/**
* @param Response $response
*
* @return string
*/
protected function getCheckedIp($response)
{
$json = $response->data;

return $json['ip'];
}
}
7 changes: 7 additions & 0 deletions src/components/Request.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

namespace shintio\yii2\proxy\components;

class Request extends \yii\httpclient\Request
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

use app\modules\base\db\Migration;

/**
* Handles the creation of table `proxy_server`.
*/
class m180916_201222_create_proxy_server_table extends Migration
{
/**
* @inheritdoc
*/
public function up()
{
$this->createTable('proxy_server', [
'id' => $this->primaryKey(),
'ip' => $this->string()->notNull(),
'port' => $this->string()->notNull(),
'password' => $this->string(),
'country' => $this->string(),
'status' => $this->integer()->defaultValue(0),
'created_at' => $this->integer(),
'updated_at' => $this->integer(),
], $this->tableOptions());
}

/**
* @inheritdoc
*/
public function down()
{
$this->dropTable('proxy_server');
}
}
Loading

0 comments on commit 57bb078

Please sign in to comment.