mirror of
https://github.com/nextcloud/server.git
synced 2026-04-15 22:11:17 -04:00
implement fseek for sftp read stream
Signed-off-by: Robin Appelman <robin@icewind.nl>
This commit is contained in:
parent
02a50bd99c
commit
373bd09fbf
2 changed files with 30 additions and 3 deletions
|
|
@ -381,11 +381,12 @@ class SFTP extends Common {
|
|||
switch ($mode) {
|
||||
case 'r':
|
||||
case 'rb':
|
||||
if (!$this->file_exists($path)) {
|
||||
$stat = $this->stat($path);
|
||||
if (!$stat) {
|
||||
return false;
|
||||
}
|
||||
SFTPReadStream::register();
|
||||
$context = stream_context_create(['sftp' => ['session' => $connection]]);
|
||||
$context = stream_context_create(['sftp' => ['session' => $connection, 'size' => $stat['size']]]);
|
||||
$handle = fopen('sftpread://' . trim($absPath, '/'), 'r', false, $context);
|
||||
return RetryWrapper::wrap($handle);
|
||||
case 'w':
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ class SFTPReadStream implements File {
|
|||
|
||||
private $buffer = '';
|
||||
private bool $pendingRead = false;
|
||||
private int $size = 0;
|
||||
|
||||
public static function register($protocol = 'sftpread') {
|
||||
if (in_array($protocol, stream_get_wrappers(), true)) {
|
||||
|
|
@ -76,6 +77,9 @@ class SFTPReadStream implements File {
|
|||
} else {
|
||||
throw new \BadMethodCallException('Invalid context, session not set');
|
||||
}
|
||||
if (isset($context['size'])) {
|
||||
$this->size = $context['size'];
|
||||
}
|
||||
return $context;
|
||||
}
|
||||
|
||||
|
|
@ -119,7 +123,25 @@ class SFTPReadStream implements File {
|
|||
}
|
||||
|
||||
public function stream_seek($offset, $whence = SEEK_SET) {
|
||||
return false;
|
||||
switch ($whence) {
|
||||
case SEEK_SET:
|
||||
$this->seekTo($offset);
|
||||
break;
|
||||
case SEEK_CUR:
|
||||
$this->seekTo($this->readPosition + $offset);
|
||||
break;
|
||||
case SEEK_END:
|
||||
$this->seekTo($this->size + $offset);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private function seekTo(int $offset) {
|
||||
$this->internalPosition = $offset;
|
||||
$this->readPosition = $offset;
|
||||
$this->buffer = '';
|
||||
$this->request_chunk(256 * 1024);
|
||||
}
|
||||
|
||||
public function stream_tell() {
|
||||
|
|
@ -143,6 +165,10 @@ class SFTPReadStream implements File {
|
|||
}
|
||||
|
||||
private function request_chunk($size) {
|
||||
if ($this->pendingRead) {
|
||||
$this->sftp->_get_sftp_packet();
|
||||
}
|
||||
|
||||
$packet = pack('Na*N3', strlen($this->handle), $this->handle, $this->internalPosition / 4294967296, $this->internalPosition, $size);
|
||||
$this->pendingRead = true;
|
||||
return $this->sftp->_send_sftp_packet(NET_SFTP_READ, $packet);
|
||||
|
|
|
|||
Loading…
Reference in a new issue