server.php

来自「PHP 知识管理系统(基于树结构的知识管理系统), 英文原版的PHP源码。」· PHP 代码 · 共 1,998 行 · 第 1/5 页

PHP
1,998
字号
<?php
//
// +----------------------------------------------------------------------+
// | PHP Version 4                                                        |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2003 The PHP Group                                |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license,      |
// | that is bundled with this package in the file LICENSE, and is        |
// | available at through the world-wide-web at                           |
// | http://www.php.net/license/2_02.txt.                                 |
// | If you did not receive a copy of the PHP license and are unable to   |
// | obtain it through the world-wide-web, please send a note to          |
// | license@php.net so we can mail you a copy immediately.               |
// +----------------------------------------------------------------------+
// | Authors: Hartmut Holzgraefe <hholzgra@php.net>                       |
// |          Christian Stocker <chregu@bitflux.ch>                       |
// +----------------------------------------------------------------------+
//
// $Id: Server.php,v 1.56 2006/10/10 11:53:16 hholzgra Exp $
//
require_once "HTTP/WebDAV/Tools/_parse_propfind.php";
require_once "HTTP/WebDAV/Tools/_parse_proppatch.php";
require_once "HTTP/WebDAV/Tools/_parse_lockinfo.php";

/**
 * Virtual base class for implementing WebDAV servers 
 *
 * WebDAV server base class, needs to be extended to do useful work
 * 
 * @package HTTP_WebDAV_Server
 * @author  Hartmut Holzgraefe <hholzgra@php.net>
 * @version @package_version@
 */
class HTTP_WebDAV_Server 
{
    // {{{ Member Variables 
    
    /**
     * complete URI for this request
     *
     * @var string 
     */
    var $uri;
    
    
    /**
     * base URI for this request
     *
     * @var string 
     */
    var $base_uri;


    /**
     * URI path for this request
     *
     * @var string 
     */
    var $path;

    /**
     * Realm string to be used in authentification popups
     *
     * @var string 
     */
    var $http_auth_realm = "PHP WebDAV";

    /**
     * String to be used in "X-Dav-Powered-By" header
     *
     * @var string 
     */
    var $dav_powered_by = "";

    /**
     * Remember parsed If: (RFC2518/9.4) header conditions  
     *
     * @var array
     */
    var $_if_header_uris = array();

    /**
     * HTTP response status/message
     *
     * @var string
     */
    var $_http_status = "200 OK";

    /**
     * encoding of property values passed in
     *
     * @var string
     */
    var $_prop_encoding = "utf-8";

    /**
     * Copy of $_SERVER superglobal array
     *
     * Derived classes may extend the constructor to
     * modify its contents
     *
     * @var array
     */
    var $_SERVER;

    // }}}

    // {{{ Constructor 

    /** 
     * Constructor
     *
     * @param void
     */
    function HTTP_WebDAV_Server() 
    {
        // PHP messages destroy XML output -> switch them off
        ini_set("display_errors", 0);

        // copy $_SERVER variables to local _SERVER array
        // so that derived classes can simply modify these
        $this->_SERVER = $_SERVER;
    }

    // }}}

    // {{{ ServeRequest() 
    /** 
     * Serve WebDAV HTTP request
     *
     * dispatch WebDAV HTTP request to the apropriate method handler
     * 
     * @param  void
     * @return void
     */
    function ServeRequest() 
    {
        // prevent warning in litmus check 'delete_fragment'
        if (strstr($this->_SERVER["REQUEST_URI"], '#')) {
            $this->http_status("400 Bad Request");
            return;
        }

        // default uri is the complete request uri
        $uri = (@$this->_SERVER["HTTPS"] === "on" ? "https:" : "http:");
        $uri.= "//$this->_SERVER[HTTP_HOST]$this->_SERVER[SCRIPT_NAME]";
        
        $path_info = empty($this->_SERVER["PATH_INFO"]) ? "/" : $this->_SERVER["PATH_INFO"];

        $this->base_uri = $uri;
        $this->uri      = $uri . $path_info;

        // set path
        $this->path = $this->_urldecode($path_info);
        if (!strlen($this->path)) {
            if ($this->_SERVER["REQUEST_METHOD"] == "GET") {
                // redirect clients that try to GET a collection
                // WebDAV clients should never try this while
                // regular HTTP clients might ...
                header("Location: ".$this->base_uri."/");
                return;
            } else {
                // if a WebDAV client didn't give a path we just assume '/'
                $this->path = "/";
            }
        } 
        
        if (ini_get("magic_quotes_gpc")) {
            $this->path = stripslashes($this->path);
        }
        
        
        // identify ourselves
        if (empty($this->dav_powered_by)) {
            header("X-Dav-Powered-By: PHP class: ".get_class($this));
        } else {
            header("X-Dav-Powered-By: ".$this->dav_powered_by);
        }

        // check authentication
        // for the motivation for not checking OPTIONS requests on / see 
        // http://pear.php.net/bugs/bug.php?id=5363
        if ( (   !(($this->_SERVER['REQUEST_METHOD'] == 'OPTIONS') && ($this->path == "/")))
             && (!$this->_check_auth())) {
            // RFC2518 says we must use Digest instead of Basic
            // but Microsoft Clients do not support Digest
            // and we don't support NTLM and Kerberos
            // so we are stuck with Basic here
            header('WWW-Authenticate: Basic realm="'.($this->http_auth_realm).'"');

            // Windows seems to require this being the last header sent
            // (changed according to PECL bug #3138)
            $this->http_status('401 Unauthorized');

            return;
        }
        
        // check 
        if (! $this->_check_if_header_conditions()) {
            return;
        }
        
        // detect requested method names
        $method  = strtolower($this->_SERVER["REQUEST_METHOD"]);
        $wrapper = "http_".$method;
        
        // activate HEAD emulation by GET if no HEAD method found
        if ($method == "head" && !method_exists($this, "head")) {
            $method = "get";
        }
        
        if (method_exists($this, $wrapper) && ($method == "options" || method_exists($this, $method))) {
            $this->$wrapper();  // call method by name
        } else { // method not found/implemented
            if ($this->_SERVER["REQUEST_METHOD"] == "LOCK") {
                $this->http_status("412 Precondition failed");
            } else {
                $this->http_status("405 Method not allowed");
                header("Allow: ".join(", ", $this->_allow()));  // tell client what's allowed
            }
        }
    }

    // }}}

    // {{{ abstract WebDAV methods 

    // {{{ GET() 
    /**
     * GET implementation
     *
     * overload this method to retrieve resources from your server
     * <br>
     * 
     *
     * @abstract 
     * @param array &$params Array of input and output parameters
     * <br><b>input</b><ul>
     * <li> path - 
     * </ul>
     * <br><b>output</b><ul>
     * <li> size - 
     * </ul>
     * @returns int HTTP-Statuscode
     */

    /* abstract
     function GET(&$params) 
     {
     // dummy entry for PHPDoc
     } 
    */

    // }}}

    // {{{ PUT() 
    /**
     * PUT implementation
     *
     * PUT implementation
     *
     * @abstract 
     * @param array &$params
     * @returns int HTTP-Statuscode
     */
    
    /* abstract
     function PUT() 
     {
     // dummy entry for PHPDoc
     } 
    */
    
    // }}}

    // {{{ COPY() 

    /**
     * COPY implementation
     *
     * COPY implementation
     *
     * @abstract 
     * @param array &$params
     * @returns int HTTP-Statuscode
     */
    
    /* abstract
     function COPY() 
     {
     // dummy entry for PHPDoc
     } 
    */

    // }}}

    // {{{ MOVE() 

    /**
     * MOVE implementation
     *
     * MOVE implementation
     *
     * @abstract 
     * @param array &$params
     * @returns int HTTP-Statuscode
     */
    
    /* abstract
     function MOVE() 
     {
     // dummy entry for PHPDoc
     } 
    */

    // }}}

    // {{{ DELETE() 

    /**
     * DELETE implementation
     *
     * DELETE implementation
     *
     * @abstract 
     * @param array &$params
     * @returns int HTTP-Statuscode
     */
    
    /* abstract
     function DELETE() 
     {
     // dummy entry for PHPDoc
     } 
    */
    // }}}

    // {{{ PROPFIND() 

    /**
     * PROPFIND implementation
     *
     * PROPFIND implementation
     *
     * @abstract 
     * @param array &$params
     * @returns int HTTP-Statuscode
     */
    
    /* abstract
     function PROPFIND() 
     {
     // dummy entry for PHPDoc
     } 
    */

    // }}}

    // {{{ PROPPATCH() 

    /**
     * PROPPATCH implementation
     *
     * PROPPATCH implementation
     *
     * @abstract 
     * @param array &$params
     * @returns int HTTP-Statuscode
     */
    
    /* abstract
     function PROPPATCH() 
     {
     // dummy entry for PHPDoc
     } 
    */
    // }}}

    // {{{ LOCK() 

    /**
     * LOCK implementation
     *
     * LOCK implementation
     *
     * @abstract 
     * @param array &$params
     * @returns int HTTP-Statuscode
     */
    
    /* abstract
     function LOCK() 
     {
     // dummy entry for PHPDoc
     } 
    */
    // }}}

    // {{{ UNLOCK() 

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?