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 + -
显示快捷键?