mirror of
https://github.com/friendica/friendica
synced 2025-05-01 19:44:23 +02:00
Merge pull request #5878 from nupplaphil/curl_response_refactoring
Curl response refactoring
This commit is contained in:
commit
a066befba5
33 changed files with 563 additions and 484 deletions
|
@ -179,17 +179,17 @@ class ExAuth
|
|||
|
||||
$url = ($ssl ? 'https' : 'http') . '://' . $host . '/noscrape/' . $user;
|
||||
|
||||
$data = Network::curl($url);
|
||||
$curlResult = Network::curl($url);
|
||||
|
||||
if (!is_array($data)) {
|
||||
if (!$curlResult->isSuccess()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($data['return_code'] != '200') {
|
||||
if ($curlResult->getReturnCode() != 200) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$json = @json_decode($data['body']);
|
||||
$json = @json_decode($curlResult->getBody());
|
||||
if (!is_object($json)) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -302,10 +302,9 @@ class HTTPSignature
|
|||
|
||||
$headers[] = 'Content-Type: application/activity+json';
|
||||
|
||||
Network::post($target, $content, $headers);
|
||||
$return_code = Network::getCurl()->getCode();
|
||||
$postResult = Network::post($target, $content, $headers);
|
||||
|
||||
logger('Transmit to ' . $target . ' returned ' . $return_code);
|
||||
logger('Transmit to ' . $target . ' returned ' . $postResult->getReturnCode());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -7,31 +7,12 @@ namespace Friendica\Util;
|
|||
use Friendica\Core\Addon;
|
||||
use Friendica\Core\System;
|
||||
use Friendica\Core\Config;
|
||||
use Friendica\Network\Curl;
|
||||
use Friendica\Network\CurlResult;
|
||||
use DOMDocument;
|
||||
use DomXPath;
|
||||
|
||||
class Network
|
||||
{
|
||||
/**
|
||||
* @var Curl The latest Curl output
|
||||
*/
|
||||
private static $curl;
|
||||
|
||||
/**
|
||||
* Returns the latest Curl output
|
||||
*
|
||||
* @return Curl The latest Curl output
|
||||
*/
|
||||
public static function getCurl()
|
||||
{
|
||||
if (empty(self::$curl)) {
|
||||
self::$curl = new Curl();
|
||||
}
|
||||
|
||||
return self::$curl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Curl wrapper
|
||||
*
|
||||
|
@ -54,7 +35,7 @@ class Network
|
|||
{
|
||||
$ret = self::fetchUrlFull($url, $binary, $redirects, $timeout, $accept_content, $cookiejar);
|
||||
|
||||
return $ret['body'];
|
||||
return $ret->getBody();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -72,7 +53,7 @@ class Network
|
|||
* @param string $accept_content supply Accept: header with 'accept_content' as the value
|
||||
* @param string $cookiejar Path to cookie jar file
|
||||
*
|
||||
* @return array With all relevant information, 'body' contains the actual fetched content.
|
||||
* @return CurlResult With all relevant information, 'body' contains the actual fetched content.
|
||||
*/
|
||||
public static function fetchUrlFull($url, $binary = false, &$redirects = 0, $timeout = 0, $accept_content = null, $cookiejar = '')
|
||||
{
|
||||
|
@ -102,12 +83,7 @@ class Network
|
|||
* 'nobody' => only return the header
|
||||
* 'cookiejar' => path to cookie jar file
|
||||
*
|
||||
* @return array an assoziative array with:
|
||||
* int 'return_code' => HTTP return code or 0 if timeout or failure
|
||||
* boolean 'success' => boolean true (if HTTP 2xx result) or false
|
||||
* string 'redirect_url' => in case of redirect, content was finally retrieved from this URL
|
||||
* string 'header' => HTTP headers
|
||||
* string 'body' => fetched content
|
||||
* @return CurlResult
|
||||
*/
|
||||
public static function curl($url, $binary = false, &$redirects = 0, $opts = [])
|
||||
{
|
||||
|
@ -120,24 +96,24 @@ class Network
|
|||
$parts = parse_url($url);
|
||||
$path_parts = explode('/', defaults($parts, 'path', ''));
|
||||
foreach ($path_parts as $part) {
|
||||
if (strlen($part) <> mb_strlen($part)) {
|
||||
if (strlen($part) <> mb_strlen($part)) {
|
||||
$parts2[] = rawurlencode($part);
|
||||
} else {
|
||||
$parts2[] = $part;
|
||||
}
|
||||
} else {
|
||||
$parts2[] = $part;
|
||||
}
|
||||
}
|
||||
$parts['path'] = implode('/', $parts2);
|
||||
$parts['path'] = implode('/', $parts2);
|
||||
$url = self::unparseURL($parts);
|
||||
|
||||
if (self::isUrlBlocked($url)) {
|
||||
logger('domain of ' . $url . ' is blocked', LOGGER_DATA);
|
||||
return $ret;
|
||||
return CurlResult::createErrorCurl($url);
|
||||
}
|
||||
|
||||
$ch = @curl_init($url);
|
||||
|
||||
if (($redirects > 8) || (!$ch)) {
|
||||
return $ret;
|
||||
return CurlResult::createErrorCurl($url);
|
||||
}
|
||||
|
||||
@curl_setopt($ch, CURLOPT_HEADER, true);
|
||||
|
@ -232,91 +208,20 @@ class Network
|
|||
$curl_info = @curl_getinfo($ch);
|
||||
}
|
||||
|
||||
if (curl_errno($ch) !== CURLE_OK) {
|
||||
logger('error fetching ' . $url . ': ' . curl_error($ch), LOGGER_INFO);
|
||||
}
|
||||
$curlResponse = new CurlResult($url, $s, $curl_info, curl_errno($ch), curl_error($ch));
|
||||
|
||||
$ret['errno'] = curl_errno($ch);
|
||||
|
||||
$base = $s;
|
||||
$ret['info'] = $curl_info;
|
||||
|
||||
$http_code = $curl_info['http_code'];
|
||||
|
||||
logger($url . ': ' . $http_code . " " . $s, LOGGER_DATA);
|
||||
$header = '';
|
||||
|
||||
// Pull out multiple headers, e.g. proxy and continuation headers
|
||||
// allow for HTTP/2.x without fixing code
|
||||
|
||||
while (preg_match('/^HTTP\/[1-2].+? [1-5][0-9][0-9]/', $base)) {
|
||||
$chunk = substr($base, 0, strpos($base, "\r\n\r\n") + 4);
|
||||
$header .= $chunk;
|
||||
$base = substr($base, strlen($chunk));
|
||||
}
|
||||
|
||||
self::$curl = new Curl($http_code, (isset($curl_info['content_type']) ? $curl_info['content_type'] : ''), $header);
|
||||
|
||||
if ($http_code == 301 || $http_code == 302 || $http_code == 303 || $http_code == 307) {
|
||||
$new_location_info = @parse_url($curl_info['redirect_url']);
|
||||
$old_location_info = @parse_url($curl_info['url']);
|
||||
|
||||
$newurl = $curl_info['redirect_url'];
|
||||
|
||||
if (empty($new_location_info['path']) && !empty($new_location_info['host'])) {
|
||||
$newurl = $new_location_info['scheme'] . '://' . $new_location_info['host'] . $old_location_info['path'];
|
||||
}
|
||||
|
||||
$matches = [];
|
||||
|
||||
if (preg_match('/(Location:|URI:)(.*?)\n/i', $header, $matches)) {
|
||||
$newurl = trim(array_pop($matches));
|
||||
}
|
||||
if (strpos($newurl, '/') === 0) {
|
||||
$newurl = $old_location_info["scheme"]."://".$old_location_info["host"].$newurl;
|
||||
}
|
||||
$old_location_query = @parse_url($url, PHP_URL_QUERY);
|
||||
|
||||
if ($old_location_query != '') {
|
||||
$newurl .= '?' . $old_location_query;
|
||||
}
|
||||
|
||||
if (filter_var($newurl, FILTER_VALIDATE_URL)) {
|
||||
$redirects++;
|
||||
@curl_close($ch);
|
||||
return self::curl($newurl, $binary, $redirects, $opts);
|
||||
}
|
||||
}
|
||||
|
||||
self::$curl->setCode($http_code);
|
||||
if (isset($curl_info['content_type'])) {
|
||||
self::$curl->setContentType($curl_info['content_type']);
|
||||
}
|
||||
|
||||
$rc = intval($http_code);
|
||||
$ret['return_code'] = $rc;
|
||||
$ret['success'] = (($rc >= 200 && $rc <= 299) ? true : false);
|
||||
$ret['redirect_url'] = $url;
|
||||
|
||||
if (!$ret['success']) {
|
||||
$ret['error'] = curl_error($ch);
|
||||
$ret['debug'] = $curl_info;
|
||||
logger('error: '.$url.': '.$ret['return_code'].' - '.$ret['error'], LOGGER_DEBUG);
|
||||
logger('debug: '.print_r($curl_info, true), LOGGER_DATA);
|
||||
}
|
||||
|
||||
$ret['body'] = substr($s, strlen($header));
|
||||
$ret['header'] = $header;
|
||||
|
||||
if (x($opts, 'debug')) {
|
||||
$ret['debug'] = $curl_info;
|
||||
if ($curlResponse->isRedirectUrl()) {
|
||||
$redirects++;
|
||||
logger('curl: redirect ' . $url . ' to ' . $curlResponse->getRedirectUrl());
|
||||
@curl_close($ch);
|
||||
return self::curl($curlResponse->getRedirectUrl(), $binary, $redirects, $opts);
|
||||
}
|
||||
|
||||
@curl_close($ch);
|
||||
|
||||
$a->saveTimestamp($stamp1, 'network');
|
||||
|
||||
return($ret);
|
||||
return $curlResponse;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -328,7 +233,7 @@ class Network
|
|||
* @param integer $redirects Recursion counter for internal use - default = 0
|
||||
* @param integer $timeout The timeout in seconds, default system config value or 60 seconds
|
||||
*
|
||||
* @return string The content
|
||||
* @return CurlResult The content
|
||||
*/
|
||||
public static function post($url, $params, $headers = null, &$redirects = 0, $timeout = 0)
|
||||
{
|
||||
|
@ -336,14 +241,14 @@ class Network
|
|||
|
||||
if (self::isUrlBlocked($url)) {
|
||||
logger('post_url: domain of ' . $url . ' is blocked', LOGGER_DATA);
|
||||
return false;
|
||||
return CurlResult::createErrorCurl($url);
|
||||
}
|
||||
|
||||
$a = get_app();
|
||||
$ch = curl_init($url);
|
||||
|
||||
if (($redirects > 8) || (!$ch)) {
|
||||
return false;
|
||||
return CurlResult::createErrorCurl($url);
|
||||
}
|
||||
|
||||
logger('post_url: start ' . $url, LOGGER_DATA);
|
||||
|
@ -397,8 +302,6 @@ class Network
|
|||
}
|
||||
}
|
||||
|
||||
self::getCurl()->setCode(0);
|
||||
|
||||
// don't let curl abort the entire application
|
||||
// if it throws any errors.
|
||||
|
||||
|
@ -406,53 +309,23 @@ class Network
|
|||
|
||||
$base = $s;
|
||||
$curl_info = curl_getinfo($ch);
|
||||
$http_code = $curl_info['http_code'];
|
||||
|
||||
logger('post_url: result ' . $http_code . ' - ' . $url, LOGGER_DATA);
|
||||
$curlResponse = new CurlResult($url, $s, $curl_info, curl_errno($ch), curl_error($ch));
|
||||
|
||||
$header = '';
|
||||
|
||||
// Pull out multiple headers, e.g. proxy and continuation headers
|
||||
// allow for HTTP/2.x without fixing code
|
||||
|
||||
while (preg_match('/^HTTP\/[1-2].+? [1-5][0-9][0-9]/', $base)) {
|
||||
$chunk = substr($base, 0, strpos($base, "\r\n\r\n") + 4);
|
||||
$header .= $chunk;
|
||||
$base = substr($base, strlen($chunk));
|
||||
if ($curlResponse->isRedirectUrl()) {
|
||||
$redirects++;
|
||||
logger('post_url: redirect ' . $url . ' to ' . $curlResponse->getRedirectUrl());
|
||||
curl_close($ch);
|
||||
return self::post($curlResponse->getRedirectUrl(), $params, $headers, $redirects, $timeout);
|
||||
}
|
||||
|
||||
if ($http_code == 301 || $http_code == 302 || $http_code == 303 || $http_code == 307) {
|
||||
$matches = [];
|
||||
$new_location_info = @parse_url($curl_info['redirect_url']);
|
||||
$old_location_info = @parse_url($curl_info['url']);
|
||||
|
||||
preg_match('/(Location:|URI:)(.*?)\n/', $header, $matches);
|
||||
$newurl = trim(array_pop($matches));
|
||||
|
||||
if (strpos($newurl, '/') === 0) {
|
||||
$newurl = $old_location_info["scheme"] . "://" . $old_location_info["host"] . $newurl;
|
||||
}
|
||||
|
||||
if (filter_var($newurl, FILTER_VALIDATE_URL)) {
|
||||
$redirects++;
|
||||
logger('post_url: redirect ' . $url . ' to ' . $newurl);
|
||||
return self::post($newurl, $params, $headers, $redirects, $timeout);
|
||||
}
|
||||
}
|
||||
|
||||
self::getCurl()->setCode($http_code);
|
||||
|
||||
$body = substr($s, strlen($header));
|
||||
|
||||
self::getCurl()->setHeaders($header);
|
||||
|
||||
curl_close($ch);
|
||||
|
||||
$a->saveTimestamp($stamp1, 'network');
|
||||
|
||||
logger('post_url: end ' . $url, LOGGER_DATA);
|
||||
|
||||
return $body;
|
||||
return $curlResponse;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -135,23 +135,23 @@ class ParseUrl
|
|||
$siteinfo['url'] = $url;
|
||||
$siteinfo['type'] = 'link';
|
||||
|
||||
$data = Network::curl($url);
|
||||
if (!$data['success']) {
|
||||
$curlResult = Network::curl($url);
|
||||
if (!$curlResult->isSuccess()) {
|
||||
return $siteinfo;
|
||||
}
|
||||
|
||||
// If the file is too large then exit
|
||||
if ($data['info']['download_content_length'] > 1000000) {
|
||||
if ($curlResult->getInfo()['download_content_length'] > 1000000) {
|
||||
return $siteinfo;
|
||||
}
|
||||
|
||||
// If it isn't a HTML file then exit
|
||||
if (($data['info']['content_type'] != '') && !strstr(strtolower($data['info']['content_type']), 'html')) {
|
||||
if (($curlResult->getContentType() != '') && !strstr(strtolower($curlResult->getContentType()), 'html')) {
|
||||
return $siteinfo;
|
||||
}
|
||||
|
||||
$header = $data['header'];
|
||||
$body = $data['body'];
|
||||
$header = $curlResult->getHeader();
|
||||
$body = $curlResult->getBody();
|
||||
|
||||
if ($do_oembed) {
|
||||
$oembed_data = OEmbed::fetchURL($url);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue