PageRenderTime 38ms CodeModel.GetById 9ms RepoModel.GetById 1ms app.codeStats 0ms

/administrator/components/com_virtuemart/helpers/connection.php

https://github.com/srgg6701/auction-ruseasons
PHP | 335 lines | 224 code | 25 blank | 86 comment | 73 complexity | 87b35aaf4149108eda1aa03ddaba95ea MD5 | raw file
Possible License(s): GPL-2.0, LGPL-3.0, LGPL-2.1, BSD-3-Clause, JSON
  1. <?php
  2. if( !defined( '_JEXEC' ) ) die( 'Direct Access to '.basename(__FILE__).' is not allowed.' );
  3. /**
  4. *
  5. * @version $Id:connection.php 431 2006-10-17 21:55:46 +0200 (Di, 17 Okt 2006) soeren_nb $
  6. * @package VirtueMart
  7. * @subpackage classes
  8. * @copyright Copyright (C) 2004-2007 soeren, 2009-2011 VirtueMart Team. All rights reserved.
  9. * @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.php
  10. * VirtueMart is free software. This version may have been modified pursuant
  11. * to the GNU General Public License, and as distributed it includes or
  12. * is derivative of works licensed under the GNU General Public License or
  13. * other free or open source software licenses.
  14. * See /administrator/components/com_virtuemart/COPYRIGHT.php for copyright notices and details.
  15. *
  16. * http://virtuemart.org
  17. */
  18. /**
  19. * Provides general tools to handle connections (http, headers, ... )
  20. *
  21. * @author soeren
  22. * @since VirtueMart 1.1.0
  23. */
  24. class VmConnector {
  25. var $handle = null;
  26. /**
  27. * Clears the output buffer, sends a http status code and a content if given
  28. * @static
  29. * @param int $http_status
  30. * @param string $mime_type
  31. * @param string $content
  32. */
  33. function sendHeaderAndContent( $http_status=200, $content='', $mime_type='text/html' ) {
  34. // Clear all Joomla header and buffer stuff
  35. while( @ob_end_clean() );
  36. $http_status = intval( $http_status );
  37. @header("HTTP/1.0 $http_status");
  38. if( $mime_type ) {
  39. @header( "Content-type: $mime_type; charset=".vmGetCharset() );
  40. } elseif( $mime_type != '' ) {
  41. @header( "Content-type: text/html; charset=".vmGetCharset() );
  42. }
  43. if( $content ) {
  44. echo $content;
  45. }
  46. }
  47. /**
  48. * This is a general function to safely open a connection to a server,
  49. * post data when needed and read the result.
  50. * Tries using cURL and switches to fopen/fsockopen if cURL is not available
  51. * @since VirtueMart 1.1.0
  52. * @static
  53. * @param string $url
  54. * @param string $postData
  55. * @param array $headers
  56. * @param resource $fileToSaveData
  57. * @return mixed
  58. */
  59. static function handleCommunication( $url, $postData='', $headers=array(), $fileToSaveData=null ) {
  60. $urlParts = parse_url( $url );
  61. if( !isset( $urlParts['port'] )) $urlParts['port'] = 80;
  62. if( !isset( $urlParts['scheme'] )) $urlParts['scheme'] = 'http';
  63. if( isset( $urlParts['query'] )){
  64. $urlParts['query'] = '?'.$urlParts['query'];
  65. if( isset( $urlParts['path'] )) $urlParts['path'] = $urlParts['path'].$urlParts['query'];
  66. }
  67. $vm_proxy_url = VmConfig::get('conf_VM_PROXY_URL','');
  68. // Check proxy
  69. if( trim( $vm_proxy_url ) != '') {
  70. if( !stristr($vm_proxy_url, 'http')) {
  71. $proxyURL['host'] = $vm_proxy_url;
  72. $proxyURL['scheme'] = 'http';
  73. } else {
  74. $proxyURL = parse_url($vm_proxy_url);
  75. }
  76. }
  77. else {
  78. $proxyURL = '';
  79. }
  80. if( function_exists( "curl_init" ) && function_exists( 'curl_exec' ) ) {
  81. $CR = curl_init();
  82. curl_setopt($CR, CURLOPT_URL, $url);
  83. // just to get sure the script doesn't die
  84. curl_setopt($CR, CURLOPT_TIMEOUT, 30 );
  85. if( !empty( $headers )) {
  86. // Add additional headers if provided
  87. curl_setopt($CR, CURLOPT_HTTPHEADER, $headers);
  88. }
  89. curl_setopt($CR, CURLOPT_FAILONERROR, true);
  90. if( $postData ) {
  91. curl_setopt($CR, CURLOPT_POSTFIELDS, $postData );
  92. curl_setopt($CR, CURLOPT_POST, 1);
  93. }
  94. if( is_resource($fileToSaveData)) {
  95. curl_setopt($CR, CURLOPT_FILE, $fileToSaveData );
  96. } else {
  97. curl_setopt($CR, CURLOPT_RETURNTRANSFER, 1);
  98. }
  99. // Do we need to set up the proxy?
  100. if( !empty($proxyURL) ) {
  101. // $vmLogger->debug( 'Setting up proxy: '.$proxyURL['host'].':'.VM_PROXY_PORT );
  102. //curl_setopt($CR, CURLOPT_HTTPPROXYTUNNEL, true);
  103. curl_setopt($CR, CURLOPT_PROXY, $proxyURL['host'] );
  104. curl_setopt($CR, CURLOPT_PROXYPORT, VM_PROXY_PORT );
  105. // Check if the proxy needs authentication
  106. if( trim( @VM_PROXY_USER ) != '') {
  107. // $vmLogger->debug( 'Using proxy authentication!' );
  108. curl_setopt($CR, CURLOPT_PROXYUSERPWD, VM_PROXY_USER.':'.VM_PROXY_PASS );
  109. }
  110. }
  111. if( $urlParts['scheme'] == 'https') {
  112. // No PEER certificate validation...as we don't have
  113. // a certificate file for it to authenticate the host www.ups.com against!
  114. curl_setopt($CR, CURLOPT_SSL_VERIFYPEER, 0);
  115. //curl_setopt($CR, CURLOPT_SSLCERT , "/usr/locale/xxxx/clientcertificate.pem");
  116. }
  117. $result = curl_exec( $CR );
  118. $error = curl_error( $CR );
  119. if( !empty( $error ) && stristr( $error, '502') && !empty( $proxyURL )) {
  120. // $vmLogger->debug( 'Switching to NTLM authenticaton.');
  121. curl_setopt( $CR, CURLOPT_PROXYAUTH, CURLAUTH_NTLM );
  122. $result = curl_exec( $CR );
  123. $error = curl_error( $CR );
  124. }
  125. curl_close( $CR );
  126. if( !empty( $error )) {
  127. //JError::raiseError(1, $error );
  128. return false;
  129. } else {
  130. return $result;
  131. }
  132. } else {
  133. if( $postData ) {
  134. if( !empty( $proxyURL )) {
  135. // If we have something to post we need to write into a socket
  136. if( $proxyURL['scheme'] == 'https') {
  137. $protocol = 'ssl';
  138. }
  139. else {
  140. $protocol = 'http';
  141. }
  142. $fp = fsockopen("$protocol://".$proxyURL['host'], VM_PROXY_PORT, $errno, $errstr, $timeout = 30);
  143. }
  144. else {
  145. // If we have something to post we need to write into a socket
  146. if( $urlParts['scheme'] == 'https') {
  147. $protocol = 'ssl';
  148. }
  149. else {
  150. $protocol = $urlParts['scheme'];
  151. }
  152. $fp = fsockopen("$protocol://".$urlParts['host'], $urlParts['port'], $errno, $errstr, $timeout = 30);
  153. }
  154. } else {
  155. if( !empty( $proxyURL )) {
  156. // Do a read-only fopen transaction
  157. $fp = fopen( $proxyURL['scheme'].'://'.$proxyURL['host'].':'.VM_PROXY_PORT, 'rb' );
  158. }
  159. else {
  160. // Do a read-only fopen transaction
  161. $fp = fopen( $urlParts['scheme'].'://'.$urlParts['host'].':'.$urlParts['port'].$urlParts['path'], 'rb' );
  162. }
  163. }
  164. if(!$fp) {
  165. //error tell us
  166. JError::raiseWarning(1, 'Possible server error! - '.$errstr .'('.$errno.')\n' );
  167. return false;
  168. }
  169. else {
  170. //Would be interesting to set this only for debug
  171. // JError::raiseNotice(1, 'Connection opened to '.$urlParts['host']);
  172. }
  173. if( $postData ) {
  174. // $vmLogger->debug('Now posting the variables.' );
  175. //send the server request
  176. if( !empty( $proxyURL )) {
  177. fputs($fp, "POST ".$urlParts['host'].':'.$urlParts['port'].$urlParts['path']." HTTP/1.0\r\n");
  178. fputs($fp, "Host: ".$proxyURL['host']."\r\n");
  179. if( trim( @VM_PROXY_USER )!= '') {
  180. fputs($fp, "Proxy-Authorization: Basic " . base64_encode (VM_PROXY_USER.':'.VM_PROXY_PASS ) . "\r\n\r\n");
  181. }
  182. }
  183. else {
  184. fputs($fp, 'POST '.$urlParts['path']." HTTP/1.0\r\n");
  185. fputs($fp, 'Host:'. $urlParts['host']."\r\n");
  186. }
  187. fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n");
  188. fputs($fp, "Content-length: ".strlen($postData)."\r\n");
  189. fputs($fp, "Connection: close\r\n\r\n");
  190. fputs($fp, $postData . "\r\n\r\n");
  191. } else {
  192. if( !empty( $proxyURL )) {
  193. fputs($fp, "GET ".$urlParts['host'].':'.$urlParts['port'].$urlParts['path']." HTTP/1.0\r\n");
  194. fputs($fp, "Host: ".$proxyURL['host']."\r\n");
  195. if( trim( @VM_PROXY_USER )!= '') {
  196. fputs($fp, "Proxy-Authorization: Basic " . base64_encode (VM_PROXY_USER.':'.VM_PROXY_PASS ) . "\r\n\r\n");
  197. }
  198. }
  199. else {
  200. // JError::raiseNotice(1, 'Host:'. $urlParts['host'].' path: '. $urlParts['path'] );
  201. fputs($fp, 'GET '.$urlParts['path']." HTTP/1.0\r\n");
  202. fputs($fp, 'Host:'. $urlParts['host']."\r\n");
  203. }
  204. }
  205. // Add additional headers if provided
  206. foreach( $headers as $header ) {
  207. fputs($fp, $header."\r\n");
  208. }
  209. $data = "";
  210. while (!feof($fp)) {
  211. $data .= @fgets ($fp, 4096);
  212. }
  213. fclose( $fp );
  214. // If didnt get content-lenght, something is wrong, return false.
  215. if ( trim($data) == '' ) {
  216. JError::raiseWarning(E_WARNING,'An error occured while communicating with the server '.$urlParts['host'].'. It didn\'t reply (correctly). Please try again later, thank you.' );
  217. return false;
  218. }
  219. $result = trim( $data );
  220. if( is_resource($fileToSaveData )) {
  221. fwrite($fileToSaveData, $result );
  222. return true;
  223. } else {
  224. return $result;
  225. }
  226. }
  227. }
  228. /**
  229. * Set headers and send the file to the client
  230. *
  231. * @author Andreas Gohr <andi@splitbrain.org>
  232. * @param string The full path to the file
  233. * @param string The Mime Type of the file
  234. */
  235. function sendFile($file,$mime, $overrideFileName='') {
  236. // send headers
  237. header("Content-Type: $mime");
  238. list($start,$len) = VmConnector::http_rangeRequest(filesize($file));
  239. header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
  240. header('Pragma: public');
  241. header('Accept-Ranges: bytes');
  242. //application mime type is downloadable
  243. if(strtolower(substr($mime,0,11)) == 'application') {
  244. if( $overrideFileName == '') {
  245. $filename = basename($file);
  246. } else {
  247. $filename = $overrideFileName;
  248. }
  249. header('Content-Disposition: attachment; filename="'.$filename.'";');
  250. }
  251. $chunksize = 1*(1024*1024);
  252. // send file contents
  253. $fp = @fopen($file,"rb");
  254. if($fp) {
  255. fseek($fp,$start); //seek to start of range
  256. $chunk = ($len > $chunksize) ? $chunksize : $len;
  257. while (!feof($fp) && $chunk > 0) {
  258. @set_time_limit(); // large files can take a lot of time
  259. print fread($fp, $chunk);
  260. flush();
  261. $len -= $chunk;
  262. $chunk = ($len > $chunksize) ? $chunksize : $len;
  263. }
  264. fclose($fp);
  265. }else {
  266. header("HTTP/1.0 500 Internal Server Error");
  267. print "Could not read $file - bad permissions?";
  268. JFactory::getApplication()->close(true);
  269. }
  270. }
  271. /**
  272. * Checks and sets headers to handle range requets
  273. *
  274. * @author Andreas Gohr <andi@splitbrain.org>
  275. * @return array The start byte and the amount of bytes to send
  276. * @param int The file size
  277. */
  278. function http_rangeRequest($size, $exitOnError=true ) {
  279. if(!isset($_SERVER['HTTP_RANGE'])) {
  280. // no range requested - send the whole file
  281. header("Content-Length: $size");
  282. return array(0,$size);
  283. }
  284. $t = explode('=', $_SERVER['HTTP_RANGE']);
  285. if (!$t[0]=='bytes') {
  286. // we only understand byte ranges - send the whole file
  287. header("Content-Length: $size");
  288. return array(0,$size);
  289. }
  290. $r = explode('-', $t[1]);
  291. $start = (int)$r[0];
  292. $end = (int)$r[1];
  293. if (!$end) $end = $size - 1;
  294. if ($start > $end || $start > $size || $end > $size) {
  295. if( $exitOnError ) {
  296. header('HTTP/1.1 416 Requested Range Not Satisfiable');
  297. print 'Bad Range Request!';
  298. JFactory::getApplication()->close(true);
  299. } else {
  300. return array(0,$size);
  301. }
  302. }
  303. $tot = $end - $start + 1;
  304. header('HTTP/1.1 206 Partial Content');
  305. header("Content-Range: bytes {$start}-{$end}/{$size}");
  306. header("Content-Length: $tot");
  307. return array($start,$tot);
  308. }
  309. }
  310. // pure php no closing tag