diff --git a/composer.json b/composer.json index 657b2ea0..46c7356b 100755 --- a/composer.json +++ b/composer.json @@ -6,7 +6,7 @@ "description" : "FTP protocol support for the XP Framework", "keywords": ["module", "xp"], "require" : { - "xp-framework/core": "^12.0 | ^11.0 | ^10.0", + "xp-framework/core": "^12.11 | ^11.11", "xp-framework/logging": "^11.0 | ^10.0 | ^9.1", "xp-framework/networking": "^11.0 | ^10.0 | ^9.3", "xp-framework/io-collections": "^10.0 | ^9.0 | ^8.0", diff --git a/src/main/php/peer/ftp/FtpConnection.class.php b/src/main/php/peer/ftp/FtpConnection.class.php index 07774f4f..37137ed1 100755 --- a/src/main/php/peer/ftp/FtpConnection.class.php +++ b/src/main/php/peer/ftp/FtpConnection.class.php @@ -268,7 +268,7 @@ public function expect($r, $codes) { * @param string name the directory's name * @param string options default NULL * @return string[] list or NULL if nothing can be found - * @throws io.IOException + * @throws io.OperationFailed */ public function listingOf($name, $options= null) { with ($transfer= $this->transferSocket()); { @@ -293,7 +293,7 @@ public function listingOf($name, $options= null) { } } else { // Unexpected response $transfer->close(); - throw new \io\IOException('Listing '.$this->name.$name.' failed ('.$code.': '.$message.')'); + throw new \io\OperationFailed('Listing '.$this->name.$name.' failed ('.$code.': '.$message.')'); } } } diff --git a/src/main/php/peer/ftp/FtpDir.class.php b/src/main/php/peer/ftp/FtpDir.class.php index 0d7cb74f..0a26e02d 100755 --- a/src/main/php/peer/ftp/FtpDir.class.php +++ b/src/main/php/peer/ftp/FtpDir.class.php @@ -1,6 +1,6 @@ connection->listingOf($this->name, '-al'))) { - throw new IOException('Cannot list "'.$this->name.'"'); + throw new OperationFailed('Cannot list "'.$this->name.'"'); } return new FtpEntryList($list, $this->connection, $this->name); @@ -46,7 +46,7 @@ public function entries() { /** * Delete this entry * - * @throws io.IOException in case of an I/O error + * @throws io.OperationFailed in case of an I/O error */ public function delete() { $this->connection->expect($this->connection->sendCommand('RMD %s', $this->name), [250]); @@ -57,7 +57,7 @@ public function delete() { * * @param string name * @return peer.ftp.FtpEntry entry or NULL if nothing was found - * @throws io.IOException in case listing fails + * @throws io.OperationFailed in case listing fails * @throws peer.ProtocolException in case listing yields an unexpected result */ protected function findEntry($name) { @@ -110,12 +110,12 @@ public function hasFile($name) { * * @param string name * @return peer.ftp.FtpFile the instance - * @throws io.FileNotFoundException in case the file was not found + * @throws io.NotFound in case the file was not found * @throws lang.IllegalStateException in case the file exists but is a directory */ public function getFile($name) { if (!($e= $this->findEntry($name))) { - throw new FileNotFoundException('File "'.$name.'" not found'); + throw new NotFound('File "'.$name.'" not found'); } else if ($e instanceof FtpDir) { throw new \lang\IllegalStateException('File "'.$name.'" is a directory'); } @@ -180,12 +180,12 @@ public function hasDir($name) { * * @param string name * @return peer.ftp.FtpDir the instance - * @throws io.FileNotFoundException in case the directory was not found + * @throws io.NotFound in case the directory was not found * @throws lang.IllegalStateException in case the directory exists but is a file */ public function getDir($name) { if (!($e= $this->findEntry($name))) { - throw new FileNotFoundException('Directory "'.$name.'" not found'); + throw new NotFound('Directory "'.$name.'" not found'); } else if ($e instanceof FtpFile) { throw new \lang\IllegalStateException('Directory "'.$name.'" is a file'); } @@ -196,7 +196,7 @@ public function getDir($name) { * Create a new directory * * @param string name - * @throws io.IOException if directory cannot be created + * @throws io.OperationFailed if directory cannot be created * @throws peer.ProtocolException in case the created directory cannot be located or is a file */ protected function makeDir($name) { @@ -217,7 +217,7 @@ protected function makeDir($name) { * @param string name * @return peer.ftp.FtpDir the created instance * @throws lang.IllegalStateException in case the directory already exists - * @throws io.IOException in case the directory could not be created + * @throws io.OperationFailed in case the directory could not be created */ public function newDir($name) { if ($e= $this->findEntry($name)) { @@ -238,7 +238,7 @@ public function newDir($name) { * @param string name * @return peer.ftp.FtpDir the instance * @throws lang.IllegalStateException in case the directory exists and is a file - * @throws io.IOException in case the directory could not be created + * @throws io.OperationFailed in case the directory could not be created */ public function dir($name) { if (!($e= $this->findEntry($name))) { diff --git a/src/main/php/peer/ftp/FtpDownload.class.php b/src/main/php/peer/ftp/FtpDownload.class.php index c118d2bb..00573795 100755 --- a/src/main/php/peer/ftp/FtpDownload.class.php +++ b/src/main/php/peer/ftp/FtpDownload.class.php @@ -66,7 +66,7 @@ public function size() { protected function doTransfer() { try { $chunk= $this->socket->readBinary(); - } catch (\io\IOException $e) { + } catch (\io\OperationFailed $e) { $this->listener && $this->listener->failed($this, $e); $this->close(); throw $e; @@ -81,7 +81,7 @@ protected function doTransfer() { try { $this->out->write($chunk); - } catch (\io\IOException $e) { + } catch (\io\OperationFailed $e) { $this->listener && $this->listener->failed($this, $e); $this->close(); throw $e; diff --git a/src/main/php/peer/ftp/FtpEntry.class.php b/src/main/php/peer/ftp/FtpEntry.class.php index c76e1ee8..f522919b 100755 --- a/src/main/php/peer/ftp/FtpEntry.class.php +++ b/src/main/php/peer/ftp/FtpEntry.class.php @@ -45,7 +45,7 @@ public function getConnection() { return $this->connection; } * Checks whether this entry exists. * * @return bool TRUE if the file exists, FALSE otherwise - * @throws io.IOException in case of an I/O error + * @throws io.OperationFailed in case of an I/O error */ public function exists() { $r= $this->connection->sendCommand('SIZE %s', $this->name); @@ -73,7 +73,7 @@ public function exists() { * * * @param string to the new name - * @throws io.IOException in case of an I/O error + * @throws io.OperationFailed in case of an I/O error */ public function rename($to) { $target= ('/' === $to[0] ? $to : dirname($this->name).'/'.$to); @@ -81,7 +81,7 @@ public function rename($to) { $this->connection->expect($this->connection->sendCommand('RNFR %s', $this->name), [350]); $this->connection->expect($this->connection->sendCommand('RNTO %s', $target), [250]); } catch (\peer\ProtocolException $e) { - throw new \io\IOException('Could not rename '.$this->name.' to '.$to.': '.$e->getMessage()); + throw new \io\OperationFailed('Could not rename '.$this->name.' to '.$to.': '.$e->getMessage()); } } @@ -90,7 +90,7 @@ public function rename($to) { * * @param peer.ftp.FtpDir to the new location * @param string name default NULL the new name - if omitted, will stay the same - * @throws io.IOException in case of an I/O error + * @throws io.OperationFailed in case of an I/O error */ public function moveTo(FtpDir $to, $name= null) { try { @@ -101,7 +101,7 @@ public function moveTo(FtpDir $to, $name= null) { $name ? $name : basename($this->name) ), [250]); } catch (\peer\ProtocolException $e) { - throw new \io\IOException('Could not rename '.$this->name.' to '.$to->getName().': '.$e->getMessage()); + throw new \io\OperationFailed('Could not rename '.$this->name.' to '.$to->getName().': '.$e->getMessage()); } } @@ -109,7 +109,7 @@ public function moveTo(FtpDir $to, $name= null) { * Change this entry's permissions * * @param int to the new permissions - * @throws io.IOException in case of an I/O error + * @throws io.OperationFailed in case of an I/O error */ public function changePermissions($to) { $this->connection->expect($this->connection->sendCommand('SITE CHMOD %s %d', $this->name, $to)); @@ -118,7 +118,7 @@ public function changePermissions($to) { /** * Delete this entry * - * @throws io.IOException in case of an I/O error + * @throws io.OperationFailed in case of an I/O error */ public abstract function delete(); @@ -253,7 +253,7 @@ public function getDate() { * Get last modified date. Uses the "MDTM" command internally. * * @return util.Date or NULL if the server does not support this - * @throws io.IOException in case the connection is closed + * @throws io.OperationFailed in case the connection is closed */ public function lastModified() { $r= $this->connection->sendCommand('MDTM %s', $this->name); diff --git a/src/main/php/peer/ftp/FtpFile.class.php b/src/main/php/peer/ftp/FtpFile.class.php index 17f01331..c6497b49 100755 --- a/src/main/php/peer/ftp/FtpFile.class.php +++ b/src/main/php/peer/ftp/FtpFile.class.php @@ -15,7 +15,7 @@ public function isFile(): bool { return true; } /** * Delete this entry * - * @throws io.IOException in case of an I/O error + * @throws io.OperationFailed in case of an I/O error */ public function delete() { $this->connection->expect($this->connection->sendCommand('DELE %s', $this->name), [250]); diff --git a/src/main/php/peer/ftp/FtpUpload.class.php b/src/main/php/peer/ftp/FtpUpload.class.php index 443bab81..19d53e01 100755 --- a/src/main/php/peer/ftp/FtpUpload.class.php +++ b/src/main/php/peer/ftp/FtpUpload.class.php @@ -1,7 +1,7 @@ in->read(8192); $this->socket->write($chunk); - } catch (IOException $e) { + } catch (OperationFailed $e) { $this->listener && $this->listener->failed($this, $e); $this->close(); throw $e; diff --git a/src/main/php/peer/ftp/collections/FtpCollection.class.php b/src/main/php/peer/ftp/collections/FtpCollection.class.php index 10d71a6e..c77a2790 100755 --- a/src/main/php/peer/ftp/collections/FtpCollection.class.php +++ b/src/main/php/peer/ftp/collections/FtpCollection.class.php @@ -171,19 +171,19 @@ public function setOrigin(IOCollection $origin) { * Gets input stream to read from this element * * @return io.streams.InputStream - * @throws io.IOException + * @throws io.OperationFailed */ public function getInputStream() { - throw new \io\IOException('Cannot read from a directory'); + throw new \io\OperationFailed('Cannot read from a directory'); } /** * Gets output stream to read from this element * * @return io.streams.OutputStream - * @throws io.IOException + * @throws io.OperationFailed */ public function getOutputStream() { - throw new \io\IOException('Cannot write to a directory'); + throw new \io\OperationFailed('Cannot write to a directory'); } } \ No newline at end of file diff --git a/src/main/php/peer/ftp/collections/FtpElement.class.php b/src/main/php/peer/ftp/collections/FtpElement.class.php index 13f41e20..0e88902b 100755 --- a/src/main/php/peer/ftp/collections/FtpElement.class.php +++ b/src/main/php/peer/ftp/collections/FtpElement.class.php @@ -109,7 +109,7 @@ public function setOrigin(\io\collections\IOCollection $origin) { * Gets input stream to read from this element * * @return io.streams.InputStream - * @throws io.IOException + * @throws io.OperationFailed */ public function getInputStream() { return new FtpInputStream($this->file); @@ -119,7 +119,7 @@ public function getInputStream() { * Gets output stream to read from this element * * @return io.streams.OutputStream - * @throws io.IOException + * @throws io.OperationFailed */ public function getOutputStream() { return new FtpOutputStream($this->file); diff --git a/src/main/php/peer/ftp/server/FtpProtocol.class.php b/src/main/php/peer/ftp/server/FtpProtocol.class.php index 2e10acec..914eddba 100755 --- a/src/main/php/peer/ftp/server/FtpProtocol.class.php +++ b/src/main/php/peer/ftp/server/FtpProtocol.class.php @@ -152,7 +152,7 @@ public function eol($type) { * @param string text * @param array lines default NULL lines of a multiline response * @return int number of bytes written - * @throws io.IOException + * @throws io.OperationFailed */ public function answer($sock, $code, $text, $lines= null) { if (is_array($lines)) { @@ -745,7 +745,7 @@ public function onDele($socket, $params) { try { $entry->delete(); - } catch (\io\IOException $e) { + } catch (\io\OperationFailed $e) { $this->answer($socket, 450, $params.': ', $e->getMessage()); return; } @@ -927,7 +927,7 @@ public function onPasv($socket, $params) { $this->datasock[$key]->create(); $this->datasock[$key]->bind(); $this->datasock[$key]->listen(); - } catch (\io\IOException $e) { + } catch (\io\OperationFailed $e) { $this->answer($socket, 425, 'Cannot open passive connection '.$e->getMessage()); unset($this->datasock[$key]); return; diff --git a/src/main/php/peer/ftp/server/storage/FilesystemStorage.class.php b/src/main/php/peer/ftp/server/storage/FilesystemStorage.class.php index 1639e40d..d63bb910 100755 --- a/src/main/php/peer/ftp/server/storage/FilesystemStorage.class.php +++ b/src/main/php/peer/ftp/server/storage/FilesystemStorage.class.php @@ -74,7 +74,7 @@ public function realname($clientId, $uri) { */ public function setBase($clientId, $uri= null) { if (!is_dir($path= $this->realname($clientId, $uri))) { - throw new \io\IOException($uri.': not a directory'); + throw new \io\OperationFailed($uri.': not a directory'); } $this->base[$clientId]= DIRECTORY_SEPARATOR.ltrim( str_replace($this->root, '', $path), @@ -134,13 +134,13 @@ public function create($clientId, $uri, $type) { switch ($type) { case ST_ELEMENT: if (false === touch($path)) { - throw new \io\IOException('File '.$path.' could not be created'); + throw new \io\OperationFailed('File '.$path.' could not be created'); } break; case ST_COLLECTION: if (false === mkdir($path)) { - throw new \io\IOException($path.' could not be created'); + throw new \io\OperationFailed($path.' could not be created'); } break; } diff --git a/src/test/php/peer/ftp/unittest/IntegrationTest.class.php b/src/test/php/peer/ftp/unittest/IntegrationTest.class.php index 6396f613..8a132471 100755 --- a/src/test/php/peer/ftp/unittest/IntegrationTest.class.php +++ b/src/test/php/peer/ftp/unittest/IntegrationTest.class.php @@ -1,7 +1,7 @@ rootDir()->hasDir(':DOES_NOT_EXIST')); } - #[Test, Expect(FileNotFoundException::class)] + #[Test, Expect(NotFound::class)] public function getNonExistantDir() { $conn= $this->connection()->connect(); $conn->rootDir()->getDir(':DOES_NOT_EXIST'); @@ -207,7 +207,7 @@ public function nonExistantFile() { Assert::false($conn->rootDir()->getDir('htdocs')->hasFile(':DOES_NOT_EXIST')); } - #[Test, Expect(FileNotFoundException::class)] + #[Test, Expect(NotFound::class)] public function getNonExistantFile() { $conn= $this->connection()->connect(); $conn->rootDir()->getDir('htdocs')->getFile(':DOES_NOT_EXIST'); @@ -329,7 +329,7 @@ public function consecutive_inputstream_reads() { try { $s= $dir->getFile('index.html')->in(); Assert::equals("\n", Streams::readAll($s)); - } catch (IOException $e) { + } catch (OperationFailed $e) { $this->fail('Round '.($i + 1), $e, null); } }