server.php.svn-base
来自「PHP 知识管理系统(基于树结构的知识管理系统), 英文原版的PHP源码。」· SVN-BASE 代码 · 共 2,047 行 · 第 1/5 页
SVN-BASE
2,047 行
} } 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() { // use uuid extension from PECL if available if (function_exists("uuid_create")) { return uuid_create(); } // fallback $uuid = md5(microtime().getmypid()); // this should be random enough for now // set variant and version fields for 'true' random uuid $uuid{12} = "4"; $n = 8 + (ord($uuid{16}) & 3); $hex = "0123456789abcdef"; $uuid{16} = $hex{$n}; // return formated uuid return substr($uuid, 0, 8)."-" . substr($uuid, 8, 4)."-" . substr($uuid, 12, 4)."-" . substr($uuid, 16, 4)."-" . substr($uuid, 20); } /** * create a new opaque lock token as defined in RFC2518 * * @param void * @return string new RFC2518 opaque lock token */ function _new_locktoken() { return "opaquelocktoken:".$this->_new_uuid(); } // }}} // {{{ WebDAV If: header parsing /** *
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?