Skip to content

Instantly share code, notes, and snippets.

@thekid
Created May 14, 2014 15:17
Show Gist options
  • Select an option

  • Save thekid/78f625191d0257b27e52 to your computer and use it in GitHub Desktop.

Select an option

Save thekid/78f625191d0257b27e52 to your computer and use it in GitHub Desktop.
Feature: Rewrite
diff --git a/core/src/main/php/xp/scriptlet/AbstractUrlHandler.class.php b/core/src/main/php/xp/scriptlet/AbstractUrlHandler.class.php
index a7ccd7d..f2c8380 100755
--- a/core/src/main/php/xp/scriptlet/AbstractUrlHandler.class.php
+++ b/core/src/main/php/xp/scriptlet/AbstractUrlHandler.class.php
@@ -66,6 +66,8 @@ abstract class AbstractUrlHandler extends \lang\Object {
* @param [:string] headers request headers
* @param string data post data
* @param peer.Socket socket
+ * @param string[] matches
+ * @return int
*/
- public abstract function handleRequest($method, $query, array $headers, $data, Socket $socket);
+ public abstract function handleRequest($method, $query, array $headers, $data, Socket $socket, $matches);
}
diff --git a/core/src/main/php/xp/scriptlet/FileHandler.class.php b/core/src/main/php/xp/scriptlet/FileHandler.class.php
index 30bc6c4..f52fdc0 100755
--- a/core/src/main/php/xp/scriptlet/FileHandler.class.php
+++ b/core/src/main/php/xp/scriptlet/FileHandler.class.php
@@ -10,16 +10,30 @@ use peer\Socket;
* File handler
*/
class FileHandler extends AbstractUrlHandler {
- protected $docroot= '';
+ protected $base= '';
+ protected $path;
/**
* Constructor
*
- * @param string docroot document root
+ * @param string base document root
* @param var notFound what to do if file is not found (default: send error)
*/
- public function __construct($docroot, $notFound= null) {
- $this->docroot= new Folder($docroot);
+ public function __construct($base, $notFound= null) {
+ if (strstr($base, '$')) {
+ $this->path= function($path, $matches) {
+ return preg_replace_callback(
+ '#\$([0-9]+)#',
+ function($m) use($matches) { return preg_replace('#\.\./?#', '/', urldecode($matches[$m[1]])); },
+ $this->base
+ );
+ };
+ } else {
+ $this->path= function($path, $matches) {
+ return $this->base.'/'.preg_replace('#\.\./?#', '/', urldecode($path));
+ };
+ }
+ $this->base= $base;
if (null === $notFound) {
$handler= $this;
$this->notFound= function($socket, $path) use($handler) {
@@ -33,7 +47,7 @@ class FileHandler extends AbstractUrlHandler {
/**
* Headers lookup
*
- * @param array<string, string> headers
+ * @param [:string] headers
* @param string name
* @return string
*/
@@ -53,15 +67,12 @@ class FileHandler extends AbstractUrlHandler {
* @param [:string] headers request headers
* @param string data post data
* @param peer.Socket socket
+ * @param string[] matches
* @return int
*/
- public function handleRequest($method, $query, array $headers, $data, Socket $socket) {
+ public function handleRequest($method, $query, array $headers, $data, Socket $socket, $matches) {
$url= parse_url($query);
- $f= new File($this->docroot, strtr(
- preg_replace('#\.\./?#', '/', urldecode($url['path'])),
- '/',
- DIRECTORY_SEPARATOR
- ));
+ $f= new File(strtr(call_user_func($this->path, $url['path'], $matches), '/', DIRECTORY_SEPARATOR));
if (!is_file($f->getURI())) {
return call_user_func($this->notFound, $socket, $url['path']);
}
@@ -102,6 +113,6 @@ class FileHandler extends AbstractUrlHandler {
* @return string
*/
public function toString() {
- return $this->getClassName().'<'.$this->docroot->toString().', '.\xp::stringOf($this->notFound).'>';
+ return $this->getClassName().'<'.$this->base.', '.\xp::stringOf($this->notFound).'>';
}
}
diff --git a/core/src/main/php/xp/scriptlet/HttpProtocol.class.php b/core/src/main/php/xp/scriptlet/HttpProtocol.class.php
index 95c1171..f476db7 100755
--- a/core/src/main/php/xp/scriptlet/HttpProtocol.class.php
+++ b/core/src/main/php/xp/scriptlet/HttpProtocol.class.php
@@ -11,6 +11,7 @@ use peer\http\HttpConstants;
class HttpProtocol extends \lang\Object implements \peer\server\ServerProtocol {
protected $handlers = array();
public $server = null;
+ public $base = '';
/**
* Initialize Protocol
@@ -19,7 +20,7 @@ class HttpProtocol extends \lang\Object implements \peer\server\ServerProtocol {
*/
public function initialize() {
$this->handlers['default'][':error']= newinstance('xp.scriptlet.AbstractUrlHandler', array(), '{
- public function handleRequest($method, $query, array $headers, $data, \peer\Socket $socket) {
+ public function handleRequest($method, $query, array $headers, $data, \peer\Socket $socket, $matches) {
$this->sendErrorMessage($socket, 400, "Bad Request", "Cannot handle request");
}
}');
@@ -69,9 +70,9 @@ class HttpProtocol extends \lang\Object implements \peer\server\ServerProtocol {
public function handleRequest($host, $method, $query, $headers, $body, $socket) {
$handlers= isset($this->handlers[$host]) ? $this->handlers[$host] : $this->handlers['default'];
foreach ($handlers as $pattern => $handler) {
- if (preg_match($pattern, $query)) {
+ if (preg_match($pattern, $query, $matches)) {
try {
- $sc= $handler->handleRequest($method, $query, $headers, $body, $socket);
+ $sc= $handler->handleRequest($method, $query, $headers, $body, $socket, $matches);
Console::$out->writeLine($sc);
if (HttpConstants::STATUS_CONTINUE === $sc) continue;
} catch (IOException $e) {
@@ -106,6 +107,8 @@ class HttpProtocol extends \lang\Object implements \peer\server\ServerProtocol {
Console::$err->writeLine('Malformed request "', addcslashes($header, "\0..\17"), '" from ', $socket->host);
return $socket->close();
}
+
+ $query= preg_replace('#^'.$this->base.'#', '', $query);
$offset= strpos($header, "\r\n")+ 2;
$headers= array();
if ($t= strtok(substr($header, $offset, $p- $offset), "\r\n")) do {
diff --git a/core/src/main/php/xp/scriptlet/ScriptletHandler.class.php b/core/src/main/php/xp/scriptlet/ScriptletHandler.class.php
index 45b7e6b..cc9c378 100755
--- a/core/src/main/php/xp/scriptlet/ScriptletHandler.class.php
+++ b/core/src/main/php/xp/scriptlet/ScriptletHandler.class.php
@@ -43,9 +43,10 @@ class ScriptletHandler extends AbstractUrlHandler {
* @param [:string] headers request headers
* @param string data post data
* @param peer.Socket socket
+ * @param string[] matches
* @return int
*/
- public function handleRequest($method, $query, array $headers, $data, Socket $socket) {
+ public function handleRequest($method, $query, array $headers, $data, Socket $socket, $matches) {
$url= new URL('http://'.(isset($headers['Host']) ? $headers['Host'] : $this->serverName).$query);
$request= $this->request->invoke($this->scriptlet, array());
$response= $this->response->invoke($this->scriptlet, array());
diff --git a/core/src/main/php/xp/scriptlet/Server.class.php b/core/src/main/php/xp/scriptlet/Server.class.php
index 04df946..00c1f53 100755
--- a/core/src/main/php/xp/scriptlet/Server.class.php
+++ b/core/src/main/php/xp/scriptlet/Server.class.php
@@ -60,6 +60,7 @@ class Server extends \lang\Object {
with ($pm= PropertyManager::getInstance(), $protocol= $server->setProtocol(new HttpProtocol())); {
$conf= new WebConfiguration(new \util\Properties($configd.DIRECTORY_SEPARATOR.'web.ini'));
+ $protocol->base= getenv('REWRITE_BASE');
$resources= $conf->staticResources($args[2]);
if (null === $resources) {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment