diff options
Diffstat (limited to 'it_url.class')
-rw-r--r-- | it_url.class | 162 |
1 files changed, 89 insertions, 73 deletions
diff --git a/it_url.class b/it_url.class index a48013e..3caa6cb 100644 --- a/it_url.class +++ b/it_url.class @@ -238,8 +238,7 @@ function get($p=null, $timeout=5) { if (!is_array($p)) $p = array('url' => $p, 'timeout' => $timeout); - - $p += array('totaltimeout' => "999999", 'timeout' => 5, 'retries' => 1); + $p += array('retries' => 1); if ($this instanceof it_url) { @@ -250,103 +249,120 @@ function get($p=null, $timeout=5) else # called statically $url = new it_url($p['url']); + if ($url->protocol == 'http') + { + $result = $url->request($p); + if ($url->headers['Location'] && preg_match('#^(https?://[^/]*)?(/)?(.*)$#i', $url->headers['Location'], $parts) && ($parts[1] != $url->url)) # Handle redirects (supports relative and global) + { + unset($p['url'], $p['headers']['Host']); + $url->it_url($parts[1] ? $parts[1].$parts[2].$parts[3] : $url->protocol.'://'.$url->realhostname.($parts[2] ? $parts[2].$parts[3] : '/'.dirname($url->path).'/'.$parts[3])); + if (++$url->redir <= 4) /* Avoid infinite redirects */ + return $url->get($p); + } + } + else + { + $results = self::get_multi(array('urls' => array('one' => $p['url'])) + $p); + $result = $results['one']; + } + + if (!$result && $p['retries'] > 0 && $url->result < 400) + $result = $url->get(array('retries' => $p['retries'] - 1) + $p); + + return $result; +} + +function request($p=array()) +{ + $p += array('totaltimeout' => "999999", 'timeout' => 5); + + $url = $this; + if ($p['url']) + $this->it_url($p['url']); + $url->result = $result = false; unset($url->data); $url->headers = array(); $p['timeout'] = min($p['timeout'], $p['totaltimeout']); # No operation may be longer than totaltimeout $endtime = time() + $p['totaltimeout']; - if ($url->protocol == 'http') + if ($fp = @fsockopen($url->realhostname, $url->port, $dummy_errno, $dummy_errstr, $p['timeout'])) { - if ($fp = @fsockopen($url->realhostname, $url->port, $dummy_errno, $dummy_errstr, $p['timeout'])) - { - # urlencode data pairs if is array - if (is_array($p['data'])) - $data = it_url::params($p['data']); - - $p['headers'] = (array)$p['headers'] + array( - 'Host' => $url->realhostname, - 'User-Agent' => "Mozilla/4.0 (compatible; MSIE 7.0; ITools)", - 'Accept-Language' => T_lang(), - ); + # urlencode data pairs if is array + if (is_array($p['data'])) + $data = it_url::params($p['data']); + else + $data = $p['data']; - if (is_int($p['filemtime'])) - $p['headers']['If-Modified-Since'] = date("r", $p['filemtime']); + $p['headers'] = (array)$p['headers'] + array( + 'Host' => $url->realhostname . ($url->port != 80 ? ":" . $url->port : ''), + 'User-Agent' => "Mozilla/4.0 (compatible; MSIE 7.0; ITools)", + 'Accept-Language' => T_lang(), + ); - if ($datalen = strlen($data)) - { - $method = "POST"; - $p['headers'] += array( - 'Content-Type' => "application/x-www-form-urlencoded", - 'Content-Length' => $datalen, - ); - } - else - $method = "GET"; + if (is_int($p['filemtime'])) + $p['headers']['If-Modified-Since'] = date("r", $p['filemtime']); - if ($url->user || $url->pass) - $p['headers'] += array('Authorization' => 'Basic ' . base64_encode($url->user . ':' . $url->pass)); + if ($datalen = strlen($data)) + { + $method = $p['method'] ?: "POST"; + $p['headers'] += array( + 'Content-Type' => "application/x-www-form-urlencoded", + 'Content-Length' => $datalen, + ); + } + else + $method = $p['method'] ?: "GET"; - foreach ($p['headers'] as $header => $value) - $headers .= "$header: $value\r\n"; + if ($url->user || $url->pass) + $p['headers'] += array('Authorization' => 'Basic ' . base64_encode($url->user . ':' . $url->pass)); - stream_set_timeout($fp, intval($p['timeout']), intval(($p['timeout']*1000000)%1000000)); - @fputs($fp, "$method /$url->path HTTP/1.0\r\n$headers\r\n$data"); + foreach ($p['headers'] as $header => $value) + $headers .= "$header: $value\r\n"; - while (!feof($fp) && ($line = @fgets($fp, 10240)) && ($line = trim($line)) && (time() < $endtime)) - { - if (preg_match('#^(HTTP\S+)\s(\d+)#', $line, $parts)) # Parse result code - $url->headers[$parts[1]] = $url->result = $parts[2]; - elseif (preg_match('#^Location: (https?://[^/]*)?(/)?(.*)$#i', $line, $parts) && ($parts[1] != $url->url)) # Handle redirects (supports relative and global) - { - unset($p['url'], $p['headers']['Host']); - $url->it_url($parts[1] ? $parts[1].$parts[2].$parts[3] : $url->protocol.'://'.$url->realhostname.($parts[2] ? $parts[2].$parts[3] : '/'.dirname($url->path).'/'.$parts[3])); - if (++$url->redir <= 4) /* Avoid infinite redirects */ - return $url->get($p); - } - elseif (preg_match('#^([^:]+): (.*)$#', $line, $parts)) - $url->headers[$parts[1]] = $parts[2]; - } + stream_set_timeout($fp, intval($p['timeout']), intval(($p['timeout']*1000000)%1000000)); + @fputs($fp, "$method /$url->path HTTP/1.0\r\n$headers\r\n$data"); - if ($url->result) + while (!feof($fp) && ($line = @fgets($fp, 10240)) && ($line = trim($line)) && (time() < $endtime)) + { + if (preg_match('#^(HTTP\S+)\s(\d+)#', $line, $parts)) # Parse result code + $url->headers[$parts[1]] = $url->result = $parts[2]; + elseif (preg_match('#^([^:]+): (.*)$#', $line, $parts)) + $url->headers[$parts[1]] = $parts[2]; + } + + if ($url->result) + { + if ($url->headers['Transfer-Encoding'] == "chunked") # Bogus HTTP/1.1 chunked answer from server (e.g. Wordpress/Apache2/PHP5) { - if ($url->headers['Transfer-Encoding'] == "chunked") # Bogus HTTP/1.1 chunked answer from server (e.g. Wordpress/Apache2/PHP5) + while ($len = hexdec(fgets($fp))) { - while ($len = hexdec(fgets($fp))) - { - $chunk = ""; + $chunk = ""; - while (!feof($fp) && (strlen($chunk) < $len) && (time() < $endtime)) - $chunk .= @fread($fp, $len - strlen($chunk)); + while (!feof($fp) && (strlen($chunk) < $len) && (time() < $endtime)) + $chunk .= @fread($fp, $len - strlen($chunk)); - $url->data .= $chunk; - } + $url->data .= $chunk; } - else - { - while (!feof($fp) && (time() < $endtime)) - $url->data .= @fread($fp, 20480); - } - - if ($p['filemtime'] && ($url->result == 304)) - $result = true; # Not modified, success but no data - else if ($url->result < 400) - $result =& $url->data; + } + else + { + while (!feof($fp) && (time() < $endtime)) + $url->data .= @fread($fp, 20480); } - @fclose($fp); + if ($p['filemtime'] && ($url->result == 304)) + $result = true; # Not modified, success but no data + else if ($url->result < 400) + $result =& $url->data; } - } else { - $results = self::get_multi(array('urls' => array('one' => $p['url'])) + $p); - $result = $results['one']; + + @fclose($fp); } if (time() >= $endtime) $result = false; - if (!$result && $p['retries'] > 0 && $url->result < 400) - $result = $url->get(array('retries' => $p['retries'] - 1) + $p); - return $result; } @@ -713,7 +729,7 @@ static function absolute($url=null) { $dir = preg_replace('#/[^/]*$#', '/', $_SERVER['PHP_SELF']); $url = preg_match('#^/#', $url) ? $url : "$dir$url"; - $url = "//" . $_SERVER['HTTP_HOST'] . ($_SERVER['SERVER_PORT'] == (isset($_SERVER['HTTPS']) ? 443 : 80) ? "" : ":{$_SERVER['SERVER_PORT']}") . $url; + $url = "//" . $_SERVER['HTTP_HOST'] . $url; } $url = "http" . (isset($_SERVER['HTTPS']) ? 's':'') . ":$url"; } |