PageRenderTime 24ms CodeModel.GetById 12ms RepoModel.GetById 1ms app.codeStats 0ms

/Ip/Internal/NetHelper.php

https://gitlab.com/x33n/ImpressPages
PHP | 156 lines | 103 code | 34 blank | 19 comment | 25 complexity | 7b2153f6e6283aef190c458814fed235 MD5 | raw file
  1. <?php
  2. /**
  3. * @package ImpressPages
  4. */
  5. namespace Ip\Internal;
  6. class NetHelper
  7. {
  8. /**
  9. * @var string
  10. */
  11. protected $lastError = null;
  12. public function __construct()
  13. {
  14. }
  15. /**
  16. * @return string
  17. */
  18. public function getLastError()
  19. {
  20. return $this->lastError;
  21. }
  22. public function downloadFile($url, $destinationDir, $desiredFilename, $forceFilename = false)
  23. {
  24. if (!$forceFilename) {
  25. $desiredFilename = \Ip\Internal\File\Functions::genUnoccupiedName($desiredFilename, $destinationDir);
  26. }
  27. if (!function_exists('curl_init')) {
  28. throw new \Exception('CURL is not installed. Cannot download file from URL.');
  29. }
  30. $ch = curl_init();
  31. $fh = fopen($destinationDir . $desiredFilename, 'w');
  32. $options = array(
  33. CURLOPT_FILE => $fh,
  34. CURLOPT_TIMEOUT => 1800, // set this to 30 min so we don't timeout on big files
  35. CURLOPT_URL => $url
  36. );
  37. curl_setopt_array($ch, $options);
  38. if (curl_exec($ch)) {
  39. return $desiredFilename;
  40. } else {
  41. $this->lastError = curl_error($ch);
  42. return false;
  43. }
  44. }
  45. public function fetchUrl($uri)
  46. {
  47. $handle = curl_init();
  48. curl_setopt($handle, CURLOPT_URL, $uri);
  49. curl_setopt($handle, CURLOPT_POST, false);
  50. curl_setopt($handle, CURLOPT_BINARYTRANSFER, false);
  51. curl_setopt($handle, CURLOPT_HEADER, true);
  52. curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
  53. curl_setopt($handle, CURLOPT_CONNECTTIMEOUT, 10);
  54. $response = self::curl_exec_follow($handle);
  55. $headerLength = curl_getinfo($handle, CURLINFO_HEADER_SIZE);
  56. $httpCode = curl_getinfo($handle, CURLINFO_HTTP_CODE);
  57. $body = substr($response, $headerLength);
  58. // If HTTP response is not 200, throw exception
  59. if ($httpCode != 200) {
  60. throw new \Ip\Exception('Could not fetch uri', array('httpCode' => $httpCode));
  61. }
  62. return $body;
  63. }
  64. /**
  65. * @see http://slopjong.de/2012/03/31/curl-follow-locations-with-safe_mode-enabled-or-open_basedir-set/
  66. *
  67. * @param $ch
  68. * @param null $maxredirect
  69. * @return bool|mixed
  70. */
  71. private function curl_exec_follow($ch, &$maxredirect = null)
  72. {
  73. $mr = $maxredirect === null ? 5 : intval($maxredirect);
  74. if (ini_get('open_basedir') == '' && ini_get('safe_mode') == 'Off') {
  75. curl_setopt($ch, CURLOPT_FOLLOWLOCATION, $mr > 0);
  76. curl_setopt($ch, CURLOPT_MAXREDIRS, $mr);
  77. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  78. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  79. } else {
  80. curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
  81. if ($mr > 0) {
  82. $original_url = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
  83. $newurl = $original_url;
  84. $rch = curl_copy_handle($ch);
  85. curl_setopt($rch, CURLOPT_HEADER, true);
  86. curl_setopt($rch, CURLOPT_NOBODY, true);
  87. curl_setopt($rch, CURLOPT_FORBID_REUSE, false);
  88. do {
  89. curl_setopt($rch, CURLOPT_URL, $newurl);
  90. $header = curl_exec($rch);
  91. if (curl_errno($rch)) {
  92. $code = 0;
  93. } else {
  94. $code = curl_getinfo($rch, CURLINFO_HTTP_CODE);
  95. if ($code == 301 || $code == 302) {
  96. preg_match('/Location:(.*?)\n/', $header, $matches);
  97. $newurl = trim(array_pop($matches));
  98. // if no scheme is present then the new url is a
  99. // relative path and thus needs some extra care
  100. if (!preg_match("/^https?:/i", $newurl)) {
  101. $newurl = $original_url . $newurl;
  102. }
  103. } else {
  104. $code = 0;
  105. }
  106. }
  107. } while ($code && --$mr);
  108. curl_close($rch);
  109. if (!$mr) {
  110. if ($maxredirect === null) {
  111. trigger_error('Too many redirects.', E_USER_WARNING);
  112. } else {
  113. $maxredirect = 0;
  114. }
  115. return false;
  116. }
  117. curl_setopt($ch, CURLOPT_URL, $newurl);
  118. }
  119. }
  120. return curl_exec($ch);
  121. }
  122. }