diff --git a/apps/files_external/lib/sftp.php b/apps/files_external/lib/sftp.php index 5dcc7686ca..f8651727fd 100644 --- a/apps/files_external/lib/sftp.php +++ b/apps/files_external/lib/sftp.php @@ -51,6 +51,27 @@ class SFTP extends \OC\Files\Storage\Common { */ protected $client; + /** + * @param string $host protocol://server:port + * @return array [$server, $port] + */ + private function splitHost($host) { + $input = $host; + if (strpos($host, '://') === false) { + // add a protocol to fix parse_url behavior with ipv6 + $host = 'http://' . $host; + } + + $parsed = parse_url($host); + if(is_array($parsed) && isset($parsed['port'])) { + return [$parsed['host'], $parsed['port']]; + } else if (is_array($parsed)) { + return [$parsed['host'], 22]; + } else { + return [$input, 22]; + } + } + /** * {@inheritdoc} */ @@ -58,21 +79,10 @@ class SFTP extends \OC\Files\Storage\Common { // Register sftp:// Stream::register(); - $this->host = $params['host']; + $parsedHost = $this->splitHost($params['host']); - //deals with sftp://server example - $proto = strpos($this->host, '://'); - if ($proto != false) { - $this->host = substr($this->host, $proto+3); - } - - //deals with server:port - $hasPort = strpos($this->host,':'); - if($hasPort != false) { - $pieces = explode(":", $this->host); - $this->host = $pieces[0]; - $this->port = $pieces[1]; - } + $this->host = $parsedHost[0]; + $this->port = $parsedHost[1]; $this->user = $params['user']; diff --git a/apps/files_external/tests/backends/sftp.php b/apps/files_external/tests/backends/sftp.php index da2c0ac6ba..aaed2b3460 100644 --- a/apps/files_external/tests/backends/sftp.php +++ b/apps/files_external/tests/backends/sftp.php @@ -26,6 +26,11 @@ namespace Test\Files\Storage; class SFTP extends Storage { + /** + * @var \OC\Files\Storage\SFTP instance + */ + protected $instance; + private $config; protected function setUp() { @@ -103,6 +108,39 @@ class SFTP extends Storage { ], 'sftp::someuser@somehost:8822//remotedir/subdir/', ], + [ + // ipv6 with port + [ + 'run' => true, + 'host' => 'FE80:0000:0000:0000:0202:B3FF:FE1E:8329', + 'user' => 'someuser', + 'password' => 'somepassword', + 'root' => 'remotedir/subdir/', + ], + 'sftp::someuser@FE80:0000:0000:0000:0202:B3FF:FE1E:8329//remotedir/subdir/', + ], + [ + // ipv6 without port + [ + 'run' => true, + 'host' => 'FE80:0000:0000:0000:0202:B3FF:FE1E:8329:8822', + 'user' => 'someuser', + 'password' => 'somepassword', + 'root' => 'remotedir/subdir/', + ], + 'sftp::someuser@FE80:0000:0000:0000:0202:B3FF:FE1E:8329:8822//remotedir/subdir/', + ], + [ + // collapsed ipv6 with port + [ + 'run' => true, + 'host' => 'FE80::0202:B3FF:FE1E:8329:8822', + 'user' => 'someuser', + 'password' => 'somepassword', + 'root' => 'remotedir/subdir/', + ], + 'sftp::someuser@FE80::0202:B3FF:FE1E:8329:8822//remotedir/subdir/', + ], ]; } }