Closed japankun closed 4 years ago
ログでは200返している。
[01/Jul/2019:14:00:09 +0000] "GET /**/dat/1558181204.dat HTTP/1.1" 200 15776 "-" "Monazilla/1.00 nicocast/1.23"
GET /**/dat/1561983167.dat HTTP/1.0 Host: bbs.jpnkn.com Range: bytes=9215- User-Agent: Monazilla/1.00 nicocast/1.23 Connection: Close
HTTP/1.1 200 OK Server: nginx/1.14.1 Date: Tue, 02 Jul 2019 09:07:41 GMT Content-Type: text/plain; charset=Shift_JIS Connection: close X-Powered-By: PHP/7.3.2 Pragma: no-cache Vary: Accept-Encoding
HTTP/1.1の仕様ではContent-LengthとTransfer-Encodingの両方をレスポンスヘッダー含めてはならない という仕様を逆手に取った解決方法なのであまり良くないと思われる。
If a Content-Length header field (Section 14.13) is present, its decimal value in OCTETs represents both the entity-length and the transfer-length. The Content-Length header field must not be sent if these two lengths are different (i.e., if a Transfer-Encoding header field is present). If a message is received with both a Transfer-Encoding header field and a Content-Length header field, the latter must be ignored. https://tools.ietf.org/html/rfc2616#section-4.4
再発のため状態をオープンに変更した。 HTTP/1.0でリクエストが来ているにも関わらず、HTTP/1.1で返していることも確認済み。 nginxの設定に穴がありそう。
GET /thread/dat/1561992624.dat HTTP/1.0 Host: bbs.jpnkn.com User-Agent: Monazilla/1.00 nicocast/1.23 Connection: Close
HTTP/1.1 200 OK Server: nginx/1.17.3 Date: Mon, 04 Nov 2019 14:18:19 GMT Content-Type: text/plain; charset=Shift_JIS Content-Length: 14077 Connection: close X-Powered-By: PHP/7.3.11 Pragma: no-cache Vary: Accept-Encoding
GET /thread/dat/1561992624.dat HTTP/1.0 Host: bbs.jpnkn.com Range: bytes=14076- User-Agent: Monazilla/1.00 nicocast/1.23 Connection: Close
HTTP/1.1 200 OK Server: nginx/1.17.3 Date: Mon, 04 Nov 2019 14:23:14 GMT Content-Type: text/plain; charset=Shift_JIS Content-Length: 14077 Connection: close X-Powered-By: PHP/7.3.11 Pragma: no-cache Vary: Accept-Encoding
これで動いてるけど大丈夫かな。 nicocast/1.23 動きます。
$total = strlen($dat);
if (isset($_SERVER["HTTP_RANGE"])) {
$pragma = str_replace("bytes=", "", $_SERVER["HTTP_RANGE"]);
$range = explode("-", $pragma);
if ($range[0] > $total) {
header('HTTP/1.1 205 Reset Content');
return;
} else {
$dat = substr($dat, $range[0]);
$part = strlen($dat);
header("Content-Length: ${part}");
header("Content-Range: bytes ".($total - $part)."-${part}/${total}");
return $dat;
}
}
nginxがHTTP/1.1で返すことについては
HTTP/1.0のリクエストが来た場合 HTTP/1.0で返すかHTTP/1.1で返すかはサーバー側が決めていいが HTTP/1.1で追加されたものを取り除いてもHTTP/1.0として解釈できるものでなければならない
さらにHTTP/1.0ではTransfer-Encoding:chunkedを解釈できないので HTTP/1.1として返答する場合であってもTransfer-Encoding:chunkedを使用してはならない
Rangeの解釈を厳格にしたほうがいいのと、一部を返してる場合に206を返したほうがいいのかな。
Jane系で壊れることがあるみたいなので後でチェックする。
クライアントの要求の答えるならこうか ちなみにrange-endだけの指定「-100」とかの指定はできないらしい。
if (isset($_SERVER["HTTP_RANGE"])) {
$pragma = str_replace("bytes=", "", $_SERVER["HTTP_RANGE"]);
$range = explode("-", $pragma);
if ($range[0] > $total) {
header('HTTP/1.1 205 Reset Content');
return;
} else if ($range[0] && $range[1] == "") {
// <range-start>-
$dat = substr($dat, $range[0]);
$part = strlen($dat);
header('HTTP/1.1 206 Partial Content');
header("Content-Length: ${part}");
header("Content-Range: bytes ".$range[0]."-".$total."/${total}");
} else {
// <range-start>-<range-end>
$dat = substr($dat, $range[0], ($range[1] - $range[0]));
$part = strlen($dat);
header('HTTP/1.1 206 Partial Content');
header("Content-Length: ${part}");
header("Content-Range: bytes ".$range[0]."-".$range[1]."/${total}");
}
}
$range[]の中身は0の場合もあるわけだからこうしないとダメか。
if (isset($_SERVER["HTTP_RANGE"])) {
$pragma = str_replace("bytes=", "", $_SERVER["HTTP_RANGE"]);
$range = explode("-", $pragma);
if ($range[0] > $total) {
header('HTTP/1.1 205 Reset Content');
return;
} else if ($range[0] != "" && $range[1] == "") {
// <range-start>-
$dat = substr($dat, $range[0]);
$part = strlen($dat);
header('HTTP/1.1 206 Partial Content');
header("Content-Length: ${part}");
header("Content-Range: bytes ".$range[0]."-".$total."/${total}");
} else {
// <range-start>-<range-end>
$dat = substr($dat, $range[0], ($range[1] - $range[0]));
$part = strlen($dat);
header('HTTP/1.1 206 Partial Content');
header("Content-Length: ${part}");
header("Content-Range: bytes ".$range[0]."-".$range[1]."/${total}");
}
}
JaneStyle/4.0.0.5で壊れないことを確認。
特に問題なさそうなので一旦クローズ
nicocast 1.23で確認