Page MenuHomePhabricator

Error: Undefined constant "CURLINFO_TOTAL_TIME_T"
Closed, ResolvedPublicBUG REPORT

Description

List of steps to reproduce (step by step, including full links if applicable):

What happens?:
The loading bar for VisualEditor gets ~2/3rds of the way through, and then an exception box appears:

[YNFAwtfG@h7hNlTI8NufSwAAAAE] Exception caught: Undefined constant "CURLINFO_TOTAL_TIME_T"

What should have happened instead?:
The VisualEditor interface finishes loading

Software version (if not a Wikimedia wiki), browser information, screenshots, other information, etc:
MediaWiki 1.36.0
PHP 8.0.2 (cgi-fcgi)
MySQL 8.0.23-0ubuntu0.20.04.1
ICU 60.2
VisualEditor: 0.1.2
Skin: Vector 1.0.0

Server Host: Dreamhost
Service type: Shared Unlimited
Host OS: Ubuntu 18.04.4 LTS
Client OS: Windows 10 Pro 21H1
Client Browser: Chrome Version 91.0.4472.11

Excerpts from debug log file

Start request POST /wiki/api.php
IP: 69.216.100.116
HTTP HEADERS:
CONNECTION: close
HOST: www.jjhritz.com
COOKIE: [Redacted]
ACCEPT-LANGUAGE: en-US,en;q=0.9
ACCEPT-ENCODING: gzip, deflate, br
REFERER: https://www.jjhritz.com/wiki/index.php?title=Main_Page&veaction=edit
SEC-FETCH-DEST: empty
SEC-FETCH-MODE: cors
SEC-FETCH-SITE: same-origin
ORIGIN: https://www.jjhritz.com
CONTENT-TYPE: application/x-www-form-urlencoded; charset=UTF-8
USER-AGENT: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.106 Safari/537.36
SEC-CH-UA-MOBILE: ?0
X-REQUESTED-WITH: XMLHttpRequest
DNT: 1
ACCEPT: application/json, text/javascript, */*; q=0.01
SEC-CH-UA: " Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"
CONTENT-LENGTH: 133
AUTHORIZATION: 
(end headers)
[session] SessionManager using store SqlBagOStuff
[localisation] LocalisationCache using store LCStoreDB
[DBQuery] Wikimedia\Rdbms\DatabaseMysqlBase::open [0s] mysql.jjhritz.com: SET group_concat_max_len = 262144, sql_mode = ''
[DBReplication] Cannot use ChronologyProtector with EmptyBagOStuff
[DBReplication] Wikimedia\Rdbms\LBFactory::getChronologyProtector: request info {
    "IPAddress": "69.216.100.116",
    "UserAgent": "Mozilla\/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/91.0.4472.106 Safari\/537.36",
    "ChronologyProtection": false,
    "ChronologyPositionIndex": 0,
    "ChronologyClientId": false
}
[exception] [YNFAwtfG@h7hNlTI8NufSwAAAAE] /wiki/api.php?action=visualeditor&format=json&paction=parse&page=Main_Page&uselang=en&formatversion=2   Error: Undefined constant "CURLINFO_TOTAL_TIME_T"
#0 /home/dh_bq7tsu/jjhritz.com/wiki/includes/libs/http/MultiHttpClient.php(481): constant(string)
#1 /home/dh_bq7tsu/jjhritz.com/wiki/includes/libs/http/MultiHttpClient.php(279): MultiHttpClient->getCurlTime(CurlHandle, integer, string)
#2 /home/dh_bq7tsu/jjhritz.com/wiki/includes/libs/http/MultiHttpClient.php(189): MultiHttpClient->runMultiCurl(array, array)
#3 /home/dh_bq7tsu/jjhritz.com/wiki/includes/libs/virtualrest/VirtualRESTServiceClient.php(254): MultiHttpClient->runMulti(array)
#4 /home/dh_bq7tsu/jjhritz.com/wiki/includes/libs/virtualrest/VirtualRESTServiceClient.php(142): VirtualRESTServiceClient->runMulti(array)
#5 /home/dh_bq7tsu/jjhritz.com/wiki/extensions/VisualEditor/includes/ApiParsoidTrait.php(141): VirtualRESTServiceClient->run(array)
#6 /home/dh_bq7tsu/jjhritz.com/wiki/extensions/VisualEditor/includes/ApiParsoidTrait.php(234): ApiVisualEditor->requestRestbase(Title, string, string, array)
#7 /home/dh_bq7tsu/jjhritz.com/wiki/extensions/VisualEditor/includes/ApiVisualEditor.php(158): ApiVisualEditor->requestRestbasePageHtml(MediaWiki\Revision\RevisionStoreRecord)
#8 /home/dh_bq7tsu/jjhritz.com/wiki/includes/api/ApiMain.php(1647): ApiVisualEditor->execute()
#9 /home/dh_bq7tsu/jjhritz.com/wiki/includes/api/ApiMain.php(617): ApiMain->executeAction()
#10 /home/dh_bq7tsu/jjhritz.com/wiki/includes/api/ApiMain.php(588): ApiMain->executeActionWithErrorHandling()
#11 /home/dh_bq7tsu/jjhritz.com/wiki/api.php(90): ApiMain->execute()
#12 /home/dh_bq7tsu/jjhritz.com/wiki/api.php(45): wfApiMain()
#13 {main}

Event Timeline

Documentation at https://www.php.net/manual/en/curl.constants.php says:

CURLINFO_TOTAL_TIME_T (int)
Available since PHP 7.3.0 and cURL 7.61.0

Our code (added in 8bde51490a68) assumes that it's always available in PHP >=7.3.0 though:

includes/libs/http/MultiHttpClient.php
							'total_time' => $this->getCurlTime(
								$ch, CURLINFO_TOTAL_TIME, 'CURLINFO_TOTAL_TIME_T'
							),
...
	private function getCurlTime( $ch, $oldOption, $newConstName ): string {
		if ( version_compare( PHP_VERSION, '7.3.0', '>=' ) ) {
			return sprintf( "%.6f", curl_getinfo( $ch, constant( $newConstName ) ) / 1e6 );
		} else {
			return (string)curl_getinfo( $ch, $oldOption );
		}
	}

@Jjhritz Can you check what your cURL version is?

@tstarling @BPirkle (you worked on that code) I wonder if we should replace version_compare( PHP_VERSION, '7.3.0', '>=' ) with defined( $newConstName )?

Ah, the box is running cURL 7.58.0. I completely missed that. Going to try updating it to 7.77.0. Unfortunately, because this is a shared host, I'm not authorized to use the package manager, so I'll be following DreamHost's instructions for a user install here.

And no dice. Running which curl as the same user the website runs under gives /home/<username>/curl/bin/curl and curl --version gives curl 7.77.0 (x86_64-pc-linux-gnu) libcurl/7.77.0 OpenSSL/1.1.1 zlib/1.2.11 OpenLDAP/2.4.45. This is what I'd expect to see. However, the exception still occurs in VisualEditor. Do I need to point the wiki's PHP at this new cURL since it lives in a different place?

@tstarling @BPirkle (you worked on that code) I wonder if we should replace version_compare( PHP_VERSION, '7.3.0', '>=' ) with defined( $newConstName )?

Yes, it should use defined(). Even today's PHP git master can lack this constant.

Change 701006 had a related patch set uploaded (by Reedy; author: Reedy):

[mediawiki/core@master] MultiHttpClient: Replace PHP version check with defined()

https://gerrit.wikimedia.org/r/701006

Change 700735 had a related patch set uploaded (by Reedy; author: Reedy):

[mediawiki/core@REL1_36] MultiHttpClient: Replace PHP version check with defined()

https://gerrit.wikimedia.org/r/700735

As per T279727: Write and send pre-release announcements for MediaWiki 1.31.15/1.35.3/1.36.1, I'm planning on getting 1.36.1 out later today. If we get this landed, it can be included.

Change 701006 merged by jenkins-bot:

[mediawiki/core@master] MultiHttpClient: Replace PHP version check with defined()

https://gerrit.wikimedia.org/r/701006

Change 700735 merged by jenkins-bot:

[mediawiki/core@REL1_36] MultiHttpClient: Replace PHP version check with defined()

https://gerrit.wikimedia.org/r/700735

Reedy claimed this task.

So should I pull and install this new master? Or do I need to do something else to get it to recognize the new version of cURL I installed?

@Jjhritz If you are using git already, you should get the REL1_36 branch, not master. If you're using a release tarball, the easiest way to do it is probably to just edit the file with a text editor. It's a one-line change. https://gerrit.wikimedia.org/r/c/mediawiki/core/+/700735/1/includes/libs/http/MultiHttpClient.php

Or wait for the 1.36.1 release that will be out in the next 12 hours (probably much less).