From 7748d48657d1d6f56bed7da093a94df46582fea0 Mon Sep 17 00:00:00 2001 From: Roan Kattouw Date: Fri, 6 Nov 2015 12:55:16 -0800 Subject: [PATCH] Work around CURL insanity breaking POST parameters that start with '@' CURL has a "feature" where passing array( 'foo' => '@bar' ) in CURLOPT_POSTFIELDS results in the contents of the file named "bar" being POSTed. This makes it impossible to POST the literal string "@bar", because array( 'foo' => '%40bar' ) gets double-encoded to foo=%2540bar. Disable this "feature" by setting CURLOPT_SAFE_UPLOAD to true. According to the PHP manual, this defaults to true starting with 5.6.0, but we've observed this behavior in production with 5.6.99-hhvm, so that suggests that HHVM hasn't picked up this change. Bug: T118032 Change-Id: I3f996e2eb87c7bd3b94ca9d3cc14a3e12f34f241 --- includes/HttpFunctions.php | 5 +++++ includes/libs/MultiHttpClient.php | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/includes/HttpFunctions.php b/includes/HttpFunctions.php index 60196ab..8372401 100644 --- a/includes/HttpFunctions.php +++ b/includes/HttpFunctions.php @@ -782,6 +782,11 @@ class CurlHttpRequest extends MWHttpRequest { } elseif ( $this->method == 'POST' ) { $this->curlOptions[CURLOPT_POST] = true; $this->curlOptions[CURLOPT_POSTFIELDS] = $this->postData; + // Don't interpret POST parameters starting with '@' as file uploads, because this + // makes it impossible to POST plain values starting with '@'. + // The PHP manual says this defaults to true in PHP 5.6 and up, but we support + // lower versions, and it doesn't actually seem to default to true in HHVM 5.6.99. + $this->curlOptions[CURLOPT_SAFE_UPLOAD] = true; // Suppress 'Expect: 100-continue' header, as some servers // will reject it with a 417 and Curl won't auto retry // with HTTP 1.0 fallback diff --git a/includes/libs/MultiHttpClient.php b/includes/libs/MultiHttpClient.php index c6fa914..c848fba 100644 --- a/includes/libs/MultiHttpClient.php +++ b/includes/libs/MultiHttpClient.php @@ -338,6 +338,11 @@ class MultiHttpClient { ); } elseif ( $req['method'] === 'POST' ) { curl_setopt( $ch, CURLOPT_POST, 1 ); + // Don't interpret POST parameters starting with '@' as file uploads, because this + // makes it impossible to POST plain values starting with '@'. + // The PHP manual says this defaults to true in PHP 5.6 and up, but we support + // lower versions, and it doesn't actually seem to default to true in HHVM 5.6.99. + curl_setopt( $ch, CURLOPT_SAFE_UPLOAD, true ); curl_setopt( $ch, CURLOPT_POSTFIELDS, $req['body'] ); } else { if ( is_resource( $req['body'] ) || $req['body'] !== '' ) { -- 1.9.1