• Модуль: dav
  • Путь к файлу: ~/bitrix/modules/dav/classes/general/webdav.php
  • Класс: CDavWebDav
  • Вызов: CDavWebDav::GETWrapper
protected function GETWrapper()
{
	/** @var CDavRequest $request */
	$request = $this->request;
	$response = $this->response;

	$arHttpRanges = null;
	$httpRange = $request->GetParameter("HTTP_RANGE");
	if (!is_null($httpRange) && preg_match('/bytess*=s*(.+)/', $httpRange, $arMatches))
	{
		$arHttpRanges = array();
		$arRanges = explode(",", $arMatches[1]);
		foreach ($arRanges as $range)
		{
			[$start, $end] = explode("-", $range);
			$arHttpRanges[] = ($start === "") ? array("last" => $end) : array("start" => $start, "end" => $end);
		}
	}

	$arResult = array();
	if (true === ($status = $this->GET($arResult)))
	{
		$status = "200 OK";
		$response->TurnOnBinaryOutput();

		if (!isset($arResult['mimetype']))
		{
			$arResult['mimetype'] = "application/octet-stream";
		}

		if ($arResult['mimetype'] === 'application/zip')
		{
			ini_set('zlib.output_compression', 0);
		}

		$response->AddHeader("Content-type: ".$arResult['mimetype']);

		if (isset($arResult['mtime']))
		{
			$response->AddHeader("Last-modified:" . gmdate("D, d M Y H:i:s ", $arResult['mtime']) . "GMT");
		}

		$response->AddHeader("Cache-Control: maxage=1");
		$response->AddHeader("Pragma: public");
		$response->AddHeader("ETag: ".($eTag = md5($arResult['id'].$arResult['name'].$arResult['mtime'])));

		if (isset($arResult['headers']))
		{
			foreach ($arResult['headers'] as $h)
			{
				$response->AddHeader($h);
			}
		}

		if (($rETag = $request->GetParameter('HTTP_IF_NONE_MATCH')) && trim($rETag, '"'') == $eTag)
		{
			$response->SetHttpStatus('304 Not Modified');
			return;
		}

		if (isset($arResult['stream']))
		{
			if (!is_null($arHttpRanges) && (0 === fseek($arResult['stream'], 0, SEEK_SET)))
			{
				if (count($arHttpRanges) === 1)
				{
					$range = $arHttpRanges[0];

					if (isset($range['start']))
					{
						fseek($arResult['stream'], $range['start'], SEEK_SET);
						if (feof($arResult['stream']))
						{
							$response->SetHttpStatus("416 Requested range not satisfiable");
							return;
						}

						if ($range['end'])
						{
							$size = $range['end'] - $range['start'] + 1;
							$response->SetHttpStatus("206 partial");
							$response->AddHeader("Content-length: ".$size);
							$response->AddHeader("Content-range: ".$range["start"]."-".$range["end"]."/".(isset($arResult['size']) ? $arResult['size'] : "*"));
							while ($size && !feof($arResult['stream']))
							{
								$buffer = fread($arResult['stream'], 4096);
								$size -= mb_strlen($buffer);
								$response->AddLine($buffer);
							}
						}
						else
						{
							$response->SetHttpStatus("206 partial");
							if (isset($arResult['size']))
							{
								$response->AddHeader("Content-length: ".($arResult['size'] - $range['start']));
								$response->AddHeader("Content-range: ".$range['start']."-".$range['end']."/".($arResult['size'] ?? "*"));
							}
							while (!feof($arResult['stream']))
							{
								$buffer = fread($arResult['stream'], 4096);
								$response->AddLine($buffer);
							}
						}
					}
					else
					{
						$response->AddHeader("Content-length: ".$range['last']);
						fseek($arResult['stream'], -$range['last'], SEEK_END);
						while (!feof($arResult['stream']))
						{
							$buffer = fread($arResult['stream'], 4096);
							$response->AddLine($buffer);
						}
					}
				}
				else
				{
					$response->MultipartByteRangeHeader();
					foreach ($arHttpRanges as $range)
					{
						if (isset($range['start']))
						{
							$from = $range['start'];
							$to = !empty($range['end']) ? $range['end'] : $arResult['size'] - 1;
						}
						else
						{
							$from = $arResult['size'] - $range['last'] - 1;
							$to = $arResult['size'] - 1;
						}
						$total = $arResult['size'] ?? "*";
						$size = $to - $from + 1;
						$this->MultipartByteRangeHeader($arResult['mimetype'], $from, $to, $total);

						fseek($arResult['stream'], $from, SEEK_SET);
						while ($size && !feof($arResult['stream']))
						{
							$buffer = fread($arResult['stream'], 4096);
							$size -= mb_strlen($buffer);
							$response->AddLine($buffer);
						}
					}
					$response->MultipartByteRangeHeader();
				}
			}
			else
			{
				if (isset($arResult['size']))
				{
					$response->AddHeader("Content-length: ".$arResult['size']);
				}

				$response->AddLine(stream_get_contents($arResult['stream']));

				return;
			}
		}
		elseif (isset($arResult['data']))
		{
			if (!is_array($arResult['data']))
			{
				$response->AddHeader("Content-length: ".mb_strlen($arResult['data']));
				$response->AddLine($arResult['data']);
			}
		}
	}
	elseif (false === $status)
	{
		$response->SetHttpStatus("404 not found");
	}
	else
	{
		$response->SetHttpStatus($status);
	}
}