Add support of Partial content downloading

This commit is contained in:
RainLoop Team 2016-04-27 02:53:44 +03:00
parent d34b83a0d5
commit b3299725f6
3 changed files with 76 additions and 6 deletions

View file

@ -753,14 +753,16 @@ class Http
if (99 < $iStatus) if (99 < $iStatus)
{ {
$aStatus = array( $aStatus = array(
200 => 'OK',
206 => 'Partial Content',
301 => 'Moved Permanently', 301 => 'Moved Permanently',
304 => 'Not Modified', 304 => 'Not Modified',
200 => 'OK',
400 => 'Bad Request', 400 => 'Bad Request',
401 => 'Unauthorized', 401 => 'Unauthorized',
403 => 'Forbidden', 403 => 'Forbidden',
404 => 'Not Found', 404 => 'Not Found',
405 => 'Method Not Allowed' 405 => 'Method Not Allowed',
416 => 'Requested range not satisfiable'
); );
$sCustomStatusText = \trim($sCustomStatusText); $sCustomStatusText = \trim($sCustomStatusText);

View file

@ -8458,6 +8458,20 @@ class Actions
$sRawKey = (string) $this->GetActionParam('RawKey', ''); $sRawKey = (string) $this->GetActionParam('RawKey', '');
$aValues = $this->getDecodedRawKeyValue($sRawKey); $aValues = $this->getDecodedRawKeyValue($sRawKey);
$sRange = $this->Http()->GetHeader('Range');
$aMatch = array();
$sRangeStart = $sRangeEnd = '';
$bIsRangeRequest = false;
if (!empty($sRange) && 'bytes=0-' !== \strtolower($sRange) && \preg_match('/^bytes=([0-9]+)-([0-9]*)/i', \trim($sRange), $aMatch))
{
$sRangeStart = $aMatch[1];
$sRangeEnd = $aMatch[2];
$bIsRangeRequest = true;
}
$sFolder = isset($aValues['Folder']) ? $aValues['Folder'] : ''; $sFolder = isset($aValues['Folder']) ? $aValues['Folder'] : '';
$iUid = isset($aValues['Uid']) ? (int) $aValues['Uid'] : 0; $iUid = isset($aValues['Uid']) ? (int) $aValues['Uid'] : 0;
$sMimeIndex = isset($aValues['MimeIndex']) ? (string) $aValues['MimeIndex'] : ''; $sMimeIndex = isset($aValues['MimeIndex']) ? (string) $aValues['MimeIndex'] : '';
@ -8511,9 +8525,14 @@ class Actions
$self = $this; $self = $this;
return $this->MailClient()->MessageMimeStream( return $this->MailClient()->MessageMimeStream(
function($rResource, $sContentType, $sFileName, $sMimeIndex = '') use ($self, $oAccount, $sRawKey, $sContentTypeIn, $sFileNameIn, $bDownload, $bThumbnail, $bDetectImageOrientation) { function($rResource, $sContentType, $sFileName, $sMimeIndex = '') use (
$self, $oAccount, $sRawKey, $sContentTypeIn, $sFileNameIn, $bDownload, $bThumbnail, $bDetectImageOrientation,
$bIsRangeRequest, $sRangeStart, $sRangeEnd
) {
if ($oAccount && \is_resource($rResource)) if ($oAccount && \is_resource($rResource))
{ {
\MailSo\Base\Utils::ResetTimeLimit();
$sContentTypeOut = $sContentTypeIn; $sContentTypeOut = $sContentTypeIn;
if (empty($sContentTypeOut)) if (empty($sContentTypeOut))
{ {
@ -8536,6 +8555,7 @@ class Actions
$sLoadedData = null; $sLoadedData = null;
$bDetectImageOrientation = false; $bDetectImageOrientation = false;
if (!$bDownload) if (!$bDownload)
{ {
if ($bThumbnail) if ($bThumbnail)
@ -8594,12 +8614,58 @@ class Actions
\header('Content-Disposition: '.($bDownload ? 'attachment' : 'inline').'; '. \header('Content-Disposition: '.($bDownload ? 'attachment' : 'inline').'; '.
\trim(\MailSo\Base\Utils::EncodeHeaderUtf8AttributeValue('filename', $sFileNameOut)), true); \trim(\MailSo\Base\Utils::EncodeHeaderUtf8AttributeValue('filename', $sFileNameOut)), true);
\header('Accept-Ranges: none', true); \header('Accept-Ranges: bytes');
\header('Content-Transfer-Encoding: binary'); \header('Content-Transfer-Encoding: binary');
if (!$bDownload && $sLoadedData) if ($bIsRangeRequest && !$sLoadedData)
{ {
echo $sLoadedData; $sLoadedData = \stream_get_contents($rResource);
}
\MailSo\Base\Utils::ResetTimeLimit();
if ($sLoadedData)
{
if ($bIsRangeRequest && (0 < \strlen($sRangeStart) || 0 < \strlen($sRangeEnd)))
{
$iFullContentLength = \strlen($sLoadedData);
$self->Http()->StatusHeader(206);
$iRangeStart = (int) $sRangeStart;
$iRangeEnd = (int) $sRangeEnd;
if ('' === $sRangeEnd)
{
$sLoadedData = 0 < $iRangeStart ? \substr($sLoadedData, $iRangeStart) : $sLoadedData;
}
else
{
if ($iRangeStart < $iRangeEnd)
{
$sLoadedData = \substr($sLoadedData, $iRangeStart, $iRangeEnd - $iRangeStart);
}
else
{
$sLoadedData = 0 < $iRangeStart ? \substr($sLoadedData, $iRangeStart) : $sLoadedData;
}
}
$iContentLength = \strlen($sLoadedData);
if (0 < $iContentLength)
{
\header('Content-Length: '.$iContentLength, true);
\header('Content-Range: bytes '.$sRangeStart.'-'.(0 < $iRangeEnd ? $iRangeEnd : $iFullContentLength - 1).'/'.$iFullContentLength);
}
echo $sLoadedData;
}
else
{
echo $sLoadedData;
}
unset($sLoadedData); unset($sLoadedData);
} }
else else

View file

@ -489,6 +489,8 @@ class ServiceActions
$sMethodName = 'Raw'.$sAction; $sMethodName = 'Raw'.$sAction;
if (\method_exists($this->oActions, $sMethodName)) if (\method_exists($this->oActions, $sMethodName))
{ {
@\header('X-Raw-Action: '.$sMethodName, true);
$sRawError = ''; $sRawError = '';
$this->oActions->SetActionParams(array( $this->oActions->SetActionParams(array(
'RawKey' => empty($this->aPaths[3]) ? '' : $this->aPaths[3], 'RawKey' => empty($this->aPaths[3]) ? '' : $this->aPaths[3],