X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=application%2FHttpUtils.php;h=ef6f3264cebe4299d1e0f3650205504475fbeef2;hb=f211e417bf637b8a83988175c29ee072c69f7642;hp=88a1efdb86382646648d9a26a2cbeab022f7ecdf;hpb=1fdb40fc169b42af7622610c4f088688de231118;p=github%2Fshaarli%2FShaarli.git diff --git a/application/HttpUtils.php b/application/HttpUtils.php index 88a1efdb..ef6f3264 100644 --- a/application/HttpUtils.php +++ b/application/HttpUtils.php @@ -1,11 +1,13 @@ idnToAscii(); @@ -62,25 +64,30 @@ function get_http_response($url, $timeout = 30, $maxBytes = 4194304) } // General cURL settings - curl_setopt($ch, CURLOPT_AUTOREFERER, true); - curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); - curl_setopt($ch, CURLOPT_HEADER, true); + curl_setopt($ch, CURLOPT_AUTOREFERER, true); + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); + curl_setopt($ch, CURLOPT_HEADER, true); curl_setopt( $ch, CURLOPT_HTTPHEADER, array('Accept-Language: ' . $acceptLanguage) ); - curl_setopt($ch, CURLOPT_MAXREDIRS, $maxRedirs); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); - curl_setopt($ch, CURLOPT_USERAGENT, $userAgent); + curl_setopt($ch, CURLOPT_MAXREDIRS, $maxRedirs); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); + curl_setopt($ch, CURLOPT_USERAGENT, $userAgent); + + if (is_callable($curlWriteFunction)) { + curl_setopt($ch, CURLOPT_WRITEFUNCTION, $curlWriteFunction); + } // Max download size management - curl_setopt($ch, CURLOPT_BUFFERSIZE, 1024); - curl_setopt($ch, CURLOPT_NOPROGRESS, false); - curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, - function($arg0, $arg1, $arg2, $arg3, $arg4 = 0) use ($maxBytes) - { + curl_setopt($ch, CURLOPT_BUFFERSIZE, 1024*16); + curl_setopt($ch, CURLOPT_NOPROGRESS, false); + curl_setopt( + $ch, + CURLOPT_PROGRESSFUNCTION, + function ($arg0, $arg1, $arg2, $arg3, $arg4 = 0) use ($maxBytes) { if (version_compare(phpversion(), '5.5', '<')) { // PHP version lower than 5.5 // Callback has 4 arguments @@ -226,7 +233,6 @@ function get_redirected_headers($url, $redirectionLimit = 3) && !empty($headers) && (strpos($headers[0], '301') !== false || strpos($headers[0], '302') !== false) && !empty($headers['Location'])) { - $redirection = is_array($headers['Location']) ? end($headers['Location']) : $headers['Location']; if ($redirection != $url) { $redirection = getAbsoluteUrl($url, $redirection); @@ -302,6 +308,13 @@ function server_url($server) $port = $server['HTTP_X_FORWARDED_PORT']; } + // This is a workaround for proxies that don't forward the scheme properly. + // Connecting over port 443 has to be in HTTPS. + // See https://github.com/shaarli/Shaarli/issues/1022 + if ($port == '443') { + $scheme = 'https'; + } + if (($scheme == 'http' && $port != '80') || ($scheme == 'https' && $port != '443') ) { @@ -401,3 +414,62 @@ function getIpAddressFromProxy($server, $trustedIps) return array_pop($ips); } + + +/** + * Return an identifier based on the advertised client IP address(es) + * + * This aims at preventing session hijacking from users behind the same proxy + * by relying on HTTP headers. + * + * See: + * - https://secure.php.net/manual/en/reserved.variables.server.php + * - https://stackoverflow.com/questions/3003145/how-to-get-the-client-ip-address-in-php + * - https://stackoverflow.com/questions/12233406/preventing-session-hijacking + * - https://stackoverflow.com/questions/21354859/trusting-x-forwarded-for-to-identify-a-visitor + * + * @param array $server The $_SERVER array + * + * @return string An identifier based on client IP address information + */ +function client_ip_id($server) +{ + $ip = $server['REMOTE_ADDR']; + + if (isset($server['HTTP_X_FORWARDED_FOR'])) { + $ip = $ip . '_' . $server['HTTP_X_FORWARDED_FOR']; + } + if (isset($server['HTTP_CLIENT_IP'])) { + $ip = $ip . '_' . $server['HTTP_CLIENT_IP']; + } + return $ip; +} + + +/** + * Returns true if Shaarli's currently browsed in HTTPS. + * Supports reverse proxies (if the headers are correctly set). + * + * @param array $server $_SERVER. + * + * @return bool true if HTTPS, false otherwise. + */ +function is_https($server) +{ + + if (isset($server['HTTP_X_FORWARDED_PORT'])) { + // Keep forwarded port + if (strpos($server['HTTP_X_FORWARDED_PORT'], ',') !== false) { + $ports = explode(',', $server['HTTP_X_FORWARDED_PORT']); + $port = trim($ports[0]); + } else { + $port = $server['HTTP_X_FORWARDED_PORT']; + } + + if ($port == '443') { + return true; + } + } + + return ! empty($server['HTTPS']); +}