|
7 | 7 | use InvalidArgumentException; |
8 | 8 | use Jeidison\JSignPDF\Sign\JSignParam; |
9 | 9 | use PharData; |
| 10 | +use PharException; |
10 | 11 | use RuntimeException; |
| 12 | +use UnexpectedValueException; |
11 | 13 |
|
12 | 14 | class JavaRuntimeService |
13 | 15 | { |
@@ -74,24 +76,57 @@ private function downloadAndExtract(string $url, string $baseDir): void |
74 | 76 | if (!filter_var($url, FILTER_VALIDATE_URL)) { |
75 | 77 | throw new InvalidArgumentException('The url to download Java is invalid: ' . $url); |
76 | 78 | } |
77 | | - $content = @file_get_contents($url); |
78 | | - if ($content === false) { |
79 | | - throw new InvalidArgumentException("Failute to download file using the url $url, error: " . print_r(error_get_last(), true)); |
| 79 | + $this->chunkDownload($url, $baseDir . '/java.tar.gz'); |
| 80 | + try { |
| 81 | + $tar = new PharData($baseDir . '/java.tar.gz'); |
| 82 | + } catch (PharException|UnexpectedValueException $e) { |
| 83 | + throw new InvalidArgumentException('The file ' . $baseDir . '/java.tar.gz cannot be extracted'); |
80 | 84 | } |
81 | | - if (!$content) { |
82 | | - throw new InvalidArgumentException('The url returned empty content: ' . $url); |
| 85 | + $rootDirInsideTar = $this->findRootDir($tar, $baseDir . '/java.tar.gz'); |
| 86 | + if (!$rootDirInsideTar) { |
| 87 | + throw new InvalidArgumentException('Invalid tar content.'); |
83 | 88 | } |
84 | | - $decompressedContent = @gzdecode($content); |
85 | | - if ($decompressedContent === false) { |
86 | | - throw new InvalidArgumentException('The file downloaded from follow URL cannot be gzdecoded: ' . $url); |
87 | | - } |
88 | | - file_put_contents($baseDir . '/java.tar.gz', $decompressedContent); |
89 | | - $tar = new PharData($baseDir . '/java.tar.gz'); |
90 | | - $tar->extractTo($baseDir, null, true); |
| 89 | + $tar->extractTo(directory: $baseDir, overwrite: true); |
| 90 | + @exec('mv ' . escapeshellarg($baseDir . '/'. $rootDirInsideTar) . '/* ' . escapeshellarg($baseDir)); |
| 91 | + @exec('rm -rf ' . escapeshellarg($baseDir . '/'. $rootDirInsideTar)); |
91 | 92 | unlink($baseDir . '/java.tar.gz'); |
92 | 93 | if (!file_exists($baseDir . '/bin/java')) { |
93 | 94 | throw new RuntimeException('Java binary not found at: ' . $baseDir . '/bin/java'); |
94 | 95 | } |
95 | 96 | chmod($baseDir . '/bin/java', 0700); |
96 | 97 | } |
| 98 | + |
| 99 | + private function findRootDir(PharData $phar, $rootDir) { |
| 100 | + $files = new \RecursiveIteratorIterator($phar, \RecursiveIteratorIterator::CHILD_FIRST); |
| 101 | + |
| 102 | + foreach ($files as $file) { |
| 103 | + $pathName = $file->getPathname(); |
| 104 | + if (str_contains($pathName, '/bin/') || str_contains($pathName, '/bin/')) { |
| 105 | + $parts = explode($rootDir, $pathName); |
| 106 | + $internalFullPath = end($parts); |
| 107 | + $parts = explode('/bin/', $internalFullPath); |
| 108 | + return trim($parts[0], '/'); |
| 109 | + } |
| 110 | + } |
| 111 | + } |
| 112 | + |
| 113 | + private function chunkDownload(string $url, string $destination): void |
| 114 | + { |
| 115 | + $fp = fopen($destination, 'w'); |
| 116 | + |
| 117 | + if ($fp) { |
| 118 | + $ch = curl_init($url); |
| 119 | + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); |
| 120 | + curl_setopt($ch, CURLOPT_FILE, $fp); |
| 121 | + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); |
| 122 | + $response = curl_exec($ch); |
| 123 | + if ($response === false) { |
| 124 | + throw new InvalidArgumentException('Failure to download file using the url ' . $url); |
| 125 | + } |
| 126 | + curl_close($ch); |
| 127 | + fclose($fp); |
| 128 | + } else { |
| 129 | + throw new InvalidArgumentException("Failute to download file using the url $url"); |
| 130 | + } |
| 131 | + } |
97 | 132 | } |
0 commit comments