$dice->create(\Friendica\Core\PConfig\Capability\IManagePersonalConfigValues::class),
$dice->create(\Friendica\Security\Authentication::class),
$dice->create(\Friendica\App\Page::class),
+ new \Friendica\Util\HTTPInputData($_SERVER),
$start_time
);
use Friendica\Util\HTTPSignature;
use Friendica\Util\Profiler;
use Friendica\Util\Strings;
-use GuzzleHttp\Psr7\Response;
use Psr\Log\LoggerInterface;
/**
*
* @param App\Router $router
* @param IManagePersonalConfigValues $pconfig
- * @param Authentication $auth The Authentication backend of the node
- * @param App\Page $page The Friendica page printing container
+ * @param Authentication $auth The Authentication backend of the node
+ * @param App\Page $page The Friendica page printing container
+ * @param HTTPInputData $httpInput A library for processing PHP input streams
+ * @param float $start_time The start time of the overall script execution
*
* @throws HTTPException\InternalServerErrorException
* @throws \ImagickException
*/
- public function runFrontend(App\Router $router, IManagePersonalConfigValues $pconfig, Authentication $auth, App\Page $page, float $start_time)
+ public function runFrontend(App\Router $router, IManagePersonalConfigValues $pconfig, Authentication $auth, App\Page $page, HTTPInputData $httpInput, float $start_time)
{
$this->profiler->set($start_time, 'start');
$this->profiler->set(microtime(true), 'classinit');
}
// Processes data from GET requests
- $httpinput = HTTPInputData::process();
- $input = array_merge($httpinput['variables'], $httpinput['files'], $request ?? $_REQUEST);
+ $httpinput = $httpInput->process();
+ $input = array_merge($httpinput['variables'], $httpinput['files'], $request ?? $_REQUEST);
// Let the module run it's internal process (init, get, post, ...)
$response = $module->run($input);
*/
class HTTPInputData
{
- public static function process()
+ /** @var array The $_SERVER variable */
+ protected $server;
+
+ public function __construct(array $server)
+ {
+ $this->server = $server;
+ }
+
+ /**
+ * Process the PHP input stream and creates an array with its content
+ *
+ * @return array|array[]
+ */
+ public function process(): array
{
- $content_parts = explode(';', static::getContentType());
+ $content_parts = explode(';', $this->server['CONTENT_TYPE'] ?? 'application/x-www-form-urlencoded');
$boundary = '';
$encoding = '';
}
if ($content_type == 'multipart/form-data') {
- return self::fetchFromMultipart($boundary);
+ return $this->fetchFromMultipart($boundary);
}
// can be handled by built in PHP functionality
return ['variables' => $variables, 'files' => []];
}
- private static function fetchFromMultipart(string $boundary)
+ private function fetchFromMultipart(string $boundary): array
{
$result = ['variables' => [], 'files' => []];
continue;
}
- $result = self::parseRawHeader($stream, $raw_headers, $boundary, $result);
+ $result = $this->parseRawHeader($stream, $raw_headers, $boundary, $result);
$raw_headers = '';
}
return $result;
}
- private static function parseRawHeader($stream, string $raw_headers, string $boundary, array $result)
+ private function parseRawHeader($stream, string $raw_headers, string $boundary, array $result)
{
$variables = $result['variables'];
$files = $result['files'];
if (strpos($header, ':') === false) {
continue;
}
- list($name, $value) = explode(':', $header, 2);
+ [$name, $value] = explode(':', $header, 2);
$headers[strtolower($name)] = ltrim($value, ' ');
}
$files[$name] = static::fetchFileData($stream, $boundary, $headers, $filename);
return ['variables' => $variables, 'files' => $files];
} else {
- $variables = self::fetchVariables($stream, $boundary, $headers, $name, $variables);
+ $variables = $this->fetchVariables($stream, $boundary, $headers, $name, $variables);
}
return ['variables' => $variables, 'files' => $files];
}
- protected static function fetchFileData($stream, string $boundary, array $headers, string $filename)
+ protected function fetchFileData($stream, string $boundary, array $headers, string $filename)
{
$error = UPLOAD_ERR_OK;
];
}
- private static function fetchVariables($stream, string $boundary, array $headers, string $name, array $variables)
+ private function fetchVariables($stream, string $boundary, array $headers, string $name, array $variables)
{
$fullValue = '';
$lastLine = null;
$tmp = [];
parse_str($fullValue, $tmp);
- return self::expandVariables(explode('[', $name), $variables, $tmp);
+ return $this->expandVariables(explode('[', $name), $variables, $tmp);
}
- private static function expandVariables(array $names, $variables, array $values)
+ private function expandVariables(array $names, $variables, array $values)
{
if (!is_array($variables)) {
return $values;
if ($name === '') {
$variables[] = reset($values);
} elseif (isset($variables[$name]) && isset($values[$name])) {
- $variables[$name] = self::expandVariables($names, $variables[$name], $values[$name]);
+ $variables[$name] = $this->expandVariables($names, $variables[$name], $values[$name]);
} elseif (isset($values[$name])) {
$variables[$name] = $values[$name];
}
*
* @return false|resource
*/
- protected static function getPhpInputStream()
+ protected function getPhpInputStream()
{
return fopen('php://input', 'rb');
}
*
* @return false|string
*/
- protected static function getPhpInputContent()
+ protected function getPhpInputContent()
{
return file_get_contents('php://input');
}
-
- /**
- * Returns the content type string of the current call
- * Mainly used for test doubling
- *
- * @return false|string
- */
- protected static function getContentType()
- {
- return $_SERVER['CONTENT_TYPE'] ?? 'application/x-www-form-urlencoded';
- }
}
class HTTPInputDataDouble extends HTTPInputData
{
/** @var false|resource */
- protected static $injectedStream = false;
+ protected $injectedStream = false;
/** @var false|string */
- protected static $injectedContent = false;
- /** @var false|string */
- protected static $injectedContentType = false;
+ protected $injectedContent = false;
/**
* injects the PHP input stream for a test
*
* @param false|resource $stream
*/
- public static function setPhpInputStream($stream)
+ public function setPhpInputStream($stream)
{
- self::$injectedStream = $stream;
+ $this->injectedStream = $stream;
}
/**
*
* @param false|string $content
*/
- public static function setPhpInputContent($content)
+ public function setPhpInputContent($content)
{
- self::$injectedContent = $content;
+ $this->injectedContent = $content;
}
/**
*
* @param false|string $contentType
*/
- public static function setPhpInputContentType($contentType)
- {
- self::$injectedContentType = $contentType;
- }
-
- /** {@inheritDoc} */
- protected static function getPhpInputStream()
+ public function setPhpInputContentType($contentType)
{
- return static::$injectedStream;
+ $this->injectedContentType = $contentType;
}
/** {@inheritDoc} */
- protected static function getPhpInputContent()
+ protected function getPhpInputStream()
{
- return static::$injectedContent;
+ return $this->injectedStream;
}
/** {@inheritDoc} */
- protected static function getContentType()
+ protected function getPhpInputContent()
{
- return static::$injectedContentType;
+ return $this->injectedContent;
}
- protected static function fetchFileData($stream, string $boundary, array $headers, string $filename)
+ protected function fetchFileData($stream, string $boundary, array $headers, string $filename)
{
$data = parent::fetchFileData($stream, $boundary, $headers, $filename);
if (!empty($data['tmp_name'])) {
*/
public function testHttpInput(string $contentType, string $input, array $expected)
{
- HTTPInputDataDouble::setPhpInputContentType($contentType);
- HTTPInputDataDouble::setPhpInputContent($input);
+ $httpInput = new HTTPInputDataDouble(['CONTENT_TYPE' => $contentType]);
+ $httpInput->setPhpInputContent($input);
+
$stream = fopen('php://memory', 'r+');
fwrite($stream, $input);
rewind($stream);
- HTTPInputDataDouble::setPhpInputStream($stream);
- $output = HTTPInputDataDouble::process();
+ $httpInput->setPhpInputStream($stream);
+ $output = $httpInput->process();
$this->assertEqualsCanonicalizing($expected, $output);
}
}