daux.io/libs/Server/Server.php

210 lines
6.4 KiB
PHP
Raw Normal View History

2015-04-22 12:23:57 +02:00
<?php namespace Todaymade\Daux\Server;
use Symfony\Component\Console\Output\NullOutput;
use Symfony\Component\Process\ProcessUtils;
use Symfony\Component\Process\PhpExecutableFinder;
use Todaymade\Daux\Config;
2015-04-22 12:23:57 +02:00
use Todaymade\Daux\Daux;
use Todaymade\Daux\DauxHelper;
2015-04-22 12:23:57 +02:00
use Todaymade\Daux\Exception;
use Todaymade\Daux\Format\Base\LiveGenerator;
use Todaymade\Daux\Format\HTML\RawPage;
2015-04-22 12:23:57 +02:00
2015-04-23 00:32:30 +02:00
class Server
{
2015-04-22 12:23:57 +02:00
private $daux;
private $params;
private $host;
private $base_url;
2015-04-22 12:23:57 +02:00
2015-07-17 23:38:06 +02:00
/**
* Serve the documentation
*
* @throws Exception
*/
2015-04-23 00:32:30 +02:00
public static function serve()
{
2015-04-22 12:23:57 +02:00
$daux = new Daux(Daux::LIVE_MODE);
$daux->initializeConfiguration();
$class = $daux->getProcessorClass();
2015-07-20 15:59:52 +02:00
if (!empty($class)) {
$daux->setProcessor(new $class($daux, new NullOutput(), 0));
}
2015-07-19 23:17:57 +02:00
// Set this critical configuration
// for the tree generation
$daux->getParams()['index_key'] = 'index';
// Improve the tree with a processor
2015-07-19 23:17:57 +02:00
$daux->generateTree();
$server = new static($daux);
2015-04-23 00:32:30 +02:00
try {
$page = $server->handle($_REQUEST);
} catch (NotFoundException $e) {
http_response_code(404);
2016-07-27 21:32:51 +02:00
$page = new ErrorPage('An error occured', $e->getMessage(), $daux->getParams());
2015-04-22 12:23:57 +02:00
}
if ($page instanceof RawPage) {
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)) {
2016-07-27 21:32:51 +02:00
echo fread($fd, 1024);
}
fclose($fd);
}
return;
}
header('Content-type: text/html; charset=utf-8');
echo $page->getContent();
2015-04-22 12:23:57 +02:00
}
public static function runServer(Config $config, $host, $port) {
chdir(__DIR__ . '/../../');
putenv("DAUX_SOURCE=" . $config->getDocumentationDirectory());
$base = ProcessUtils::escapeArgument(__DIR__ . '/../../');
$binary = ProcessUtils::escapeArgument((new PhpExecutableFinder)->find(false));
echo "Daux development server started on http://{$host}:{$port}/\n";
if (defined('HHVM_VERSION')) {
if (version_compare(HHVM_VERSION, '3.8.0') >= 0) {
passthru("{$binary} -m server -v Server.Type=proxygen -v Server.SourceRoot={$base}/ -v Server.IP={$host} -v Server.Port={$port} -v Server.DefaultDocument=server.php -v Server.ErrorDocument404=server.php");
} else {
throw new Exception("HHVM's built-in server requires HHVM >= 3.8.0.");
}
} else {
passthru("{$binary} -S {$host}:{$port} {$base}/index.php");
}
}
2015-04-23 00:32:30 +02:00
public function __construct(Daux $daux)
{
2015-04-22 12:23:57 +02:00
$this->daux = $daux;
$this->host = $_SERVER['HTTP_HOST'];
// The path has a special treatment on windows, revert the slashes
$dir = dirname($_SERVER['PHP_SELF']);
2016-07-27 21:32:51 +02:00
$this->base_url = $_SERVER['HTTP_HOST'] . (DIRECTORY_SEPARATOR == '\\' ? str_replace('\\', '/', $dir) : $dir);
$t = strrpos($this->base_url, '/index.php');
if ($t != false) {
$this->base_url = substr($this->base_url, 0, $t);
}
if (substr($this->base_url, -1) !== '/') {
$this->base_url .= '/';
}
}
2015-07-17 23:38:06 +02:00
/**
* @return \Todaymade\Daux\Config
*/
public function getParams()
{
$params = $this->daux->getParams();
$params['host'] = $this->host;
2015-07-19 14:05:12 +02:00
DauxHelper::rebaseConfiguration($params, '//' . $this->base_url);
$params['base_page'] = '//' . $this->base_url;
2015-07-19 16:36:34 +02:00
if (!$this->daux->options['live']['clean_urls']) {
$params['base_page'] .= 'index.php/';
}
2016-03-13 21:51:58 +01:00
// Text search would be too slow on live server
$params['html']['search'] = false;
return $params;
2015-04-22 12:23:57 +02:00
}
2015-07-17 23:38:06 +02:00
/**
* Handle an incoming request
*
* @param array $query
2015-07-20 15:59:52 +02:00
* @return \Todaymade\Daux\Format\Base\Page
2015-07-17 23:38:06 +02:00
* @throws Exception
* @throws NotFoundException
*/
2015-04-23 00:32:30 +02:00
public function handle($query = [])
{
$this->params = $this->getParams();
2015-04-22 12:23:57 +02:00
2015-04-23 21:04:00 +02:00
$request = $this->getRequest();
2015-04-22 12:23:57 +02:00
$request = urldecode($request);
2015-07-19 23:17:57 +02:00
if ($request == 'index_page') {
$request = $this->daux->tree->getIndexPage()->getUri();
2015-04-22 12:23:57 +02:00
}
2015-07-18 00:56:53 +02:00
return $this->getPage($request);
2015-04-22 12:23:57 +02:00
}
2015-07-17 23:38:06 +02:00
/**
* @param string $request
2015-07-20 15:59:52 +02:00
* @return \Todaymade\Daux\Format\Base\Page
2015-07-17 23:38:06 +02:00
* @throws NotFoundException
*/
2015-04-23 00:32:30 +02:00
private function getPage($request)
{
$file = DauxHelper::getFile($this->daux->tree, $request);
2015-04-23 00:32:30 +02:00
if ($file === false) {
throw new NotFoundException('The Page you requested is yet to be made. Try again later.');
}
$generator = $this->daux->getGenerator();
if (!$generator instanceof LiveGenerator) {
throw new \RuntimeException(
"The generator '" . get_class($generator) . "' does not implement the interface " .
"'Todaymade\\Daux\\Format\\Base\\LiveGenerator' and thus doesn't support live rendering."
);
}
2016-03-13 21:51:58 +01:00
return $this->daux->getGenerator()->generateOne($file, $this->params);
2015-04-22 12:23:57 +02:00
}
2015-04-23 21:04:00 +02:00
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'] = '';
2016-07-27 21:32:51 +02:00
$_GET = [];
2015-04-23 21:04:00 +02:00
}
$uri = parse_url($uri, PHP_URL_PATH);
} else {
return false;
}
2016-07-27 21:32:51 +02:00
$uri = str_replace(['//', '../'], '/', trim($uri, '/'));
if ($uri == '') {
$uri = 'index_page';
2015-04-23 21:04:00 +02:00
}
2016-07-27 21:32:51 +02:00
2015-04-23 21:04:00 +02:00
return $uri;
}
2015-04-22 12:23:57 +02:00
}