Passed
Push — master ( b5dddf...91d417 )
by Richard
09:12
created

Snoopy::_httprequest()   F

Complexity

Conditions 47
Paths > 20000

Size

Total Lines 165

Duplication

Lines 52
Ratio 31.52 %

Importance

Changes 0
Metric Value
cc 47
nc 11819520
nop 6
dl 52
loc 165
rs 0
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/*************************************************
4
 *
5
 * Snoopy - the PHP net client
6
 * Author: Monte Ohrt <[email protected]>
7
 * Copyright (c): 1999-2014, all rights reserved
8
 * Version: 1.2.5
9
 * This library is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU Lesser General Public
11
 * License as published by the Free Software Foundation; either
12
 * version 2.1 of the License, or (at your option) any later version.
13
 *
14
 * This library is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
 * Lesser General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Lesser General Public
20
 * License along with this library; if not, write to the Free Software
21
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22
 *
23
 * You may contact the author of Snoopy by e-mail at:
24
 * [email protected]
25
 *
26
 * The latest version of Snoopy can be obtained from:
27
 * http://snoopy.sourceforge.net/
28
 *************************************************/
29
class Snoopy
30
{
31
    /**** Public variables ****/
32
33
    /* user definable vars */
34
35
    var $host = "www.php.net"; // host name we are connecting to
36
    var $port = 80; // port we are connecting to
37
    var $proxy_host = ""; // proxy host to use
38
    var $proxy_port = ""; // proxy port to use
39
    var $proxy_user = ""; // proxy user to use
40
    var $proxy_pass = ""; // proxy password to use
41
42
    var $agent = "Snoopy v1.2.5"; // agent we masquerade as
43
    var $referer = ""; // referer info to pass
44
    var $cookies = array(); // array of cookies to pass
45
    // $cookies["username"]="joe";
46
    var $rawheaders = array(); // array of raw headers to send
47
    // $rawheaders["Content-type"]="text/html";
48
49
    var $maxredirs = 5; // http redirection depth maximum. 0 = disallow
50
    var $lastredirectaddr = ""; // contains address of last redirected address
51
    var $offsiteok = true; // allows redirection off-site
52
    var $maxframes = 0; // frame content depth maximum. 0 = disallow
53
    var $expandlinks = true; // expand links to fully qualified URLs.
54
    // this only applies to fetchlinks()
55
    // submitlinks(), and submittext()
56
    var $passcookies = true; // pass set cookies back through redirects
57
    // NOTE: this currently does not respect
58
    // dates, domains or paths.
59
60
    var $user = ""; // user for http authentication
61
    var $pass = ""; // password for http authentication
62
63
    // http accept types
64
    var $accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*";
65
66
    var $results = ""; // where the content is put
67
68
    var $error = ""; // error messages sent here
69
    var $response_code = ""; // response code returned from server
70
    var $headers = array(); // headers returned from server sent here
71
    var $maxlength = 500000; // max return data length (body)
72
    var $read_timeout = 0; // timeout on read operations, in seconds
73
    // supported only since PHP 4 Beta 4
74
    // set to 0 to disallow timeouts
75
    var $timed_out = false; // if a read operation timed out
76
    var $status = 0; // http request status
77
78
    var $temp_dir = "/tmp"; // temporary directory that the webserver
79
    // has permission to write to.
80
    // under Windows, this should be C:\temp
81
82
    var $curl_path = "/usr/bin/curl";
83
    // Snoopy will use cURL for fetching
84
    // SSL content if a full system path to
85
    // the cURL binary is supplied here.
86
    // set to false if you do not have
87
    // cURL installed. See http://curl.haxx.se
88
    // for details on installing cURL.
89
    // Snoopy does *not* use the cURL
90
    // library functions built into php,
91
    // as these functions are not stable
92
    // as of this Snoopy release.
93
94
    // send Accept-encoding: gzip?
95
    var $use_gzip = true;
96
    /**** Private variables ****/
97
98
    var $_maxlinelen = 4096; // max line length (headers)
99
100
    var $_httpmethod = "GET"; // default http request method
101
    var $_httpversion = "HTTP/1.0"; // default http request version
102
    var $_submit_method = "POST"; // default submit method
103
    var $_submit_type = "application/x-www-form-urlencoded"; // default submit type
104
    var $_mime_boundary = ""; // MIME boundary for multipart/form-data submit type
105
    var $_redirectaddr = false; // will be set if page fetched is a redirect
106
    var $_redirectdepth = 0; // increments on an http redirect
107
    var $_frameurls = array(); // frame src urls
108
    var $_framedepth = 0; // increments on frame depth
109
110
    var $_isproxy = false; // set if using a proxy server
111
    var $_fp_timeout = 30; // timeout for socket connection
112
113
    /*======================================================================*\
114
        Function:	fetch
115
        Purpose:	fetch the contents of a web page
116
                    (and possibly other protocols in the
117
                    future like ftp, nntp, gopher, etc.)
118
        Input:		$URI	the location of the page to fetch
119
        Output:		$this->results	the output text from the fetch
120
    \*======================================================================*/
121
122
    function fetch($URI)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
123
    {
124
125
        //preg_match("|^([^:]+)://([^:/]+)(:[\d]+)*(.*)|",$URI,$URI_PARTS);
126
        $URI_PARTS = parse_url($URI);
127
        if (!empty($URI_PARTS["user"]))
128
            $this->user = $URI_PARTS["user"];
129
        if (!empty($URI_PARTS["pass"]))
130
            $this->pass = $URI_PARTS["pass"];
131
        if (empty($URI_PARTS["query"]))
132
            $URI_PARTS["query"] = '';
133
        if (empty($URI_PARTS["path"]))
134
            $URI_PARTS["path"] = '';
135
136
        switch (strtolower($URI_PARTS["scheme"])) {
137
            case "http":
138
                $this->host = $URI_PARTS["host"];
139
                if (!empty($URI_PARTS["port"]))
140
                    $this->port = $URI_PARTS["port"];
141
                if ($this->_connect($fp)) {
142
                    if ($this->_isproxy) {
143
                        // using proxy, send entire URI
144
                        $this->_httprequest($URI, $fp, $URI, $this->_httpmethod);
145
                    } else {
146
                        $path = $URI_PARTS["path"] . ($URI_PARTS["query"] ? "?" . $URI_PARTS["query"] : "");
147
                        // no proxy, send only the path
148
                        $this->_httprequest($path, $fp, $URI, $this->_httpmethod);
149
                    }
150
151
                    $this->_disconnect($fp);
152
153
                    if ($this->_redirectaddr) {
154
                        /* url was redirected, check if we've hit the max depth */
155
                        if ($this->maxredirs > $this->_redirectdepth) {
156
                            // only follow redirect if it's on this site, or offsiteok is true
157
                            if (preg_match("|^http://" . preg_quote($this->host) . "|i", $this->_redirectaddr) || $this->offsiteok) {
158
                                /* follow the redirect */
159
                                $this->_redirectdepth++;
160
                                $this->lastredirectaddr = $this->_redirectaddr;
161
                                $this->fetch($this->_redirectaddr);
162
                            }
163
                        }
164
                    }
165
166
                    if ($this->_framedepth < $this->maxframes && count($this->_frameurls) > 0) {
167
                        $frameurls = $this->_frameurls;
168
                        $this->_frameurls = array();
169
170
                        while (list(, $frameurl) = each($frameurls)) {
0 ignored issues
show
Deprecated Code introduced by
The function each() has been deprecated: 7.2 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

170
                        while (list(, $frameurl) = /** @scrutinizer ignore-deprecated */ each($frameurls)) {

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
171
                            if ($this->_framedepth < $this->maxframes) {
172
                                $this->fetch($frameurl);
173
                                $this->_framedepth++;
174
                            } else
175
                                break;
176
                        }
177
                    }
178
                } else {
179
                    return false;
180
                }
181
                return true;
182
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
183
            case "https":
184
                if (!$this->curl_path)
185
                    return false;
186
                if (function_exists("is_executable"))
187
                    if (!is_executable($this->curl_path))
188
                        return false;
189
                $this->host = $URI_PARTS["host"];
190
                if (!empty($URI_PARTS["port"]))
191
                    $this->port = $URI_PARTS["port"];
192
                if ($this->_isproxy) {
193
                    // using proxy, send entire URI
194
                    $this->_httpsrequest($URI, $URI, $this->_httpmethod);
195
                } else {
196
                    $path = $URI_PARTS["path"] . ($URI_PARTS["query"] ? "?" . $URI_PARTS["query"] : "");
197
                    // no proxy, send only the path
198
                    $this->_httpsrequest($path, $URI, $this->_httpmethod);
199
                }
200
201
                if ($this->_redirectaddr) {
202
                    /* url was redirected, check if we've hit the max depth */
203
                    if ($this->maxredirs > $this->_redirectdepth) {
204
                        // only follow redirect if it's on this site, or offsiteok is true
205
                        if (preg_match("|^http://" . preg_quote($this->host) . "|i", $this->_redirectaddr) || $this->offsiteok) {
0 ignored issues
show
Bug introduced by
$this->_redirectaddr of type true is incompatible with the type string expected by parameter $subject of preg_match(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

205
                        if (preg_match("|^http://" . preg_quote($this->host) . "|i", /** @scrutinizer ignore-type */ $this->_redirectaddr) || $this->offsiteok) {
Loading history...
206
                            /* follow the redirect */
207
                            $this->_redirectdepth++;
208
                            $this->lastredirectaddr = $this->_redirectaddr;
209
                            $this->fetch($this->_redirectaddr);
210
                        }
211
                    }
212
                }
213
214
                if ($this->_framedepth < $this->maxframes && count($this->_frameurls) > 0) {
215
                    $frameurls = $this->_frameurls;
216
                    $this->_frameurls = array();
217
218
                    while (list(, $frameurl) = each($frameurls)) {
0 ignored issues
show
Deprecated Code introduced by
The function each() has been deprecated: 7.2 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

218
                    while (list(, $frameurl) = /** @scrutinizer ignore-deprecated */ each($frameurls)) {

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
219
                        if ($this->_framedepth < $this->maxframes) {
220
                            $this->fetch($frameurl);
221
                            $this->_framedepth++;
222
                        } else
223
                            break;
224
                    }
225
                }
226
                return true;
227
                break;
228
            default:
229
                // not a valid protocol
230
                $this->error = 'Invalid protocol "' . $URI_PARTS["scheme"] . '"\n';
231
                return false;
232
                break;
233
        }
234
        return true;
0 ignored issues
show
Unused Code introduced by
return true is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
235
    }
236
237
    /*======================================================================*\
238
        Function:	submit
239
        Purpose:	submit an http form
240
        Input:		$URI	the location to post the data
241
                    $formvars	the formvars to use.
242
                        format: $formvars["var"] = "val";
243
                    $formfiles  an array of files to submit
244
                        format: $formfiles["var"] = "/dir/filename.ext";
245
        Output:		$this->results	the text output from the post
246
    \*======================================================================*/
247
248
    function submit($URI, $formvars = "", $formfiles = "")
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
249
    {
250
        unset($postdata);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $postdata seems to be never defined.
Loading history...
251
252
        $postdata = $this->_prepare_post_body($formvars, $formfiles);
253
254
        $URI_PARTS = parse_url($URI);
255
        if (!empty($URI_PARTS["user"]))
256
            $this->user = $URI_PARTS["user"];
257
        if (!empty($URI_PARTS["pass"]))
258
            $this->pass = $URI_PARTS["pass"];
259
        if (empty($URI_PARTS["query"]))
260
            $URI_PARTS["query"] = '';
261
        if (empty($URI_PARTS["path"]))
262
            $URI_PARTS["path"] = '';
263
264
        switch (strtolower($URI_PARTS["scheme"])) {
265
            case "http":
266
                $this->host = $URI_PARTS["host"];
267
                if (!empty($URI_PARTS["port"]))
268
                    $this->port = $URI_PARTS["port"];
269
                if ($this->_connect($fp)) {
270
                    if ($this->_isproxy) {
271
                        // using proxy, send entire URI
272
                        $this->_httprequest($URI, $fp, $URI, $this->_submit_method, $this->_submit_type, $postdata);
273
                    } else {
274
                        $path = $URI_PARTS["path"] . ($URI_PARTS["query"] ? "?" . $URI_PARTS["query"] : "");
275
                        // no proxy, send only the path
276
                        $this->_httprequest($path, $fp, $URI, $this->_submit_method, $this->_submit_type, $postdata);
277
                    }
278
279
                    $this->_disconnect($fp);
280
281
                    if ($this->_redirectaddr) {
282
                        /* url was redirected, check if we've hit the max depth */
283
                        if ($this->maxredirs > $this->_redirectdepth) {
284
                            if (!preg_match("|^" . $URI_PARTS["scheme"] . "://|", $this->_redirectaddr))
285
                                $this->_redirectaddr = $this->_expandlinks($this->_redirectaddr, $URI_PARTS["scheme"] . "://" . $URI_PARTS["host"]);
286
287
                            // only follow redirect if it's on this site, or offsiteok is true
288
                            if (preg_match("|^http://" . preg_quote($this->host) . "|i", $this->_redirectaddr) || $this->offsiteok) {
289
                                /* follow the redirect */
290
                                $this->_redirectdepth++;
291
                                $this->lastredirectaddr = $this->_redirectaddr;
292
                                if (strpos($this->_redirectaddr, "?") > 0)
293
                                    $this->fetch($this->_redirectaddr); // the redirect has changed the request method from post to get
294
                                else
295
                                    $this->submit($this->_redirectaddr, $formvars, $formfiles);
296
                            }
297
                        }
298
                    }
299
300
                    if ($this->_framedepth < $this->maxframes && count($this->_frameurls) > 0) {
301
                        $frameurls = $this->_frameurls;
302
                        $this->_frameurls = array();
303
304
                        while (list(, $frameurl) = each($frameurls)) {
0 ignored issues
show
Deprecated Code introduced by
The function each() has been deprecated: 7.2 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

304
                        while (list(, $frameurl) = /** @scrutinizer ignore-deprecated */ each($frameurls)) {

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
305
                            if ($this->_framedepth < $this->maxframes) {
306
                                $this->fetch($frameurl);
307
                                $this->_framedepth++;
308
                            } else
309
                                break;
310
                        }
311
                    }
312
313
                } else {
314
                    return false;
315
                }
316
                return true;
317
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
318
            case "https":
319
                if (!$this->curl_path)
320
                    return false;
321
                if (function_exists("is_executable"))
322
                    if (!is_executable($this->curl_path))
323
                        return false;
324
                $this->host = $URI_PARTS["host"];
325
                if (!empty($URI_PARTS["port"]))
326
                    $this->port = $URI_PARTS["port"];
327
                if ($this->_isproxy) {
328
                    // using proxy, send entire URI
329
                    $this->_httpsrequest($URI, $URI, $this->_submit_method, $this->_submit_type, $postdata);
330
                } else {
331
                    $path = $URI_PARTS["path"] . ($URI_PARTS["query"] ? "?" . $URI_PARTS["query"] : "");
332
                    // no proxy, send only the path
333
                    $this->_httpsrequest($path, $URI, $this->_submit_method, $this->_submit_type, $postdata);
334
                }
335
336
                if ($this->_redirectaddr) {
337
                    /* url was redirected, check if we've hit the max depth */
338
                    if ($this->maxredirs > $this->_redirectdepth) {
339
                        if (!preg_match("|^" . $URI_PARTS["scheme"] . "://|", $this->_redirectaddr))
0 ignored issues
show
Bug introduced by
$this->_redirectaddr of type true is incompatible with the type string expected by parameter $subject of preg_match(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

339
                        if (!preg_match("|^" . $URI_PARTS["scheme"] . "://|", /** @scrutinizer ignore-type */ $this->_redirectaddr))
Loading history...
340
                            $this->_redirectaddr = $this->_expandlinks($this->_redirectaddr, $URI_PARTS["scheme"] . "://" . $URI_PARTS["host"]);
341
342
                        // only follow redirect if it's on this site, or offsiteok is true
343
                        if (preg_match("|^http://" . preg_quote($this->host) . "|i", $this->_redirectaddr) || $this->offsiteok) {
344
                            /* follow the redirect */
345
                            $this->_redirectdepth++;
346
                            $this->lastredirectaddr = $this->_redirectaddr;
347
                            if (strpos($this->_redirectaddr, "?") > 0)
0 ignored issues
show
Bug introduced by
It seems like $this->_redirectaddr can also be of type true; however, parameter $haystack of strpos() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

347
                            if (strpos(/** @scrutinizer ignore-type */ $this->_redirectaddr, "?") > 0)
Loading history...
348
                                $this->fetch($this->_redirectaddr); // the redirect has changed the request method from post to get
349
                            else
350
                                $this->submit($this->_redirectaddr, $formvars, $formfiles);
351
                        }
352
                    }
353
                }
354
355
                if ($this->_framedepth < $this->maxframes && count($this->_frameurls) > 0) {
356
                    $frameurls = $this->_frameurls;
357
                    $this->_frameurls = array();
358
359
                    while (list(, $frameurl) = each($frameurls)) {
0 ignored issues
show
Deprecated Code introduced by
The function each() has been deprecated: 7.2 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

359
                    while (list(, $frameurl) = /** @scrutinizer ignore-deprecated */ each($frameurls)) {

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
360
                        if ($this->_framedepth < $this->maxframes) {
361
                            $this->fetch($frameurl);
362
                            $this->_framedepth++;
363
                        } else
364
                            break;
365
                    }
366
                }
367
                return true;
368
                break;
369
370
            default:
371
                // not a valid protocol
372
                $this->error = 'Invalid protocol "' . $URI_PARTS["scheme"] . '"\n';
373
                return false;
374
                break;
375
        }
376
        return true;
0 ignored issues
show
Unused Code introduced by
return true is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
377
    }
378
379
    /*======================================================================*\
380
        Function:	fetchlinks
381
        Purpose:	fetch the links from a web page
382
        Input:		$URI	where you are fetching from
383
        Output:		$this->results	an array of the URLs
384
    \*======================================================================*/
385
386
    function fetchlinks($URI)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
387
    {
388
        if ($this->fetch($URI)) {
389
            if ($this->lastredirectaddr)
390
                $URI = $this->lastredirectaddr;
391
            if (is_array($this->results)) {
0 ignored issues
show
introduced by
The condition is_array($this->results) is always false.
Loading history...
392
                for ($x = 0; $x < count($this->results); $x++)
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
393
                    $this->results[$x] = $this->_striplinks($this->results[$x]);
394
            } else
395
                $this->results = $this->_striplinks($this->results);
396
397
            if ($this->expandlinks)
398
                $this->results = $this->_expandlinks($this->results, $URI);
399
            return true;
400
        } else
401
            return false;
402
    }
403
404
    /*======================================================================*\
405
        Function:	fetchform
406
        Purpose:	fetch the form elements from a web page
407
        Input:		$URI	where you are fetching from
408
        Output:		$this->results	the resulting html form
409
    \*======================================================================*/
410
411
    function fetchform($URI)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
412
    {
413
414
        if ($this->fetch($URI)) {
415
416
            if (is_array($this->results)) {
0 ignored issues
show
introduced by
The condition is_array($this->results) is always false.
Loading history...
417
                for ($x = 0; $x < count($this->results); $x++)
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
418
                    $this->results[$x] = $this->_stripform($this->results[$x]);
419
            } else
420
                $this->results = $this->_stripform($this->results);
421
422
            return true;
423
        } else
424
            return false;
425
    }
426
427
428
    /*======================================================================*\
429
        Function:	fetchtext
430
        Purpose:	fetch the text from a web page, stripping the links
431
        Input:		$URI	where you are fetching from
432
        Output:		$this->results	the text from the web page
433
    \*======================================================================*/
434
435
    function fetchtext($URI)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
436
    {
437
        if ($this->fetch($URI)) {
438
            if (is_array($this->results)) {
0 ignored issues
show
introduced by
The condition is_array($this->results) is always false.
Loading history...
439
                for ($x = 0; $x < count($this->results); $x++)
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
440
                    $this->results[$x] = $this->_striptext($this->results[$x]);
441
            } else
442
                $this->results = $this->_striptext($this->results);
443
            return true;
444
        } else
445
            return false;
446
    }
447
448
    /*======================================================================*\
449
        Function:	submitlinks
450
        Purpose:	grab links from a form submission
451
        Input:		$URI	where you are submitting from
452
        Output:		$this->results	an array of the links from the post
453
    \*======================================================================*/
454
455
    function submitlinks($URI, $formvars = "", $formfiles = "")
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
456
    {
457
        if ($this->submit($URI, $formvars, $formfiles)) {
458
            if ($this->lastredirectaddr)
459
                $URI = $this->lastredirectaddr;
460
            if (is_array($this->results)) {
0 ignored issues
show
introduced by
The condition is_array($this->results) is always false.
Loading history...
461
                for ($x = 0; $x < count($this->results); $x++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
462
                    $this->results[$x] = $this->_striplinks($this->results[$x]);
463
                    if ($this->expandlinks)
464
                        $this->results[$x] = $this->_expandlinks($this->results[$x], $URI);
465
                }
466
            } else {
467
                $this->results = $this->_striplinks($this->results);
468
                if ($this->expandlinks)
469
                    $this->results = $this->_expandlinks($this->results, $URI);
470
            }
471
            return true;
472
        } else
473
            return false;
474
    }
475
476
    /*======================================================================*\
477
        Function:	submittext
478
        Purpose:	grab text from a form submission
479
        Input:		$URI	where you are submitting from
480
        Output:		$this->results	the text from the web page
481
    \*======================================================================*/
482
483
    function submittext($URI, $formvars = "", $formfiles = "")
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
484
    {
485
        if ($this->submit($URI, $formvars, $formfiles)) {
486
            if ($this->lastredirectaddr)
487
                $URI = $this->lastredirectaddr;
488
            if (is_array($this->results)) {
0 ignored issues
show
introduced by
The condition is_array($this->results) is always false.
Loading history...
489
                for ($x = 0; $x < count($this->results); $x++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
490
                    $this->results[$x] = $this->_striptext($this->results[$x]);
491
                    if ($this->expandlinks)
492
                        $this->results[$x] = $this->_expandlinks($this->results[$x], $URI);
493
                }
494
            } else {
495
                $this->results = $this->_striptext($this->results);
496
                if ($this->expandlinks)
497
                    $this->results = $this->_expandlinks($this->results, $URI);
498
            }
499
            return true;
500
        } else
501
            return false;
502
    }
503
504
505
    /*======================================================================*\
506
        Function:	set_submit_multipart
507
        Purpose:	Set the form submission content type to
508
                    multipart/form-data
509
    \*======================================================================*/
510
    function set_submit_multipart()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
511
    {
512
        $this->_submit_type = "multipart/form-data";
513
    }
514
515
516
    /*======================================================================*\
517
        Function:	set_submit_normal
518
        Purpose:	Set the form submission content type to
519
                    application/x-www-form-urlencoded
520
    \*======================================================================*/
521
    function set_submit_normal()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
522
    {
523
        $this->_submit_type = "application/x-www-form-urlencoded";
524
    }
525
526
527
528
529
    /*======================================================================*\
530
        Private functions
531
    \*======================================================================*/
532
533
534
    /*======================================================================*\
535
        Function:	_striplinks
536
        Purpose:	strip the hyperlinks from an html document
537
        Input:		$document	document to strip.
538
        Output:		$match		an array of the links
539
    \*======================================================================*/
540
541
    function _striplinks($document)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
542
    {
543
        preg_match_all("'<\s*a\s.*?href\s*=\s*			# find <a href=
544
						([\"\'])?					# find single or double quote
545
						(?(1) (.*?)\\1 | ([^\s\>]+))		# if quote found, match up to next matching
546
													# quote, otherwise match up to next space
547
						'isx", $document, $links);
548
549
550
        // catenate the non-empty matches from the conditional subpattern
551
552
        while (list($key, $val) = each($links[2])) {
0 ignored issues
show
Deprecated Code introduced by
The function each() has been deprecated: 7.2 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

552
        while (list($key, $val) = /** @scrutinizer ignore-deprecated */ each($links[2])) {

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
553
            if (!empty($val))
554
                $match[] = $val;
555
        }
556
557
        while (list($key, $val) = each($links[3])) {
0 ignored issues
show
Deprecated Code introduced by
The function each() has been deprecated: 7.2 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

557
        while (list($key, $val) = /** @scrutinizer ignore-deprecated */ each($links[3])) {

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
558
            if (!empty($val))
559
                $match[] = $val;
560
        }
561
562
        // return the links
563
        return $match;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $match does not seem to be defined for all execution paths leading up to this point.
Loading history...
564
    }
565
566
    /*======================================================================*\
567
        Function:	_stripform
568
        Purpose:	strip the form elements from an html document
569
        Input:		$document	document to strip.
570
        Output:		$match		an array of the links
571
    \*======================================================================*/
572
573
    function _stripform($document)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
574
    {
575
        preg_match_all("'<\/?(FORM|INPUT|SELECT|TEXTAREA|(OPTION))[^<>]*>(?(2)(.*(?=<\/?(option|select)[^<>]*>[\r\n]*)|(?=[\r\n]*))|(?=[\r\n]*))'Usi", $document, $elements);
576
577
        // catenate the matches
578
        $match = implode("\r\n", $elements[0]);
579
580
        // return the links
581
        return $match;
582
    }
583
584
585
    /*======================================================================*\
586
        Function:	_striptext
587
        Purpose:	strip the text from an html document
588
        Input:		$document	document to strip.
589
        Output:		$text		the resulting text
590
    \*======================================================================*/
591
592
    function _striptext($document)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
593
    {
594
595
        // I didn't use preg eval (//e) since that is only available in PHP 4.0.
596
        // so, list your entities one by one here. I included some of the
597
        // more common ones.
598
599
        $search = array("'<script[^>]*?>.*?</script>'si", // strip out javascript
600
            "'<[\/\!]*?[^<>]*?>'si", // strip out html tags
601
            "'([\r\n])[\s]+'", // strip out white space
602
            "'&(quot|#34|#034|#x22);'i", // replace html entities
603
            "'&(amp|#38|#038|#x26);'i", // added hexadecimal values
604
            "'&(lt|#60|#060|#x3c);'i",
605
            "'&(gt|#62|#062|#x3e);'i",
606
            "'&(nbsp|#160|#xa0);'i",
607
            "'&(iexcl|#161);'i",
608
            "'&(cent|#162);'i",
609
            "'&(pound|#163);'i",
610
            "'&(copy|#169);'i",
611
            "'&(reg|#174);'i",
612
            "'&(deg|#176);'i",
613
            "'&(#39|#039|#x27);'",
614
            "'&(euro|#8364);'i", // europe
615
            "'&a(uml|UML);'", // german
616
            "'&o(uml|UML);'",
617
            "'&u(uml|UML);'",
618
            "'&A(uml|UML);'",
619
            "'&O(uml|UML);'",
620
            "'&U(uml|UML);'",
621
            "'&szlig;'i",
622
        );
623
        $replace = array("",
624
            "",
625
            "\\1",
626
            "\"",
627
            "&",
628
            "<",
629
            ">",
630
            " ",
631
            chr(161),
632
            chr(162),
633
            chr(163),
634
            chr(169),
635
            chr(174),
636
            chr(176),
637
            chr(39),
638
            chr(128),
639
            "ä",
640
            "ö",
641
            "ü",
642
            "Ä",
643
            "Ö",
644
            "Ü",
645
            "ß",
646
        );
647
648
        $text = preg_replace($search, $replace, $document);
649
650
        return $text;
651
    }
652
653
    /*======================================================================*\
654
        Function:	_expandlinks
655
        Purpose:	expand each link into a fully qualified URL
656
        Input:		$links			the links to qualify
657
                    $URI			the full URI to get the base from
658
        Output:		$expandedLinks	the expanded links
659
    \*======================================================================*/
660
661
    function _expandlinks($links, $URI)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
662
    {
663
664
        preg_match("/^[^\?]+/", $URI, $match);
665
666
        $match = preg_replace("|/[^\/\.]+\.[^\/\.]+$|", "", $match[0]);
667
        $match = preg_replace("|/$|", "", $match);
668
        $match_part = parse_url($match);
669
        $match_root =
670
            $match_part["scheme"] . "://" . $match_part["host"];
671
672
        $search = array("|^http://" . preg_quote($this->host) . "|i",
673
            "|^(\/)|i",
674
            "|^(?!http://)(?!mailto:)|i",
675
            "|/\./|",
676
            "|/[^\/]+/\.\./|"
677
        );
678
679
        $replace = array("",
680
            $match_root . "/",
681
            $match . "/",
682
            "/",
683
            "/"
684
        );
685
686
        $expandedLinks = preg_replace($search, $replace, $links);
687
688
        return $expandedLinks;
689
    }
690
691
    /*======================================================================*\
692
        Function:	_httprequest
693
        Purpose:	go get the http data from the server
694
        Input:		$url		the url to fetch
695
                    $fp			the current open file pointer
696
                    $URI		the full URI
697
                    $body		body contents to send if any (POST)
698
        Output:
699
    \*======================================================================*/
700
701
    function _httprequest($url, $fp, $URI, $http_method, $content_type = "", $body = "")
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
702
    {
703
        $cookie_headers = '';
704
        if ($this->passcookies && $this->_redirectaddr)
705
            $this->setcookies();
706
707
        $URI_PARTS = parse_url($URI);
708
        if (empty($url))
709
            $url = "/";
710
        $headers = $http_method . " " . $url . " " . $this->_httpversion . "\r\n";
711
        if (!empty($this->agent))
712
            $headers .= "User-Agent: " . $this->agent . "\r\n";
713
        if (!empty($this->host) && !isset($this->rawheaders['Host'])) {
714
            $headers .= "Host: " . $this->host;
715
            if (!empty($this->port) && $this->port != '80')
716
                $headers .= ":" . $this->port;
717
            $headers .= "\r\n";
718
        }
719
        if (!empty($this->accept))
720
            $headers .= "Accept: " . $this->accept . "\r\n";
721
        if ($this->use_gzip) {
722
            // make sure PHP was built with --with-zlib
723
            // and we can handle gzipp'ed data
724
            if (function_exists('gzinflate')) {
725
                $headers .= "Accept-encoding: gzip\r\n";
726
            } else {
727
                trigger_error(
728
                    "use_gzip is on, but PHP was built without zlib support." .
729
                    "  Requesting file(s) without gzip encoding.",
730
                    E_USER_NOTICE);
731
            }
732
        }
733
        if (!empty($this->referer))
734
            $headers .= "Referer: " . $this->referer . "\r\n";
735
        if (!empty($this->cookies)) {
736
            if (!is_array($this->cookies))
0 ignored issues
show
introduced by
The condition is_array($this->cookies) is always true.
Loading history...
737
                $this->cookies = (array)$this->cookies;
738
739
            reset($this->cookies);
740
            if (count($this->cookies) > 0) {
741
                $cookie_headers .= 'Cookie: ';
742
                foreach ($this->cookies as $cookieKey => $cookieVal) {
743
                    $cookie_headers .= $cookieKey . "=" . urlencode($cookieVal) . "; ";
744
                }
745
                $headers .= substr($cookie_headers, 0, -2) . "\r\n";
746
            }
747
        }
748
        if (!empty($this->rawheaders)) {
749
            if (!is_array($this->rawheaders))
0 ignored issues
show
introduced by
The condition is_array($this->rawheaders) is always true.
Loading history...
750
                $this->rawheaders = (array)$this->rawheaders;
751
            while (list($headerKey, $headerVal) = each($this->rawheaders))
0 ignored issues
show
Deprecated Code introduced by
The function each() has been deprecated: 7.2 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

751
            while (list($headerKey, $headerVal) = /** @scrutinizer ignore-deprecated */ each($this->rawheaders))

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
752
                $headers .= $headerKey . ": " . $headerVal . "\r\n";
753
        }
754
        if (!empty($content_type)) {
755
            $headers .= "Content-type: $content_type";
756
            if ($content_type == "multipart/form-data")
757
                $headers .= "; boundary=" . $this->_mime_boundary;
758
            $headers .= "\r\n";
759
        }
760
        if (!empty($body))
761
            $headers .= "Content-length: " . strlen($body) . "\r\n";
762
        if (!empty($this->user) || !empty($this->pass))
763
            $headers .= "Authorization: Basic " . base64_encode($this->user . ":" . $this->pass) . "\r\n";
764
765
        //add proxy auth headers
766
        if (!empty($this->proxy_user))
767
            $headers .= 'Proxy-Authorization: ' . 'Basic ' . base64_encode($this->proxy_user . ':' . $this->proxy_pass) . "\r\n";
768
769
770
        $headers .= "\r\n";
771
772
        // set the read timeout if needed
773
        if ($this->read_timeout > 0)
774
            socket_set_timeout($fp, $this->read_timeout);
775
        $this->timed_out = false;
776
777
        fwrite($fp, $headers . $body, strlen($headers . $body));
778
779
        $this->_redirectaddr = false;
780
        unset($this->headers);
781
782
        // content was returned gzip encoded?
783
        $is_gzipped = false;
784
785
        while ($currentHeader = fgets($fp, $this->_maxlinelen)) {
786
            if ($this->read_timeout > 0 && $this->_check_timeout($fp)) {
787
                $this->status = -100;
788
                return false;
789
            }
790
791
            if ($currentHeader == "\r\n")
792
                break;
793
794
            // if a header begins with Location: or URI:, set the redirect
795
            if (preg_match("/^(Location:|URI:)/i", $currentHeader)) {
796
                // get URL portion of the redirect
797
                preg_match("/^(Location:|URI:)[ ]+(.*)/i", chop($currentHeader), $matches);
798
                // look for :// in the Location header to see if hostname is included
799
                if (!preg_match("|\:\/\/|", $matches[2])) {
800
                    // no host in the path, so prepend
801
                    $this->_redirectaddr = $URI_PARTS["scheme"] . "://" . $this->host . ":" . $this->port;
802
                    // eliminate double slash
803
                    if (!preg_match("|^/|", $matches[2]))
804
                        $this->_redirectaddr .= "/" . $matches[2];
805
                    else
806
                        $this->_redirectaddr .= $matches[2];
807
                } else
808
                    $this->_redirectaddr = $matches[2];
809
            }
810
811
            if (preg_match("|^HTTP/|", $currentHeader)) {
812
                if (preg_match("|^HTTP/[^\s]*\s(.*?)\s|", $currentHeader, $status)) {
813
                    $this->status = $status[1];
814
                }
815
                $this->response_code = $currentHeader;
816
            }
817
818
            if (preg_match("/Content-Encoding: gzip/", $currentHeader)) {
819
                $is_gzipped = true;
820
            }
821
822
            $this->headers[] = $currentHeader;
823
        }
824
825
        $results = '';
826
        do {
827
            $_data = fread($fp, $this->maxlength);
828
            if (strlen($_data) == 0) {
829
                break;
830
            }
831
            $results .= $_data;
832
        } while (true);
833
834
        // gunzip
835
        if ($is_gzipped) {
836
            // per http://www.php.net/manual/en/function.gzencode.php
837
            $results = substr($results, 10);
838
            $results = gzinflate($results);
839
        }
840
841
        if ($this->read_timeout > 0 && $this->_check_timeout($fp)) {
842
            $this->status = -100;
843
            return false;
844
        }
845
846
        // check if there is a a redirect meta tag
847
848
        if (preg_match("'<meta[\s]*http-equiv[^>]*?content[\s]*=[\s]*[\"\']?\d+;[\s]*URL[\s]*=[\s]*([^\"\']*?)[\"\']?>'i", $results, $match)) {
849
            $this->_redirectaddr = $this->_expandlinks($match[1], $URI);
850
        }
851
852
        // have we hit our frame depth and is there frame src to fetch?
853
        if (($this->_framedepth < $this->maxframes) && preg_match_all("'<frame\s+.*src[\s]*=[\'\"]?([^\'\"\>]+)'i", $results, $match)) {
854
            $this->results[] = $results;
855
            for ($x = 0; $x < count($match[1]); $x++)
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
856
                $this->_frameurls[] = $this->_expandlinks($match[1][$x], $URI_PARTS["scheme"] . "://" . $this->host);
857
        } // have we already fetched framed content?
858
        elseif (is_array($this->results))
0 ignored issues
show
introduced by
The condition is_array($this->results) is always false.
Loading history...
859
            $this->results[] = $results;
860
        // no framed content
861
        else
862
            $this->results = $results;
863
864
        return true;
865
    }
866
867
    /*======================================================================*\
868
        Function:	_httpsrequest
869
        Purpose:	go get the https data from the server using curl
870
        Input:		$url		the url to fetch
871
                    $URI		the full URI
872
                    $body		body contents to send if any (POST)
873
        Output:
874
    \*======================================================================*/
875
876
    function _httpsrequest($url, $URI, $http_method, $content_type = "", $body = "")
0 ignored issues
show
Unused Code introduced by
The parameter $http_method is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

876
    function _httpsrequest($url, $URI, /** @scrutinizer ignore-unused */ $http_method, $content_type = "", $body = "")

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
877
    {
878
        if ($this->passcookies && $this->_redirectaddr)
879
            $this->setcookies();
880
881
        $headers = array();
882
883
        $URI_PARTS = parse_url($URI);
884
        if (empty($url))
885
            $url = "/";
0 ignored issues
show
Unused Code introduced by
The assignment to $url is dead and can be removed.
Loading history...
886
        // GET ... header not needed for curl
887
        //$headers[] = $http_method." ".$url." ".$this->_httpversion;
888
        if (!empty($this->agent))
889
            $headers[] = "User-Agent: " . $this->agent;
890
        if (!empty($this->host))
891
            if (!empty($this->port))
892
                $headers[] = "Host: " . $this->host . ":" . $this->port;
893
            else
894
                $headers[] = "Host: " . $this->host;
895
        if (!empty($this->accept))
896
            $headers[] = "Accept: " . $this->accept;
897
        if (!empty($this->referer))
898
            $headers[] = "Referer: " . $this->referer;
899
        if (!empty($this->cookies)) {
900
            if (!is_array($this->cookies))
0 ignored issues
show
introduced by
The condition is_array($this->cookies) is always true.
Loading history...
901
                $this->cookies = (array)$this->cookies;
902
903
            reset($this->cookies);
904
            if (count($this->cookies) > 0) {
905
                $cookie_str = 'Cookie: ';
906
                foreach ($this->cookies as $cookieKey => $cookieVal) {
907
                    $cookie_str .= $cookieKey . "=" . urlencode($cookieVal) . "; ";
908
                }
909
                $headers[] = substr($cookie_str, 0, -2);
910
            }
911
        }
912
        if (!empty($this->rawheaders)) {
913
            if (!is_array($this->rawheaders))
0 ignored issues
show
introduced by
The condition is_array($this->rawheaders) is always true.
Loading history...
914
                $this->rawheaders = (array)$this->rawheaders;
915
            while (list($headerKey, $headerVal) = each($this->rawheaders))
0 ignored issues
show
Deprecated Code introduced by
The function each() has been deprecated: 7.2 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

915
            while (list($headerKey, $headerVal) = /** @scrutinizer ignore-deprecated */ each($this->rawheaders))

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
916
                $headers[] = $headerKey . ": " . $headerVal;
917
        }
918
        if (!empty($content_type)) {
919
            if ($content_type == "multipart/form-data")
920
                $headers[] = "Content-type: $content_type; boundary=" . $this->_mime_boundary;
921
            else
922
                $headers[] = "Content-type: $content_type";
923
        }
924
        if (!empty($body))
925
            $headers[] = "Content-length: " . strlen($body);
926
        if (!empty($this->user) || !empty($this->pass))
927
            $headers[] = "Authorization: BASIC " . base64_encode($this->user . ":" . $this->pass);
928
929
        for ($curr_header = 0; $curr_header < count($headers); $curr_header++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
930
            $safer_header = strtr($headers[$curr_header], "\"", " ");
931
            $cmdline_params .= " -H \"" . $safer_header . "\"";
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $cmdline_params seems to be never defined.
Loading history...
932
        }
933
934
        if (!empty($body))
935
            $cmdline_params .= " -d \"$body\"";
936
937
        if ($this->read_timeout > 0)
938
            $cmdline_params .= " -m " . $this->read_timeout;
939
940
        $headerfile = tempnam($temp_dir, "sno");
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $temp_dir seems to be never defined.
Loading history...
941
942
        exec($this->curl_path . " -k -D \"$headerfile\"" . $cmdline_params . " " . escapeshellarg($URI), $results, $return);
943
944
        if ($return) {
945
            $this->error = "Error: cURL could not retrieve the document, error $return.";
946
            return false;
947
        }
948
949
950
        $results = implode("\r\n", $results);
951
952
        $result_headers = file("$headerfile");
953
954
        $this->_redirectaddr = false;
955
        unset($this->headers);
956
957
        for ($currentHeader = 0; $currentHeader < count($result_headers); $currentHeader++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
Bug introduced by
It seems like $result_headers can also be of type false; however, parameter $var of count() does only seem to accept Countable|array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

957
        for ($currentHeader = 0; $currentHeader < count(/** @scrutinizer ignore-type */ $result_headers); $currentHeader++) {
Loading history...
958
959
            // if a header begins with Location: or URI:, set the redirect
960
            if (preg_match("/^(Location: |URI: )/i", $result_headers[$currentHeader])) {
961
                // get URL portion of the redirect
962
                preg_match("/^(Location: |URI:)\s+(.*)/", chop($result_headers[$currentHeader]), $matches);
963
                // look for :// in the Location header to see if hostname is included
964
                if (!preg_match("|\:\/\/|", $matches[2])) {
965
                    // no host in the path, so prepend
966
                    $this->_redirectaddr = $URI_PARTS["scheme"] . "://" . $this->host . ":" . $this->port;
967
                    // eliminate double slash
968
                    if (!preg_match("|^/|", $matches[2]))
969
                        $this->_redirectaddr .= "/" . $matches[2];
970
                    else
971
                        $this->_redirectaddr .= $matches[2];
972
                } else
973
                    $this->_redirectaddr = $matches[2];
974
            }
975
976
            if (preg_match("|^HTTP/|", $result_headers[$currentHeader])) {
977
                $this->response_code = $result_headers[$currentHeader];
978
                if (preg_match("|^HTTP/[^\s]*\s(.*?)\s|", $this->response_code, $match)) {
979
                    $this->status = $match[1];
980
                }
981
            }
982
983
            $this->headers[] = $result_headers[$currentHeader];
984
        }
985
986
        // check if there is a a redirect meta tag
987
988
        if (preg_match("'<meta[\s]*http-equiv[^>]*?content[\s]*=[\s]*[\"\']?\d+;[\s]*URL[\s]*=[\s]*([^\"\']*?)[\"\']?>'i", $results, $match)) {
989
            $this->_redirectaddr = $this->_expandlinks($match[1], $URI);
990
        }
991
992
        // have we hit our frame depth and is there frame src to fetch?
993
        if (($this->_framedepth < $this->maxframes) && preg_match_all("'<frame\s+.*src[\s]*=[\'\"]?([^\'\"\>]+)'i", $results, $match)) {
994
            $this->results[] = $results;
995
            for ($x = 0; $x < count($match[1]); $x++)
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
996
                $this->_frameurls[] = $this->_expandlinks($match[1][$x], $URI_PARTS["scheme"] . "://" . $this->host);
997
        } // have we already fetched framed content?
998
        elseif (is_array($this->results))
0 ignored issues
show
introduced by
The condition is_array($this->results) is always false.
Loading history...
999
            $this->results[] = $results;
1000
        // no framed content
1001
        else
1002
            $this->results = $results;
1003
1004
        unlink("$headerfile");
1005
1006
        return true;
1007
    }
1008
1009
    /*======================================================================*\
1010
        Function:	setcookies()
1011
        Purpose:	set cookies for a redirection
1012
    \*======================================================================*/
1013
1014
    function setcookies()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1015
    {
1016
        for ($x = 0; $x < count($this->headers); $x++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
1017
            if (preg_match('/^set-cookie:[\s]+([^=]+)=([^;]+)/i', $this->headers[$x], $match))
1018
                $this->cookies[$match[1]] = urldecode($match[2]);
1019
        }
1020
    }
1021
1022
1023
    /*======================================================================*\
1024
        Function:	_check_timeout
1025
        Purpose:	checks whether timeout has occurred
1026
        Input:		$fp	file pointer
1027
    \*======================================================================*/
1028
1029
    function _check_timeout($fp)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1030
    {
1031
        if ($this->read_timeout > 0) {
1032
            $fp_status = socket_get_status($fp);
1033
            if ($fp_status["timed_out"]) {
1034
                $this->timed_out = true;
1035
                return true;
1036
            }
1037
        }
1038
        return false;
1039
    }
1040
1041
    /*======================================================================*\
1042
        Function:	_connect
1043
        Purpose:	make a socket connection
1044
        Input:		$fp	file pointer
1045
    \*======================================================================*/
1046
1047
    function _connect(&$fp)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1048
    {
1049
        if (!empty($this->proxy_host) && !empty($this->proxy_port)) {
1050
            $this->_isproxy = true;
1051
1052
            $host = $this->proxy_host;
1053
            $port = $this->proxy_port;
1054
        } else {
1055
            $host = $this->host;
1056
            $port = $this->port;
1057
        }
1058
1059
        $this->status = 0;
1060
1061
        if ($fp = fsockopen(
1062
            $host,
1063
            $port,
0 ignored issues
show
Bug introduced by
It seems like $port can also be of type string; however, parameter $port of fsockopen() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1063
            /** @scrutinizer ignore-type */ $port,
Loading history...
1064
            $errno,
1065
            $errstr,
1066
            $this->_fp_timeout
1067
        )
1068
        ) {
1069
            // socket connection succeeded
1070
1071
            return true;
1072
        } else {
1073
            // socket connection failed
1074
            $this->status = $errno;
1075
            switch ($errno) {
1076
                case -3:
1077
                    $this->error = "socket creation failed (-3)";
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment if this fall-through is intended.
Loading history...
1078
                case -4:
1079
                    $this->error = "dns lookup failure (-4)";
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment if this fall-through is intended.
Loading history...
1080
                case -5:
1081
                    $this->error = "connection refused or timed out (-5)";
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment if this fall-through is intended.
Loading history...
1082
                default:
1083
                    $this->error = "connection failed (" . $errno . ")";
1084
            }
1085
            return false;
1086
        }
1087
    }
1088
1089
    /*======================================================================*\
1090
        Function:	_disconnect
1091
        Purpose:	disconnect a socket connection
1092
        Input:		$fp	file pointer
1093
    \*======================================================================*/
1094
1095
    function _disconnect($fp)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1096
    {
1097
        return (fclose($fp));
1098
    }
1099
1100
1101
    /*======================================================================*\
1102
        Function:	_prepare_post_body
1103
        Purpose:	Prepare post body according to encoding type
1104
        Input:		$formvars  - form variables
1105
                    $formfiles - form upload files
1106
        Output:		post body
1107
    \*======================================================================*/
1108
1109
    function _prepare_post_body($formvars, $formfiles)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1110
    {
1111
        settype($formvars, "array");
1112
        settype($formfiles, "array");
1113
        $postdata = '';
1114
1115
        if (count($formvars) == 0 && count($formfiles) == 0)
1116
            return;
1117
1118
        switch ($this->_submit_type) {
1119
            case "application/x-www-form-urlencoded":
1120
                reset($formvars);
1121
                while (list($key, $val) = each($formvars)) {
0 ignored issues
show
Deprecated Code introduced by
The function each() has been deprecated: 7.2 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

1121
                while (list($key, $val) = /** @scrutinizer ignore-deprecated */ each($formvars)) {

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
1122
                    if (is_array($val) || is_object($val)) {
1123
                        while (list($cur_key, $cur_val) = each($val)) {
0 ignored issues
show
Deprecated Code introduced by
The function each() has been deprecated: 7.2 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

1123
                        while (list($cur_key, $cur_val) = /** @scrutinizer ignore-deprecated */ each($val)) {

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
1124
                            $postdata .= urlencode($key) . "[]=" . urlencode($cur_val) . "&";
1125
                        }
1126
                    } else
1127
                        $postdata .= urlencode($key) . "=" . urlencode($val) . "&";
1128
                }
1129
                break;
1130
1131
            case "multipart/form-data":
1132
                $this->_mime_boundary = "Snoopy" . md5(uniqid(microtime()));
1133
1134
                reset($formvars);
1135
                while (list($key, $val) = each($formvars)) {
0 ignored issues
show
Deprecated Code introduced by
The function each() has been deprecated: 7.2 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

1135
                while (list($key, $val) = /** @scrutinizer ignore-deprecated */ each($formvars)) {

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
1136
                    if (is_array($val) || is_object($val)) {
1137
                        while (list($cur_key, $cur_val) = each($val)) {
0 ignored issues
show
Deprecated Code introduced by
The function each() has been deprecated: 7.2 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

1137
                        while (list($cur_key, $cur_val) = /** @scrutinizer ignore-deprecated */ each($val)) {

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
1138
                            $postdata .= "--" . $this->_mime_boundary . "\r\n";
1139
                            $postdata .= "Content-Disposition: form-data; name=\"$key\[\]\"\r\n\r\n";
1140
                            $postdata .= "$cur_val\r\n";
1141
                        }
1142
                    } else {
1143
                        $postdata .= "--" . $this->_mime_boundary . "\r\n";
1144
                        $postdata .= "Content-Disposition: form-data; name=\"$key\"\r\n\r\n";
1145
                        $postdata .= "$val\r\n";
1146
                    }
1147
                }
1148
1149
                reset($formfiles);
1150
                while (list($field_name, $file_names) = each($formfiles)) {
0 ignored issues
show
Deprecated Code introduced by
The function each() has been deprecated: 7.2 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

1150
                while (list($field_name, $file_names) = /** @scrutinizer ignore-deprecated */ each($formfiles)) {

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
1151
                    settype($file_names, "array");
1152
                    while (list(, $file_name) = each($file_names)) {
0 ignored issues
show
Deprecated Code introduced by
The function each() has been deprecated: 7.2 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

1152
                    while (list(, $file_name) = /** @scrutinizer ignore-deprecated */ each($file_names)) {

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
1153
                        if (!is_readable($file_name)) continue;
1154
1155
                        $fp = fopen($file_name, "r");
1156
                        $file_content = fread($fp, filesize($file_name));
0 ignored issues
show
Bug introduced by
It seems like $fp can also be of type false; however, parameter $handle of fread() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1156
                        $file_content = fread(/** @scrutinizer ignore-type */ $fp, filesize($file_name));
Loading history...
1157
                        fclose($fp);
0 ignored issues
show
Bug introduced by
It seems like $fp can also be of type false; however, parameter $handle of fclose() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1157
                        fclose(/** @scrutinizer ignore-type */ $fp);
Loading history...
1158
                        $base_name = basename($file_name);
1159
1160
                        $postdata .= "--" . $this->_mime_boundary . "\r\n";
1161
                        $postdata .= "Content-Disposition: form-data; name=\"$field_name\"; filename=\"$base_name\"\r\n\r\n";
1162
                        $postdata .= "$file_content\r\n";
1163
                    }
1164
                }
1165
                $postdata .= "--" . $this->_mime_boundary . "--\r\n";
1166
                break;
1167
        }
1168
1169
        return $postdata;
1170
    }
1171
}
1172
1173
?>
0 ignored issues
show
Best Practice introduced by
It is not recommended to use PHP's closing tag ?> in files other than templates.

Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore.

A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever.

Loading history...
1174