Skip to content

setSurrogateHeader() が手動設定キーとの連結時に重複排除されない #175

@suzumaze

Description

@suzumaze

SurrogateKeys::setSurrogateHeader() は内部で生成したキーには array_unique() を適用しますが、ResourceObject に手動設定済みのヘッダと連結する際は重複排除しません。

連結後の値全体に array_unique() を適用すると、何か弊害があるのでしょうか? Surrogate-Keyはスペース区切りのトークン集合で順序も問わないため、重複排除しても問題なさそうに見えますが、手動設定キーには手を加えない、といった意図があれば知りたいです。

https://github.com/bearsunday/BEAR.QueryRepository/blob/1.x/src/SurrogateKeys.php#L39-L50

$key = implode(' ', array_unique($this->surrogateKeys));  // unique あり
if ($wasSetManually) {
    $ro->headers[Header::SURROGATE_KEY] .= ' ' . $key;     // unique なし
    return;
}

再現

親リソースとembedされる子リソースが同じ共通タグ(全体一括パージ用など)を手動設定していると、子のタグが内部コレクションにマージされ、親の手動設定ヘッダと連結される際に重複します。

影響

重複自体はパージ動作には無害ですが、内部キーは array_unique() 済みである一方、連結時だけ重複が残るのは不整合です。embedが多いほどヘッダが不要に肥大化し、ヘッダ長に上限を設けるCDNではパージ漏れの潜在リスクにもなります。

修正案

連結後の集合全体に適用する形が考えられます:

if ($wasSetManually) {
    $existing = explode(' ', $ro->headers[Header::SURROGATE_KEY]);
    $ro->headers[Header::SURROGATE_KEY] = implode(' ', array_unique([...$existing, ...$this->surrogateKeys]));
    return;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions