mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-22 21:40:55 +01:00
Make "Range" HTTP header work for Celerity static resource requests
Summary: Ref T7567. In T8266 I fixed a bunch of obscure "Range" issues, but only for file downloads -- not for Celerity. Extend all that stuff to Celerity, which is fortunately much easier. I believe this will fix Conpherence sounds in Safari. Test Plan: - Wrote out an HTTP request in a text file with `Range: bytes=0-1` and similar, piped it to localhost with `cat request.txt | nc localhost 80`, saw server return appropriate range responses consistent with file behavior after T8266, which all seems to work. - Also did that for files to try to make sure I wasn't breaking anything. Reviewers: chad, amckinley Reviewed By: chad Maniphest Tasks: T7567 Differential Revision: https://secure.phabricator.com/D17724
This commit is contained in:
parent
ece9579d25
commit
b479941ceb
3 changed files with 51 additions and 21 deletions
|
@ -139,4 +139,29 @@ final class AphrontFileResponse extends AphrontResponse {
|
||||||
return $this->getCompressResponse();
|
return $this->getCompressResponse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function parseHTTPRange($range) {
|
||||||
|
$begin = null;
|
||||||
|
$end = null;
|
||||||
|
|
||||||
|
$matches = null;
|
||||||
|
if (preg_match('/^bytes=(\d+)-(\d*)$/', $range, $matches)) {
|
||||||
|
// Note that the "Range" header specifies bytes differently than
|
||||||
|
// we do internally: the range 0-1 has 2 bytes (byte 0 and byte 1).
|
||||||
|
$begin = (int)$matches[1];
|
||||||
|
|
||||||
|
// The "Range" may be "200-299" or "200-", meaning "until end of file".
|
||||||
|
if (strlen($matches[2])) {
|
||||||
|
$range_end = (int)$matches[2];
|
||||||
|
$end = $range_end + 1;
|
||||||
|
} else {
|
||||||
|
$range_end = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->setHTTPResponseCode(206);
|
||||||
|
$this->setRange($begin, $range_end);
|
||||||
|
}
|
||||||
|
|
||||||
|
return array($begin, $end);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,9 +104,30 @@ abstract class CelerityResourceController extends PhabricatorController {
|
||||||
}
|
}
|
||||||
|
|
||||||
$response = id(new AphrontFileResponse())
|
$response = id(new AphrontFileResponse())
|
||||||
|
->setMimeType($type_map[$type]);
|
||||||
|
|
||||||
|
$range = AphrontRequest::getHTTPHeader('Range');
|
||||||
|
|
||||||
|
if (strlen($range)) {
|
||||||
|
$response->setContentLength(strlen($data));
|
||||||
|
|
||||||
|
list($range_begin, $range_end) = $response->parseHTTPRange($range);
|
||||||
|
|
||||||
|
if ($range_begin !== null) {
|
||||||
|
if ($range_end !== null) {
|
||||||
|
$data = substr($data, $range_begin, ($range_end - $range_begin));
|
||||||
|
} else {
|
||||||
|
$data = substr($data, $range_begin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$response->setContentIterator(array($data));
|
||||||
|
} else {
|
||||||
|
$response
|
||||||
->setContent($data)
|
->setContent($data)
|
||||||
->setMimeType($type_map[$type])
|
|
||||||
->setCompressResponse(true);
|
->setCompressResponse(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// NOTE: This is a piece of magic required to make WOFF fonts work in
|
// NOTE: This is a piece of magic required to make WOFF fonts work in
|
||||||
// Firefox and IE. Possibly we should generalize this more.
|
// Firefox and IE. Possibly we should generalize this more.
|
||||||
|
|
|
@ -62,24 +62,8 @@ final class PhabricatorFileDataController extends PhabricatorFileController {
|
||||||
// an initial request for bytes 0-1 of the audio file, and things go south
|
// an initial request for bytes 0-1 of the audio file, and things go south
|
||||||
// if we can't respond with a 206 Partial Content.
|
// if we can't respond with a 206 Partial Content.
|
||||||
$range = $request->getHTTPHeader('range');
|
$range = $request->getHTTPHeader('range');
|
||||||
if ($range) {
|
if (strlen($range)) {
|
||||||
$matches = null;
|
list($begin, $end) = $response->parseHTTPRange($range);
|
||||||
if (preg_match('/^bytes=(\d+)-(\d*)$/', $range, $matches)) {
|
|
||||||
// Note that the "Range" header specifies bytes differently than
|
|
||||||
// we do internally: the range 0-1 has 2 bytes (byte 0 and byte 1).
|
|
||||||
$begin = (int)$matches[1];
|
|
||||||
|
|
||||||
// The "Range" may be "200-299" or "200-", meaning "until end of file".
|
|
||||||
if (strlen($matches[2])) {
|
|
||||||
$range_end = (int)$matches[2];
|
|
||||||
$end = $range_end + 1;
|
|
||||||
} else {
|
|
||||||
$range_end = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$response->setHTTPResponseCode(206);
|
|
||||||
$response->setRange($begin, $range_end);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$is_viewable = $file->isViewableInBrowser();
|
$is_viewable = $file->isViewableInBrowser();
|
||||||
|
|
Loading…
Reference in a new issue