🌐 AI搜索 & 代理 主页
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 22 additions & 20 deletions src/Symfony/Component/HttpFoundation/Request.php
Original file line number Diff line number Diff line change
Expand Up @@ -285,26 +285,30 @@ public function initialize(array $query = [], array $request = [], array $attrib
*/
public static function createFromGlobals(): static
{
$request = self::createRequestFromFactory($_GET, $_POST, [], $_COOKIE, $_FILES, $_SERVER);

if (!\in_array($request->server->get('REQUEST_METHOD', 'GET'), ['PUT', 'DELETE', 'PATCH', 'QUERY'], true)) {
return $request;
if (!\in_array($_SERVER['REQUEST_METHOD'] ?? null, ['PUT', 'DELETE', 'PATCH', 'QUERY'], true)) {
return self::createRequestFromFactory($_GET, $_POST, [], $_COOKIE, $_FILES, $_SERVER);
}

if (\PHP_VERSION_ID >= 80400) {
try {
[$post, $files] = request_parse_body();

$request->request->add($post);
$request->files->add($files);
} catch (\RequestParseBodyException) {
if (\PHP_VERSION_ID < 80400) {
if (!isset($_SERVER['CONTENT_TYPE']) || str_starts_with($_SERVER['CONTENT_TYPE'], 'application/x-www-form-urlencoded')) {
$content = file_get_contents('php://input');
parse_str($content, $post);
} else {
$content = null;
$post = $_POST;
}
} elseif (str_starts_with($request->headers->get('CONTENT_TYPE', ''), 'application/x-www-form-urlencoded')) {
parse_str($request->getContent(), $data);
$request->request = new InputBag($data);

return self::createRequestFromFactory($_GET, $post, [], $_COOKIE, $_FILES, $_SERVER, $content);
}

return $request;
try {
[$post, $files] = request_parse_body();
} catch (\RequestParseBodyException) {
$post = $_POST;
$files = $_FILES;
}

return self::createRequestFromFactory($_GET, $post, [], $_COOKIE, $files, $_SERVER);
}

/**
Expand Down Expand Up @@ -1538,10 +1542,8 @@ public function getProtocolVersion(): ?string
*/
public function getContent(bool $asResource = false)
{
$currentContentIsResource = \is_resource($this->content);

if (true === $asResource) {
if ($currentContentIsResource) {
if ($asResource) {
if (\is_resource($this->content)) {
rewind($this->content);

return $this->content;
Expand All @@ -1561,7 +1563,7 @@ public function getContent(bool $asResource = false)
return fopen('php://input', 'r');
}

if ($currentContentIsResource) {
if (\is_resource($this->content)) {
rewind($this->content);

return stream_get_contents($this->content);
Expand Down
63 changes: 58 additions & 5 deletions src/Symfony/Component/HttpFoundation/Tests/RequestTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1431,9 +1431,17 @@ public function testFormUrlEncodedBodyParsing(string $method)
$_SERVER['REQUEST_METHOD'] = $method;
$_SERVER['CONTENT_TYPE'] = 'application/x-www-form-urlencoded';

$request = RequestContentProxy::createFromGlobals();
MockPhpStreamWrapper::setInputContent('content=mycontent');
stream_wrapper_unregister('php');
stream_wrapper_register('php', MockPhpStreamWrapper::class);

$this->assertEquals('mycontent', $request->request->get('content'));
try {
$request = Request::createFromGlobals();

$this->assertSame('mycontent', $request->request->get('content'));
} finally {
stream_wrapper_restore('php');
}
}

public function testOverrideGlobals()
Expand Down Expand Up @@ -3050,11 +3058,56 @@ public static function providePreferredFormatRfc9110(): iterable
}
}

class RequestContentProxy extends Request
class MockPhpStreamWrapper
{
public function getContent($asResource = false)
/** @var resource|null */
public $context;

private static string $inputContent = '';
private string $content = '';
private int $position = 0;

public static function setInputContent(string $content): void
{
self::$inputContent = $content;
}

public function stream_open(string $path, string $mode, int $options, ?string &$opened_path): bool
{
if ('php://input' === $path) {
$this->content = self::$inputContent;
$this->position = 0;

return true;
}

return false;
}

public function stream_read(int $count): string
{
$result = substr($this->content, $this->position, $count);
$this->position += \strlen($result);

return $result;
}

public function stream_eof(): bool
{
return $this->position >= \strlen($this->content);
}

public function stream_stat(): array
{
return http_build_query(['content' => 'mycontent'], '', '&');
return [
'size' => \strlen($this->content),
'mode' => 0,
'uid' => 0,
'gid' => 0,
'atime' => 0,
'mtime' => 0,
'ctime' => 0,
];
}
}

Expand Down