Page MenuHomePhabricator

HttpFunctions.php not compatible with Php 5.3.19? (bug setting sslVerifyHost => true)
Closed, ResolvedPublic

Description

Since my hosting provider upgraded to php 5.3.19 a template on my wiki fails with '/includes/HttpFunctions.php(68): CurlHttpRequest->execute()' as the top line of the backtrace.


Version: 1.20.x
Severity: major
See Also:
https://bugzilla.wikimedia.org/show_bug.cgi?id=44135
https://bugzilla.wikimedia.org/show_bug.cgi?id=42468
https://bugzilla.wikimedia.org/show_bug.cgi?id=70262

Details

Reference
bz42441

Event Timeline

bzimport raised the priority of this task from to Low.Nov 22 2014, 12:58 AM
bzimport set Reference to bz42441.
bzimport added a subscriber: Unknown Object (MLST).

Can you please provide the full stack trace?

#0 /home/wow/domains/wow.wikibase.nl/public_html/includes/HttpFunctions.php(68): CurlHttpRequest->execute()
#1 /home/wow/domains/wow.wikibase.nl/public_html/includes/HttpFunctions.php(88): Http::request('GET', 'http://maps.goo...', Array)
#2 /home/wow/domains/wow.wikibase.nl/public_html/extensions/Maps/includes/Maps_Geocoder.php(111): Http::get('http://maps.goo...')
#3 /home/wow/domains/wow.wikibase.nl/public_html/extensions/Maps/includes/Maps_Geocoders.php(205): MapsGeocoder->geocode('Anthony Fokkers...')
#4 /home/wow/domains/wow.wikibase.nl/public_html/extensions/Maps/includes/Maps_Geocoders.php(127): MapsGeocoders::geocode('Anthony Fokkers...', 'google', 'googlemaps3')
#5 /home/wow/domains/wow.wikibase.nl/public_html/extensions/Maps/includes/Maps_Geocoders.php(144): MapsGeocoders::attemptToGeocode('Anthony Fokkers...', 'google', 'googlemaps3')
#6 /home/wow/domains/wow.wikibase.nl/public_html/extensions/Maps/includes/criteria/CriterionIsLocation.php(55): MapsGeocoders::isLocation('Anthony Fokkers...', 'google', 'googlemaps3')
#7 /home/wow/domains/wow.wikibase.nl/public_html/extensions/Validator/includes/ItemParameterCriterion.php(75): CriterionIsLocation->doValidation('Anthony Fokkers...', Object(ListParameter), Array)
#8 /home/wow/domains/wow.wikibase.nl/public_html/extensions/Validator/includes/Parameter.php(424): ItemParameterCriterion->validate(Object(ListParameter), Array)
#9 /home/wow/domains/wow.wikibase.nl/public_html/extensions/Validator/includes/Parameter.php(399): Parameter->validateCriteria(Array)
#10 /home/wow/domains/wow.wikibase.nl/public_html/extensions/Validator/includes/ListParameter.php(137): Parameter->doValidation(Array)
#11 /home/wow/domains/wow.wikibase.nl/public_html/extensions/Validator/includes/Validator.php(291): ListParameter->validate(Array)
#12 /home/wow/domains/wow.wikibase.nl/public_html/extensions/Validator/includes/Validator.php(253): Validator->doParamProcessing()
#13 /home/wow/domains/wow.wikibase.nl/public_html/extensions/Validator/includes/ParserHook.php(372): Validator->validateParameters()
#14 /home/wow/domains/wow.wikibase.nl/public_html/extensions/Validator/includes/ParserHook.php(295): ParserHook->validateAndRender(Array, 1)
#15 [internal function]: ParserHook->renderFunction(Object(Parser), 'Anthony Fokkers...', 'service=googlem...', 'geoservice=goog...', 'height=200', 'controls=zoom')
#16 /home/wow/domains/wow.wikibase.nl/public_html/extensions/Validator/includes/ParserHook.php(337): call_user_func_array(Array, Array)
#17 /home/wow/domains/wow.wikibase.nl/public_html/extensions/Validator/includes/ParserHook.php(636): ParserHook->renderFunctionObj(Object(Parser), Object(PPTemplateFrame_DOM), Array)
#18 [internal function]: ParserHookCaller->runFunctionHookObj(Object(Parser), Object(PPTemplateFrame_DOM), Array)
#19 /home/wow/domains/wow.wikibase.nl/public_html/includes/parser/Parser.php(3250): call_user_func_array(Array, Array)
#20 /home/wow/domains/wow.wikibase.nl/public_html/includes/parser/Preprocessor_DOM.php(1083): Parser->braceSubstitution(Array, Object(PPTemplateFrame_DOM))
#21 /home/wow/domains/wow.wikibase.nl/public_html/includes/parser/Parser.php(3416): PPFrame_DOM->expand(Object(PPNode_DOM))
#22 /home/wow/domains/wow.wikibase.nl/public_html/includes/parser/Preprocessor_DOM.php(1083): Parser->braceSubstitution(Array, Object(PPFrame_DOM))
#23 /home/wow/domains/wow.wikibase.nl/public_html/includes/parser/Parser.php(3038): PPFrame_DOM->expand(Object(PPNode_DOM), 0)
#24 /home/wow/domains/wow.wikibase.nl/public_html/includes/parser/Parser.php(1136): Parser->replaceVariables('{{Organization?...')
#25 /home/wow/domains/wow.wikibase.nl/public_html/includes/parser/Parser.php(370): Parser->internalParse('{{Organization?...')
#26 /home/wow/domains/wow.wikibase.nl/public_html/includes/job/RefreshLinksJob.php(78): Parser->parse('{{Organization?...', Object(Title), Object(ParserOptions), true, true, 4481)
#27 /home/wow/domains/wow.wikibase.nl/public_html/includes/job/RefreshLinksJob.php(66): RefreshLinksJob::runForTitleInternal(Object(Title), Object(Revision), 'RefreshLinksJob...')
#28 /home/wow/domains/wow.wikibase.nl/public_html/includes/Wiki.php(594): RefreshLinksJob->run()
#29 /home/wow/domains/wow.wikibase.nl/public_html/includes/Wiki.php(556): MediaWiki->doJobs()
#30 /home/wow/domains/wow.wikibase.nl/public_html/includes/Wiki.php(447): MediaWiki->restInPeace()
#31 /home/wow/domains/wow.wikibase.nl/public_html/index.php(59): MediaWiki->run()
#32 {main}

What was the error you got? (just before the stack trace)
Are you absolutely sure PHP cURL support is enabled?

I got a page called 'Internal error' with text:
'Error setting curl options.' and the backtrace above.

As I said my hosting provider upgraded to php 5.3.19 and I cannot answer your question about cURL support. I will ask them about it.

(In reply to comment #4)

As I said my hosting provider upgraded to php 5.3.19 and I cannot answer your
question about cURL support. I will ask them about it.

Create a .php file with "<?php phpinfo();", go to it in your browser and try to find the cURL section.

That means that curl_setopt_array() failed, which could be due to any of the up to 18 options we set in that call.

I don't see we use any option added in PHP > 5.3.19 http://www.php.net/manual/en/function.curl-setopt.php

Moreover, it doesn't make sense that upgrading to a newer version of php broke it. There was likely some configuration change as well, which is bitting you.

Can you see the error log for when you got the error?
It should have generated a notice telling about the option which failed.

I'm sorry but I don't see anything about this error in the error console. Did find the cURL:

cURL support enabled
cURL Information 7.28.1
Age 3
Features
AsynchDNS No
Debug No
GSS-Negotiate No
IDN No
IPv6 Yes
Largefile Yes
NTLM Yes
SPNEGO No
SSL Yes
SSPI No
krb4 No
libz Yes
CharConv No
Protocols dict, file, ftp, ftps, gopher, http, https, imap, imaps, pop3, pop3s, rtsp, smtp, smtps, telnet, tftp
Host x86_64-unknown-linux-gnu
SSL Version OpenSSL/0.9.8o
ZLib Version 1.2.3

Hi, I have upgraded to:
MW 1.20, SMW 1.8 rc1, SRF 1.8rc2, Semantic Maps 2.0

and the problem still remains.

From the php options above it seems clear that cURL is supported. What can I do to help researching on this problem?

It should have appeared in the php error log :S

Can you add var_dump( $this->curlOptions ); above this line?
if ( !curl_setopt_array( $curlHandle, $this->curlOptions ) ) {

around line 761 of HttpFunctions.php.
This shouls at least give us which options it is trying to set.

I did as you suggested. The dump looks impressive to me!

array(13) { [10004]=> NULL [13]=> int(25) [84]=> int(1) [20011]=> array(2) { [0]=> object(CurlHttpRequest)#488 (24) { ["curlOptions":protected]=> *RECURSION* ["headerText":protected]=> string(0) "" ["content":protected]=> string(0) "" ["timeout":protected]=> int(25) ["headersOnly":protected]=> NULL ["postData":protected]=> NULL ["proxy":protected]=> NULL ["noProxy":protected]=> bool(false) ["sslVerifyHost":protected]=> bool(true) ["sslVerifyCert":protected]=> bool(true) ["caInfo":protected]=> NULL ["method":protected]=> string(3) "GET" ["reqHeaders":protected]=> array(2) { ["Referer"]=> string(54) "http://wow.wikibase.nl/index.php/Template:Organization" ["User-Agent"]=> string(16) "MediaWiki/1.20.0" } ["url":protected]=> string(79) "http://maps.googleapis.com/maps/api/geocode/xml?address=%2C++Breda&sensor=false" ["parsedUrl":protected]=> array(5) { ["scheme"]=> string(4) "http" ["host"]=> string(19) "maps.googleapis.com" ["path"]=> string(21) "/maps/api/geocode/xml" ["query"]=> string(31) "address=%2C++Breda&sensor=false" ["delimiter"]=> string(3) "://" } ["callback":protected]=> *RECURSION* ["maxRedirects":protected]=> int(5) ["followRedirects":protected]=> bool(false) ["cookieJar":protected]=> NULL ["headerList":protected]=> array(0) { } ["respVersion":protected]=> string(3) "0.9" ["respStatus":protected]=> string(6) "200 Ok" ["respHeaders":protected]=> array(0) { } ["status"]=> object(Status)#487 (7) { ["ok"]=> bool(true) ["value"]=> int(100) ["successCount"]=> int(0) ["failCount"]=> int(0) ["success"]=> array(0) { } ["errors"]=> array(0) { } ["cleanCallback"]=> bool(false) } } [1]=> string(4) "read" } [20079]=> array(2) { [0]=> object(CurlHttpRequest)#488 (24) { ["curlOptions":protected]=> *RECURSION* ["headerText":protected]=> string(0) "" ["content":protected]=> string(0) "" ["timeout":protected]=> int(25) ["headersOnly":protected]=> NULL ["postData":protected]=> NULL ["proxy":protected]=> NULL ["noProxy":protected]=> bool(false) ["sslVerifyHost":protected]=> bool(true) ["sslVerifyCert":protected]=> bool(true) ["caInfo":protected]=> NULL ["method":protected]=> string(3) "GET" ["reqHeaders":protected]=> array(2) { ["Referer"]=> string(54) "http://wow.wikibase.nl/index.php/Template:Organization" ["User-Agent"]=> string(16) "MediaWiki/1.20.0" } ["url":protected]=> string(79) "http://maps.googleapis.com/maps/api/geocode/xml?address=%2C++Breda&sensor=false" ["parsedUrl":protected]=> array(5) { ["scheme"]=> string(4) "http" ["host"]=> string(19) "maps.googleapis.com" ["path"]=> string(21) "/maps/api/geocode/xml" ["query"]=> string(31) "address=%2C++Breda&sensor=false" ["delimiter"]=> string(3) "://" } ["callback":protected]=> array(2) { [0]=> *RECURSION* [1]=> string(4) "read" } ["maxRedirects":protected]=> int(5) ["followRedirects":protected]=> bool(false) ["cookieJar":protected]=> NULL ["headerList":protected]=> array(0) { } ["respVersion":protected]=> string(3) "0.9" ["respStatus":protected]=> string(6) "200 Ok" ["respHeaders":protected]=> array(0) { } ["status"]=> object(Status)#487 (7) { ["ok"]=> bool(true) ["value"]=> int(100) ["successCount"]=> int(0) ["failCount"]=> int(0) ["success"]=> array(0) { } ["errors"]=> array(0) { } ["cleanCallback"]=> bool(false) } } [1]=> string(10) "readHeader" } [68]=> int(5) [10102]=> string(0) "" [10016]=> string(54) "http://wow.wikibase.nl/index.php/Template:Organization" [10018]=> string(16) "MediaWiki/1.20.0" [81]=> bool(true) [64]=> bool(true) [10036]=> string(3) "GET" [10023]=> array(2) { [0]=> string(63) "Referer: http://wow.wikibase.nl/index.php/Template:Organization" [1]=> string(28) "User-Agent: MediaWiki/1.20.0" } }

After a bit of fancy formatting:
array(13) {
[10004]=> NULL CURLOPT_PROXY
[13]=> int(25)
CURLOPT_TIMEOUT
[84]=> int(1) CURLOPT_HTTP_VERSION = CURL_HTTP_VERSION_1_0;
[20011]=> array(2) {
CURLOPT_WRITEFUNCTION = CurlHttpRequest::read

		[0]=> object(CurlHttpRequest)#488 (24) {
			["curlOptions":protected]=> *RECURSION*
			["headerText":protected]=> string(0) ""
			["content":protected]=> string(0) ""
			["timeout":protected]=> int(25)
			["headersOnly":protected]=> NULL
			["postData":protected]=> NULL
			["proxy":protected]=> NULL
			["noProxy":protected]=> bool(false)
			["sslVerifyHost":protected]=> bool(true)
			["sslVerifyCert":protected]=> bool(true)
			["caInfo":protected]=> NULL
			["method":protected]=> string(3) "GET"
			["reqHeaders":protected]=> array(2) {
				["Referer"]=> string(54) "http://wow.wikibase.nl/index.php/Template:Organization"
				["User-Agent"]=> string(16) "MediaWiki/1.20.0" 
			}
			["url":protected]=> string(79) "http://maps.googleapis.com/maps/api/geocode/xml?address=%2C++Breda&sensor=false"
			["parsedUrl":protected]=> array(5) {
				["scheme"]=> string(4) "http"
				["host"]=> string(19) "maps.googleapis.com"
				["path"]=> string(21) "/maps/api/geocode/xml"
				["query"]=> string(31) "address=%2C++Breda&sensor=false"
				["delimiter"]=> string(3) "://" 
			}
			["callback":protected]=> *RECURSION*
			["maxRedirects":protected]=> int(5)
			["followRedirects":protected]=> bool(false)
			["cookieJar":protected]=> NULL
			["headerList":protected]=> array(0) { }
			["respVersion":protected]=> string(3) "0.9"
			["respStatus":protected]=> string(6) "200 Ok"
			["respHeaders":protected]=> array(0) { }
			["status"]=> object(Status)#487 (7) {
				["ok"]=> bool(true)
				["value"]=> int(100)
				["successCount"]=> int(0)
				["failCount"]=> int(0)
				["success"]=> array(0) { }
				["errors"]=> array(0) { }
				["cleanCallback"]=> bool(false)
			}
		}
		[1]=> string(4) "read"

}
[20079]=> array(2) { // CURLOPT_HEADERFUNCTION = CurlHttpRequest::readHeader

		[0]=> object(CurlHttpRequest)#488 (24) {
			["curlOptions":protected]=> *RECURSION*
			["headerText":protected]=> string(0) ""
			["content":protected]=> string(0) ""
			["timeout":protected]=> int(25)
			["headersOnly":protected]=> NULL
			["postData":protected]=> NULL
			["proxy":protected]=> NULL
			["noProxy":protected]=> bool(false)
			["sslVerifyHost":protected]=> bool(true)
			["sslVerifyCert":protected]=> bool(true)
			["caInfo":protected]=> NULL
			["method":protected]=> string(3) "GET"
			["reqHeaders":protected]=> array(2) {
				["Referer"]=> string(54) "http://wow.wikibase.nl/index.php/Template:Organization"
				["User-Agent"]=> string(16) "MediaWiki/1.20.0"
			}
			["url":protected]=> string(79) "http://maps.googleapis.com/maps/api/geocode/xml?address=%2C++Breda&sensor=false"
			["parsedUrl":protected]=> array(5) {
				["scheme"]=> string(4) "http"
				["host"]=> string(19) "maps.googleapis.com"
				["path"]=> string(21) "/maps/api/geocode/xml"
				["query"]=> string(31) "address=%2C++Breda&sensor=false"
				["delimiter"]=> string(3) "://" 
			}
			["callback":protected]=> array(2) {
				[0]=> *RECURSION*
				[1]=> string(4) "read"
			}
			["maxRedirects":protected]=> int(5)
			["followRedirects":protected]=> bool(false)
			["cookieJar":protected]=> NULL
			["headerList":protected]=> array(0) { }
			["respVersion":protected]=> string(3) "0.9"
			["respStatus":protected]=> string(6) "200 Ok"
			["respHeaders":protected]=> array(0) { }
				["status"]=> object(Status)#487 (7) {
					["ok"]=> bool(true)
					["value"]=> int(100)
					["successCount"]=> int(0)
					["failCount"]=> int(0)
					["success"]=> array(0) { }
					["errors"]=> array(0) { }
					["cleanCallback"]=> bool(false)
				}
			}
		[1]=> string(10) "readHeader"

}
[68]=> int(5) CURLOPT_MAXREDIRS = 5
[10102]=> string(0) ""
CURLOPT_ENCODING
[10016]=> string(54) "http://wow.wikibase.nl/index.php/Template:Organization" CURLOPT_REFERER
[10018]=> string(16) "MediaWiki/1.20.0"
CURLOPT_USERAGENT
[81]=> bool(true) CURLOPT_SSL_VERIFYHOST = true
[64]=> bool(true)
CURLOPT_SSL_VERIFYPEER = true
[10036]=> string(3) "GET" CURLOPT_CUSTOMREQUEST = "GET"
[10023]=> array(2) {
CURLOPT_HTTPHEADER

		[0]=> string(63) "Referer: http://wow.wikibase.nl/index.php/Template:Organization"
		[1]=> string(28) "User-Agent: MediaWiki/1.20.0"

}
}

It was very long due to the reference to the CurlHttpRequest being expanded.

In summary, it is failing at:
curl_setopt_array( $curlHandle, array(
CURLOPT_PROXY => NULL,
CURLOPT_TIMEOUT => 25,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_0,
CURLOPT_WRITEFUNCTION => CurlHttpRequest::read,
CURLOPT_HEADERFUNCTION => CurlHttpRequest::readHeader,
CURLOPT_MAXREDIRS => 5,
CURLOPT_ENCODING => "",
CURLOPT_REFERER => "http://wow.wikibase.nl/index.php/Template:Organization",
CURLOPT_USERAGENT => "MediaWiki/1.20.0",
CURLOPT_SSL_VERIFYHOST => true,
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => array( "Referer: http://wow.wikibase.nl/index.php/Template:Organization", "User-Agent: MediaWiki/1.20.0" )
) );

I don't see anything obviously wrong.

Is it possible that your php does not support SSL and is failing on the CURLOPT_SSL_* options?

There is a small bug in doing sslVerifyHost => true, that was fixed after 1.20 (bce969).

After a bit of testing that seems to return false without a notice on 5.3.x

Change protected $sslVerifyHost = true; to protected $sslVerifyHost = 2; on the beginning of MWHttpRequest (around line 190). and see if it fixes.

If it is still failing, can you create a file with these lines and check its output?

<?php
ini_set('display_errors',1);
error_reporting(E_ALL | E_STRICT);
$curlHandle=curl_init();
var_dump( curl_setopt_array( $curlHandle, array(
CURLOPT_PROXY => NULL,
CURLOPT_TIMEOUT => 25,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_0,
CURLOPT_MAXREDIRS => 5,
CURLOPT_ENCODING => "",
CURLOPT_REFERER => "http://wow.wikibase.nl/index.php/Template:Organization",
CURLOPT_USERAGENT => "MediaWiki/1.20.0",
CURLOPT_SSL_VERIFYHOST => true,
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => array( "Referer: http://wow.wikibase.nl/index.php/Template:Organization", "User-Agent: MediaWiki/1.20.0" )
) ) );

Bingo! I did the 'Change protected $sslVerifyHost = true; to protected $sslVerifyHost = 2; on
the beginning of MWHttpRequest (around line 190)' and everything is back to normal again.

(In reply to comment #12)

There is a small bug in doing sslVerifyHost => true, that was fixed after 1.20
(bce969).

bce969 has six digits, ChangeIds require last least eight digits - any chance to clarify in order to identify the commit?

It's not a change-id but a commit hash. Which is non-ambiguous: bce969ea1803ba77ad4dfbdb2d5057a34c496d1e by IAlex, which merges 5c8d6fa60f521073136012f67e66bdb72010e720 by Tyler Romeo.

(In reply to comment #15)

It's not a change-id but a commit hash. Which is non-ambiguous:
bce969ea1803ba77ad4dfbdb2d5057a34c496d1e by IAlex, which merges

Does not show anything here.

5c8d6fa60f521073136012f67e66bdb72010e720 by Tyler Romeo.

Wondering if this was fixed by the two commits, or what is left to do here.

It was fixed in master (available in 1.21wmf5). Other than a potential backport, it is FIXED.

(In reply to comment #16)

(In reply to comment #15)

It's not a change-id but a commit hash. Which is non-ambiguous:
bce969ea1803ba77ad4dfbdb2d5057a34c496d1e by IAlex, which merges

Does not show anything here.

Well it exists in the repository. It's not going to be found in Gerrit as a change if that's what you were expecting.

alex@alex:/var/www/MediaWiki/Git/core (master)$ git show bce969ea1803ba77ad4dfbdb2d5057a34c496d1e
commit bce969ea1803ba77ad4dfbdb2d5057a34c496d1e
Merge: 6ba4674 5c8d6fa
Author: IAlex <ialex.wiki@gmail.com>
Date: Thu Nov 15 10:24:11 2012 +0000

Merge "Made SSL validation in Curl HTTP requests the default."

FYI Ia6535f10 is the gerrit Change-ID.

I think the way the bug was fixed was not the right way to do it. For one thing, the documentation is now incorrect:

  • - sslVerifyHost (curl only) Set to 2 to verify hostname against certificate
  • Setting to 1 (or true) will NOT verify the host name. It will
  • only check its existence. Setting to 0 (or false) disables entirely.

It should say that if you set it to 1 or true, it will throw a fatal error after curl 7.28.1. But that's a ridiculous convention. The option to Http::request() should have been left as it was, true for enabling, false for disabling, and that should have been converted to whatever curl (or whatever other backend we use) needs, i.e. 0 or 2.

It's lucky that the callers only either set that parameter to false or omit it. If any set it to true, they would have been badly broken by this change.

  • Bug 45564 has been marked as a duplicate of this bug. ***

(confirming that this has been backported and is available in 1.20.3)