<?php
/*
edit.php, used for editing files from a URI.
Copyright (C) 2004 Arend van Beelen, Auton Rijnsburg
This program is free software; you can redistribute it and/or modify it under the terms of the
GNU General Public License as published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if
not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
MA 02111-1307 USA
For any questions, comments or whatever, you may mail me at: hide@address.com
*/
// Uncomment the next line if you can't adjust the include_path setting in your
// php.ini file:
//set_include_path('.:aukyla/base:aukyla/apps:aukyla/plugins');
ignore_user_abort(true);
if(isset($_GET['username']) == false)
{
$_GET['username'] = '';
}
if(isset($_GET['sessionid']) == false)
{
$_GET['sessionid'] = '';
}
$_COOKIE['username'] = $_GET['username'];
$_COOKIE['sessionid'] = $_GET['sessionid'];
if(($garbage = strchr($_COOKIE['sessionid'], '/')) !== false)
{
$_COOKIE['sessionid'] = substr($_COOKIE['sessionid'], 0, strlen($_COOKIE['sessionid']) - strlen($garbage));
}
require_once('Config.php');
require_once('Login.php');
require_once('MIME.php');
require_once('Output.php');
require_once('String.php');
require_once('URI.php');
Output::disableTransformation();
WebDAV::handleRequest();
function getMimeType($file)
{
$name = Config::request('name');
$mime = MIME::type($name, false);
if($mime == '')
{
$mime = MIME::type($file);
}
return $mime;
}
class WebDAV_MultistatusStruct
{
public function __construct($responseStructs)
{
$this->responseStructs = $responseStructs;
}
public $responseStructs;
}
class WebDAV_ResponseStruct
{
public function __construct($href, $propstatStructs)
{
$this->href = $href;
$this->propstatStructs = $propstatStructs;
}
public $href;
public $propstatStructs;
}
class WebDAV_PropstatStruct
{
public function __construct($propertiesArray, $statusCode)
{
$this->propertiesArray = $propertiesArray;
$this->statusCode = $statusCode;
}
public $propertiesArray;
public $statusCode;
}
class WebDAV
{
public function handleRequest()
{
$file = Config::request('file');
$scriptname = basename($_SERVER['SCRIPT_FILENAME']);
switch($_SERVER['REQUEST_METHOD'])
{
case 'GET':
$mime = getMimeType($file);
header("Content-type: $mime");
$contents = URI::fileGetContents($file);
if($contents === false)
{
self::sendResponse(404, "The requested URL $file was not found on this server.");
}
self::sendResponse(200, $contents);
case 'OPTIONS':
$mime = getMimeType($file);
header('DAV: 1,2');
header('DAV: <http://apache.org/dav/propset/fs/1>', false);
header("MS-Author-Via: DAV");
header('Allow: OPTIONS,GET,HEAD,POST,DELETE,TRACE,PROPFIND,PROPPATCH,COPY,MOVE,PUT,LOCK,UNLOCK');
header("Content-Length: 0");
if(strstr(String::substringBefore($_SERVER['REQUEST_URI'], '?'), $scriptname) !== false)
{
header("Content-Type: $mime");
}
else
{
header("Content-Type: httpd/unix-directory");
}
self::sendResponse(200);
case 'PROPFIND':
$name = Config::request('name');
$requestString = file_get_contents('php://input');
$request = DOMDocument::loadXML($requestString);
$href = Config::globals('editURL')."?file=$file&name=$name&username={$_GET['username']}&sessionid={$_GET['sessionid']}";
if($request->hasChildNodes() == false)
{
self::sendResponse(400);
}
switch($request->firstChild->nodeName)
{
case 'propfind':
$propfindNode = $request->firstChild;
if($propfindNode->hasChildNodes() == false)
{
self::sendResponse(400);
}
switch($propfindNode->firstChild->nodeName)
{
case 'prop':
$propNode = $propfindNode->firstChild;
if($propNode->hasChildNodes() == false)
{
self::sendResponse(400);
}
$matches = array();
$unmatched = array();
$node = $propNode->firstChild;
do
{
if($node->nodeName == '#text')
{
continue;
}
if($node->namespaceURI != 'DAV:')
{
$unmatched["{$node->namespaceURI}|{$node->nodeName}"] = '';
continue;
}
switch($node->nodeName)
{
case 'displayname':
$matches['displayname'] = $name;
break;
case 'resourcetype':
if(strstr(String::substringBefore($_SERVER['REQUEST_URI'], '?'), $scriptname) !== false)
{
$mime = getMimeType($file);
$matches['resourcetype'] = $mime;
}
else
{
$matches['resourcetype'] = 'httpd/unix-directory';
}
break;
default:
$unmatched[$node->nodeName] = '';
}
} while(($node = $node->nextSibling) != NULL);
$propstatStructs = array();
if(sizeof($matches) > 0)
{
$propstatStruct = new WebDAV_PropstatStruct($matches, 200);
$propstatStructs[] = $propstatStruct;
}
if(sizeof($unmatched) > 0)
{
$propstatStruct = new WebDAV_PropstatStruct($unmatched, 404);
$propstatStructs[] = $propstatStruct;
}
$responseStruct = new WebDAV_ResponseStruct($href, $propstatStructs);
$multiStatusStruct = new WebDAV_MultistatusStruct(array($responseStruct));
$responseDocument = self::buildMultistatusDocument($multiStatusStruct);
self::sendResponse(207, $responseDocument->saveXML());
break;
case 'propname':
$propstatStruct = new WebDAV_PropstatStruct(array('displayname' => '',
'resourcetype' => ''), 200);
$responseStruct = new WebDAV_ResponseStruct($href, array($propstatStruct));
$multiStatusStruct = new WebDAV_MultistatusStruct(array($responseStruct));
$responseDocument = self::buildMultistatusDocument($multiStatusStruct);
self::sendResponse(207, $responseDocument->saveXML());
break;
default:
self::sendResponse(400);
}
break;
default:
self::sendResponse(400);
}
self::sendResponse(400);
case 'PUT':
if((URI::permissions($file) & PERMISSION_MODIFY) == false)
{
self::sendResponse(403, "You don't have permission to access the requested file or directory.");
}
$putdata = fopen('php://input', 'r');
$fp = fopen($file, 'w');
while($data = fread($putdata, 1024))
{
fwrite($fp, $data);
}
fclose($fp);
fclose($putdata);
self::sendResponse(200);
default:
self::sendResponse(400);
}
}
private function sendResponse($status, $document = '')
{
if($status == '207')
{
header('Content-Type: text/xml; charset="utf-8"');
}
header(self::statusString($status));
exit($document);
}
private static function buildMultistatusDocument(WebDAV_MultistatusStruct $multistatusStruct)
{
$document = new DOMDocument();
$multistatusTag = $document->createElementNS('DAV:', 'multistatus');
$document->appendChild($multistatusTag);
foreach($multistatusStruct->responseStructs as $responseStruct)
{
$responseTag = self::buildResponseTag($document, $responseStruct);
$multistatusTag->appendChild($responseTag);
}
return $document;
}
private static function buildResponseTag(DOMDocument $document, WebDAV_ResponseStruct $responseStruct)
{
$responseTag = $document->createElement('response');
$hrefTag = $document->createElement('href');
$hrefContents = $document->createTextNode($responseStruct->href);
$hrefTag->appendChild($hrefContents);
$responseTag->appendChild($hrefTag);
foreach($responseStruct->propstatStructs as $propstatStruct)
{
$propstatTag = self::buildPropstatTag($document, $propstatStruct);
$responseTag->appendChild($propstatTag);
}
return $responseTag;
}
private static function buildPropstatTag(DOMDocument $document, WebDAV_PropstatStruct $propstatStruct)
{
$propstatTag = $document->createElement('propstat');
$propTag = $document->createElement('prop');
$propstatTag->appendChild($propTag);
foreach($propstatStruct->propertiesArray as $propertyName => $propertyValue)
{
if(String::substringBefore($propertyName, '|') != '')
{
$propertyTag = $document->createElementNS(String::substringBefore($propertyName, '|'),
String::substringAfter($propertyName, '|'));
}
else
{
$propertyTag = $document->createElement($propertyName);
}
if($propertyValue != '')
{
if($propertyName == 'resourcetype' && $propertyValue == 'httpd/unix-directory')
{
$collectionTag = $document->createElement('collection');
$propertyTag->appendChild($collectionTag);
}
else
{
$propertyContents = $document->createTextNode($propertyValue);
$propertyTag->appendChild($propertyContents);
}
}
$propTag->appendChild($propertyTag);
}
$statusTag = $document->createElement('status');
$statusContents = $document->createTextNode(self::statusString($propstatStruct->statusCode));
$statusTag->appendChild($statusContents);
$propstatTag->appendChild($statusTag);
return $propstatTag;
}
private static function statusString($statusCode)
{
return "HTTP/1.1 $statusCode ".self::$statusCodes[$statusCode];
}
private static $statusCodes = array(200 => 'OK',
207 => 'Multi-Status',
400 => 'Bad Request',
403 => 'Access Forbidden',
404 => 'Not Found',
500 => 'Internal Server Error');
}
?>