Skip to content

Commit 57bb078

Browse files
committed
Initial commit
0 parents  commit 57bb078

File tree

9 files changed

+544
-0
lines changed

9 files changed

+544
-0
lines changed

README.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
Yii2 Proxy Httpclient
2+
=====================
3+
Native httpclient with custom or autoparsed free proxy servers
4+
5+
Installation
6+
------------
7+
8+
The preferred way to install this extension is through [composer](http://getcomposer.org/download/).
9+
10+
Either run
11+
12+
```
13+
php composer.phar require --prefer-dist shintio/yii2-proxy-httpclient "*"
14+
```
15+
16+
or add
17+
18+
```
19+
"shintio/yii2-proxy-httpclient": "*"
20+
```
21+
22+
to the require section of your `composer.json` file.
23+
24+
25+
Usage
26+
-----
27+
28+
Once the extension is installed, simply use it in your code by :
29+
30+
```php
31+
<?= \shintio\yii2\proxy\AutoloadExample::widget(); ?>```

composer.json

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"name": "shintio/yii2-proxy-httpclient",
3+
"description": "Native httpclient with custom or autoparsed free proxy servers",
4+
"type": "yii2-extension",
5+
"keywords": [
6+
"yii2",
7+
"extension",
8+
"proxy",
9+
"curl",
10+
"httpclient"
11+
],
12+
"license": "BSD-3-Clause",
13+
"authors": [
14+
{
15+
"name": "Aleksey Fedorenko",
16+
"email": "shintio.afedorenko@gmail.com"
17+
}
18+
],
19+
"require": {
20+
"yiisoft/yii2": "~2.0.0",
21+
"yiisoft/yii2-httpclient": "^2.0",
22+
"electrolinux/phpquery": "^0.9.6"
23+
},
24+
"autoload": {
25+
"psr-4": {
26+
"shintio\\yii2\\proxy\\": "src/"
27+
}
28+
}
29+
}

src/components/Client.php

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php
2+
3+
namespace shintio\yii2\proxy\components;
4+
5+
use shintio\yii2\proxy\models\ProxyServerInterface;
6+
use yii\helpers\ArrayHelper;
7+
8+
/**
9+
* Class Client
10+
* @package shintio\yii2\proxy\components
11+
*
12+
* @property ProxyServerInterface $proxyServerClass
13+
* @property ProxyManager $proxyManager
14+
*/
15+
class Client extends \yii\httpclient\Client
16+
{
17+
public $proxyServerClass;
18+
19+
public $proxyManager;
20+
21+
public function createRequest($rescan = true, $checkProxy = true, $checkTimeout = 5)
22+
{
23+
ArrayHelper::setValue($this->requestConfig, 'class', $this->requestConfig['class'] ?? Request::class);
24+
25+
$request = parent::createRequest();
26+
27+
$proxy = $this->getProxyManager()->getProxyString($checkProxy, $checkTimeout);
28+
29+
if (!$proxy && $rescan) {
30+
$this->getProxyManager()->parseNewProxy();
31+
32+
$proxy = $this->getProxyManager()->getProxyString($checkProxy, $checkTimeout);
33+
}
34+
35+
if ($proxy) {
36+
$request->setOptions(['proxy' => $proxy]);
37+
}
38+
39+
return $request;
40+
}
41+
42+
public function getProxyManager()
43+
{
44+
return $this->proxyManager ?? new ProxyManager();
45+
}
46+
}

src/components/ProxyManager.php

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
<?php
2+
3+
namespace shintio\yii2\proxy\components;
4+
5+
use shintio\yii2\proxy\models\ProxyServer;
6+
use shintio\yii2\proxy\models\ProxyServerInterface;
7+
use yii\helpers\ArrayHelper;
8+
use yii\httpclient\Response;
9+
10+
/**
11+
* Class ProxyParser
12+
* @package shintio\yii2\proxy\components
13+
*
14+
* @property ProxyServerInterface $proxyServerModel
15+
*/
16+
class ProxyManager
17+
{
18+
public $proxyServerModel = ProxyServer::class;
19+
20+
public $client;
21+
22+
public $checkerUrl = 'https://ipleak.net/json/';
23+
public $proxyLists = [
24+
[
25+
'url' => 'https://free-proxy-list.net/',
26+
'container' => 'table#proxylisttable',
27+
'ip' => 0,
28+
'port' => 1,
29+
'country' => 3,
30+
]
31+
];
32+
33+
/**
34+
* @return integer
35+
*/
36+
public function parseNewProxy()
37+
{
38+
$count = 0;
39+
40+
foreach ($this->proxyLists as $proxyList) {
41+
$url = ArrayHelper::remove($proxyList, 'url');
42+
$container = ArrayHelper::remove($proxyList, 'container');
43+
44+
$client = $this->getClient();
45+
46+
$request = $client->createRequest()->setMethod('get')->setUrl($url);
47+
48+
$response = $request->send();
49+
50+
if ($response->isOk) {
51+
$document = \phpQuery::newDocumentHTML($response->content);
52+
53+
$proxies = [];
54+
55+
foreach ($proxyList as $key => $attribute) {
56+
foreach ($document->find("$container tr") as $item) {
57+
/** @var \DOMElement $item */
58+
if ($item->childNodes[$proxyList['ip']]->tagName == 'td') {
59+
($this->proxyServerModel)::saveNew($item->childNodes[$proxyList['ip']]->nodeValue,
60+
$item->childNodes[$proxyList['port']]->nodeValue,
61+
$item->childNodes[$proxyList['password']]->nodeValue ?? null,
62+
$item->childNodes[$proxyList['country']]->nodeValue ?? null);
63+
64+
$count++;
65+
}
66+
}
67+
}
68+
}
69+
}
70+
71+
return $count;
72+
}
73+
74+
/**
75+
* @param ProxyServerInterface|null $proxy
76+
* @param integer $timeout
77+
*
78+
* @return ProxyServerInterface|boolean
79+
*/
80+
public function checkProxy($proxy = null, $timeout = 5)
81+
{
82+
if (isset($proxy)) {
83+
return $this->sendCheckRequest($proxy, $timeout);
84+
} else {
85+
do {
86+
$proxy = ($this->proxyServerModel)::findNew();
87+
88+
if (isset($proxy)) {
89+
$proxy = $this->sendCheckRequest($proxy, $timeout);
90+
} else {
91+
return false;
92+
}
93+
} while (empty($proxy));
94+
95+
return $proxy;
96+
}
97+
}
98+
99+
public function getClient()
100+
{
101+
return $this->client ?? new \yii\httpclient\Client();
102+
}
103+
104+
/**
105+
* @param bool $check
106+
* @param integer $timeout
107+
*
108+
* @return ProxyServerInterface
109+
*/
110+
public function getProxy($check = true, $timeout = 5)
111+
{
112+
$proxy = ($this->proxyServerModel)::findActive();
113+
114+
return $check ? $this->checkProxy($proxy, $timeout) : $proxy;
115+
}
116+
117+
/**
118+
* @param bool $check
119+
* @param integer $timeout
120+
*
121+
* @return string|boolean
122+
*/
123+
public function getProxyString($check = true, $timeout = 5)
124+
{
125+
$proxy = $this->getProxy($check, $timeout);
126+
127+
return $proxy ? $this->formatProxyString($proxy) : false;
128+
}
129+
130+
/**
131+
* @param ProxyServerInterface $proxy
132+
*
133+
* @return string
134+
*/
135+
public function formatProxyString($proxy)
136+
{
137+
return 'tcp://' . $proxy->getIp() . ':' . $proxy->getPort();
138+
}
139+
140+
/**
141+
* @param ProxyServerInterface $proxy
142+
* @param integer $timeout
143+
*
144+
* @return ProxyServerInterface|boolean
145+
*/
146+
protected function sendCheckRequest($proxy, $timeout = 5)
147+
{
148+
$client = $this->getClient();
149+
150+
$request = $client->createRequest()->setMethod('get')->setOptions([
151+
'proxy' => $this->formatProxyString($proxy),
152+
'timeout' => $timeout
153+
])->setUrl($this->checkerUrl);
154+
155+
try {
156+
$response = $request->send();
157+
158+
if ($response->isOk) {
159+
$ip = $this->getCheckedIp($response);
160+
161+
if ($ip == $proxy->getIp()) {
162+
$proxy->setActive();
163+
164+
return $proxy;
165+
}
166+
}
167+
} catch (\Exception $exception) {
168+
169+
}
170+
171+
$proxy->setUnActive();
172+
173+
return false;
174+
}
175+
176+
/**
177+
* @param Response $response
178+
*
179+
* @return string
180+
*/
181+
protected function getCheckedIp($response)
182+
{
183+
$json = $response->data;
184+
185+
return $json['ip'];
186+
}
187+
}

src/components/Request.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
namespace shintio\yii2\proxy\components;
4+
5+
class Request extends \yii\httpclient\Request
6+
{
7+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
use app\modules\base\db\Migration;
4+
5+
/**
6+
* Handles the creation of table `proxy_server`.
7+
*/
8+
class m180916_201222_create_proxy_server_table extends Migration
9+
{
10+
/**
11+
* @inheritdoc
12+
*/
13+
public function up()
14+
{
15+
$this->createTable('proxy_server', [
16+
'id' => $this->primaryKey(),
17+
'ip' => $this->string()->notNull(),
18+
'port' => $this->string()->notNull(),
19+
'password' => $this->string(),
20+
'country' => $this->string(),
21+
'status' => $this->integer()->defaultValue(0),
22+
'created_at' => $this->integer(),
23+
'updated_at' => $this->integer(),
24+
], $this->tableOptions());
25+
}
26+
27+
/**
28+
* @inheritdoc
29+
*/
30+
public function down()
31+
{
32+
$this->dropTable('proxy_server');
33+
}
34+
}

0 commit comments

Comments
 (0)