Skip to content

Commit b3b8acd

Browse files
committed
curl: change UrlResolve -> Preprocessor
1 parent 7278312 commit b3b8acd

File tree

4 files changed

+129
-28
lines changed

4 files changed

+129
-28
lines changed

examples/curl.php

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,28 +19,36 @@
1919
use iTXTech\SimpleFramework\Console\Logger;
2020
use iTXTech\SimpleFramework\Framework;
2121
use iTXTech\SimpleFramework\Util\Curl\Curl;
22-
use iTXTech\SimpleFramework\Util\Curl\UrlResolver;
22+
use iTXTech\SimpleFramework\Util\Curl\Preprocessor;
2323

2424
Logger::$logLevel = Logger::DEBUG;
2525
Initializer::initTerminal(true);
2626

2727
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);
28+
/** @var Preprocessor */
29+
public static $processor;
30+
31+
public static function init(){
32+
self::$processor = new class implements Preprocessor{
33+
public function process(Curl $curl){
34+
$u = parse_url($curl->getUrl());
3235
Logger::debug("Parsed URL: " . json_encode($u));
33-
return $url;
3436
}
35-
});
37+
};
38+
}
39+
40+
public function __construct(){
41+
parent::__construct()->setPreprocessor(self::$processor);
3642
}
3743
}
3844

45+
CustomizedCurl::init();
3946
$res = Curl::setCurlClass(CustomizedCurl::class);
4047
Logger::info("CustomizedCurl init result: " . ($res ? "true" : "false"));
4148

4249
$curl = Curl::newInstance();
4350
$resp = $curl->setUrl("https://github.com")
51+
->setHeader(["Expect:"])
4452
->setUserAgent(Framework::PROG_NAME . " " . Framework::PROG_VERSION)
4553
->exec();
4654

src/iTXTech/SimpleFramework/Util/Curl.php

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
namespace iTXTech\SimpleFramework\Util;
1818

19+
use iTXTech\SimpleFramework\Util\Curl\Preprocessor;
20+
1921
//This class is created for backward compatibility
2022
//TODO: Deprecate in 2.3
2123
class Curl extends \iTXTech\SimpleFramework\Util\Curl\Curl{
@@ -45,6 +47,17 @@ public function setUA(string $ua){
4547
parent::setUserAgent($ua);
4648
}
4749

50+
public function setUrl(string $url){
51+
$this->url = $url;
52+
curl_setopt($this->curl, CURLOPT_URL, $url);
53+
return $this;
54+
}
55+
56+
public function setHeader($arr, string $v = ""){
57+
curl_setopt($this->curl, CURLOPT_HTTPHEADER, $arr);
58+
return $this;
59+
}
60+
4861
public function getContent(){
4962
return $this->content;
5063
}
@@ -67,4 +80,72 @@ public function getCookie(){
6780
}
6881
return $payload;
6982
}
83+
84+
public function uploadFile(array $assoc = [], array $files = [],
85+
string $fileType = "application/octet-stream",
86+
array $extraHeaders = []){
87+
$body = [];
88+
// invalid characters for "name" and "filename"
89+
$disallow = ["\0", "\"", "\r", "\n"];
90+
91+
// build normal parameters
92+
foreach($assoc as $k => $v){
93+
$k = str_replace($disallow, "_", $k);
94+
$body[] = implode("\r\n", [
95+
"Content-Disposition: form-data; name=\"{$k}\"",
96+
"",
97+
filter_var($v),
98+
]);
99+
}
100+
101+
foreach($files as $k => $v){
102+
switch(true){
103+
case false === $v = realpath(filter_var($v)):
104+
case !is_file($v):
105+
case !is_readable($v):
106+
continue;
107+
}
108+
$data = file_get_contents($v);
109+
$v = explode(DIRECTORY_SEPARATOR, $v);
110+
$v = end($v);
111+
$k = str_replace($disallow, "_", $k);
112+
$v = str_replace($disallow, "_", $v);
113+
$body[] = implode("\r\n", [
114+
"Content-Disposition: form-data; name=\"{$k}\"; filename=\"{$v}\"",
115+
"Content-Type: $fileType",
116+
"",
117+
$data,
118+
]);
119+
}
120+
121+
// generate safe boundary
122+
do{
123+
$boundary = "---------------------" . md5(mt_rand() . microtime());
124+
}while(preg_grep("/{$boundary}/", $body));
125+
126+
// add boundary for each parameters
127+
array_walk($body, function(&$part) use ($boundary){
128+
$part = "--{$boundary}\r\n{$part}";
129+
});
130+
131+
// add final boundary
132+
$body[] = "--{$boundary}--";
133+
$body[] = "";
134+
135+
// set options
136+
@curl_setopt_array($this->curl, [
137+
CURLOPT_POST => true,
138+
CURLOPT_POSTFIELDS => implode("\r\n", $body),
139+
CURLOPT_HTTPHEADER => array_merge([
140+
"Expect: ",
141+
"Content-Type: multipart/form-data; boundary={$boundary}", // change Content-Type
142+
], $extraHeaders)
143+
]);
144+
145+
return $this;
146+
}
147+
148+
public function setPreprocessor(Preprocessor $preprocessor){
149+
throw new \RuntimeException("Unsupported operation: setPreprocessor");
150+
}
70151
}

src/iTXTech/SimpleFramework/Util/Curl/Curl.php

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,14 @@
2020

2121
class Curl{
2222
protected $curl;
23-
protected $url;
23+
24+
protected $headers = [];
25+
public $url;
26+
2427
/** @var Response */
2528
protected $response;
26-
/** @var UrlResolver */
27-
protected $resolver;
29+
/** @var Preprocessor */
30+
protected $preprocessor;
2831

2932
private static $CURL_CLASS = Curl::class;
3033

@@ -59,8 +62,9 @@ public function reload(){
5962
return $this;
6063
}
6164

62-
public function setResolver(UrlResolver $resolver) : void{
63-
$this->resolver = $resolver;
65+
public function setPreprocessor(Preprocessor $preprocessor){
66+
$this->preprocessor = $preprocessor;
67+
return $this;
6468
}
6569

6670
public function certVerify(bool $enable){
@@ -92,16 +96,19 @@ public function setUserAgent(string $ua){
9296
}
9397

9498
public function setUrl(string $url){
95-
if($this->resolver !== null){
96-
$url = $this->resolver->resolve($url);
97-
}
9899
$this->url = $url;
99-
curl_setopt($this->curl, CURLOPT_URL, $url);
100100
return $this;
101101
}
102102

103-
public function setHeader(array $arr){
104-
curl_setopt($this->curl, CURLOPT_HTTPHEADER, $arr);
103+
public function setHeaders(array $arr){
104+
$this->headers = $arr;
105+
return $this;
106+
}
107+
108+
public function setHeader($k, string $v = ""){
109+
if(is_string($k)){
110+
$this->headers[$k] = $v;
111+
}
105112
return $this;
106113
}
107114

@@ -158,6 +165,15 @@ public function setOpt(int $option, $value){
158165
}
159166

160167
public function exec(){
168+
if($this->preprocessor !== null){
169+
$this->preprocessor->process($this);
170+
}
171+
$headers = [];
172+
foreach($this->headers as $k => $v){
173+
$headers[] = $k . ": " . $v;
174+
}
175+
curl_setopt($this->curl, CURLOPT_HTTPHEADER, $headers);
176+
curl_setopt($this->curl, CURLOPT_URL, $this->url);
161177
$this->response = new Response(curl_exec($this->curl));
162178
$this->reload();
163179
return $this->response;
@@ -168,8 +184,7 @@ public function hasError(){
168184
}
169185

170186
public function uploadFile(array $assoc = [], array $files = [],
171-
string $fileType = "application/octet-stream",
172-
array $extraHeaders = []){
187+
string $fileType = "application/octet-stream"){
173188
$body = [];
174189
// invalid characters for "name" and "filename"
175190
$disallow = ["\0", "\"", "\r", "\n"];
@@ -221,13 +236,10 @@ public function uploadFile(array $assoc = [], array $files = [],
221236
// set options
222237
@curl_setopt_array($this->curl, [
223238
CURLOPT_POST => true,
224-
CURLOPT_POSTFIELDS => implode("\r\n", $body),
225-
CURLOPT_HTTPHEADER => array_merge([
226-
"Expect: ",
227-
"Content-Type: multipart/form-data; boundary={$boundary}", // change Content-Type
228-
], $extraHeaders)
239+
CURLOPT_POSTFIELDS => implode("\r\n", $body)
229240
]);
230241

231-
return $this;
242+
return $this->setHeader("Expect", "")
243+
->setHeader("Content-Type", "multipart/form-data; boundary={$boundary}");
232244
}
233245
}

src/iTXTech/SimpleFramework/Util/Curl/UrlResolver.php renamed to src/iTXTech/SimpleFramework/Util/Curl/Preprocessor.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,6 @@
1616

1717
namespace iTXTech\SimpleFramework\Util\Curl;
1818

19-
interface UrlResolver{
20-
public function resolve(string $url) : string;
19+
interface Preprocessor{
20+
public function process(Curl $curl);
2121
}

0 commit comments

Comments
 (0)