Skip to content

Commit e922e8b

Browse files
committed
curl: huge improvements
1 parent 3c7f799 commit e922e8b

File tree

7 files changed

+505
-180
lines changed

7 files changed

+505
-180
lines changed

examples/curl.php

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<?php
2+
3+
/*
4+
*
5+
* SimpleFramework
6+
*
7+
* This program is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation, either version 3 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* @author iTX Technologies
13+
* @link https://itxtech.org
14+
*
15+
*/
16+
17+
require_once "../autoload.php";
18+
19+
use iTXTech\SimpleFramework\Console\Logger;
20+
use iTXTech\SimpleFramework\Framework;
21+
use iTXTech\SimpleFramework\Util\Curl\Curl;
22+
use iTXTech\SimpleFramework\Util\Curl\UrlResolver;
23+
24+
Logger::$logLevel = Logger::DEBUG;
25+
Initializer::initTerminal(true);
26+
27+
class CustomizedCurl extends Curl{
28+
public function __construct(){
29+
parent::__construct()->setResolver(new class implements UrlResolver{
30+
public function resolve(string $url) : string{
31+
$u = parse_url($url);
32+
Logger::debug("Parsed URL: " . json_encode($u));
33+
return $url;
34+
}
35+
});
36+
}
37+
}
38+
39+
$res = Curl::setCurlClass(CustomizedCurl::class);
40+
Logger::info("CustomizedCurl init result: " . ($res ? "true" : "false"));
41+
42+
$curl = Curl::newInstance();
43+
$resp = $curl->setUrl("https://github.com")
44+
->setUserAgent(Framework::PROG_NAME . " " . Framework::PROG_VERSION)
45+
->exec();
46+
47+
if($resp->isSuccessfully()){
48+
Logger::info("Code: " . $resp->getHttpCode());
49+
Logger::info("Got " . count($resp->getCookies()) . " cookies");
50+
Logger::info("Got " . count($resp->getHeaders()) . " headers");
51+
Logger::info("Body len: " . strlen($resp->getBody()));
52+
}else{
53+
Logger::error("Cannot reach target");
54+
}

src/iTXTech/SimpleFramework/Util/Curl.php

Lines changed: 11 additions & 175 deletions
Original file line numberDiff line numberDiff line change
@@ -16,133 +16,37 @@
1616

1717
namespace iTXTech\SimpleFramework\Util;
1818

19-
class Curl{
20-
protected $curl;
21-
protected $url;
19+
//This class is created for backward compatibility
20+
//TODO: Deprecate in 2.3
21+
class Curl extends \iTXTech\SimpleFramework\Util\Curl\Curl{
2222
protected $content;
2323

24-
public function __construct(){
25-
$this->reload();
26-
return $this;
27-
}
28-
29-
public function reload(){
30-
if(is_resource($this->curl)){
31-
curl_close($this->curl);
32-
}
33-
$this->curl = curl_init();
34-
if(Util::getOS() === Util::OS_WINDOWS){
35-
$this->certVerify(false);
36-
}
37-
curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true);
38-
$this->returnHeader(true);
39-
$this->setTimeout(10);
40-
return $this;
41-
}
42-
43-
public function certVerify(bool $enable){
44-
curl_setopt($this->curl, CURLOPT_SSL_VERIFYHOST, $enable ? 1 : 0);
45-
curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER, $enable ? 1 : 0);
46-
return $this;
47-
}
48-
49-
public function setSocks5Proxy(string $address, string $pass = ""){
50-
curl_setopt($this->curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
51-
curl_setopt($this->curl, CURLOPT_PROXY, $address);
52-
if($pass !== ""){
53-
curl_setopt($this->curl, CURLOPT_PROXYUSERPWD, $pass);
54-
}
55-
return $this;
56-
}
57-
58-
public function getUrl(){
59-
return $this->url;
60-
}
61-
62-
public function getContent(){
63-
return $this->content;
64-
}
65-
66-
public function setUA(string $ua){
67-
curl_setopt($this->curl, CURLOPT_USERAGENT, $ua);
68-
return $this;
69-
}
70-
71-
public function setUrl(string $url){
72-
$this->url = $url;
73-
curl_setopt($this->curl, CURLOPT_URL, $url);
74-
return $this;
75-
}
76-
7724
public function returnHeader(bool $bool){
78-
curl_setopt($this->curl, CURLOPT_HEADER, ($bool == true) ? 1 : 0);
25+
curl_setopt($this->curl, CURLOPT_HEADER, $bool ? 1 : 0);
7926
return $this;
8027
}
8128

8229
public function returnBody(bool $bool){
83-
curl_setopt($this->curl, CURLOPT_NOBODY, ($bool == false) ? 1 : 0);
84-
return $this;
85-
}
86-
87-
public function setHeader(array $arr){
88-
curl_setopt($this->curl, CURLOPT_HTTPHEADER, $arr);
30+
curl_setopt($this->curl, CURLOPT_NOBODY, $bool ? 0 : 1);
8931
return $this;
9032
}
9133

9234
public function setCookie(array $cookies){
93-
$payload = '';
35+
$payload = "";
9436
foreach($cookies as $key => $cookie){
9537
$payload .= "$key=$cookie; ";
9638
}
39+
$payload = substr($payload, 0, strlen($payload) - 2);
9740
curl_setopt($this->curl, CURLOPT_COOKIE, $payload);
9841
return $this;
9942
}
10043

101-
public function setReferer(string $referer){
102-
curl_setopt($this->curl, CURLOPT_REFERER, $referer);
103-
return $this;
104-
}
105-
106-
public function setGet(array $get){
107-
$payload = '?';
108-
foreach($get as $key => $content){
109-
$payload .= urlencode($key) . '=' . urlencode($content) . '&';
110-
}
111-
curl_setopt($this->curl, CURLOPT_URL, $this->url . substr($payload, 0, strlen($payload) - 1));
112-
return $this;
113-
}
114-
115-
public function setPost(array $post){
116-
$payload = '';
117-
foreach($post as $key => $content){
118-
$payload .= urlencode($key) . '=' . urlencode($content) . '&';
119-
}
120-
curl_setopt($this->curl, CURLOPT_POST, 1);
121-
curl_setopt($this->curl, CURLOPT_POSTFIELDS, substr($payload, 0, strlen($payload) - 1));
122-
return $this;
123-
}
124-
125-
public function setEncPost($post){
126-
curl_setopt($this->curl, CURLOPT_POST, 1);
127-
curl_setopt($this->curl, CURLOPT_POSTFIELDS, $post);
128-
return $this;
129-
}
130-
131-
public function setTimeout(int $timeout){
132-
curl_setopt($this->curl, CURLOPT_CONNECTTIMEOUT, $timeout);
133-
curl_setopt($this->curl, CURLOPT_TIMEOUT, $timeout);
134-
return $this;
135-
}
136-
137-
public function setOpt(int $option, $value){
138-
curl_setopt($this->curl, $option, $value);
139-
return $this;
44+
public function setUA(string $ua){
45+
parent::setUserAgent($ua);
14046
}
14147

142-
public function keepCookie(){
143-
curl_setopt($this->curl, CURLOPT_COOKIEJAR, '');
144-
curl_setopt($this->curl, CURLOPT_COOKIEFILE, '');
145-
return $this;
48+
public function getContent(){
49+
return $this->content;
14650
}
14751

14852
public function exec(){
@@ -163,72 +67,4 @@ public function getCookie(){
16367
}
16468
return $payload;
16569
}
166-
167-
public function isError(){
168-
return (curl_errno($this->curl)) ? true : false;
169-
}
170-
171-
public function uploadFile(array $assoc = [], array $files = [],
172-
string $fileType = "application/octet-stream",
173-
array $extraHeaders = []){
174-
$body = [];
175-
// invalid characters for "name" and "filename"
176-
$disallow = ["\0", "\"", "\r", "\n"];
177-
178-
// build normal parameters
179-
foreach($assoc as $k => $v){
180-
$k = str_replace($disallow, "_", $k);
181-
$body[] = implode("\r\n", [
182-
"Content-Disposition: form-data; name=\"{$k}\"",
183-
"",
184-
filter_var($v),
185-
]);
186-
}
187-
188-
foreach($files as $k => $v){
189-
switch(true){
190-
case false === $v = realpath(filter_var($v)):
191-
case !is_file($v):
192-
case !is_readable($v):
193-
continue;
194-
}
195-
$data = file_get_contents($v);
196-
$v = explode(DIRECTORY_SEPARATOR, $v);
197-
$v = end($v);
198-
$k = str_replace($disallow, "_", $k);
199-
$v = str_replace($disallow, "_", $v);
200-
$body[] = implode("\r\n", [
201-
"Content-Disposition: form-data; name=\"{$k}\"; filename=\"{$v}\"",
202-
"Content-Type: $fileType",
203-
"",
204-
$data,
205-
]);
206-
}
207-
208-
// generate safe boundary
209-
do{
210-
$boundary = "---------------------" . md5(mt_rand() . microtime());
211-
}while(preg_grep("/{$boundary}/", $body));
212-
213-
// add boundary for each parameters
214-
array_walk($body, function (&$part) use ($boundary){
215-
$part = "--{$boundary}\r\n{$part}";
216-
});
217-
218-
// add final boundary
219-
$body[] = "--{$boundary}--";
220-
$body[] = "";
221-
222-
// set options
223-
@curl_setopt_array($this->curl, [
224-
CURLOPT_POST => true,
225-
CURLOPT_POSTFIELDS => implode("\r\n", $body),
226-
CURLOPT_HTTPHEADER => array_merge([
227-
"Expect: ",
228-
"Content-Type: multipart/form-data; boundary={$boundary}", // change Content-Type
229-
], $extraHeaders)
230-
]);
231-
232-
return $this;
233-
}
23470
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php
2+
3+
/*
4+
*
5+
* SimpleFramework
6+
*
7+
* This program is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation, either version 3 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* @author iTX Technologies
13+
* @link https://itxtech.org
14+
*
15+
*/
16+
17+
namespace iTXTech\SimpleFramework\Util\Curl;
18+
19+
class Cookie{
20+
private $name;
21+
private $value;
22+
private $prop;
23+
24+
public function __construct(string $payload){
25+
$parts = explode("; ", $payload);
26+
list($this->name, $this->value) = explode("=", $parts[0]);
27+
array_shift($parts);
28+
foreach($parts as $part){
29+
$p = explode("=", $part);
30+
$this->prop[$p[0]] = $p[1] ?? "";
31+
}
32+
}
33+
34+
public function getName(){
35+
return $this->name;
36+
}
37+
38+
public function getValue(){
39+
return $this->value;
40+
}
41+
42+
public function hasProperty(string $name){
43+
return isset($this->prop[$name]);
44+
}
45+
46+
public function getProperty(string $name) : ?string{
47+
return $this->prop[$name] ?? null;
48+
}
49+
50+
public function __toString(){
51+
$buffer = $this->name . "=" . $this->value . "; ";
52+
foreach($this->prop as $k => $v){
53+
if($v === ""){
54+
$buffer .= $k . "; ";
55+
}else{
56+
$buffer .= $k . "=$v; ";
57+
}
58+
}
59+
return substr($buffer, 0, strlen($buffer) - 2);
60+
}
61+
}

0 commit comments

Comments
 (0)