Rely on symfony's HttpFoundation to handle requests. Fixes weird bugs

This commit is contained in:
Stéphane Goetz 2017-06-08 23:07:18 +02:00
parent 5a24c48788
commit 0758366430
4 changed files with 103 additions and 155 deletions

View File

@ -22,7 +22,8 @@
"symfony/finder": "~3.0", "symfony/finder": "~3.0",
"webuni/commonmark-table-extension": "0.6.*", "webuni/commonmark-table-extension": "0.6.*",
"webuni/front-matter": "^1.0.0", "webuni/front-matter": "^1.0.0",
"symfony/process": "^3.1" "symfony/process": "^3.1",
"symfony/http-foundation": "^3.3"
}, },
"autoload": { "autoload": {
"psr-4": { "psr-4": {

55
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "89c196ac8c5858ac075e9a7eccadbf1a", "content-hash": "177814363edbcc8b16c48140e2b439ef",
"packages": [ "packages": [
{ {
"name": "guzzlehttp/guzzle", "name": "guzzlehttp/guzzle",
@ -621,6 +621,59 @@
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2017-06-01T21:01:25+00:00" "time": "2017-06-01T21:01:25+00:00"
}, },
{
"name": "symfony/http-foundation",
"version": "v3.3.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-foundation.git",
"reference": "80eb5a1f968448b77da9e8b2c0827f6e8d767846"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/80eb5a1f968448b77da9e8b2c0827f6e8d767846",
"reference": "80eb5a1f968448b77da9e8b2c0827f6e8d767846",
"shasum": ""
},
"require": {
"php": ">=5.5.9",
"symfony/polyfill-mbstring": "~1.1"
},
"require-dev": {
"symfony/expression-language": "~2.8|~3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.3-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Component\\HttpFoundation\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony HttpFoundation Component",
"homepage": "https://symfony.com",
"time": "2017-06-05T13:06:51+00:00"
},
{ {
"name": "symfony/polyfill-mbstring", "name": "symfony/polyfill-mbstring",
"version": "v1.3.0", "version": "v1.3.0",

View File

@ -1,81 +0,0 @@
<?php namespace Todaymade\Daux\Server;
/**
* Class MimeType
* @author Dennis Fridrich <fridrich.dennis@gmail.com>
* @see http://www.php.net/mime_content_type
*/
class MimeType
{
/**
* @var array
*/
protected static $mimeTypes = [
'txt' => 'text/plain',
'htm' => 'text/html',
'html' => 'text/html',
'php' => 'text/html',
'css' => 'text/css',
'js' => 'application/javascript',
'json' => 'application/json',
'xml' => 'application/xml',
'swf' => 'application/x-shockwave-flash',
'flv' => 'video/x-flv',
// Images
'png' => 'image/png',
'jpe' => 'image/jpeg',
'jpeg' => 'image/jpeg',
'jpg' => 'image/jpeg',
'gif' => 'image/gif',
'bmp' => 'image/bmp',
'ico' => 'image/vnd.microsoft.icon',
'tiff' => 'image/tiff',
'tif' => 'image/tiff',
'svg' => 'image/svg+xml',
'svgz' => 'image/svg+xml',
// Archives
'zip' => 'application/zip',
'rar' => 'application/x-rar-compressed',
'exe' => 'application/x-msdownload',
'msi' => 'application/x-msdownload',
'cab' => 'application/vnd.ms-cab-compressed',
// Audio/video
'mp3' => 'audio/mpeg',
'qt' => 'video/quicktime',
'mov' => 'video/quicktime',
// Adobe
'pdf' => 'application/pdf',
'psd' => 'image/vnd.adobe.photoshop',
'ai' => 'application/postscript',
'eps' => 'application/postscript',
'ps' => 'application/postscript',
// MS Office
'doc' => 'application/msword',
'rtf' => 'application/rtf',
'xls' => 'application/vnd.ms-excel',
'ppt' => 'application/vnd.ms-powerpoint',
// Open Office
'odt' => 'application/vnd.oasis.opendocument.text',
'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
];
/**
* @param $filename
* @return string
*/
public static function get($filename)
{
$pathInfo = pathinfo($filename);
$extension = strtolower($pathInfo['extension']);
if (array_key_exists($extension, self::$mimeTypes)) {
return self::$mimeTypes[$extension];
} elseif (function_exists('finfo_open') && is_file($filename)) {
$finfo = finfo_open(FILEINFO_MIME);
$mimetype = finfo_file($finfo, $filename);
finfo_close($finfo);
return $mimetype;
} else {
return 'application/octet-stream';
}
}
}

View File

@ -1,18 +1,21 @@
<?php namespace Todaymade\Daux\Server; <?php namespace Todaymade\Daux\Server;
use Symfony\Component\Console\Output\NullOutput; use Symfony\Component\Console\Output\NullOutput;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Todaymade\Daux\Daux; use Todaymade\Daux\Daux;
use Todaymade\Daux\DauxHelper; use Todaymade\Daux\DauxHelper;
use Todaymade\Daux\Exception; use Todaymade\Daux\Exception;
use Todaymade\Daux\Format\Base\ComputedRawPage; use Todaymade\Daux\Format\Base\ComputedRawPage;
use Todaymade\Daux\Format\Base\LiveGenerator; use Todaymade\Daux\Format\Base\LiveGenerator;
use Todaymade\Daux\Format\Base\Page;
use Todaymade\Daux\Format\HTML\RawPage; use Todaymade\Daux\Format\HTML\RawPage;
class Server class Server
{ {
private $daux; private $daux;
private $params; private $params;
private $host;
private $base_url; private $base_url;
/** /**
@ -42,50 +45,60 @@ class Server
try { try {
$page = $server->handle(); $page = $server->handle();
} catch (NotFoundException $e) { } catch (NotFoundException $e) {
http_response_code(404);
$page = new ErrorPage('An error occured', $e->getMessage(), $daux->getParams()); $page = new ErrorPage('An error occured', $e->getMessage(), $daux->getParams());
} }
if ($page instanceof RawPage) { $server->createResponse($page)->prepare($server->request)->send();
header('Content-type: ' . MimeType::get($page->getFile()));
// Transfer file in 1024 byte chunks to save memory usage.
if ($fd = fopen($page->getFile(), 'rb')) {
while (!feof($fd)) {
echo fread($fd, 1024);
}
fclose($fd);
}
return;
}
if ($page instanceof ComputedRawPage) {
header('Content-type: ' . MimeType::get($page->getFilename()));
} else {
header('Content-type: text/html; charset=utf-8');
}
echo $page->getContent();
} }
public function __construct(Daux $daux) public function __construct(Daux $daux)
{ {
$this->daux = $daux; $this->daux = $daux;
$this->host = $_SERVER['HTTP_HOST']; $this->request = Request::createFromGlobals();
$this->base_url = $this->request->getHttpHost() . $this->request->getBaseUrl() . "/";
}
// The path has a special treatment on windows, revert the slashes /**
$dir = dirname($_SERVER['PHP_SELF']); * Create a temporary file with the file suffix, for mime type detection.
$this->base_url = $_SERVER['HTTP_HOST'] . (DIRECTORY_SEPARATOR == '\\' ? str_replace('\\', '/', $dir) : $dir); *
* @param string $postfix
* @return string
*/
function getTemporaryFile($postfix) {
$sysFileName = tempnam(sys_get_temp_dir(), 'daux');
if ($sysFileName === false) {
throw new \RuntimeException("Could not create temporary file");
}
$t = strrpos($this->base_url, '/index.php'); $newFileName = $sysFileName . $postfix;
if ($t != false) { if ($sysFileName == $newFileName) {
$this->base_url = substr($this->base_url, 0, $t); return $sysFileName;
} }
if (substr($this->base_url, -1) !== '/') {
$this->base_url .= '/'; if (DIRECTORY_SEPARATOR == '\\' ? rename($sysFileName, $newFileName) : link($sysFileName, $newFileName)) {
return $newFileName;
} }
throw new \RuntimeException("Could not create temporary file");
}
/**
* @param Page $page
* @return Response
*/
public function createResponse(Page $page) {
if ($page instanceof RawPage) {
return new BinaryFileResponse($page->getFile());
}
if ($page instanceof ComputedRawPage) {
$file = $this->getTemporaryFile($page->getFilename());
file_put_contents($file, $page->getContent());
return new BinaryFileResponse($file);
}
return new Response($page->getContent(), $page instanceof ErrorPage ? 404 : 200);
} }
/** /**
@ -95,8 +108,6 @@ class Server
{ {
$params = $this->daux->getParams(); $params = $this->daux->getParams();
$params['host'] = $this->host;
DauxHelper::rebaseConfiguration($params, '//' . $this->base_url); DauxHelper::rebaseConfiguration($params, '//' . $this->base_url);
$params['base_page'] = '//' . $this->base_url; $params['base_page'] = '//' . $this->base_url;
if (!$this->daux->options['live']['clean_urls']) { if (!$this->daux->options['live']['clean_urls']) {
@ -120,14 +131,13 @@ class Server
{ {
$this->params = $this->getParams(); $this->params = $this->getParams();
$request = $this->getRequest(); $request = substr($this->request->getRequestUri(), 1);
$request = urldecode($request);
if (substr($request, 0, 7) == 'themes/') { if (substr($request, 0, 7) == 'themes/') {
return $this->serveTheme(substr($request, 6)); return $this->serveTheme(substr($request, 6));
} }
if ($request == 'index_page') { if ($request == '') {
$request = $this->daux->tree->getIndexPage()->getUri(); $request = $this->daux->tree->getIndexPage()->getUri();
} }
@ -177,39 +187,4 @@ class Server
return $this->daux->getGenerator()->generateOne($file, $this->params); return $this->daux->getGenerator()->generateOne($file, $this->params);
} }
public function getRequest()
{
if (isset($_SERVER['PATH_INFO'])) {
$uri = $_SERVER['PATH_INFO'];
} elseif (isset($_SERVER['REQUEST_URI'])) {
$uri = $_SERVER['REQUEST_URI'];
if (strpos($uri, $_SERVER['SCRIPT_NAME']) === 0) {
$uri = substr($uri, strlen($_SERVER['SCRIPT_NAME']));
} elseif (strpos($uri, dirname($_SERVER['SCRIPT_NAME'])) === 0) {
$uri = substr($uri, strlen(dirname($_SERVER['SCRIPT_NAME'])));
}
if (strncmp($uri, '?/', 2) === 0) {
$uri = substr($uri, 2);
}
$parts = preg_split('#\?#i', $uri, 2);
$uri = $parts[0];
if (isset($parts[1])) {
$_SERVER['QUERY_STRING'] = $parts[1];
parse_str($_SERVER['QUERY_STRING'], $_GET);
} else {
$_SERVER['QUERY_STRING'] = '';
$_GET = [];
}
$uri = parse_url($uri, PHP_URL_PATH);
} else {
return false;
}
$uri = str_replace(['//', '../'], '/', trim($uri, '/'));
if ($uri == '') {
$uri = 'index_page';
}
return $uri;
}
} }