mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
fix: use cURL cookie engine instead of parse_str for RFC 6265 compliance
parse_str() URL-decodes cookie values, causing the test client to behave differently from real clients (Dart, Swift) which store values verbatim per RFC 6265. This masked a production bug where base64 session values containing %3D%3D would fail to decode on real devices. Replaces the manual Set-Cookie header parsing with cURL's built-in cookie engine (CURLOPT_COOKIEFILE='') and reads cookies via CURLINFO_COOKIELIST, which stores and returns values verbatim without any decoding. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
9feb204fd5
commit
e2d7dd837d
+7
-22
@@ -219,7 +219,8 @@ class Client
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $formattedHeaders);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 0);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 120);
|
||||
curl_setopt($ch, CURLOPT_HEADERFUNCTION, function ($curl, $header) use (&$responseHeaders, &$cookies) {
|
||||
curl_setopt($ch, CURLOPT_COOKIEFILE, ''); // enable in-memory RFC 6265 cookie engine
|
||||
curl_setopt($ch, CURLOPT_HEADERFUNCTION, function ($curl, $header) use (&$responseHeaders) {
|
||||
$len = strlen($header);
|
||||
$header = explode(':', $header, 2);
|
||||
|
||||
@@ -227,12 +228,6 @@ class Client
|
||||
return $len;
|
||||
}
|
||||
|
||||
if (strtolower(trim($header[0])) == 'set-cookie') {
|
||||
$parsed = $this->parseCookie((string)trim($header[1]));
|
||||
$name = array_key_first($parsed);
|
||||
$cookies[$name] = $parsed[$name];
|
||||
}
|
||||
|
||||
$responseHeaders[strtolower(trim($header[0]))] = trim($header[1]);
|
||||
|
||||
return $len;
|
||||
@@ -259,6 +254,11 @@ class Client
|
||||
$responseType = $responseHeaders['content-type'] ?? '';
|
||||
$responseStatus = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
|
||||
foreach (curl_getinfo($ch, CURLINFO_COOKIELIST) as $line) {
|
||||
$parts = explode("\t", $line);
|
||||
$cookies[$parts[5]] = $parts[6] ?? '';
|
||||
}
|
||||
|
||||
if ($decode && $method !== self::METHOD_HEAD) {
|
||||
$strpos = strpos($responseType, ';');
|
||||
$strpos = \is_bool($strpos) ? \strlen($responseType) : $strpos;
|
||||
@@ -309,21 +309,6 @@ class Client
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse Cookie String
|
||||
*
|
||||
* @param string $cookie
|
||||
* @return array
|
||||
*/
|
||||
public function parseCookie(string $cookie): array
|
||||
{
|
||||
$cookies = [];
|
||||
|
||||
parse_str(strtr($cookie, ['&' => '%26', '+' => '%2B', ';' => '&']), $cookies);
|
||||
|
||||
return $cookies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flatten params array to PHP multiple format
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user