From 949ac40c5b10daa8ed8a5bbe62c2d76b02a774c5 Mon Sep 17 00:00:00 2001 From: Alex Barth <alex_b@53995.no-reply.drupal.org> Date: Wed, 4 Nov 2009 17:20:36 +0000 Subject: [PATCH] Block curl to download from anything else than http or https. Throw exception when download fails. --- libraries/http_request.inc | 74 +++++++++++++++++++++--------------- plugins/FeedsHTTPFetcher.inc | 3 ++ 2 files changed, 46 insertions(+), 31 deletions(-) diff --git a/libraries/http_request.inc b/libraries/http_request.inc index b4ed90c8..c6f037ee 100644 --- a/libraries/http_request.inc +++ b/libraries/http_request.inc @@ -150,41 +150,53 @@ function http_request_get($url, $username = NULL, $password = NULL, $accept_inva if ($curl) { $headers[] = 'User-Agent: Drupal (+http://drupal.org/)'; $result = new stdClass(); - $download = curl_init($url); - curl_setopt($download, CURLOPT_FOLLOWLOCATION, TRUE); - if (!empty($username)) { - curl_setopt($download, CURLOPT_USERPWD, "{$username}:{$password}"); - } - curl_setopt($download, CURLOPT_HTTPHEADER, $headers); - curl_setopt($download, CURLOPT_HEADER, TRUE); - curl_setopt($download, CURLOPT_RETURNTRANSFER, TRUE); - curl_setopt($download, CURLOPT_ENCODING, ''); - if ($accept_invalid_cert) { - curl_setopt($download, CURLOPT_SSL_VERIFYPEER, 0); + + // Only download via cURL if we can validate the scheme to be either http or + // https. + // Validate in PHP, CURLOPT_PROTOCOLS is only supported with cURL 7.19.4 + $uri = parse_url($url); + if ($uri['scheme'] != 'http' && $uri['scheme'] != 'https') { + $result->error = 'invalid schema '. $uri['scheme']; + $result->code = -1003; // This corresponds to drupal_http_request() } - $header = ''; - $data = curl_exec($download); - $header_size = curl_getinfo($download, CURLINFO_HEADER_SIZE); - $header = substr($data, 0, $header_size - 1); - $result->data = substr($data, $header_size); - $header_lines = preg_split("/\r\n|\n|\r/", $header); - - $result->headers = array(); - array_shift($header_lines); // skip HTTP response status - while ($line = trim(array_shift($header_lines))) { - list($header, $value) = explode(':', $line, 2); - if (isset($result->headers[$header]) && $header == 'Set-Cookie') { - // RFC 2109: the Set-Cookie response header comprises the token Set- - // Cookie:, followed by a comma-separated list of one or more cookies. - $result->headers[$header] .= ','. trim($value); + else { + + $download = curl_init($url); + curl_setopt($download, CURLOPT_FOLLOWLOCATION, TRUE); + if (!empty($username)) { + curl_setopt($download, CURLOPT_USERPWD, "{$username}:{$password}"); } - else { - $result->headers[$header] = trim($value); + curl_setopt($download, CURLOPT_HTTPHEADER, $headers); + curl_setopt($download, CURLOPT_HEADER, TRUE); + curl_setopt($download, CURLOPT_RETURNTRANSFER, TRUE); + curl_setopt($download, CURLOPT_ENCODING, ''); + if ($accept_invalid_cert) { + curl_setopt($download, CURLOPT_SSL_VERIFYPEER, 0); } - } - $result->code = curl_getinfo($download, CURLINFO_HTTP_CODE); + $header = ''; + $data = curl_exec($download); + $header_size = curl_getinfo($download, CURLINFO_HEADER_SIZE); + $header = substr($data, 0, $header_size - 1); + $result->data = substr($data, $header_size); + $header_lines = preg_split("/\r\n|\n|\r/", $header); + + $result->headers = array(); + array_shift($header_lines); // skip HTTP response status + while ($line = trim(array_shift($header_lines))) { + list($header, $value) = explode(':', $line, 2); + if (isset($result->headers[$header]) && $header == 'Set-Cookie') { + // RFC 2109: the Set-Cookie response header comprises the token Set- + // Cookie:, followed by a comma-separated list of one or more cookies. + $result->headers[$header] .= ','. trim($value); + } + else { + $result->headers[$header] = trim($value); + } + } + $result->code = curl_getinfo($download, CURLINFO_HTTP_CODE); - curl_close($download); + curl_close($download); + } } else { $result = drupal_http_request($url, $headers); diff --git a/plugins/FeedsHTTPFetcher.inc b/plugins/FeedsHTTPFetcher.inc index d139abd5..78ad0f11 100644 --- a/plugins/FeedsHTTPFetcher.inc +++ b/plugins/FeedsHTTPFetcher.inc @@ -31,6 +31,9 @@ class FeedsHTTPFetcher extends FeedsFetcher { else { $result = http_request_get($url); } + if ($result->code != 200) { + throw new Exception(t('Download of @url failed with code !code.', array('@url' => $url, '!code' => $result->code))); + } return new FeedsFetcherResult($result->data, 'text/xml'); } -- GitLab