mirror of
https://github.com/phpseclib/phpseclib.git
synced 2024-12-24 11:05:30 +00:00
Merge remote-tracking branch 'audrey/sftp-put-callback-for-1.0' into 1.0
This commit is contained in:
commit
1d772c3a6f
@ -102,6 +102,11 @@ define('NET_SFTP_LOCAL_FILE', 1);
|
|||||||
*/
|
*/
|
||||||
// this value isn't really used anymore but i'm keeping it reserved for historical reasons
|
// this value isn't really used anymore but i'm keeping it reserved for historical reasons
|
||||||
define('NET_SFTP_STRING', 2);
|
define('NET_SFTP_STRING', 2);
|
||||||
|
/**
|
||||||
|
* Reads data from callback:
|
||||||
|
* function callback($length) returns string to proceed, null for EOF
|
||||||
|
*/
|
||||||
|
define('NET_SFTP_CALLBACK', 16);
|
||||||
/**
|
/**
|
||||||
* Resumes an upload
|
* Resumes an upload
|
||||||
*/
|
*/
|
||||||
@ -1759,6 +1764,10 @@ class Net_SFTP extends Net_SSH2
|
|||||||
*
|
*
|
||||||
* If $data is a resource then it'll be used as a resource instead.
|
* If $data is a resource then it'll be used as a resource instead.
|
||||||
*
|
*
|
||||||
|
*
|
||||||
|
* Setting $mode to self::SOURCE_CALLBACK will use $data as callback function, which gets only one parameter -- number
|
||||||
|
* of bytes to return, and returns a string if there is some data or null if there is no more data
|
||||||
|
*
|
||||||
* Currently, only binary mode is supported. As such, if the line endings need to be adjusted, you will need to take
|
* Currently, only binary mode is supported. As such, if the line endings need to be adjusted, you will need to take
|
||||||
* care of that, yourself.
|
* care of that, yourself.
|
||||||
*
|
*
|
||||||
@ -1837,7 +1846,15 @@ class Net_SFTP extends Net_SSH2
|
|||||||
}
|
}
|
||||||
|
|
||||||
// http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.2.3
|
// http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.2.3
|
||||||
|
$callback = false;
|
||||||
switch (true) {
|
switch (true) {
|
||||||
|
case $mode & NET_SFTP_CALLBACK;
|
||||||
|
if (!is_callable($data)) {
|
||||||
|
user_error("\$data should be is_callable if you set NET_SFTP_CALLBACK flag");
|
||||||
|
}
|
||||||
|
$callback = $data;
|
||||||
|
// do nothing
|
||||||
|
break;
|
||||||
case is_resource($data):
|
case is_resource($data):
|
||||||
$mode = $mode & ~NET_SFTP_LOCAL_FILE;
|
$mode = $mode & ~NET_SFTP_LOCAL_FILE;
|
||||||
$fp = $data;
|
$fp = $data;
|
||||||
@ -1864,6 +1881,8 @@ class Net_SFTP extends Net_SSH2
|
|||||||
} else {
|
} else {
|
||||||
fseek($fp, $offset);
|
fseek($fp, $offset);
|
||||||
}
|
}
|
||||||
|
} elseif ($callback) {
|
||||||
|
$size = 0;
|
||||||
} else {
|
} else {
|
||||||
$size = strlen($data);
|
$size = strlen($data);
|
||||||
}
|
}
|
||||||
@ -1875,8 +1894,15 @@ class Net_SFTP extends Net_SSH2
|
|||||||
// make the SFTP packet be exactly 4096 bytes by including the bytes in the NET_SFTP_WRITE packets "header"
|
// make the SFTP packet be exactly 4096 bytes by including the bytes in the NET_SFTP_WRITE packets "header"
|
||||||
$sftp_packet_size-= strlen($handle) + 25;
|
$sftp_packet_size-= strlen($handle) + 25;
|
||||||
$i = 0;
|
$i = 0;
|
||||||
while ($sent < $size) {
|
while ($callback || ($sent < $size)) {
|
||||||
$temp = isset($fp) ? fread($fp, $sftp_packet_size) : substr($data, $sent, $sftp_packet_size);
|
if ($callback) {
|
||||||
|
$temp = call_user_func($callback, $sftp_packet_size);
|
||||||
|
if (is_null($temp)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$temp = isset($fp) ? fread($fp, $sftp_packet_size) : substr($data, $sent, $sftp_packet_size);
|
||||||
|
}
|
||||||
$subtemp = $offset + $sent;
|
$subtemp = $offset + $sent;
|
||||||
$packet = pack('Na*N3a*', strlen($handle), $handle, $subtemp / 4294967296, $subtemp, strlen($temp), $temp);
|
$packet = pack('Na*N3a*', strlen($handle), $handle, $subtemp / 4294967296, $subtemp, strlen($temp), $temp);
|
||||||
if (!$this->_send_sftp_packet(NET_SFTP_WRITE, $packet)) {
|
if (!$this->_send_sftp_packet(NET_SFTP_WRITE, $packet)) {
|
||||||
|
@ -11,6 +11,7 @@ class Functional_Net_SFTPUserStoryTest extends PhpseclibFunctionalTestCase
|
|||||||
static protected $scratchDir;
|
static protected $scratchDir;
|
||||||
static protected $exampleData;
|
static protected $exampleData;
|
||||||
static protected $exampleDataLength;
|
static protected $exampleDataLength;
|
||||||
|
static protected $buffer;
|
||||||
|
|
||||||
static public function setUpBeforeClass()
|
static public function setUpBeforeClass()
|
||||||
{
|
{
|
||||||
@ -132,6 +133,41 @@ class Functional_Net_SFTPUserStoryTest extends PhpseclibFunctionalTestCase
|
|||||||
return $sftp;
|
return $sftp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static function callback($length)
|
||||||
|
{
|
||||||
|
$r = substr(self::$buffer, 0, $length);
|
||||||
|
self::$buffer = substr(self::$buffer, $length);
|
||||||
|
if (strlen($r)) return $r;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @depends testStatOnDir
|
||||||
|
*/
|
||||||
|
public function testPutSizeGetFileCallback($sftp)
|
||||||
|
{
|
||||||
|
self::$buffer = self::$exampleData;
|
||||||
|
$this->assertTrue(
|
||||||
|
$sftp->put('file1.txt', array(__CLASS__, 'callback'), NET_SFTP_CALLBACK),
|
||||||
|
'Failed asserting that example data could be successfully put().'
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertSame(
|
||||||
|
self::$exampleDataLength,
|
||||||
|
$sftp->size('file1.txt'),
|
||||||
|
'Failed asserting that put example data has the expected length'
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertSame(
|
||||||
|
self::$exampleData,
|
||||||
|
$sftp->get('file1.txt'),
|
||||||
|
'Failed asserting that get() returns expected example data.'
|
||||||
|
);
|
||||||
|
|
||||||
|
return $sftp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @depends testStatOnDir
|
* @depends testStatOnDir
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user