Патч ETags в NixOS
Здравствуйте. В NixOS используется патч ETags для корректного определения изменения файла, расположенного в папке /nix/store. В этой папке все файлы имеют временную метку установленную в 0. Поэтому без использования этого патча файлы в кэше перестают обновляться. Возможно ли добавить этот патч в Upstream? Подробнее: https://github.com/NixOS/nixpkgs/blob/master/doc/packages/nginx.section.md Либо добавить дополнительный параметр, в котором можно указать папки для которых используется только механизм ETags. -- С уважением, Izorkin mailto:izor...@gmail.com ___ nginx-ru mailing list nginx-ru@nginx.org https://mailman.nginx.org/mailman/listinfo/nginx-ru
Re: Патч ETags в NixOS
Hello! On Sun, Nov 19, 2023 at 04:15:42PM +0300, izor...@gmail.com wrote: > Здравствуйте. > > В NixOS используется патч ETags для корректного определения изменения > файла, расположенного в папке /nix/store. В этой папке все файлы имеют > временную метку установленную в 0. Поэтому без использования этого > патча файлы в кэше перестают обновляться. Возможно ли добавить этот > патч в Upstream? > Подробнее: > https://github.com/NixOS/nixpkgs/blob/master/doc/packages/nginx.section.md > > Либо добавить дополнительный параметр, в котором можно указать папки > для которых используется только механизм ETags. Если я правильно понимаю, речь про вот этот патч: https://github.com/NixOS/nixpkgs/blob/nixos-23.05/pkgs/servers/http/nginx/nix-etag-1.15.4.patch Патч выглядит, скажем так, непригодным для включения куда-либо. Если для задачи достаточно не выдавать пользователю Last-Modified, а выдавать только ETag (этого, вероятно, будет достаточно как минимум если в URI виден полный путь из /nix/store, включающий hash, а также в остальных случаях, если на размер можно полагаться для идентификации файлов), то просто убрать Last-Modified из ответов можно стандартным механизмом add_header (http://nginx.org/r/add_header): add_header Last-Modified ""; Соответственно у ответов будет только ETag, сформированный nginx'ом из даты модификации файла (0 в случае /nix/store) и размера файла. -- Maxim Dounin http://mdounin.ru/ ___ nginx-ru mailing list nginx-ru@nginx.org https://mailman.nginx.org/mailman/listinfo/nginx-ru
Re: Патч ETags в NixOS
Здравствуйте, Maxim. Да, этот патч, забыл указать ссылку. Проверил без патча и добавлением строки `add_header Last-Modified "";` В ответе генерируется ETag: "1-4e", "1-75" и т.д. Если после изменения содержимого файла без изменения размера, то при запросе отдаётся файл из кеша, т.к. при этом ETag не изменяется. А если размер файла меняется, кеш обновляется. Вариант с использованием хеадера Last-Modified не подходит, может надо как-то учитывать путь к файлу для генерации ETag. Вы писали 20 ноября 2023 г., 5:57:08: > Hello! > On Sun, Nov 19, 2023 at 04:15:42PM +0300, izor...@gmail.com wrote: > Если я правильно понимаю, речь про вот этот патч: > https://github.com/NixOS/nixpkgs/blob/nixos-23.05/pkgs/servers/http/nginx/nix-etag-1.15.4.patch > Патч выглядит, скажем так, непригодным для включения куда-либо. > Если для задачи достаточно не выдавать пользователю Last-Modified, > а выдавать только ETag (этого, вероятно, будет достаточно как > минимум если в URI виден полный путь из /nix/store, включающий > hash, а также в остальных случаях, если на размер можно полагаться для > идентификации файлов), то просто убрать Last-Modified из ответов > можно стандартным механизмом add_header > (http://nginx.org/r/add_header): > add_header Last-Modified ""; > Соответственно у ответов будет только ETag, сформированный > nginx'ом из даты модификации файла (0 в случае /nix/store) и > размера файла. -- С уважением, Izorkin mailto:izor...@gmail.com ___ nginx-ru mailing list nginx-ru@nginx.org https://mailman.nginx.org/mailman/listinfo/nginx-ru
Re: Патч ETags в NixOS
Hello! On Tue, Nov 21, 2023 at 09:53:16PM +0300, izor...@gmail.com wrote: > Да, этот патч, забыл указать ссылку. > Проверил без патча и добавлением строки `add_header Last-Modified "";` > В ответе генерируется ETag: "1-4e", "1-75" и т.д. Если после изменения > содержимого файла без изменения размера, то при запросе отдаётся файл > из кеша, т.к. при этом ETag не изменяется. А если размер файла меняется, > кеш обновляется. > Вариант с использованием хеадера Last-Modified не подходит, может надо > как-то учитывать путь к файлу для генерации ETag. Если размера для идентификации версии файла недостаточно, то ожидаемо нужны другие идентификаторы. В классических файловых системах таким идентификатором выступает время модификации файла. В /nix/store, как я понимаю, идея состоит в том, что время модификации не нужно, потому что файлы в рамках конкретного пути не меняются. Решением, целиком повторяющим эту идею, будет использование полного пути из /nix/store в URI, тогда всё будет работать так, как ожидают создатели /nix/store. Если же хочется выкинуть из URI полный путь, то наверное имеет смысл думать в сторону возможности установки ETag'а из переменных (сейчас его можно поменять в ответе клиенту, но это происходит после проверок If-Modified-Since / If-None-Match, и выставленное значение не используется самим nginx'ом). Тогда можно будет поставить и использовать произвольный ETag, основываясь, например, на переменной $realpath_root - то есть сделать штатными средствами примерно то же, что пытались накостылить авторы соответствующего патча в NixOS. -- Maxim Dounin http://mdounin.ru/ ___ nginx-ru mailing list nginx-ru@nginx.org https://mailman.nginx.org/mailman/listinfo/nginx-ru
Re: Патч ETags в NixOS
Здравствуйте, Максим. Вариант использования полного пути в URI выглядит не очень удобно. Второй вариант с использованием `$realpath_root` работает, но как сделать так, чтобы генерировался хэш от значения `$realpath_root`, в противном случае отображается для всех полный путь к файлу, не думаю, что такой вариант не безопасен: add_header ETag $realpath_root; К тому же это надо дополнительно везде прописывать add_header, пользователь легко может упустить в конфигурации места, где надо его изменить. Судя по коду в src/http/ngx_http_core_module.c для генерации ETag используется только время модификации файла и его размер. А вот путь до файл не учитывается. Как можно попробовать добавить возможность учитывать полный путь до файла для проверки? Может подойдёт такой вариант: ETag = путь к файлу + размер файла + время модификации файла. Если подойдёт, тогда всё будет работать автоматически. Вы писали 25 ноября 2023 г., 3:59:57: > Hello! > On Tue, Nov 21, 2023 at 09:53:16PM +0300, izor...@gmail.com wrote: > Если размера для идентификации версии файла недостаточно, то > ожидаемо нужны другие идентификаторы. В классических файловых > системах таким идентификатором выступает время модификации файла. > В /nix/store, как я понимаю, идея состоит в том, что время > модификации не нужно, потому что файлы в рамках конкретного пути > не меняются. Решением, целиком повторяющим эту идею, будет > использование полного пути из /nix/store в URI, тогда всё будет > работать так, как ожидают создатели /nix/store. > Если же хочется выкинуть из URI полный путь, то наверное имеет > смысл думать в сторону возможности установки ETag'а из переменных > (сейчас его можно поменять в ответе клиенту, но это происходит > после проверок If-Modified-Since / If-None-Match, и выставленное > значение не используется самим nginx'ом). Тогда можно будет > поставить и использовать произвольный ETag, основываясь, например, > на переменной $realpath_root - то есть сделать штатными средствами > примерно то же, что пытались накостылить авторы соответствующего > патча в NixOS. -- С уважением, Izorkin mailto:izor...@gmail.com ___ nginx-ru mailing list nginx-ru@nginx.org https://mailman.nginx.org/mailman/listinfo/nginx-ru
Re: Патч ETags в NixOS
Добрый утро, Максим. Обнаружилась ещё одна ошибка с текущим вариантом патча: https://github.com/NixOS/nixpkgs/pull/278380 Некорректно кэшируются файлы, которые предварительно сжаты в формат gzip и/или brotli форматы. Может получится найти какое-то альтернативный вариант решения генерации Etags для файлов, которые имеют фиксированную дату? Сейчас, Etags генерируется на основе размера файла + даты изменения. Поможет ли добавление ещё одного параметра, например полного пути к файлу? Получится такой вариант: размер файла + дата изменения + полный путь к файлу -- С уважением, Izorkin mailto:izor...@gmail.com ___ nginx-ru mailing list nginx-ru@nginx.org https://mailman.nginx.org/mailman/listinfo/nginx-ru
Re: Патч ETags в NixOS
Hello! On Sun, Jan 07, 2024 at 09:57:45AM +0300, izor...@gmail.com wrote: > Обнаружилась ещё одна ошибка с текущим вариантом патча: > https://github.com/NixOS/nixpkgs/pull/278380 > > Некорректно кэшируются файлы, которые предварительно сжаты в формат > gzip и/или brotli форматы. > > Может получится найти какое-то альтернативный вариант решения генерации > Etags для файлов, которые имеют фиксированную дату? > > Сейчас, Etags генерируется на основе размера файла + даты изменения. ETag на основе размера файла и даты модификации файла - кажется вполне достаточным для уникальности в рамках требований к strong entity tags. Тем более, что даже при совпадении ETag'ов между различными представлениями одного ресурса - сломаться что-либо может скорее теоретически, если вдруг меняются правила выбора представлений (e.g., включают или выключают gzip_static, а клиент в это время пытается делать range-запрос и комбинировать его с ранее полученными от другой конфигурации ответами). Что либо менять в nginx'е я тут смысла не вижу, ETag сейчас содержит достаточно информации, чтобы проблем не возникало. Что до nix store, то кажется, что возвращение размера в ETag также должно проблему решить. > Поможет ли добавление ещё одного параметра, например полного пути к > файлу? Получится такой вариант: > размер файла + дата изменения + полный путь к файлу Полный путь к файлу в ETag точно не имеет смысла. Более того, его там быть точно не должно: если вдруг ресурс обслуживается двумя разными origin-серверами, это приведёт к требованию совпадения путей к файлу на этих серверах, а при их несовпадении - соответственно к полным ответам вместе 304, то есть сломает кэширование там, где оно сейчас работает. Теоретически, наверное, можно пытаться в ETag вставлять какой-то идентификатор представления, то если для gzip_static добавлять в ETag что-нибудь вроде "...-gz". Но при наличии размера в том же ETag'е смысла в этом исчезающие мало. -- Maxim Dounin http://mdounin.ru/ ___ nginx-ru mailing list nginx-ru@nginx.org https://mailman.nginx.org/mailman/listinfo/nginx-ru
Re: Патч ETags в NixOS
Добрый вечер, Максим. Вы писали 9 января 2024 г., 5:26:08: > Что до nix store, то кажется, что возвращение размера в ETag также > должно проблему решить. В том то и дело, что размер не всегда меняется. > Полный путь к файлу в ETag точно не имеет смысла. Более того, его > там быть точно не должно: если вдруг ресурс обслуживается двумя > разными origin-серверами, это приведёт к требованию совпадения > путей к файлу на этих серверах, а при их несовпадении - > соответственно к полным ответам вместе 304, то есть сломает > кэширование там, где оно сейчас работает. Не подумал о таком варианте использования. > Теоретически, наверное, можно пытаться в ETag вставлять какой-то > идентификатор представления, то если для gzip_static добавлять в > ETag что-нибудь вроде "...-gz". Но при наличии размера в том же > ETag'е смысла в этом исчезающие мало. А вариант добавить вычисления простой хэш суммы при условии, что дата равно нулю - размер файла + хэш сумма. Теоретически на остальное не должно повлиять. -- С уважением, Izorkin mailto:izor...@gmail.com ___ nginx-ru mailing list nginx-ru@nginx.org https://mailman.nginx.org/mailman/listinfo/nginx-ru
Re: Патч ETags в NixOS
Hello! On Fri, Jan 12, 2024 at 10:35:38PM +0300, izor...@gmail.com wrote: > Вы писали 9 января 2024 г., 5:26:08: > > > Что до nix store, то кажется, что возвращение размера в ETag также > > должно проблему решить. > > В том то и дело, что размер не всегда меняется. Дата модификации и размер - на практике достаточная комбинация для отслеживания версий файлов и их различных представлений, по крайней мере в рамках тех представлений файлов, которые умеет возвращать nginx (исходный файл и его gzip-версия). В nix store, в силу отказа от времени, время надо на что-то заменять, как минимум в ситуациях, когда полных путь, включающих store hash, не фигурирует в URL'е. Но это ортогональный вопрос (и скорее вопрос к самой концепции, которая получилась не очень совместимой с HTTP). > > Теоретически, наверное, можно пытаться в ETag вставлять какой-то > > идентификатор представления, то если для gzip_static добавлять в > > ETag что-нибудь вроде "...-gz". Но при наличии размера в том же > > ETag'е смысла в этом исчезающие мало. > > А вариант добавить вычисления простой хэш суммы при условии, что дата > равно нулю - размер файла + хэш сумма. > Теоретически на остальное не должно повлиять. Hash-сумма файла в качестве ETag - в целом отличное решение, проблема тут ровно одна: её нужно как-то получить, ибо системный вызов fstat() никаких hash-сумм почему-то не возвращает. Считать на лету - очевидно, плохой вариант для нагруженного сервера, так как файл придётся на каждый запрос читать дважды. А получать hash-сумму откуда-то ещё, скажем из внешнего файла или extended-атрибутов - выглядит в лучшем случае дополнительной фичей (смотри https://trac.nginx.org/nginx/ticket/2351 например). -- Maxim Dounin http://mdounin.ru/ ___ nginx-ru mailing list nginx-ru@nginx.org https://mailman.nginx.org/mailman/listinfo/nginx-ru
Re: Патч ETags в NixOS
Добрый день, Максим. Вы писали 13 января 2024 г., 3:28:36: > Hello! > Hash-сумма файла в качестве ETag - в целом отличное решение, > проблема тут ровно одна: её нужно как-то получить, ибо системный > вызов fstat() никаких hash-сумм почему-то не возвращает. Считать > на лету - очевидно, плохой вариант для нагруженного сервера, так > как файл придётся на каждый запрос читать дважды. А получать > hash-сумму откуда-то ещё, скажем из внешнего файла или > extended-атрибутов - выглядит в лучшем случае дополнительной фичей > (смотри https://trac.nginx.org/nginx/ticket/2351 например). Теоретически можно было бы сделать предварительное сканирование файлов и генерация хэш сумм при старте в фоновом режиме, для тех файлов, которыее расположены только в /nix/store или любой другой директории, указанной пользователем. А результаты сохранить в кеш. Если генерировать хэш-сумму на лету, то зачем надо генерировать её каждый раз при повторном запросе? Можно же в кэше результат сохранить. Да и это надо делать только для тех файлов, которые имеют нулевую дату. А файлы в /nix/store меняются не часто, только при обновлении ОС. Вариант с файлами хэш-сумм выглядит более оптимальным. При генерации файлов в /nix/store можно дополнительно добавить возможность генерации хэш-суммы для каждого файла, который требуется для работы сайта. Таким же способом в некоторых приложениях организована генерация статических файлов в gzip и brotli форматы. -- С уважением, Izorkin mailto:izor...@gmail.com ___ nginx-ru mailing list nginx-ru@nginx.org https://mailman.nginx.org/mailman/listinfo/nginx-ru
Re: Патч ETags в NixOS
Hello! On Sat, Jan 13, 2024 at 10:34:08AM +0300, izor...@gmail.com wrote: > Добрый день, Максим. > > Вы писали 13 января 2024 г., 3:28:36: > > > Hello! > > > Hash-сумма файла в качестве ETag - в целом отличное решение, > > проблема тут ровно одна: её нужно как-то получить, ибо системный > > вызов fstat() никаких hash-сумм почему-то не возвращает. Считать > > на лету - очевидно, плохой вариант для нагруженного сервера, так > > как файл придётся на каждый запрос читать дважды. А получать > > hash-сумму откуда-то ещё, скажем из внешнего файла или > > extended-атрибутов - выглядит в лучшем случае дополнительной фичей > > (смотри https://trac.nginx.org/nginx/ticket/2351 например). > > Теоретически можно было бы сделать предварительное сканирование > файлов и генерация хэш сумм при старте в фоновом режиме, для тех > файлов, которыее расположены только в /nix/store или любой другой > директории, указанной пользователем. А результаты сохранить в кеш. > > Если генерировать хэш-сумму на лету, то зачем надо генерировать её > каждый раз при повторном запросе? Можно же в кэше результат сохранить. > Да и это надо делать только для тех файлов, которые имеют нулевую дату. > А файлы в /nix/store меняются не часто, только при обновлении ОС. Всё это предполагает какой-то кэш, который надо как-то отдельно делать и конфигурировать, и выглядит в лучшем случае дополнительной фичей. > Вариант с файлами хэш-сумм выглядит более оптимальным. При генерации > файлов в /nix/store можно дополнительно добавить возможность генерации > хэш-суммы для каждого файла, который требуется для работы сайта. Таким > же способом в некоторых приложениях организована генерация статических > файлов в gzip и brotli форматы. Именно об этом и тикет, да. Мне тоже вариант с файлами кажется более интересным - с extended-атрибутами, возможно, код будет чуть проще и, вероятно, быстрее, в силу меньшего количества необходимых системных вызовов, но там сразу возникает масса проблем как с портабельностью, так и с хранением/синхронизацией (e.g., в том же nix store они могут просто не работать). -- Maxim Dounin http://mdounin.ru/ ___ nginx-ru mailing list nginx-ru@nginx.org https://mailman.nginx.org/mailman/listinfo/nginx-ru
Re: Патч ETags в NixOS
Добрый день, Максим. Вы писали 13 января 2024 г., 16:21:12: > Именно об этом и тикет, да. Мне тоже вариант с файлами кажется > более интересным - с extended-атрибутами, возможно, код будет чуть > проще и, вероятно, быстрее, в силу меньшего количества необходимых > системных вызовов, но там сразу возникает масса проблем как с > портабельностью, так и с хранением/синхронизацией (e.g., в том же > nix store они могут просто не работать). Имеется в виду синхронизация дополнительных файлов между основным и кэширующим сервером? Мне кажется, что если основной сервер предоставит необходимый ETags, тогда синхронизация не потребуется. Мне предполагается такой вариант, что надо добавить дополнительный параметр, при включении которого в блоке location Nginx начинает искать дополнительные файлы по расширению (например .crc) при запросе основного файла. Если доп. файл отсутствует, то использовать существующую логику работы с ETags, а если есть - применить на основе доп. файла. При активном параметре и отсутствии дополнительного файла выводить в лог предупреждение, чтобы пользователь самостоятельно добавил необходимые файлы. А при отключенном параметре вообще игнорировать дополнительные файлы с crc или ETags. Можно ещё добавить параметры, которые позволяют указать расширение для дополнительных файлов и метод использования этих файлов - на основе hash-суммы (crc, md5, sha и т.п.), либо прямое указание ETags. Но с последним вариантом мне кажется может возникнуть проблемы, например, если пользователь обновит основной файл, а дополнительный забудет. -- С уважением, Izorkin mailto:izor...@gmail.com ___ nginx-ru mailing list nginx-ru@nginx.org https://mailman.nginx.org/mailman/listinfo/nginx-ru
Re: Патч ETags в NixOS
Hello! On Sat, Jan 13, 2024 at 06:01:26PM +0300, izor...@gmail.com wrote: > Добрый день, Максим. > > Вы писали 13 января 2024 г., 16:21:12: > > > Именно об этом и тикет, да. Мне тоже вариант с файлами кажется > > более интересным - с extended-атрибутами, возможно, код будет чуть > > проще и, вероятно, быстрее, в силу меньшего количества необходимых > > системных вызовов, но там сразу возникает масса проблем как с > > портабельностью, так и с хранением/синхронизацией (e.g., в том же > > nix store они могут просто не работать). > > Имеется в виду синхронизация дополнительных файлов между основным > и кэширующим сервером? Мне кажется, что если основной сервер > предоставит необходимый ETags, тогда синхронизация не потребуется. Имеется в виду, что если файловое хранилище копируется и/или синхронизируется между серверами, с помощью какого-нибудь scp или rsync, или просто перекладывается в соседнюю папку с помощью cp, то забыть необходимые флаги для копирования extended-атрибутов - куда проще, чем забыть скопировать дополнительные файлы. В случае полноценного HTTP-кэширования, понятно, никаких проблем не будет, так как ETag, полученный от исходного сервера, будет сохранён вместе с заголовками ответа. (Ну а в случае proxy_store, где заголовки не сохраняются, проблемы с будут с любыми кастомными ETag'ами.) -- Maxim Dounin http://mdounin.ru/ ___ nginx-ru mailing list nginx-ru@nginx.org https://mailman.nginx.org/mailman/listinfo/nginx-ru