|
1 | | -<!DOCTYPE html> |
| 1 | +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> |
2 | 2 | <html> |
3 | | - <head> |
4 | | - |
5 | | - </head> |
6 | | - <body> |
7 | | - <print>Hello, World!</print> |
8 | | - </body> |
| 3 | +<head> |
| 4 | + <title>HTML2Canvas PHP Proxy</title> |
| 5 | +</head> |
| 6 | +<body> |
| 7 | + <?php |
| 8 | + /* |
| 9 | + * html2canvas-php-proxy 1.1.4 |
| 10 | + * |
| 11 | + * Copyright (c) 2020 Guilherme Nascimento (brcontainer@yahoo.com.br) |
| 12 | + * |
| 13 | + * Released under the MIT license |
| 14 | + */ |
| 15 | + |
| 16 | + // Turn off errors because the script already own uses "error_get_last" |
| 17 | + ini_set('display_errors', 'Off'); |
| 18 | + |
| 19 | + // Setup |
| 20 | + define('H2CP_PATH', 'cache'); // Relative folder where the images are saved |
| 21 | + define('H2CP_PERMISSION', 0666); // use 644 or 666 for remove execution for prevent sploits |
| 22 | + define('H2CP_CACHE', 60 * 5 * 1000); // Limit access-control and cache, define 0/false/null/-1 to prevent cache |
| 23 | + define('H2CP_TIMEOUT', 20); // Timeout from load Socket |
| 24 | + define('H2CP_MAX_LOOP', 10); // Configure loop limit for redirects (location header) |
| 25 | + define('H2CP_DATAURI', false); // Enable use of "data URI scheme" |
| 26 | + define('H2CP_PREFER_CURL', true); // Enable curl if avaliable or disable |
| 27 | + define('H2CP_SECPREFIX', 'h2cp_'); // Prefix temp filename |
| 28 | + define('H2CP_ALLOWED_DOMAINS', '*'); // * allow all domains, *.site.com for sub-domains, or fixed domains use `define('H2CP_ALLOWED_DOMAINS', 'site.com,www.site.com' ) |
| 29 | + define('H2CP_ALLOWED_PORTS', '80,443'); // Allowed ports |
| 30 | + define('H2CP_ALTERNATIVE', 'console.log'); // callback alternative |
| 31 | + |
| 32 | + /* |
| 33 | + * Set false for disable SSL check |
| 34 | + * Set true for enable SSL check, require config `curl.cainfo=/path/to/cacert.pem` in php.ini |
| 35 | + * Set path (string) if need config CAINFO manually like this define('H2CP_SSL_VERIFY_PEER', '/path/to/cacert.pem'); |
| 36 | + */ |
| 37 | + define('H2CP_SSL_VERIFY_PEER', false); |
| 38 | + |
| 39 | + // Constants (don't change) |
| 40 | + define('H2CP_EOL', chr(10)); |
| 41 | + define('H2CP_GMDATECACHE', gmdate('D, d M Y H:i:s')); |
| 42 | + define('H2CP_INIT_EXEC', time()); |
| 43 | + |
| 44 | + if (empty($_GET['callback'])) { |
| 45 | + $callback = false; |
| 46 | + } else { |
| 47 | + $callback = $_GET['callback']; |
| 48 | + } |
| 49 | + |
| 50 | + /* |
| 51 | + If execution has reached the time limit prevents page goes blank (off errors) |
| 52 | + or generate an error in PHP, which does not work with the DEBUG (from html2canvas.js) |
| 53 | + */ |
| 54 | + $maxExec = (int) ini_get('max_execution_time'); |
| 55 | + define('H2CP_MAX_EXEC', $maxExec < 1 ? 0 : ($maxExec - 5));//reduces 5 seconds to ensure the execution of the DEBUG |
| 56 | + |
| 57 | + $http_port = 0; |
| 58 | + |
| 59 | + $tmp = null;//tmp var usage |
| 60 | + $response = array(); |
| 61 | + |
| 62 | + // The rest of the PHP script goes here... |
| 63 | + // Functions: asciiToInline, supportSSL, removeOldFiles, checkContentType, JsonEncodeString, setHeaders, relativeToAbsolute, isHttpUrl, isAllowedUrl, createFolder, createTmpFile, curlDownloadSource, downloadSource |
| 64 | + |
| 65 | + // Additional PHP code |
| 66 | + if (empty($_SERVER['HTTP_HOST'])) { |
| 67 | + $response = array('error' => 'The client did not send the Host header'); |
| 68 | + } elseif (empty($_SERVER['SERVER_PORT'])) { |
| 69 | + $response = array('error' => 'The Server-proxy did not send the PORT (configure PHP)'); |
| 70 | + } elseif (H2CP_MAX_EXEC < 10) { |
| 71 | + $response = array('error' => 'Execution time is less 15 seconds, configure this with ini_set/set_time_limit or "php.ini" (if safe_mode is enabled), recommended time is 30 seconds or more'); |
| 72 | + } elseif (H2CP_MAX_EXEC <= H2CP_TIMEOUT) { |
| 73 | + $response = array('error' => 'The execution time is not configured enough to TIMEOUT in SOCKET, configure this with ini_set/set_time_limit or "php.ini" (if safe_mode is enabled), recommended that the "max_execution_time =;" be a minimum of 5 seconds longer or reduce the TIMEOUT in "define(\'H2CP_TIMEOUT\', ' . H2CP_TIMEOUT . ');"'); |
| 74 | + } elseif (empty($_GET['url'])) { |
| 75 | + $response = array('error' => 'No such parameter "url"'); |
| 76 | + } elseif (isHttpUrl($_GET['url']) === false) { |
| 77 | + $response = array('error' => 'Only http scheme and https scheme are allowed'); |
| 78 | + } elseif (isAllowedUrl($_GET['url'], $message) === false) { |
| 79 | + $response = array('error' => $message); |
| 80 | + } elseif (createFolder() === false) { |
| 81 | + $err = error_get_last(); |
| 82 | + $response = array('error' => 'Can not create directory'. ( |
| 83 | + $err !== null && empty($err['message']) ? '' : (': ' . $err['message']) |
| 84 | + )); |
| 85 | + $err = null; |
| 86 | + } else { |
| 87 | + $http_port = (int) $_SERVER['SERVER_PORT']; |
| 88 | + |
| 89 | + $tmp = createTmpFile($_GET['url'], false); |
| 90 | + |
| 91 | + if ($tmp === false) { |
| 92 | + $err = error_get_last(); |
| 93 | + $response = array('error' => 'Can not create file'. ( |
| 94 | + $err !== null && empty($err['message']) ? '' : (': ' . $err['message']) |
| 95 | + )); |
| 96 | + $err = null; |
| 97 | + } elseif (H2CP_PREFER_CURL && function_exists('curl_init')) { |
| 98 | + $response = curlDownloadSource($_GET['url'], $tmp['source']); |
| 99 | + } else { |
| 100 | + $response = downloadSource($_GET['url'], $tmp['source'], 0); |
| 101 | + } |
| 102 | + |
| 103 | + if ($tmp) fclose($tmp['source']); |
| 104 | + } |
| 105 | + |
| 106 | + //set mime-type |
| 107 | + header('Content-Type: application/javascript'); |
| 108 | + |
| 109 | + if (is_array($response) && false === empty($response['mime'])) { |
| 110 | + clearstatcache(); |
| 111 | + |
| 112 | + if (false === file_exists($tmp['location'])) { |
| 113 | + $response = array('error' => 'Request was downloaded, but file can not be found, try again'); |
| 114 | + } elseif (filesize($tmp['location']) < 1) { |
| 115 | + $response = array('error' => 'Request was downloaded, but there was some problem and now the file is empty, try again'); |
| 116 | + } else { |
| 117 | + $extension = str_replace(array('image/', 'text/', 'application/'), '', $response['mime']); |
| 118 | + $extension = str_replace(array('windows-bmp', 'ms-bmp'), 'bmp', $extension); |
| 119 | + $extension = str_replace(array('svg+xml', 'svg-xml'), 'svg', $extension); |
| 120 | + $extension = str_replace('xhtml+xml', 'xhtml', $extension); |
| 121 | + $extension = str_replace('jpeg', 'jpg', $extension); |
| 122 | + |
| 123 | + $locationFile = preg_replace('#[.][0-9_]+$#', '.' . $extension, $tmp['location']); |
| 124 | + |
| 125 | + if (file_exists($locationFile)) { |
| 126 | + unlink($locationFile); |
| 127 | + } |
| 128 | + |
| 129 | + if (rename($tmp['location'], $locationFile)) { |
| 130 | + //set cache |
| 131 | + setHeaders(false); |
| 132 | + |
| 133 | + removeOldFiles(); |
| 134 | + |
| 135 | + $mime = $response['mime']; |
| 136 | + |
| 137 | + if ($response['encode'] !== null) { |
| 138 | + $mime .= ';charset=' . JsonEncodeString($response['encode'], true); |
| 139 | + } |
| 140 | + |
| 141 | + if ($callback === false) { |
| 142 | + header('Content-Type: ' . $mime); |
| 143 | + echo file_get_contents($locationFile); |
| 144 | + } elseif (H2CP_DATAURI) { |
| 145 | + $tmp = $response = null; |
| 146 | + |
| 147 | + header('Content-Type: application/javascript'); |
| 148 | + |
| 149 | + if (strpos($mime, 'image/svg') !== 0 && strpos($mime, 'image/') === 0) { |
| 150 | + echo $callback, '("data:', $mime, ';base64,', |
| 151 | + base64_encode( |
| 152 | + file_get_contents($locationFile) |
| 153 | + ), |
| 154 | + '");'; |
| 155 | + } else { |
| 156 | + echo $callback, '("data:', $mime, ',', |
| 157 | + asciiToInline(file_get_contents($locationFile)), |
| 158 | + '");'; |
| 159 | + } |
| 160 | + } else { |
| 161 | + $tmp = $response = null; |
| 162 | + |
| 163 | + header('Content-Type: application/javascript'); |
| 164 | + |
| 165 | + $dir_name = dirname($_SERVER['SCRIPT_NAME']); |
| 166 | + |
| 167 | + if ($dir_name === '\/' || $dir_name === '\\') { |
| 168 | + $dir_name = ''; |
| 169 | + } |
| 170 | + |
| 171 | + echo $callback, '(', |
| 172 | + JsonEncodeString( |
| 173 | + ($http_port === 443 ? 'https://' : 'http://') . |
| 174 | + preg_replace('#[:]\\d+$#', '', $_SERVER['HTTP_HOST']) . |
| 175 | + ($http_port === 80 || $http_port === 443 ? '' : ( |
| 176 | + ':' . $_SERVER['SERVER_PORT'] |
| 177 | + )) . |
| 178 | + $dir_name. '/' . |
| 179 | + $locationFile |
| 180 | + ), |
| 181 | + ');'; |
| 182 | + } |
| 183 | + exit; |
| 184 | + } else { |
| 185 | + $response = array('error' => 'Failed to rename the temporary file'); |
| 186 | + } |
| 187 | + } |
| 188 | + } |
| 189 | + |
| 190 | + if (is_array($tmp) && isset($tmp['location']) && file_exists($tmp['location'])) { |
| 191 | + // Remove temporary file if an error occurred |
| 192 | + unlink($tmp['location']); |
| 193 | + } |
| 194 | + |
| 195 | + setHeaders(true); // no-cache |
| 196 | + |
| 197 | + header('Content-Type: application/javascript'); |
| 198 | + |
| 199 | + removeOldFiles(); |
| 200 | + |
| 201 | + if ($callback === false) { |
| 202 | + $callback = H2CP_ALTERNATIVE; |
| 203 | + } |
| 204 | + |
| 205 | + echo $callback, '(', |
| 206 | + JsonEncodeString('error: html2canvas-proxy-php: ' . $response['error']), |
| 207 | + ');'; |
| 208 | + ?> |
| 209 | +</body> |
9 | 210 | </html> |
0 commit comments