server.php
来自「PHP 知识管理系统(基于树结构的知识管理系统), 英文原版的PHP源码。」· PHP 代码 · 共 1,998 行 · 第 1/5 页
PHP
1,998 行
}
}
$options["stream"] = fopen("php://input", "r");
$stat = $this->PUT($options);
if ($stat === false) {
$stat = "403 Forbidden";
} else if (is_resource($stat) && get_resource_type($stat) == "stream") {
$stream = $stat;
$stat = $options["new"] ? "201 Created" : "204 No Content";
if (!empty($options["ranges"])) {
// TODO multipart support is missing (see also above)
if (0 == fseek($stream, $range[0]["start"], SEEK_SET)) {
$length = $range[0]["end"]-$range[0]["start"]+1;
if (!fwrite($stream, fread($options["stream"], $length))) {
$stat = "403 Forbidden";
}
} else {
$stat = "403 Forbidden";
}
} else {
while (!feof($options["stream"])) {
if (false === fwrite($stream, fread($options["stream"], 4096))) {
$stat = "403 Forbidden";
break;
}
}
}
fclose($stream);
}
$this->http_status($stat);
} else {
$this->http_status("423 Locked");
}
}
// }}}
// {{{ http_DELETE()
/**
* DELETE method handler
*
* @param void
* @return void
*/
function http_DELETE()
{
// check RFC 2518 Section 9.2, last paragraph
if (isset($this->_SERVER["HTTP_DEPTH"])) {
if ($this->_SERVER["HTTP_DEPTH"] != "infinity") {
$this->http_status("400 Bad Request");
return;
}
}
// check lock status
if ($this->_check_lock_status($this->path)) {
// ok, proceed
$options = Array();
$options["path"] = $this->path;
$stat = $this->DELETE($options);
$this->http_status($stat);
} else {
// sorry, its locked
$this->http_status("423 Locked");
}
}
// }}}
// {{{ http_COPY()
/**
* COPY method handler
*
* @param void
* @return void
*/
function http_COPY()
{
// no need to check source lock status here
// destination lock status is always checked by the helper method
$this->_copymove("copy");
}
// }}}
// {{{ http_MOVE()
/**
* MOVE method handler
*
* @param void
* @return void
*/
function http_MOVE()
{
if ($this->_check_lock_status($this->path)) {
// destination lock status is always checked by the helper method
$this->_copymove("move");
} else {
$this->http_status("423 Locked");
}
}
// }}}
// {{{ http_LOCK()
/**
* LOCK method handler
*
* @param void
* @return void
*/
function http_LOCK()
{
$options = Array();
$options["path"] = $this->path;
if (isset($this->_SERVER['HTTP_DEPTH'])) {
$options["depth"] = $this->_SERVER["HTTP_DEPTH"];
} else {
$options["depth"] = "infinity";
}
if (isset($this->_SERVER["HTTP_TIMEOUT"])) {
$options["timeout"] = explode(",", $this->_SERVER["HTTP_TIMEOUT"]);
}
if (empty($this->_SERVER['CONTENT_LENGTH']) && !empty($this->_SERVER['HTTP_IF'])) {
// check if locking is possible
if (!$this->_check_lock_status($this->path)) {
$this->http_status("423 Locked");
return;
}
// refresh lock
$options["locktoken"] = substr($this->_SERVER['HTTP_IF'], 2, -2);
$options["update"] = $options["locktoken"];
// setting defaults for required fields, LOCK() SHOULD overwrite these
$options['owner'] = "unknown";
$options['scope'] = "exclusive";
$options['type'] = "write";
$stat = $this->LOCK($options);
} else {
// extract lock request information from request XML payload
$lockinfo = new _parse_lockinfo("php://input");
if (!$lockinfo->success) {
$this->http_status("400 bad request");
}
// check if locking is possible
if (!$this->_check_lock_status($this->path, $lockinfo->lockscope === "shared")) {
$this->http_status("423 Locked");
return;
}
// new lock
$options["scope"] = $lockinfo->lockscope;
$options["type"] = $lockinfo->locktype;
$options["owner"] = $lockinfo->owner;
$options["locktoken"] = $this->_new_locktoken();
$stat = $this->LOCK($options);
}
if (is_bool($stat)) {
$http_stat = $stat ? "200 OK" : "423 Locked";
} else {
$http_stat = $stat;
}
$this->http_status($http_stat);
if ($http_stat{0} == 2) { // 2xx states are ok
if ($options["timeout"]) {
// more than a million is considered an absolute timestamp
// less is more likely a relative value
if ($options["timeout"]>1000000) {
$timeout = "Second-".($options['timeout']-time());
} else {
$timeout = "Second-$options[timeout]";
}
} else {
$timeout = "Infinite";
}
header('Content-Type: text/xml; charset="utf-8"');
header("Lock-Token: <$options[locktoken]>");
echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
echo "<D:prop xmlns:D=\"DAV:\">\n";
echo " <D:lockdiscovery>\n";
echo " <D:activelock>\n";
echo " <D:lockscope><D:$options[scope]/></D:lockscope>\n";
echo " <D:locktype><D:$options[type]/></D:locktype>\n";
echo " <D:depth>$options[depth]</D:depth>\n";
echo " <D:owner>$options[owner]</D:owner>\n";
echo " <D:timeout>$timeout</D:timeout>\n";
echo " <D:locktoken><D:href>$options[locktoken]</D:href></D:locktoken>\n";
echo " </D:activelock>\n";
echo " </D:lockdiscovery>\n";
echo "</D:prop>\n\n";
}
}
// }}}
// {{{ http_UNLOCK()
/**
* UNLOCK method handler
*
* @param void
* @return void
*/
function http_UNLOCK()
{
$options = Array();
$options["path"] = $this->path;
if (isset($this->_SERVER['HTTP_DEPTH'])) {
$options["depth"] = $this->_SERVER["HTTP_DEPTH"];
} else {
$options["depth"] = "infinity";
}
// strip surrounding <>
$options["token"] = substr(trim($this->_SERVER["HTTP_LOCK_TOKEN"]), 1, -1);
// call user method
$stat = $this->UNLOCK($options);
$this->http_status($stat);
}
// }}}
// }}}
// {{{ _copymove()
function _copymove($what)
{
$options = Array();
$options["path"] = $this->path;
if (isset($this->_SERVER["HTTP_DEPTH"])) {
$options["depth"] = $this->_SERVER["HTTP_DEPTH"];
} else {
$options["depth"] = "infinity";
}
extract(parse_url($this->_SERVER["HTTP_DESTINATION"]));
$path = urldecode($path);
$http_host = $host;
if (isset($port) && $port != 80)
$http_host.= ":$port";
$http_header_host = preg_replace("/:80$/", "", $this->_SERVER["HTTP_HOST"]);
if ($http_host == $http_header_host &&
!strncmp($this->_SERVER["SCRIPT_NAME"], $path,
strlen($this->_SERVER["SCRIPT_NAME"]))) {
$options["dest"] = substr($path, strlen($this->_SERVER["SCRIPT_NAME"]));
if (!$this->_check_lock_status($options["dest"])) {
$this->http_status("423 Locked");
return;
}
} else {
$options["dest_url"] = $this->_SERVER["HTTP_DESTINATION"];
}
// see RFC 2518 Sections 9.6, 8.8.4 and 8.9.3
if (isset($this->_SERVER["HTTP_OVERWRITE"])) {
$options["overwrite"] = $this->_SERVER["HTTP_OVERWRITE"] == "T";
} else {
$options["overwrite"] = true;
}
$stat = $this->$what($options);
$this->http_status($stat);
}
// }}}
// {{{ _allow()
/**
* check for implemented HTTP methods
*
* @param void
* @return array something
*/
function _allow()
{
// OPTIONS is always there
$allow = array("OPTIONS" =>"OPTIONS");
// all other METHODS need both a http_method() wrapper
// and a method() implementation
// the base class supplies wrappers only
foreach (get_class_methods($this) as $method) {
if (!strncmp("http_", $method, 5)) {
$method = strtoupper(substr($method, 5));
if (method_exists($this, $method)) {
$allow[$method] = $method;
}
}
}
// we can emulate a missing HEAD implemetation using GET
if (isset($allow["GET"]))
$allow["HEAD"] = "HEAD";
// no LOCK without checklok()
if (!method_exists($this, "checklock")) {
unset($allow["LOCK"]);
unset($allow["UNLOCK"]);
}
return $allow;
}
// }}}
/**
* helper for property element creation
*
* @param string XML namespace (optional)
* @param string property name
* @param string property value
* @return array property array
*/
function mkprop()
{
$args = func_get_args();
if (count($args) == 3) {
return array("ns" => $args[0],
"name" => $args[1],
"val" => $args[2]);
} else {
return array("ns" => "DAV:",
"name" => $args[0],
"val" => $args[1]);
}
}
// {{{ _check_auth
/**
* check authentication if check is implemented
*
* @param void
* @return bool true if authentication succeded or not necessary
*/
function _check_auth()
{
if (method_exists($this, "checkAuth")) {
// PEAR style method name
return $this->checkAuth(@$this->_SERVER["AUTH_TYPE"],
@$this->_SERVER["PHP_AUTH_USER"],
@$this->_SERVER["PHP_AUTH_PW"]);
} else if (method_exists($this, "check_auth")) {
// old (pre 1.0) method name
return $this->check_auth(@$this->_SERVER["AUTH_TYPE"],
@$this->_SERVER["PHP_AUTH_USER"],
@$this->_SERVER["PHP_AUTH_PW"]);
} else {
// no method found -> no authentication required
return true;
}
}
// }}}
// {{{ UUID stuff
/**
* generate Unique Universal IDentifier for lock token
*
* @param void
* @return string a new UUID
*/
function _new_uuid()
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?