1<?php 2 3namespace Mpdf; 4 5use Mpdf\Utils\Arrays; 6use Psr\Log\LoggerInterface; 7use Mpdf\Log\Context as LogContext; 8 9class RemoteContentFetcher implements \Psr\Log\LoggerAwareInterface 10{ 11 12 /** 13 * @var \Mpdf\Mpdf 14 */ 15 private $mpdf; 16 17 /** 18 * @var \Psr\Log\LoggerInterface 19 */ 20 private $logger; 21 22 public function __construct(Mpdf $mpdf, LoggerInterface $logger) 23 { 24 $this->mpdf = $mpdf; 25 $this->logger = $logger; 26 } 27 28 public function getFileContentsByCurl($url) 29 { 30 $this->logger->debug(sprintf('Fetching (cURL) content of remote URL "%s"', $url), ['context' => LogContext::REMOTE_CONTENT]); 31 32 $ch = curl_init($url); 33 34 curl_setopt($ch, CURLOPT_USERAGENT, $this->mpdf->curlUserAgent); 35 curl_setopt($ch, CURLOPT_HEADER, 0); 36 curl_setopt($ch, CURLOPT_NOBODY, 0); 37 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 38 curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $this->mpdf->curlTimeout); 39 40 if ($this->mpdf->curlExecutionTimeout) { 41 curl_setopt($ch, CURLOPT_TIMEOUT, $this->mpdf->curlExecutionTimeout); 42 } 43 44 if ($this->mpdf->curlFollowLocation) { 45 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); 46 } 47 48 if ($this->mpdf->curlAllowUnsafeSslRequests) { 49 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); 50 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); 51 } 52 53 if ($this->mpdf->curlCaCertificate && is_file($this->mpdf->curlCaCertificate)) { 54 curl_setopt($ch, CURLOPT_CAINFO, $this->mpdf->curlCaCertificate); 55 } 56 57 if ($this->mpdf->curlProxy) { 58 curl_setopt($ch, CURLOPT_PROXY, $this->mpdf->curlProxy); 59 if ($this->mpdf->curlProxyAuth) { 60 curl_setopt($ch, CURLOPT_PROXYUSERPWD, $this->mpdf->curlProxyAuth); 61 } 62 } 63 64 $data = curl_exec($ch); 65 66 if (curl_error($ch)) { 67 $message = sprintf('cURL error: "%s"', curl_error($ch)); 68 $this->logger->error($message, ['context' => LogContext::REMOTE_CONTENT]); 69 70 if ($this->mpdf->debug) { 71 throw new \Mpdf\MpdfException($message); 72 } 73 } 74 75 $info = curl_getinfo($ch); 76 if (isset($info['http_code']) && $info['http_code'] !== 200) { 77 $message = sprintf('HTTP error: %d', $info['http_code']); 78 $this->logger->error($message, ['context' => LogContext::REMOTE_CONTENT]); 79 80 if ($this->mpdf->debug) { 81 throw new \Mpdf\MpdfException($message); 82 } 83 } 84 85 curl_close($ch); 86 87 return $data; 88 } 89 90 public function getFileContentsBySocket($url) 91 { 92 $this->logger->debug(sprintf('Fetching (socket) content of remote URL "%s"', $url), ['context' => LogContext::REMOTE_CONTENT]); 93 // mPDF 5.7.3 94 95 $timeout = 1; 96 $p = parse_url($url); 97 98 $file = Arrays::get($p, 'path', ''); 99 $scheme = Arrays::get($p, 'scheme', ''); 100 $port = Arrays::get($p, 'port', 80); 101 $prefix = ''; 102 103 if ($scheme === 'https') { 104 $prefix = 'ssl://'; 105 $port = Arrays::get($p, 'port', 443); 106 } 107 108 $query = Arrays::get($p, 'query', null); 109 if ($query) { 110 $file .= '?' . $query; 111 } 112 113 if (!($fh = @fsockopen($prefix . $p['host'], $port, $errno, $errstr, $timeout))) { 114 $this->logger->error(sprintf('Socket error "%s": "%s"', $errno, $errstr), ['context' => LogContext::REMOTE_CONTENT]); 115 return false; 116 } 117 118 $getstring = 'GET ' . $file . " HTTP/1.0 \r\n" . 119 'Host: ' . $p['host'] . " \r\n" . 120 "Connection: close\r\n\r\n"; 121 122 fwrite($fh, $getstring); 123 124 // Get rid of HTTP header 125 $s = fgets($fh, 1024); 126 if (!$s) { 127 return false; 128 } 129 130 while (!feof($fh)) { 131 $s = fgets($fh, 1024); 132 if ($s === "\r\n") { 133 break; 134 } 135 } 136 137 $data = ''; 138 139 while (!feof($fh)) { 140 $data .= fgets($fh, 1024); 141 } 142 143 fclose($fh); 144 145 return $data; 146 } 147 148 public function setLogger(LoggerInterface $logger) 149 { 150 $this->logger = $logger; 151 } 152} 153