public static function download($url, $timeout = 3000) { xapp_import('xapp.Commons.Error'); xapp_import('xapp.Utils.Strings'); xapp_import('xapp.Http.MiniHTTP'); xapp_import('xapp.Directory.Utils'); xapp_import('xapp.File.Utils'); if (!$url) { return new XApp_Error('http_no_url', 'Invalid URL Provided.'); } $tmpfname = XApp_Directory_Utils::tempname($url); if (!$tmpfname) { return new XApp_Error_Base('http_no_file', 'Could not create Temporary file.'); } $http = new XApp_Http(); $response = $http->request($url, array('timeout' => $timeout, 'stream' => true, 'filename' => $tmpfname)); /*xapp_clog($response);*/ if (XApp_Error_Base::is_error($response)) { unlink($tmpfname); return $response; } /* if ( 200 != self::remote_retrieve_response_code( $response ) ){ unlink( $tmpfname ); return self::remote_retrieve_response_message( $response ); }*/ $content_md5 = self::remote_retrieve_header($response, 'content-md5'); if ($content_md5) { $md5_check = XApp_File_Utils::verify_file_md5($tmpfname, $content_md5); if (XApp_Error::is_error($md5_check)) { unlink($tmpfname); return $md5_check; } } return $tmpfname; }
/** * Send a HTTP request to a URI using cURL extension. * * @access public * * @param string $url The request URL. * @param string|array $args Optional. Override the defaults. * @return array|Error Array containing 'headers', 'body', 'response', 'cookies', 'filename'. A Error instance upon error */ public function request($url, $args = array()) { $defaults = array('method' => 'GET', 'timeout' => 5, 'redirection' => 5, 'httpversion' => '1.0', 'blocking' => true, 'headers' => array(), 'body' => null, 'cookies' => array()); $r = XApp_Utils_Array::parse_args($args, $defaults); if (isset($r['headers']['User-Agent'])) { $r['user-agent'] = $r['headers']['User-Agent']; unset($r['headers']['User-Agent']); } else { if (isset($r['headers']['user-agent'])) { $r['user-agent'] = $r['headers']['user-agent']; unset($r['headers']['user-agent']); } } // Construct Cookie: header if any cookies are set. //XAppHttp::buildCookieHeader( $r ); $handle = curl_init(); $is_local = isset($r['local']) && $r['local']; $ssl_verify = isset($r['sslverify']) && $r['sslverify']; if ($is_local) { /** This filter is documented in wp-includes/class-http.php */ $ssl_verify = false; } elseif (!$is_local) { /** This filter is documented in wp-includes/class-http.php */ $ssl_verify = false; } /* * CURLOPT_TIMEOUT and CURLOPT_CONNECTTIMEOUT expect integers. Have to use ceil since. * a value of 0 will allow an unlimited timeout. */ $timeout = (int) ceil($r['timeout']); curl_setopt($handle, CURLOPT_CONNECTTIMEOUT, $timeout); curl_setopt($handle, CURLOPT_TIMEOUT, $timeout); curl_setopt($handle, CURLOPT_URL, $url); curl_setopt($handle, CURLOPT_RETURNTRANSFER, true); curl_setopt($handle, CURLOPT_SSL_VERIFYHOST, $ssl_verify === true ? 2 : false); curl_setopt($handle, CURLOPT_SSL_VERIFYPEER, $ssl_verify); curl_setopt($handle, CURLOPT_CAINFO, $r['sslcertificates']); curl_setopt($handle, CURLOPT_USERAGENT, $r['user-agent']); //curl_setopt($handle, CURLOPT_PROGRESSFUNCTION, 'curl_progress'); //curl_setopt($handle, CURLOPT_NOPROGRESS, false); // needed to make progress function work /* * The option doesn't work with safe mode or when open_basedir is set, and there's * a bug #17490 with redirected POST requests, so handle redirections outside Curl. */ curl_setopt($handle, CURLOPT_FOLLOWLOCATION, false); if (defined('CURLOPT_PROTOCOLS')) { // PHP 5.2.10 / cURL 7.19.4 curl_setopt($handle, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS); } switch ($r['method']) { case 'HEAD': curl_setopt($handle, CURLOPT_NOBODY, true); break; case 'POST': curl_setopt($handle, CURLOPT_POST, true); curl_setopt($handle, CURLOPT_POSTFIELDS, $r['body']); break; case 'PUT': curl_setopt($handle, CURLOPT_CUSTOMREQUEST, 'PUT'); curl_setopt($handle, CURLOPT_POSTFIELDS, $r['body']); break; default: curl_setopt($handle, CURLOPT_CUSTOMREQUEST, $r['method']); if (!is_null($r['body'])) { curl_setopt($handle, CURLOPT_POSTFIELDS, $r['body']); } break; } if (true === $r['blocking']) { curl_setopt($handle, CURLOPT_HEADERFUNCTION, array($this, 'stream_headers')); curl_setopt($handle, CURLOPT_WRITEFUNCTION, array($this, 'stream_body')); } curl_setopt($handle, CURLOPT_HEADER, false); if (isset($r['limit_response_size'])) { $this->max_body_length = intval($r['limit_response_size']); } else { $this->max_body_length = false; } // If streaming to a file open a file handle, and setup our curl streaming handler. if ($r['stream']) { $this->stream_handle = @fopen($r['filename'], 'w+'); if (!$this->stream_handle) { return new XApp_Error('http_request_failed', sprintf('Could not open handle for fopen() to %s', $r['filename'])); } } else { $this->stream_handle = false; } if (!empty($r['headers'])) { // cURL expects full header strings in each element. $headers = array(); foreach ($r['headers'] as $name => $value) { $headers[] = "{$name}: {$value}"; } curl_setopt($handle, CURLOPT_HTTPHEADER, $headers); } if ($r['httpversion'] == '1.0') { curl_setopt($handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); } else { curl_setopt($handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); } /** * Fires before the cURL request is executed. * * Cookies are not currently handled by the HTTP API. This action allows * plugins to handle cookies themselves. * * @param resource &$handle The cURL handle returned by curl_init(). * @param array $r The HTTP request arguments. * @param string $url The request URL. */ // We don't need to return the body, so don't. Just execute request and return. if (!$r['blocking']) { curl_exec($handle); if ($curl_error = curl_error($handle)) { curl_close($handle); return new XApp_Error('http_request_failed', $curl_error); } if (in_array(curl_getinfo($handle, CURLINFO_HTTP_CODE), array(301, 302))) { curl_close($handle); return new XApp_Error('http_request_failed', 'Too many redirects.'); } curl_close($handle); return array('headers' => array(), 'body' => '', 'response' => array('code' => false, 'message' => false), 'cookies' => array()); } curl_exec($handle); $theHeaders = XApp_Http::processHeaders($this->headers, $url); $theBody = $this->body; $this->headers = ''; $this->body = ''; $curl_error = curl_errno($handle); // If an error occurred, or, no response. if ($curl_error || 0 == strlen($theBody) && empty($theHeaders['headers'])) { if (CURLE_WRITE_ERROR == $curl_error && $r['stream']) { fclose($this->stream_handle); return new XApp_Error('http_request_failed', 'Failed to write request to temporary file.'); } if ($curl_error = curl_error($handle)) { curl_close($handle); return new XApp_Error('http_request_failed', $curl_error); } if (in_array(curl_getinfo($handle, CURLINFO_HTTP_CODE), array(301, 302))) { curl_close($handle); return new XApp_Error('http_request_failed', 'Too many redirects.'); } } $response = array(); $response['code'] = curl_getinfo($handle, CURLINFO_HTTP_CODE); $response['message'] = 'no message'; // get_status_header_desc($response['code']); curl_close($handle); if ($r['stream']) { fclose($this->stream_handle); } $response = array('headers' => $theHeaders['headers'], 'body' => null, 'response' => $response, 'cookies' => $theHeaders['cookies'], 'filename' => $r['filename']); // Handle redirects. //if ( false !== ( $redirect_response = XAppHTTP::handle_redirects( $url, $r, $response ) ) ) // return $redirect_response; //if ( true === $r['decompress'] && true === XAppHttp_Encoding::should_decode($theHeaders['headers']) ) // $theBody = XAppHttp_Encoding::decompress( $theBody ); $response['body'] = $theBody; return $response; }