SFTP: backport "parallel" upload code from master branch

This commit is contained in:
terrafrost 2016-09-10 15:50:34 -07:00
parent 845135f887
commit ff7bc85a8f

View File

@ -2137,17 +2137,42 @@ class Net_SFTP extends Net_SSH2
$fclose_check = $local_file !== false && !is_resource($local_file); $fclose_check = $local_file !== false && !is_resource($local_file);
$start = $offset; $start = $offset;
$size = $this->max_sftp_packet < $length || $length < 0 ? $this->max_sftp_packet : $length; $read = 0;
while (true) { while (true) {
$packet = pack('Na*N3', strlen($handle), $handle, $offset / 4294967296, $offset, $size); $i = 0;
while ($i < NET_SFTP_QUEUE_SIZE && ($length < 0 || $read < $length)) {
$tempoffset = $start + $read;
$packet_size = $length > 0 ? min($this->max_sftp_packet, $length - $read) : $this->max_sftp_packet;
$packet = pack('Na*N3', strlen($handle), $handle, $tempoffset / 4294967296, $tempoffset, $packet_size);
if (!$this->_send_sftp_packet(NET_SFTP_READ, $packet)) { if (!$this->_send_sftp_packet(NET_SFTP_READ, $packet)) {
if ($fclose_check) { if ($fclose_check) {
fclose($fp); fclose($fp);
} }
return false; return false;
} }
$packet = null;
$read+= $packet_size;
$i++;
}
if (!$i) {
break;
}
$clear_responses = false;
while ($i > 0) {
$i--;
if ($clear_responses) {
$this->_get_sftp_packet();
continue;
} else {
$response = $this->_get_sftp_packet(); $response = $this->_get_sftp_packet();
}
switch ($this->packet_type) { switch ($this->packet_type) {
case NET_SFTP_DATA: case NET_SFTP_DATA:
$temp = substr($response, 4); $temp = substr($response, 4);
@ -2157,20 +2182,23 @@ class Net_SFTP extends Net_SSH2
} else { } else {
fputs($fp, $temp); fputs($fp, $temp);
} }
$temp = null;
break; break;
case NET_SFTP_STATUS: case NET_SFTP_STATUS:
// could, in theory, return false if !strlen($content) but we'll hold off for the time being // could, in theory, return false if !strlen($content) but we'll hold off for the time being
$this->_logError($response); $this->_logError($response);
break 2; $clear_responses = true; // don't break out of the loop yet, so we can read the remaining responses
break;
default: default:
user_error('Expected SSH_FXP_DATA or SSH_FXP_STATUS');
if ($fclose_check) { if ($fclose_check) {
fclose($fp); fclose($fp);
} }
return false; user_error('Expected SSH_FX_DATA or SSH_FXP_STATUS');
}
$response = null;
} }
if ($length > 0 && $length <= $offset - $start) { if ($clear_responses) {
break; break;
} }
} }