1 <?php
2 3 4 5 6 7
8
9 defined('FOF_INCLUDED') or die;
10
11 12 13
14 class FOFDownloadAdapterCurl extends FOFDownloadAdapterAbstract implements FOFDownloadInterface
15 {
16 protected = array();
17
18 public function __construct()
19 {
20 $this->priority = 110;
21 $this->supportsFileSize = true;
22 $this->supportsChunkDownload = true;
23 $this->name = 'curl';
24 $this->isSupported = function_exists('curl_init') && function_exists('curl_exec') && function_exists('curl_close');
25 }
26
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
46 public function downloadAndReturn($url, $from = null, $to = null, array $params = array())
47 {
48 $ch = curl_init();
49
50 if (empty($from))
51 {
52 $from = 0;
53 }
54
55 if (empty($to))
56 {
57 $to = 0;
58 }
59
60 if ($to < $from)
61 {
62 $temp = $to;
63 $to = $from;
64 $from = $temp;
65
66 unset($temp);
67 }
68
69
70 $options = array(
71 CURLOPT_AUTOREFERER => 1,
72 CURLOPT_SSL_VERIFYPEER => 1,
73 CURLOPT_SSL_VERIFYHOST => 2,
74 CURLOPT_SSLVERSION => 0,
75 CURLOPT_AUTOREFERER => 1,
76 CURLOPT_URL => $url,
77 CURLOPT_BINARYTRANSFER => 1,
78 CURLOPT_RETURNTRANSFER => 1,
79 CURLOPT_FOLLOWLOCATION => 1,
80 CURLOPT_CAINFO => __DIR__ . '/cacert.pem',
81 CURLOPT_HEADERFUNCTION => array($this, 'reponseHeaderCallback')
82 );
83
84 if (!(empty($from) && empty($to)))
85 {
86 $options[CURLOPT_RANGE] = "$from-$to";
87 }
88
89
90
91 $options = $params + $options;
92
93 @curl_setopt_array($ch, $options);
94
95 $this->headers = array();
96
97 $result = curl_exec($ch);
98
99 $errno = curl_errno($ch);
100 $errmsg = curl_error($ch);
101 $http_status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
102
103 if ($result === false)
104 {
105 $error = JText::sprintf('LIB_FOF_DOWNLOAD_ERR_CURL_ERROR', $errno, $errmsg);
106 }
107 elseif (($http_status >= 300) && ($http_status <= 399) && isset($this->headers['Location']) && !empty($this->headers['Location']))
108 {
109 return $this->downloadAndReturn($this->headers['Location'], $from, $to, $params);
110 }
111 elseif ($http_status > 399)
112 {
113 $result = false;
114 $errno = $http_status;
115 $error = JText::sprintf('LIB_FOF_DOWNLOAD_ERR_HTTPERROR', $http_status);
116 }
117
118 curl_close($ch);
119
120 if ($result === false)
121 {
122 throw new Exception($error, $errno);
123 }
124 else
125 {
126 return $result;
127 }
128 }
129
130 131 132 133 134 135 136
137 public function getFileSize($url)
138 {
139 $result = -1;
140
141 $ch = curl_init();
142
143 curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
144 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
145 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
146 curl_setopt($ch, CURLOPT_SSLVERSION, 0);
147
148 curl_setopt($ch, CURLOPT_URL, $url);
149 curl_setopt($ch, CURLOPT_NOBODY, true );
150 curl_setopt($ch, CURLOPT_HEADER, true );
151 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true );
152 @curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true );
153 @curl_setopt($ch, CURLOPT_CAINFO, __DIR__ . '/cacert.pem');
154
155 $data = curl_exec($ch);
156 curl_close($ch);
157
158 if ($data)
159 {
160 $content_length = "unknown";
161 $status = "unknown";
162 $redirection = null;
163
164 if (preg_match( "/^HTTP\/1\.[01] (\d\d\d)/", $data, $matches))
165 {
166 $status = (int)$matches[1];
167 }
168
169 if (preg_match( "/Content-Length: (\d+)/", $data, $matches))
170 {
171 $content_length = (int)$matches[1];
172 }
173
174 if (preg_match( "/Location: (.*)/", $data, $matches))
175 {
176 $redirection = (int)$matches[1];
177 }
178
179 if ($status == 200)
180 {
181 $result = $content_length;
182 }
183
184 if (($status > 300) && ($status <= 308))
185 {
186 if (!empty($redirection))
187 {
188 return $this->getFileSize($redirection);
189 }
190
191 return -1;
192 }
193 }
194
195 return $result;
196 }
197
198 199 200 201 202 203 204 205
206 protected function (&$ch, &$data)
207 {
208 $strlen = strlen($data);
209
210 if (($strlen) <= 2)
211 {
212 return $strlen;
213 }
214
215 if (substr($data, 0, 4) == 'HTTP')
216 {
217 return $strlen;
218 }
219
220 list($header, $value) = explode(': ', trim($data), 2);
221
222 $this->headers[$header] = $value;
223
224 return $strlen;
225 }
226 }