diff options
Diffstat (limited to 'application/HttpUtils.php')
-rw-r--r-- | application/HttpUtils.php | 79 |
1 files changed, 70 insertions, 9 deletions
diff --git a/application/HttpUtils.php b/application/HttpUtils.php index e705cfd6..83a4c5e2 100644 --- a/application/HttpUtils.php +++ b/application/HttpUtils.php | |||
@@ -3,9 +3,11 @@ | |||
3 | * GET an HTTP URL to retrieve its content | 3 | * GET an HTTP URL to retrieve its content |
4 | * Uses the cURL library or a fallback method | 4 | * Uses the cURL library or a fallback method |
5 | * | 5 | * |
6 | * @param string $url URL to get (http://...) | 6 | * @param string $url URL to get (http://...) |
7 | * @param int $timeout network timeout (in seconds) | 7 | * @param int $timeout network timeout (in seconds) |
8 | * @param int $maxBytes maximum downloaded bytes (default: 4 MiB) | 8 | * @param int $maxBytes maximum downloaded bytes (default: 4 MiB) |
9 | * @param callable|string $curlWriteFunction Optional callback called during the download (cURL CURLOPT_WRITEFUNCTION). | ||
10 | * Can be used to add download conditions on the headers (response code, content type, etc.). | ||
9 | * | 11 | * |
10 | * @return array HTTP response headers, downloaded content | 12 | * @return array HTTP response headers, downloaded content |
11 | * | 13 | * |
@@ -29,7 +31,7 @@ | |||
29 | * @see http://stackoverflow.com/q/9183178 | 31 | * @see http://stackoverflow.com/q/9183178 |
30 | * @see http://stackoverflow.com/q/1462720 | 32 | * @see http://stackoverflow.com/q/1462720 |
31 | */ | 33 | */ |
32 | function get_http_response($url, $timeout = 30, $maxBytes = 4194304) | 34 | function get_http_response($url, $timeout = 30, $maxBytes = 4194304, $curlWriteFunction = null) |
33 | { | 35 | { |
34 | $urlObj = new Url($url); | 36 | $urlObj = new Url($url); |
35 | $cleanUrl = $urlObj->idnToAscii(); | 37 | $cleanUrl = $urlObj->idnToAscii(); |
@@ -75,8 +77,12 @@ function get_http_response($url, $timeout = 30, $maxBytes = 4194304) | |||
75 | curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); | 77 | curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); |
76 | curl_setopt($ch, CURLOPT_USERAGENT, $userAgent); | 78 | curl_setopt($ch, CURLOPT_USERAGENT, $userAgent); |
77 | 79 | ||
80 | if (is_callable($curlWriteFunction)) { | ||
81 | curl_setopt($ch, CURLOPT_WRITEFUNCTION, $curlWriteFunction); | ||
82 | } | ||
83 | |||
78 | // Max download size management | 84 | // Max download size management |
79 | curl_setopt($ch, CURLOPT_BUFFERSIZE, 1024); | 85 | curl_setopt($ch, CURLOPT_BUFFERSIZE, 1024*16); |
80 | curl_setopt($ch, CURLOPT_NOPROGRESS, false); | 86 | curl_setopt($ch, CURLOPT_NOPROGRESS, false); |
81 | curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, | 87 | curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, |
82 | function($arg0, $arg1, $arg2, $arg3, $arg4 = 0) use ($maxBytes) | 88 | function($arg0, $arg1, $arg2, $arg3, $arg4 = 0) use ($maxBytes) |
@@ -122,7 +128,7 @@ function get_http_response($url, $timeout = 30, $maxBytes = 4194304) | |||
122 | $content = substr($response, $headSize); | 128 | $content = substr($response, $headSize); |
123 | $headers = array(); | 129 | $headers = array(); |
124 | foreach (preg_split('~[\r\n]+~', $rawHeadersLastRedir) as $line) { | 130 | foreach (preg_split('~[\r\n]+~', $rawHeadersLastRedir) as $line) { |
125 | if (empty($line) or ctype_space($line)) { | 131 | if (empty($line) || ctype_space($line)) { |
126 | continue; | 132 | continue; |
127 | } | 133 | } |
128 | $splitLine = explode(': ', $line, 2); | 134 | $splitLine = explode(': ', $line, 2); |
@@ -297,13 +303,40 @@ function server_url($server) | |||
297 | // Keep forwarded port | 303 | // Keep forwarded port |
298 | if (strpos($server['HTTP_X_FORWARDED_PORT'], ',') !== false) { | 304 | if (strpos($server['HTTP_X_FORWARDED_PORT'], ',') !== false) { |
299 | $ports = explode(',', $server['HTTP_X_FORWARDED_PORT']); | 305 | $ports = explode(',', $server['HTTP_X_FORWARDED_PORT']); |
300 | $port = ':' . trim($ports[0]); | 306 | $port = trim($ports[0]); |
307 | } else { | ||
308 | $port = $server['HTTP_X_FORWARDED_PORT']; | ||
309 | } | ||
310 | |||
311 | // This is a workaround for proxies that don't forward the scheme properly. | ||
312 | // Connecting over port 443 has to be in HTTPS. | ||
313 | // See https://github.com/shaarli/Shaarli/issues/1022 | ||
314 | if ($port == '443') { | ||
315 | $scheme = 'https'; | ||
316 | } | ||
317 | |||
318 | if (($scheme == 'http' && $port != '80') | ||
319 | || ($scheme == 'https' && $port != '443') | ||
320 | ) { | ||
321 | $port = ':' . $port; | ||
301 | } else { | 322 | } else { |
302 | $port = ':' . $server['HTTP_X_FORWARDED_PORT']; | 323 | $port = ''; |
303 | } | 324 | } |
304 | } | 325 | } |
305 | 326 | ||
306 | return $scheme.'://'.$server['SERVER_NAME'].$port; | 327 | if (isset($server['HTTP_X_FORWARDED_HOST'])) { |
328 | // Keep forwarded host | ||
329 | if (strpos($server['HTTP_X_FORWARDED_HOST'], ',') !== false) { | ||
330 | $hosts = explode(',', $server['HTTP_X_FORWARDED_HOST']); | ||
331 | $host = trim($hosts[0]); | ||
332 | } else { | ||
333 | $host = $server['HTTP_X_FORWARDED_HOST']; | ||
334 | } | ||
335 | } else { | ||
336 | $host = $server['SERVER_NAME']; | ||
337 | } | ||
338 | |||
339 | return $scheme.'://'.$host.$port; | ||
307 | } | 340 | } |
308 | 341 | ||
309 | // SSL detection | 342 | // SSL detection |
@@ -381,3 +414,31 @@ function getIpAddressFromProxy($server, $trustedIps) | |||
381 | 414 | ||
382 | return array_pop($ips); | 415 | return array_pop($ips); |
383 | } | 416 | } |
417 | |||
418 | /** | ||
419 | * Returns true if Shaarli's currently browsed in HTTPS. | ||
420 | * Supports reverse proxies (if the headers are correctly set). | ||
421 | * | ||
422 | * @param array $server $_SERVER. | ||
423 | * | ||
424 | * @return bool true if HTTPS, false otherwise. | ||
425 | */ | ||
426 | function is_https($server) | ||
427 | { | ||
428 | |||
429 | if (isset($server['HTTP_X_FORWARDED_PORT'])) { | ||
430 | // Keep forwarded port | ||
431 | if (strpos($server['HTTP_X_FORWARDED_PORT'], ',') !== false) { | ||
432 | $ports = explode(',', $server['HTTP_X_FORWARDED_PORT']); | ||
433 | $port = trim($ports[0]); | ||
434 | } else { | ||
435 | $port = $server['HTTP_X_FORWARDED_PORT']; | ||
436 | } | ||
437 | |||
438 | if ($port == '443') { | ||
439 | return true; | ||
440 | } | ||
441 | } | ||
442 | |||
443 | return ! empty($server['HTTPS']); | ||
444 | } | ||