grav icon indicating copy to clipboard operation
grav copied to clipboard

Encode routes to increase compatibility

Open newbthenewbd opened this issue 5 years ago • 1 comments

Currently, when routes are being built in Grav, the supplied paths are automatically decoded. Because of this, when they contain special characters, encoded to be used as ordinary parts of the paths, the resulting routes may function differently than expected.

The problem is particularly visible in the case of a question mark, encoded as %3F. For example, if redirect_trailing_slash is set to true in system.yaml in a Grav installation on localhost, trying to access http://localhost/test%3F/?foo=bar may be redirected to http://localhost/test??foo=bar, instead of http://localhost/test%3F?foo=bar, where test%3F refers to a page called test?. As a result, a page called test will be loaded.

This pull request aims to fix that by encoding the routes after work is done on them, although frankly, I am not entirely convinced that the change that I propose, even if free of problems on its own (FWIW, I haven't observed any), completely resolves the described underlying issue. Perhaps it'd be a good idea to take a deeper look into this, if time allows.

newbthenewbd avatar Dec 25 '19 19:12 newbthenewbd

I'll just throw this out there as an addendum, it's a similar problem but the patch above doesn't solve it. So given the function

<?php
namespace Grav\Plugin;

use Grav\Common\Page\Page;
use Grav\Common\Plugin;

class SlovarminiPlugin extends Plugin
{
	protected $route = '/info';
	public static function getSubscribedEvents()
	{
		return [
			'onPluginsInitialized' => ['onPluginsInitialized', 0]
		];
	}
	public function onPluginsInitialized()
	{
		if ($this->isAdmin()) {
			return;
		}
		$uri = $this->grav['uri'];
		$route = str_replace('/' . $uri->basename(),"",$uri->path());
		if ($this->route && $this->route == $route) {
			$this->enable([
				'onPagesInitialized' => ['addMyPage', 0],
				'onTwigSiteVariables' => ['onTwigSiteVariables', 0]
			]);
		}
	}

	public function addMyPage()
	{
		$uri = $this->grav['uri'];
		$this->addPage($uri->path(), 'slovarmini.md');
	}
		
	public function queryDatabaseExample($slovo) {
		return require_once ('slovarmini_core.php');
	}

	public function onTwigSiteVariables() {
		$twig = $this->grav['twig'];
		$uri = $this->grav['uri'];
		$twig->twig_vars['dictionary'] = $this->queryDatabaseExample(urldecode($uri->basename()));
		$twig->twig_vars['dictquery'] = urldecode($uri->basename());
	}

	public function addPage($url, $filename)
	{
		$pages = $this->grav['pages'];
		$page = $pages->dispatch($url);

		if (!$page) {
			$page = new Page;
			$page->init(new \SplFileInfo(__DIR__ . '/pages/' . $filename));
			$url = urldecode($url);
			$page->slug(basename($url));
			$pages->addPage($page, $url);
		}
	}
}

Slug requests such as /info/myrequest%3F will inevitably pass "myreqeust" to queryDatabaseExample function above instead of the expected "myrequest?" or "myrequest%3F". This is relevant when passing unusual strings, such as in my case when doing a db query against a dictionary database, when your word/request is actually a phrase that ends with a question mark. The intention is to do the search as it is present in the database, the complete phrase with a question mark at the end.

urldecoding that truncates the "?" apparently happens between 'onPagesInitialized' and 'onPageInitialized'

qumuq-til avatar Dec 28 '19 11:12 qumuq-til