Skip to content

Conversation

@adamziel
Copy link
Collaborator

@adamziel adamziel commented Sep 24, 2025

Motivation for the change, related issues

Disables the curl_share_init function in the default php.ini file on the web. Composer uses a "shared curl handle" to share DNS cache, cookies, TLS cache etc. between the handles as an optimization. Turns out, Playground TLS handler doesn't support shared handles at the moment. Using one triggers this PHP error on the second connection:

SSL routines:ossl_statem_client_read_transition:unexpected message

For anyone in dire need of curl_share_init, it can still be re-enabled by editing the php.ini file.

Implementation details

In a perfect world, we'd adjust the TLS handler to support shared handlers. In practice, they don't seem to matter on the web. The TLS handler is only there to make PHP think it's talking to a server over an actual socket connection. All the requests are handled by fetch() in the end and fetch() is already optimized. This PR, though, takes the shortcut and just disables the curl_share_init() function to trigger this condition in CurlDownloader.php:

        if (function_exists('curl_share_init')) {
            curl_setopt($curlHandle, CURLOPT_SHARE, $this->shareHandle);
        }

Testing Instructions (or ideally a Blueprint)

Run this in devtools:

if(!window.composer) { window.composer = new Uint8Array(await (await fetch("https://wordpress-playground-cors-proxy.net/?https://getcomposer.org/download/2.8.12/composer.phar")).arrayBuffer()); }

await playground.writeFile('/tmp/composer.phar', window.composer)
await playground.writeFile('/wordpress/composer.json', `{
    "require": {
        "monolog/monolog": "3.9.*"
    }
}`);
const r = await playground.run({ code: `<?php 
$_SERVER["argv"]=["/tmp/composer.phar", "install", "-vvvv"]; 
require_once "/tmp/composer.phar";
` })
console.log(await r.text);
await playground.listFiles("/wordpress/vendor/monolog/monolog");

Confirm that, after a while, you can see an output similar to:

#!/usr/bin/env php
Pool optimizer completed in 0.002 seconds
Found 61 package versions referenced in your dependency graph. 3 (5%) were optimized away.

(5) ['CHANGELOG.md', 'LICENSE', 'README.md', 'composer.json', 'src']

As a side note, it would be cool to call playground.cli() and stream the output bytes, but we'll need a Comlink transfer handle for the StreamedResponse instance before we can do that.

cc @mho22 @akirk

@adamziel adamziel merged commit 34bf6d9 into trunk Sep 24, 2025
26 checks passed
@adamziel adamziel deleted the disable_curl_share_init branch September 24, 2025 17:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants