Нашли или выдавили из себя код, который нельзя назвать нормальным,
на который без улыбки не взглянешь?
Не торопитесь его удалять или рефакторить, — запостите его на
говнокод.ру, посмеёмся вместе!
Вот есть такая крутая фича под названием «preload»: https://developer.mozilla.org/en-US/docs/Web/HTML/Preloading_content.
Tl;dr: указываем «<link rel="preload" href="/comments.html" [...]>» в начале index.html, после чего браузер начнёт загружать comments.html в фоновом режиме. В «NGK» «Ангуляр» загружает этот самый comments.html для отрисовки главной страницы, поэтому предварительная загрузка (до того, как загрузится, собственно, «Ангуляр») может сэкономить несколько десятков миллисекунд. Ура.
Но нельзя так просто взять и сделать что-то без пердолинга! Чтобы браузер смог использовать предварительно загруженный документ, необходимо, чтобы все заголовки, за исключением представленных в коде, в обоих запросах (из preload и из «Ангуляра») совпадали, что, конечно же, не лишено смысла. Поэтому, если просто взять и включить предварительную загрузку, «Хром» выдаст печальное «A preload for 'https://gcode.space/comments.html' is found, but is not used because the request headers do not match».
Окей, повозившись с CORS, наш инженерный отдел добился полного совпадения заголовков, за исключением «Origin» (его браузер в «простых» запросах через XHR принципиально не ставит) и «Accept». «Ангуляр» по-умолчанию суёт в «Accept» «application/json, text/plain, */*», а для запроса через preload консоль разработчика показывает просто «*/*».
Не беда! Наш инженерный отдел нагуглил, как поправить заголовки запросов в «Ангуляре», поставил там «*/*» и, довольный собой, приготовился наблюдать неебическое ускорение загрузки: https://i.imgur.com/q0CtQXp.png.
Хуй. Не работает. И какие заголовки ему не нравятся — не говорит.
На этом моменте наш инженерный отдел знатно охуел, взял в руки «x64dbg» и пошёл копать. Первые попытки ручной правки регистра заголовков-исключений (ну, мало ли, вдруг разрабы «Хрома» забыли) оказались неудачными. Первые результаты принёс патчинг самого начала chrome.dll!ShouldIgnoreHeaderForCacheReu se() на «xor rax, rax; inc rax; ret»: заработало!
Но, конечно, предлагать пользователям установить грубо запатченный «Хром» — не очень хорошая затея (в первую очередь потому, что такой патч вреда принесёт гораздо больше, чем пользы). Стало понятно, что без пошаговой отладки не обойтись.
Наконец, после нескольких бесплодных попыток (как же долго «x64dbg» загружает pdb для chrome.dll…) виновник сего безобразия был найден. Вот он:
Консоль разработчика нагло пиздит. В preload запросе попросту нет заголовка «Accept», и «old_headers.Get(header_name)» возвращает null. А null — это не то же самое, что и «*/*». А консоль разработчика говорит, что то же самое. Но оно не то же!
Поэтому для корректной работы предварительной загрузки документов заголовок «Accept» нужно удалить.
Подписанный, там рядом с chrome.dll лежит «chrome.dll.sig». На время дебага я её удолил, но «Хром» на это внимания не обратил и спокойно загрузил пропатченную дллку.
> не хочешь исправить, и послать гуглу пул реквест? Станешь контрибутером хрома
Не, там простого фикса не выйдет. По сути надо завести список дефолтных значений заголовков (или взять их откуда-то из глубины движка, если такое есть) и сравнивать с ним в случае, если в одном из запросов заголовка не найдено. А для этого надо хорошо знать, какие заголовки как себя ведут, какие имеют дефолтные значения, какие не имеют, а какие имеют только в определённых контекстах.
Кстати, с «Accept» всё просто: «If no Accept header field is present, then it is assumed that the client accepts all media types». Если он отсутствует, то он считается равным «*/*».
> все заголовки, за исключением представленных в коде, в обоих запросах (из preload и из «Ангуляра») совпадали, что, конечно же, не лишено смысла
А мне кажется, питушня.
Приложение может использовать свои нестандартные заголовки, меняющиеся по неизвестным принципам для авторов правила равных заголовков (например, для каких-то целей может потребоваться заголовок Timestamp или Request-Id).
Равенство должно требоваться только для списка уже известных авторам правила равных заголовков стандартных заголовков.
Точно? Я перед тем, как пейсать комментарий, чуть взгуглил тему. На SO писали, что заголовки с хэ настолько часто вставляли в стандарт (не убирая хэ из-за обратной совместимости; не осилили переобувание boost:: в std::), что теперь просят писать без хэ и осмысленные имена, чтобы потом при случае стандартизовать эту психозу без кобенных префиксов.
Нагуглил статейку: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers.
>>> Custom proprietary headers have historically been used with an X- prefix, but this convention was deprecated in June 2012 because of the inconveniences it caused when nonstandard fields became standard in RFC 6648;
⿌
The primary problem with the "X-" convention is that unstandardized
parameters have a tendency to leak into the protected space of
standardized parameters, thus introducing the need for migration from
the "X-" name to a standardized name. Migration, in turn, introduces
interoperability issues (and sometimes security issues) because older
implementations will support only the "X-" name and newer
implementations might support only the standardized name. To
preserve interoperability, newer implementations simply support the
"X-" name forever, which means that the unstandardized name has
become a de facto standard (thus obviating the need for segregation
of the name space into standardized and unstandardized areas in the
first place).
We have already seen this phenomenon at work with regard to FTP in
the quote from [RFC1123] in Appendix A. The HTTP community had the
same experience with the "x-gzip" and "x-compress" media types, as
noted in [RFC2068]:
For compatibility with previous implementations of HTTP,
applications should consider "x-gzip" and "x-compress" to be
equivalent to "gzip" and "compress" respectively.
Гугуру торансурейто не может перевести, потому что это не иероглиф, а радикал. Иероглиф состоящий только из этого радикала вот: 黽
В японском (китайский мне неинтересен) этот кандзи не входит в список дзёё кандзи и означает следующее (ЯРКСИ):
При переезде на новый сервер что-то сломалось, и теперь «Говнокод» не принимает символы с кодами выше 0xFFFF. Вероятно, «MySQL» с кодировкой «utf8» вместо «utf8mb4» (только последняя поддерживает символы с большими кодами).
Блядь, ну вот как можно быть настолько тупой макакой, чтобы трёхбайтное говно назвать «utf8» (это алиас для «utf8mb3»)?!
Пиздец, сразу видно, что эти долбоёбы математику не учили.
Если в запросе какие-то заголовки изменились — значит, с сервера может прийти другой ответ. Реальный пример: preloadим GET /hujLen -> 42, далее в скрипте посылается запрос GET /hujLen с кастомным заколовком «Secret: 123456», на который сервер бы ответил реальной длиной 12. Но если «Хром» будет игнорировать заголовки — скрипт получит из кэша значение 42.
Вообще, в мире с побочными эффектами всегда приходит другой ответ.
Поэтому preload должен никогда не работать. Стоило бы дать возможность комитету крепких вопросов к столетию юбилея Попову Юрию Алексаилычу пользователю указать, какие два запроса считать эквивалентными.
Мне кажется, это наоборот важно, что современная наука не может поменять значение времени. Из-за этого время является уникальным идентификатором и может служить единственным аргументом нечистых функций (вместо питушарского мира в этих ваших анскильных хаскелях).
> современная наука не может поменять значение времени
Квантово-релятивсткие питухи.
>время является уникальным идентификатором
Если верить «современной науке» время везде течёт по-разному.
>питушарского мира в этих ваших анскильных хаскелях
Всё очень просто, процессор Вселенной лениво разворачивает список иммутабельных состояний пространства. (см. аппорию Зенона о стреле висящей в воздухе).
Соответственно время — просто id текущего иммутабельного снепшота трёхмерного пространства.
>>время является уникальным идентификатором
>Если верить «современной науке» время везде течёт по-разному.
1. Мы рассматриваем только точку, где работает функция, поскольку даже без релятушни две функции, работающие одновременно, нарушат питушню об уникальности, и придётся добавлять ещё пространственные координаты для глобального уникального иденпитухатора.
2. Движется ли время назад, стоит ли оно? Если нет, то идентификатор всегда меняется со временем, нелинейность интересует только авторов физической реализации, которым придётся поднимать разрешение тайстемпа.
3. Как ведёт себя функция от времени? Аппаратура, которая её вычисляет, следит за временем или привязана к метавремени, а время - это то, что показывают часы? Если вычислитель функции замедляется во времени, когда замедляется время, то для него время всегда линейно, таймстемпы должны иметь фиксированное разрешение, проблем нет, кроме случаев, когда время решило пойти назад, а функция вычислилась по-другому.
Вариант, когда вычислитель функции рассинхронизован со временем, не так невозможен, как это кажется на первый взгляд. Вероятно, это вообще будет единственной из реальных проблем. Дело в том, что вычислитель функции и часы будут неминуемо находиться в разных точках пространства, время там будет течь по-другому, и передача результата куда-то наружу может занимать чуть разное время.
Мне кажется вы просто не мыслите хацкельно-функционально.
В программе на хаскеле нужно думать четрырёхмерно, т.к там нет времени.
У переменных нет прошлого состояния и нет будущего состояния.
Точнее они есть, просто в виде ещё одного измерения — последовательности состояний.
Есть множество переменных, представляющих совокупность состояний переменной в императивной программе (представьте себе миллион стрел соответсвующих стреле в каждой точке её полёта).
Проще всего представить время обычным счётчиком.
Как сделать переменную-счётчик, если простое i=i+1 в хаскеле не работает? Вернуть монаду! То же и со временем.
ЕМНИП, GET по стандарту идемпотентен, так что его можно смело кэшировать/прелоадить.
Но да, было бы неплохо доложить в полковую канцелярию список солдат, которым не была сделана тифозная прививка правила обработки заголовков.
> GET по стандарту идемпотентен
Открыл для интереса "govnokod.ru". Сетевая вкладка в инструментах питуха в браузере говорит, что это был БАГОР GET.
Но "govnokod.ru" постоянно выдаёт разные эффекты, как и остальные сайты.
Так что если этот стандарт есть, то любая питушня с обновляемым контентом (чуть менее, чем каждая заглавная страница) его нарушает.
Так что тут как-то сложно с правилами. Захотел кто-то явно прелоада или кэширования - ну так дайте, не видите, что человеку плохо? А не просил - значит творится любая питушня.
Неправильно я ЕМНИПнул. https://stackoverflow.com/questions/45016234/what-is-idempotency-in-http-methods.
>>> A request method is considered "idempotent" if the intended effect on the server of multiple identical requests with that method is the same as the effect for a single such request.
Действительно, про ответ тут ничего не говорится.
Какая-то питушня, не относящаяся к реальной жизни. Какая-то идемпотентность со множеством оговорок, звёздочек и скрытых комиссий.
Идемпотентность GET имеет только сайт-визитка CSS/HTML-программиста на бесплатном хостинге, где PHP выключен на сервере.
В старое время были PUT и DELETE, которые меняли эффект GET. Сейчас это POST-питушня, влияющая на БД.
Имеется ввиду, что ты не должен делать ничего разрушительного по GETу, потому что браузер умеет право его несколько раз вызвать.
А POST браузер сам не делает: его надо явно попросить. Обновлял странцу, полученную в результате поста коглда-нить? Видел сообщение про повторный пост?
Ну почему, вроде всё нормально:
>>> To illustrate this, consider the DELETE method, which is defined as idempotent. Now consider a client performs a DELETE request to delete a resource from the server. The server processes the request, the resource gets deleted and the server returns 204. Then the client repeats the same DELETE request and, as the resource has already been deleted, the server returns 404.
>>>Despite the different status code received by the client, the effect produced by a single DELETE request is the same effect of multiple DELETE requests to the same URI.
Сколько раз govnokod.ru/comments не дёргай — эффект на состояние сервера будет одинаковым.
На этом моменте наш инженерный отдел знатно охуел, взял в руки «x64dbg» и пошёл копать. Первые попытки ручной правки регистра заголовков-исключений (ну, мало ли, вдруг разрабы «Хрома» забыли) оказались неудачными. Первые результаты принёс патчинг самого начала chrome.dll!ShouldIgnoreHeaderForCacheReu se() на «xor rax, rax; inc rax; ret»: заработало!
Но, конечно, предлагать пользователям установить грубо запатченный «Хром» — не очень хорошая затея (в первую очередь потому, что такой патч вреда принесёт гораздо больше, чем пользы). Стало понятно, что без пошаговой отладки не обойтись.
Наконец, после нескольких бесплодных попыток (как же долго «x64dbg» загружает pdb для chrome.dll…) виновник сего безобразия был найден. Вот он:
Консоль разработчика нагло пиздит. В preload запросе попросту нет заголовка «Accept», и «old_headers.Get(header_name)» возвращает null. А null — это не то же самое, что и «*/*». А консоль разработчика говорит, что то же самое. Но оно не то же!
Поэтому для корректной работы предварительной загрузки документов заголовок «Accept» нужно удалить.
Такой вот багор.
не хочешь исправить, и послать гуглу пул реквест? Станешь контрибутером хрома
> не хочешь исправить, и послать гуглу пул реквест? Станешь контрибутером хрома
Не, там простого фикса не выйдет. По сути надо завести список дефолтных значений заголовков (или взять их откуда-то из глубины движка, если такое есть) и сравнивать с ним в случае, если в одном из запросов заголовка не найдено. А для этого надо хорошо знать, какие заголовки как себя ведут, какие имеют дефолтные значения, какие не имеют, а какие имеют только в определённых контекстах.
However, many RFCs are informational or experimental in nature and are not standards.
Obsoleted by: 7230, 7231, 7232, 7233, 7234, 7235
Updated by: 2817, 5785, 6266, 6585
чо не пофиксить то?
А мне кажется, питушня.
Приложение может использовать свои нестандартные заголовки, меняющиеся по неизвестным принципам для авторов правила равных заголовков (например, для каких-то целей может потребоваться заголовок Timestamp или Request-Id).
Равенство должно требоваться только для списка уже известных авторам правила равных заголовков стандартных заголовков.
такие заголовки все обязаны игнорировать (кроме тех, кто их понимает)
>>> Custom proprietary headers have historically been used with an X- prefix, but this convention was deprecated in June 2012 because of the inconveniences it caused when nonstandard fields became standard in RFC 6648;
веб параша стала еще более неконсистентной
там дают пример x-gzip
веб параша стала еще более неконсистентной
хм
а мне говорят, что это "Radical Frog Unicode Character"
Отличное прозвище, куда лучше свинособак
В японском (китайский мне неинтересен) этот кандзи не входит в список дзёё кандзи и означает следующее (ЯРКСИ):
黽 «Лягушка» | ボー, ビン, ベン | 13 штрихов | +/x
黽部 ぼうぶ «лягушка» (ключ 205)
黽 かえる あおがえる べん то же
В сочетаниях непродуктивен
△水黽 あめんぼ водомерка болотная, водяной клоп, Aquarius paludum; Ср. 飴ん棒 あめんぼう
黽勉 びんべん кн. усердие, старание
Пиздец, сразу видно, что эти долбоёбы математику не учили.
Нечто вроде мемоизации функции. Если хочешь получить ответ из кэша, используй те же самые аргументы.
Поэтому preload должен никогда не работать. Стоило бы дать возможность комитету крепких вопросов к столетию юбилея Попову Юрию Алексаилычу пользователю указать, какие два запроса считать эквивалентными.
Какая-нибудь питушня вроде /dev/random as a service или govnokod.ru/comments, или даже govnokod.ru будет выдавать разный ответ на тот же запрос.
Грубо говоря функция возвращает одно и тоже значение в одно и тоже время. Является ли она чистой?
К сожалению, современная наука не может пока поменять значение времени, но это не важно
Квантово-релятивсткие питухи.
>время является уникальным идентификатором
Если верить «современной науке» время везде течёт по-разному.
>питушарского мира в этих ваших анскильных хаскелях
Всё очень просто, процессор Вселенной лениво разворачивает список иммутабельных состояний пространства. (см. аппорию Зенона о стреле висящей в воздухе).
Соответственно время — просто id текущего иммутабельного снепшота трёхмерного пространства.
>Если верить «современной науке» время везде течёт по-разному.
1. Мы рассматриваем только точку, где работает функция, поскольку даже без релятушни две функции, работающие одновременно, нарушат питушню об уникальности, и придётся добавлять ещё пространственные координаты для глобального уникального иденпитухатора.
2. Движется ли время назад, стоит ли оно? Если нет, то идентификатор всегда меняется со временем, нелинейность интересует только авторов физической реализации, которым придётся поднимать разрешение тайстемпа.
3. Как ведёт себя функция от времени? Аппаратура, которая её вычисляет, следит за временем или привязана к метавремени, а время - это то, что показывают часы? Если вычислитель функции замедляется во времени, когда замедляется время, то для него время всегда линейно, таймстемпы должны иметь фиксированное разрешение, проблем нет, кроме случаев, когда время решило пойти назад, а функция вычислилась по-другому.
Вариант, когда вычислитель функции рассинхронизован со временем, не так невозможен, как это кажется на первый взгляд. Вероятно, это вообще будет единственной из реальных проблем. Дело в том, что вычислитель функции и часы будут неминуемо находиться в разных точках пространства, время там будет течь по-другому, и передача результата куда-то наружу может занимать чуть разное время.
В программе на хаскеле нужно думать четрырёхмерно, т.к там нет времени.
У переменных нет прошлого состояния и нет будущего состояния.
Точнее они есть, просто в виде ещё одного измерения — последовательности состояний.
Есть множество переменных, представляющих совокупность состояний переменной в императивной программе (представьте себе миллион стрел соответсвующих стреле в каждой точке её полёта).
Проще всего представить время обычным счётчиком.
Как сделать переменную-счётчик, если простое i=i+1 в хаскеле не работает? Вернуть монаду! То же и со временем.
Так же служить аргументом нечистых функций может обычный монадный счётчик.
Просто вы не мыслите в дискурсе вневременной иммутабельности.
https://phoeagon.github.io/dev-random-as-a-service/
Но да, было бы неплохо доложить в полковую канцелярию список солдат, которым не была сделана тифозная прививка правила обработки заголовков.
Открыл для интереса "govnokod.ru". Сетевая вкладка в инструментах питуха в браузере говорит, что это был БАГОР GET.
Но "govnokod.ru" постоянно выдаёт разные эффекты, как и остальные сайты.
Так что если этот стандарт есть, то любая питушня с обновляемым контентом (чуть менее, чем каждая заглавная страница) его нарушает.
Так что тут как-то сложно с правилами. Захотел кто-то явно прелоада или кэширования - ну так дайте, не видите, что человеку плохо? А не просил - значит творится любая питушня.
https://stackoverflow.com/questions/45016234/what-is-idempotency-in-http-methods.
>>> A request method is considered "idempotent" if the intended effect on the server of multiple identical requests with that method is the same as the effect for a single such request.
Действительно, про ответ тут ничего не говорится.
Идемпотентность GET имеет только сайт-визитка CSS/HTML-программиста на бесплатном хостинге, где PHP выключен на сервере.
В старое время были PUT и DELETE, которые меняли эффект GET. Сейчас это POST-питушня, влияющая на БД.
А POST браузер сам не делает: его надо явно попросить. Обновлял странцу, полученную в результате поста коглда-нить? Видел сообщение про повторный пост?
Сообщение видел.
>>> To illustrate this, consider the DELETE method, which is defined as idempotent. Now consider a client performs a DELETE request to delete a resource from the server. The server processes the request, the resource gets deleted and the server returns 204. Then the client repeats the same DELETE request and, as the resource has already been deleted, the server returns 404.
>>>Despite the different status code received by the client, the effect produced by a single DELETE request is the same effect of multiple DELETE requests to the same URI.
Сколько раз govnokod.ru/comments не дёргай — эффект на состояние сервера будет одинаковым.