[BUGFIX] Ignore cURL proxy header block 08/47308/2
authorAlbrecht Köhnlein <typo3@bestof1983.de>
Fri, 19 Feb 2016 14:28:46 +0000 (15:28 +0100)
committerAndreas Wolf <andreas.wolf@typo3.org>
Mon, 18 Apr 2016 09:34:22 +0000 (11:34 +0200)
When cURL is enabled with a proxy, the proxy’s HTTP header (sent as a
response to the client CONNECT request) was not removed correctly for
https requests.

See also RFC 2817.

Resolves: #73567
Releases: master, 7.6, 6.2
Change-Id: I0f11933f523b099dd23a5bef631699904ffcefc8
(cherry picked from commit 09f1f5632e05a9140a7d65ceca0f38caa5f335eb)
Reviewed-on: https://review.typo3.org/47308
Reviewed-by: Jonas Götze <jonnsn@gmail.com>
Tested-by: Jonas Götze <jonnsn@gmail.com>
Reviewed-by: Andreas Wolf <andreas.wolf@typo3.org>
Tested-by: Andreas Wolf <andreas.wolf@typo3.org>
Reviewed-by: Dmitry Dulepov <dmitry.dulepov@gmail.com>
Reviewed-by: Stefan Neufeind <typo3.neufeind@speedpartner.de>
Reviewed-by: Daniel Goerz <ervaude@gmail.com>
typo3/sysext/core/Classes/Utility/GeneralUtility.php

index 26572ee..d439ae0 100755 (executable)
@@ -2480,8 +2480,9 @@ class GeneralUtility {
 
                        $followLocationSucceeded = @curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
 
+                       $curlIncludeHeaders = !$followLocationSucceeded || $includeHeader;
                        curl_setopt($ch, CURLOPT_URL, $url);
-                       curl_setopt($ch, CURLOPT_HEADER, !$followLocationSucceeded || $includeHeader ? 1 : 0);
+                       curl_setopt($ch, CURLOPT_HEADER, $curlIncludeHeaders ? 1 : 0);
                        curl_setopt($ch, CURLOPT_NOBODY, $includeHeader == 2 ? 1 : 0);
                        curl_setopt($ch, CURLOPT_HTTPGET, $includeHeader == 2 ? 'HEAD' : 'GET');
                        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
@@ -2507,6 +2508,23 @@ class GeneralUtility {
                        $content = curl_exec($ch);
                        $curlInfo = curl_getinfo($ch);
 
+                       // Remove additional proxy header block, when proxy is used for https request and CURL_HEADER is enabled.
+                       // Most HTTPS proxies add a second header before the actual server headers in their response, as a
+                       // response to the CONNECT message sent by the client to the proxy. cURL does not strip this since 2005,
+                       // so there are two headers arriving here, of which the first is not of interest to us—therefore, we can
+                       // safely strip it.
+                       // Detecting two linebreaks followed by a "HTTP/" (as done here) is the only reliable way to detect the
+                       // proxy headers, as the relevant RFCs do not specify the exact status code (it might be any of 2xx) or
+                       // the status message. Therefore, we check if there is a second HTTP headers block and then strip the
+                       // first one.
+                       if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyServer']
+                           && $curlIncludeHeaders
+                           && preg_match('/^https:/', $url)
+                           && strpos($content, "\r\n\r\nHTTP/") !== false
+                       ) {
+                               $content = self::stripHttpHeaders($content);
+                       }
+
                        if (!$followLocationSucceeded) {
                                // Check if we need to do redirects
                                if ($curlInfo['http_code'] >= 300 && $curlInfo['http_code'] < 400) {