request.php

来自「视频监控网络部分的协议ddns,的模块的实现代码,请大家大胆指正.」· PHP 代码 · 共 1,144 行 · 第 1/3 页

PHP
1,144
字号
                $postdata = '';                if (!empty($this->_postData)) {                    $flatData = $this->_flattenArray('', $this->_postData);                    foreach ($flatData as $item) {                        $postdata .= '--' . $boundary . "\r\n";                        $postdata .= 'Content-Disposition: form-data; name="' . $item[0] . '"';                        $postdata .= "\r\n\r\n" . urldecode($item[1]) . "\r\n";                    }                }                foreach ($this->_postFiles as $name => $value) {                    if (is_array($value['name'])) {                        $varname       = $name . ($this->_useBrackets? '[]': '');                    } else {                        $varname       = $name;                        $value['name'] = array($value['name']);                    }                    foreach ($value['name'] as $key => $filename) {                        $fp   = fopen($filename, 'r');                        $data = fread($fp, filesize($filename));                        fclose($fp);                        $basename = basename($filename);                        $type     = is_array($value['type'])? @$value['type'][$key]: $value['type'];                        $postdata .= '--' . $boundary . "\r\n";                        $postdata .= 'Content-Disposition: form-data; name="' . $varname . '"; filename="' . $basename . '"';                        $postdata .= "\r\nContent-Type: " . $type;                        $postdata .= "\r\n\r\n" . $data . "\r\n";                    }                }                $postdata .= '--' . $boundary . "\r\n";            }            $request .= 'Content-Length: ' . strlen($postdata) . "\r\n\r\n";            $request .= $postdata;        // Post data if it's raw        } elseif(!empty($this->_postData)) {            $request .= 'Content-Length: ' . strlen($this->_postData) . "\r\n\r\n";            $request .= $this->_postData;        }                return $request;    }   /**    * Helper function to change the (probably multidimensional) associative array    * into the simple one.    *    * @param    string  name for item    * @param    mixed   item's values    * @return   array   array with the following items: array('item name', 'item value');    */    function _flattenArray($name, $values)    {        if (!is_array($values)) {            return array(array($name, $values));        } else {            $ret = array();            foreach ($values as $k => $v) {                if (empty($name)) {                    $newName = $k;                } elseif ($this->_useBrackets) {                    $newName = $name . '[' . $k . ']';                } else {                    $newName = $name;                }                $ret = array_merge($ret, $this->_flattenArray($newName, $v));            }            return $ret;        }    }   /**    * Adds a Listener to the list of listeners that are notified of    * the object's events    *     * @param    object   HTTP_Request_Listener instance to attach    * @return   boolean  whether the listener was successfully attached    * @access   public    */    function attach(&$listener)    {        if (!is_a($listener, 'HTTP_Request_Listener')) {            return false;        }        $this->_listeners[$listener->getId()] =& $listener;        return true;    }   /**    * Removes a Listener from the list of listeners     *     * @param    object   HTTP_Request_Listener instance to detach    * @return   boolean  whether the listener was successfully detached    * @access   public    */    function detach(&$listener)    {        if (!is_a($listener, 'HTTP_Request_Listener') ||             !isset($this->_listeners[$listener->getId()])) {            return false;        }        unset($this->_listeners[$listener->getId()]);        return true;    }   /**    * Notifies all registered listeners of an event.    *     * Events sent by HTTP_Request object    * 'sentRequest': after the request was sent    * Events sent by HTTP_Response object    * 'gotHeaders': after receiving response headers (headers are passed in $data)    * 'tick': on receiving a part of response body (the part is passed in $data)    * 'gzTick': on receiving a gzip-encoded part of response body (ditto)    * 'gotBody': after receiving the response body (passes the decoded body in $data if it was gzipped)    *     * @param    string  Event name    * @param    mixed   Additional data    * @access   private    */    function _notify($event, $data = null)    {        foreach (array_keys($this->_listeners) as $id) {            $this->_listeners[$id]->update($this, $event, $data);        }    }}/*** Response class to complement the Request class*/class HTTP_Response{    /**    * Socket object    * @var object    */    var $_sock;    /**    * Protocol    * @var string    */    var $_protocol;        /**    * Return code    * @var string    */    var $_code;        /**    * Response headers    * @var array    */    var $_headers;    /**    * Cookies set in response      * @var array    */    var $_cookies;    /**    * Response body    * @var string    */    var $_body = '';   /**    * Used by _readChunked(): remaining length of the current chunk    * @var string    */    var $_chunkLength = 0;   /**    * Attached listeners    * @var array    */    var $_listeners = array();    /**    * Constructor    *    * @param  object Net_Socket     socket to read the response from    * @param  array                 listeners attached to request    * @return mixed PEAR Error on error, true otherwise    */    function HTTP_Response(&$sock, &$listeners)    {        $this->_sock      =& $sock;        $this->_listeners =& $listeners;    }   /**    * Processes a HTTP response    *     * This extracts response code, headers, cookies and decodes body if it     * was encoded in some way    *    * @access public    * @param  bool      Whether to store response body in object property, set    *                   this to false if downloading a LARGE file and using a Listener.    *                   This is assumed to be true if body is gzip-encoded.    * @throws PEAR_Error    * @return mixed     true on success, PEAR_Error in case of malformed response    */    function process($saveBody = true)    {        do {            $line = $this->_sock->readLine();            if (sscanf($line, 'HTTP/%s %s', $http_version, $returncode) != 2) {                return PEAR::raiseError('Malformed response.');            } else {                $this->_protocol = 'HTTP/' . $http_version;                $this->_code     = intval($returncode);            }            while ('' !== ($header = $this->_sock->readLine())) {                $this->_processHeader($header);            }        } while (100 == $this->_code);        $this->_notify('gotHeaders', $this->_headers);        // If response body is present, read it and decode        $chunked = isset($this->_headers['transfer-encoding']) && ('chunked' == $this->_headers['transfer-encoding']);        $gzipped = isset($this->_headers['content-encoding']) && ('gzip' == $this->_headers['content-encoding']);        $hasBody = false;        while (!$this->_sock->eof()) {            if ($chunked) {                $data = $this->_readChunked();            } else {                $data = $this->_sock->read(4096);            }            if ('' != $data) {                $hasBody = true;                if ($saveBody || $gzipped) {                    $this->_body .= $data;                }                $this->_notify($gzipped? 'gzTick': 'tick', $data);            }        }        if ($hasBody) {            // Uncompress the body if needed            if ($gzipped) {                $this->_body = gzinflate(substr($this->_body, 10));                $this->_notify('gotBody', $this->_body);            } else {                $this->_notify('gotBody');            }        }        return true;    }   /**    * Processes the response header    *    * @access private    * @param  string    HTTP header    */    function _processHeader($header)    {        list($headername, $headervalue) = explode(':', $header, 2);        $headername_i = strtolower($headername);        $headervalue  = ltrim($headervalue);                if ('set-cookie' != $headername_i) {            $this->_headers[$headername]   = $headervalue;            $this->_headers[$headername_i] = $headervalue;        } else {            $this->_parseCookie($headervalue);        }    }   /**    * Parse a Set-Cookie header to fill $_cookies array    *    * @access private    * @param  string    value of Set-Cookie header    */    function _parseCookie($headervalue)    {        $cookie = array(            'expires' => null,            'domain'  => null,            'path'    => null,            'secure'  => false        );        // Only a name=value pair        if (!strpos($headervalue, ';')) {            $pos = strpos($headervalue, '=');            $cookie['name']  = trim(substr($headervalue, 0, $pos));            $cookie['value'] = trim(substr($headervalue, $pos + 1));        // Some optional parameters are supplied        } else {            $elements = explode(';', $headervalue);            $pos = strpos($elements[0], '=');            $cookie['name']  = trim(substr($elements[0], 0, $pos));            $cookie['value'] = trim(substr($elements[0], $pos + 1));            for ($i = 1; $i < count($elements); $i++) {                if (false === strpos($elements[$i], '=')) {                    $elName  = trim($elements[$i]);                    $elValue = null;                } else {                    list ($elName, $elValue) = array_map('trim', explode('=', $elements[$i]));                }                $elName = strtolower($elName);                if ('secure' == $elName) {                    $cookie['secure'] = true;                } elseif ('expires' == $elName) {                    $cookie['expires'] = str_replace('"', '', $elValue);                } elseif ('path' == $elName || 'domain' == $elName) {                    $cookie[$elName] = urldecode($elValue);                } else {                    $cookie[$elName] = $elValue;                }            }        }        $this->_cookies[] = $cookie;    }   /**    * Read a part of response body encoded with chunked Transfer-Encoding    *     * @access private    * @return string    */    function _readChunked()    {        // at start of the next chunk?        if (0 == $this->_chunkLength) {            $line = $this->_sock->readLine();            if (preg_match('/^([0-9a-f]+)/i', $line, $matches)) {                $this->_chunkLength = hexdec($matches[1]);                 // Chunk with zero length indicates the end                if (0 == $this->_chunkLength) {                    $this->_sock->readAll(); // make this an eof()                    return '';                }            } elseif ($this->_sock->eof()) {                return '';            }        }        $data = $this->_sock->read($this->_chunkLength);        $this->_chunkLength -= strlen($data);        if (0 == $this->_chunkLength) {            $this->_sock->readLine(); // Trailing CRLF        }        return $data;    }   /**    * Notifies all registered listeners of an event.    *     * @param    string  Event name    * @param    mixed   Additional data    * @access   private    * @see HTTP_Request::_notify()    */    function _notify($event, $data = null)    {        foreach (array_keys($this->_listeners) as $id) {            $this->_listeners[$id]->update($this, $event, $data);        }    }} // End class HTTP_Response?>

⌨️ 快捷键说明

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