typedef typename Tail::inUnion dummy;
Однако я не уверен, что реализация inUnion верна. Если я правильно понимаю, этот класс не должен быть создан, поэтому вкладка «fail» никогда не будет автоматически терпеть неудачу. Возможно, было бы лучше указать, находится ли тип в объединении или нет с простым булевым значением.
template
struct Contains; template struct Contains > { enum { result = Contains ::result }; }; template struct Contains > { enum { result = true }; }; template struct Contains { enum { result = false }; }; PS: Посмотрите на Boost :: Variant
PS2: посмотрите на typelists , особенно в книге Андрея Александреску: Modern C ++ Design
Да. Поддержка byteranges. Посмотрите раздел RFC 2616 14.35 .
Это в основном означает, что необходимо читать Range
заголовок и начать служить файлу от указанного смещения.
Это означает, что Вы не можете использовать readfile (), так как это служит целому файлу. Вместо этого используйте fopen () первый, тогда fseek () к правильному положению, и затем используйте fpassthru () для обслуживания файла.
Да, можно использовать заголовок Диапазона для этого. Необходимо дать еще 3 заголовка клиенту для полной загрузки:
header ("Accept-Ranges: bytes");
header ("Content-Length: " . $fileSize);
header ("Content-Range: bytes 0-" . $fileSize - 1 . "/" . $fileSize . ";");
, Чем для прерванной загрузки необходимо проверить заголовок запроса Диапазона:
$headers = getAllHeaders ();
$range = substr ($headers['Range'], '6');
И в этом случае не забывают служить содержанию с 206 кодами статуса:
header ("HTTP/1.1 206 Partial content");
header ("Accept-Ranges: bytes");
header ("Content-Length: " . $remaining_length);
header ("Content-Range: bytes " . $start . "-" . $to . "/" . $fileSize . ";");
Вы будете получать переменные $start и $to из заголовка запроса и использовать fseek () для поиска на правильное положение в файле.
Возобновление загрузок в HTTP сделано через Range
заголовок. Если запрос содержит Range
заголовок, и если другие индикаторы (например, If-Match
, If-Unmodified-Since
) указывают, что содержание не изменилось, так как загрузка была запущена, Вы даете 206 кодов ответа (а не 200), указываете на диапазон байтов, которые Вы возвращаете в Content-Range
заголовок, то обеспечиваете тот диапазон в органе по ответу.
я не знаю, как сделать это в PHP, все же.
Первая вещь, которую необходимо сделать, состоит в том, чтобы отправить Accept-Ranges: bytes
заголовок во всех ответах, чтобы сказать клиенту, что Вы поддерживаете частичное содержание. Затем если запрос с a Range: bytes=x-y
заголовок получен (с x
и y
будучи числами) Вы анализируете диапазон, который запрашивает клиент, откройте файл, как обычно, ищите x
байты вперед и отправляют следующее y
- x
байты. Также установите ответ на HTTP/1.0 206 Partial Content
.
Не протестировав что-либо, это могло работать, более или менее:
$filesize = filesize($file);
$offset = 0;
$length = $filesize;
if ( isset($_SERVER['HTTP_RANGE']) ) {
// if the HTTP_RANGE header is set we're dealing with partial content
$partialContent = true;
// find the requested range
// this might be too simplistic, apparently the client can request
// multiple ranges, which can become pretty complex, so ignore it for now
preg_match('/bytes=(\d+)-(\d+)?/', $_SERVER['HTTP_RANGE'], $matches);
$offset = intval($matches[1]);
$length = intval($matches[2]) - $offset;
} else {
$partialContent = false;
}
$file = fopen($file, 'r');
// seek to the requested offset, this is 0 if it's not a partial content request
fseek($file, $offset);
$data = fread($file, $length);
fclose($file);
if ( $partialContent ) {
// output the right headers for partial content
header('HTTP/1.1 206 Partial Content');
header('Content-Range: bytes ' . $offset . '-' . ($offset + $length) . '/' . $filesize);
}
// output the regular HTTP headers
header('Content-Type: ' . $ctype);
header('Content-Length: ' . $filesize);
header('Content-Disposition: attachment; filename="' . $fileName . '"');
header('Accept-Ranges: bytes');
// don't forget to send the data too
print($data);
Я, возможно, пропустил что-то очевидное, и я совершенно определенно проигнорировал некоторые потенциальные источники ошибок, но это должен быть запуск.
Существует описание частичного содержания здесь, и я нашел некоторую информацию о частичном содержании на странице документации для освобожденного.
Действительно хороший способ решить эту проблему без необходимости «катить свой собственный» PHP-код - это использовать модуль Apache mod_xsendfile. Затем в PHP вы просто устанавливаете соответствующие заголовки. Apache делает свое дело.
header("X-Sendfile: /path/to/file");
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; file=\"filename\"");