PluginProbe
Migrate to WordPress.com / 5.88
Migrate to WordPress.com v5.88
6.72 6.65 trunk 5.72 5.81 5.88
wpcom-migration / callback / streams.php

streams.php in Migrate to WordPress.com 5.88, at callback/streams.php

255 lines 7.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 // phpcs:disable WordPress.WP.AlternativeFunctions.file_system_operations_fread
3 // phpcs:disable WordPress.WP.AlternativeFunctions.file_system_operations_fwrite
4 // phpcs:disable WordPress.WP.AlternativeFunctions.file_system_operations_fsockopen
5 // We use php method like fread, fwrite to read only a portion of a file, we don't have a direct method for partial reads since WP_Filesystem doesn't support a direct equivalent to fread, fwrite.
6 // The entire file deals with custom stream handling
7 // We need direct socket/file operations for this functionality
8 // WordPress filesystem alternatives wouldn't work for this use case
9 // It's better to disable these specific rules at file level than adding individual ignore comments
10 if (!defined('ABSPATH')) exit;
11 if (!class_exists('BVRespStream')) :
12
13 class BVStream extends BVCallbackBase {
14 public $bvb64stream;
15 public $bvb64cksize;
16 public $checksum;
17
18 function __construct($request) {
19 $this->bvb64stream = $request->bvb64stream;
20 $this->bvb64cksize = $request->bvb64cksize;
21 $this->checksum = $request->checksum;
22 }
23
24 public function writeChunk($chunk) {
25 }
26
27 public static function startStream($account, $request) {
28 $result = array();
29 $params = $request->params;
30 $stream = new BVRespStream($request);
31 if ($request->isAPICall()) {
32 $stream = new BVHttpStream($request);
33 if (!$stream->connect()) {
34 $apicallstatus = array(
35 "httperror" => "Cannot Open Connection to Host",
36 "streamerrno" => $stream->errno,
37 "streamerrstr" => $stream->errstr
38 );
39 return array("apicallstatus" => $apicallstatus);
40 }
41 if (array_key_exists('acbmthd', $params)) {
42 $qstr = http_build_query(array('bvapicheck' => $params['bvapicheck']));
43 $url = '/bvapi/'.$params['acbmthd']."?".$qstr;
44 if (array_key_exists('acbqry', $params)) {
45 $url .= "&".$params['acbqry'];
46 }
47 $stream->multipartChunkedPost($url);
48 } else {
49 return array("apicallstatus" => array("httperror" => "ApiCall method not present"));
50 }
51 }
52 return array('stream' => $stream);
53 }
54
55 public function writeStream($chunk) {
56 if (strlen($chunk) > 0) {
57 $bvb64_prefix = "";
58 if ($this->bvb64stream) {
59 $chunk_size = $this->bvb64cksize;
60 $chunk = $this->base64Encode($chunk, $chunk_size);
61 $bvb64_prefix .= "BVB64" . ":";
62 }
63
64 $hash_prefix = "";
65 if ($this->checksum == 'crc32') {
66 $hash_prefix .= "CRC32" . ":" . crc32($chunk) . ":";
67 } else if ($this->checksum == 'md5') {
68 $hash_prefix .= "MD5" . ":" . md5($chunk) . ":";
69 }
70
71 $chunk = $hash_prefix . $bvb64_prefix . strlen($chunk) . ":" . $chunk;
72
73 $this->writeChunk($chunk);
74 }
75 }
76 }
77
78 class BVRespStream extends BVStream {
79 public $bvboundry;
80
81 function __construct($request) {
82 parent::__construct($request);
83 $this->bvboundry = $request->bvboundry;
84 }
85
86 public function writeChunk($chunk) {
87 echo $this->bvboundry . "ckckckckck" . $chunk . $this->bvboundry . "ckckckckck";
88 }
89 public function endStream() {
90 echo $this->bvboundry . "rerererere";
91
92 return array();
93 }
94 }
95
96 class BVHttpStream extends BVStream {
97 var $user_agent = 'BVHttpStream';
98 var $host;
99 var $port;
100 var $timeout = 20;
101 var $conn;
102 var $errno;
103 var $errstr;
104 var $boundary;
105 var $apissl;
106
107 function __construct($request) {
108 parent::__construct($request);
109 $this->host = $request->params['apihost'];
110 $this->port = intval($request->params['apiport']);
111 $this->apissl = array_key_exists('apissl', $request->params);
112 }
113
114 public function connect() {
115 if ($this->apissl && function_exists('stream_socket_client')) {
116 $this->conn = stream_socket_client("ssl://".$this->host.":".$this->port, $errno, $errstr, $this->timeout);
117 } else {
118 $this->conn = @fsockopen($this->host, $this->port, $errno, $errstr, $this->timeout);
119 }
120 if (!$this->conn) {
121 $this->errno = $errno;
122 $this->errstr = $errstr;
123 return false;
124 }
125 socket_set_timeout($this->conn, $this->timeout);
126 return true;
127 }
128
129 public function write($data) {
130 fwrite($this->conn, $data);
131 }
132
133 public function sendChunk($data) {
134 $this->write(sprintf("%x\r\n", strlen($data)));
135 $this->write($data);
136 $this->write("\r\n");
137 }
138
139 public function sendRequest($method, $url, $headers = array(), $body = null) {
140 $def_hdrs = array("Connection" => "keep-alive",
141 "Host" => $this->host);
142 $headers = array_merge($def_hdrs, $headers);
143 $request = strtoupper($method)." ".$url." HTTP/1.1\r\n";
144 if (null != $body) {
145 $headers["Content-length"] = strlen($body);
146 }
147 foreach($headers as $key=>$val) {
148 $request .= $key.":".$val."\r\n";
149 }
150 $request .= "\r\n";
151 if (null != $body) {
152 $request .= $body;
153 }
154 $this->write($request);
155 return $request;
156 }
157
158 public function post($url, $headers = array(), $body = "") {
159 if(is_array($body)) {
160 $b = "";
161 foreach($body as $key=>$val) {
162 $b .= $key."=".urlencode($val)."&";
163 }
164 $body = substr($b, 0, strlen($b) - 1);
165 }
166 $this->sendRequest("POST", $url, $headers, $body);
167 }
168
169 public function streamedPost($url, $headers = array()) {
170 $headers['Transfer-Encoding'] = "chunked";
171 $this->sendRequest("POST", $url, $headers);
172 }
173
174 public function multipartChunkedPost($url) {
175 $mph = array(
176 "Content-Disposition" => "form-data; name=bvinfile; filename=data",
177 "Content-Type" => "application/octet-stream"
178 );
179 $rnd = rand(100000, 999999); // phpcs:ignore WordPress.WP.AlternativeFunctions.rand_rand
180 $this->boundary = "----".$rnd;
181 $prologue = "--".$this->boundary."\r\n";
182 foreach($mph as $key=>$val) {
183 $prologue .= $key.":".$val."\r\n";
184 }
185 $prologue .= "\r\n";
186 $headers = array('Content-Type' => "multipart/form-data; boundary=".$this->boundary);
187 $this->streamedPost($url, $headers);
188 $this->sendChunk($prologue);
189 }
190
191 public function writeChunk($data) {
192 $this->sendChunk($data);
193 }
194
195 public function closeChunk() {
196 $this->sendChunk("");
197 }
198
199 public function endStream() {
200 $epilogue = "\r\n\r\n--".$this->boundary."--\r\n";
201 $this->sendChunk($epilogue);
202 $this->closeChunk();
203
204 $result = array();
205 $resp = $this->getResponse();
206 if (array_key_exists('httperror', $resp)) {
207 $result["httperror"] = $resp['httperror'];
208 } else {
209 $result["respstatus"] = $resp['status'];
210 $result["respstatus_string"] = $resp['status_string'];
211 }
212 return array("apicallstatus" => $result);
213 }
214
215 public function getResponse() {
216 $response = array();
217 $response['headers'] = array();
218 $state = 1;
219 $conlen = 0;
220 stream_set_timeout($this->conn, 300);
221 while (!feof($this->conn)) {
222 $line = fgets($this->conn, 4096);
223 if (1 == $state) {
224 if (!WPCOMHelper::safePregMatch('/HTTP\/(\\d\\.\\d)\\s*(\\d+)\\s*(.*)/', $line, $m)) {
225 $response['httperror'] = "Status code line invalid: ".htmlentities($line);
226 return $response;
227 }
228 $response['http_version'] = $m[1];
229 $response['status'] = $m[2];
230 $response['status_string'] = $m[3];
231 $state = 2;
232 } else if (2 == $state) {
233 # End of headers
234 if (2 == strlen($line)) {
235 if ($conlen > 0)
236 $response['body'] = fread($this->conn, $conlen);
237 return $response;
238 }
239 if (!WPCOMHelper::safePregMatch('/([^:]+):\\s*(.*)/', $line, $m)) {
240 // Skip to the next header
241 continue;
242 }
243 $key = strtolower(trim($m[1]));
244 $val = trim($m[2]);
245 $response['headers'][$key] = $val;
246 if ($key == "content-length") {
247 $conlen = intval($val);
248 }
249 }
250 }
251 return $response;
252 }
253 }
254 // phpcs:enable
255 endif;