Проверка связи (для стариков: "МЕЯ ВИДО?"). В связи с окончательным отрывом ЖЖ от реальности и закукливанием в режиме специальной ментальной резекции, напоминаю читателям (в особенности - знакомым IRL), что этот журнал переехал на нейтральную и безопасную платформу https://coolwolf0.dreamwidth.org/
И заодно анонс: сегодня приземлился завершив более чем недельную поездку на венецианский карнавал.
Подробности тут Собственно, я не 8, а 15 лет назад подробно описал причины и последствия нынешнего кошмара. И всё это время, как Пифия, пытался достучаться до оставшихся за заборчиком: добром это не кончится, быстро или медленно, но система сама себя вынесет. Заметьте, я трезво оценивал ситуацию и понимал, что никакой мирной смены власти не предвидится (назовите мне хоть один случай смены власти на нечто противоположное путём выборов). Короче, что случилось, то случилось, если кто хочет комментировать - вы знаете, где меня искать.
... с хостером. Не пугайтесь, я на других фронтах раненый ;-)
Короче, хостер у меня строгий, но справедливый: на халяву разрешает только в бирюльки играться. Чуть какая важная функция - давай, бабки гони. Но я и не претендую ни на что особенное: малюсенькая база MySQL (footprint практически не растёт, потому что накопить информацию вручную много не получится), какой-никакой PHP (не самая последняя версия, но и не старьё), доступ по FTP - вот и все требования. И вот настал тот час, когда у хостера начали периодически выскакивать отлупы при соединении апачевской сессии с базой. В результате скрипт вылетает по мерзкому эксцепшену "Connection failed: SQLSTATE[HY000] [2002] Connection refused". Я его конечно же оттрассировал и попытался "поймать" через try ... catch, но проблема в том, что поймать можно что угодно, а потом-то чего прикажете делать? Попытаться тут же в цикле повторить соединение? Плохая идея, ибо в таких делах надо уметь держать себя в руках и дать второй стороне шанс успокоиться. Короче, в архитектурном плане стандартное решение - retry after delay (и так несколько раз, увеличивая длительность задержек). Но, как оказалось после первой попытки, мой хостер тупо запретил sleep, usleep и вообще, любые попытки затянуть время обработки запроса. Я почесал лысую репу и выдал то, чему учат сисадмины: exec("ping -n 2 -i 1 127.0.0.1"); то есть "чеши яйца с интервалом в секунду". Второй раз забросил старик невод, и пришёл невод с той же тиной морскою - хостер строжайше запретил любые экзеки (хорошо хоть в ответ по морде не навешал). Ладно, думаю, ты так, а мы - вот так! Запросы наружу по TCP работают? Значит им можно тайм-аут назначить? Ну вот тут-то ты и попался!
Короче, вот вам функция, которая ходит туда, незнамо куда, и отрубается в строго отсчитанный момент.
Скорее всего гугловский DNS не обидится, что ему шлют запросы на несуществующий URL. Я же его не DoS-ю, а так, в качестве "груши" использую, когда со мной родная база говорить отказывается.
Если кто не помнит, то при сралине это был юридический - что надо, то и докажут, ещё спасибо скажешь, что в живых оставили. С началом закошмаривания независимых СМИ (где-то после "Курска") ненужным факультетом стала журналистика, потому что кроме озвучивания мнения свыше и нейтральной мутоты, у "журналистов" никаких вариантов не осталось.
Вот теперь и экономика. Бизнесмены, а также участники пищевой цепочки от углеводородов, поздравляю с новой реальностью. Ясно было, что "вертикаль" долго не продержится, но чтобы вот так, радикально подпилить трубу, на которой сидел почти весь внешнеторговый баланс?
Когда я в интернетах периодически вставлял цитату "бегите, глупцы!", это была не шутка. Вы верите, что у фюрера-неадеквата не реквизируют иностранные активы? Мне видится весьма печальная перспектива и очень жаль оставшихся там. Независимо от дальнейшего развития событий, мир уже не станет таким как прежде.
Что дальше? В краткосрочной перспективе - экономическую ситуацию продолжат называть стыдливым словом "кризис", хотя давно понятно, что причины пробуксовки экономики - санкции и изоляционистская политика. А про долгосрочную даже думать не хочется, глядя как удаётся реальности приподносить нам сюрпризы. Вполне может быть, что интернет отключат, а там уже и до всяких экзотических сценариев недалеко. Москва-2042, например.
Не у меня - я проверялся несколько раз домашним тестом на антиген. Мы этих тестов накупили целую упаковку из 20 штук, чтоб не думалось. Жена официально переболела в начале месяца - абсолютно без симптомов, если не считать першение в горле и лёгкий насморк. Вот теперь - тёща. В пятницу антиген показал у неё две полоски, поэтому в субботу мы с ней смотались в драйв-ин пункт тестирования PCR. Я заполнил простенькую онлайн-анкету, девочка-медсестра просканировала полученный код, выдала нам напечатанную тут же на мобильном принтере наклейку и сказала - вам в левую очередь, для тех, кому за 60 и "групп риска". Мы элегантно объехали очередь из десятка машин и нас действительно обслужили. А на следующий день - звонок. Сначала говорили на иврите, но тёща уверенно ответила заученной фразой "лё медабэрет ..." и перезвонила телефонистка на русском языке. То есть они сходу отказались от опции оповещения через СМС, ввиду возраста пациентки. Тест оказался положительным, так что тёща у нас пока сидит в четырёх стенах (что было и раньше, куда же ей ходить?). Потом перезвонила лечащий врач-терапевт и долго расспрашивала про симптомы, инструктировала по поводу возможных осложнений и дальнейших действий. Заодно упомянула, что для удалённого наблюдения нам будет доставлен прибор, измеряющий уровень кислорода в крови. И вот сегодня позвонил посыльный - он оставил у дверей коробочку с символикой нашей больничной кассы. Внутри оказалась листовка с инструкцией, электронный термометр и тот самый прибор - всё новенькое, в оригинальной упаковке. Вставил прилагаемые батарейки, тёща измерила уровень кислорода и пульс - всё в норме. Короче, ура, и дай бог чтоб на этом всё кончилось.
Всё, это конец эпохи и начало новой. FreeRSS1, рождённый как упражнение в мультидисциплинарном программировании (веб, базы данных, обработка информации) окончательно ушёл в архив. С сегодняшнего дня я могу полноценно читать RSS-подписки со всеми фильтрами, поиском и обновлениями. Да, это "нулевая" версия, там конь не валялся в плане настроек, но уже работает аутентификация и даже добавление/удаление новых лент. Ну и самое главное - система полностью вышла в онлайн, нет необходимости держать включённым домашний комп и выставлять наружу открытый порт для доступа к аппликации извне. В процессе интеграций я открыл для себя много интересных способов выстрелить себе в ногу. Например, сраный PHP не предупреждает о странном использовании неинициализированной переменной и молча выдаёт пустую строку там, где я ошибся на одну буковку в идентификаторе. При этом он мстительно игнорирует глобальные переменные (ибо антипаттерн). Вообще этот язык лишь условно можно назвать языком программирования. Если ты не добрался на хостинге до 8-й версии, то названия встроенных функций у тебя выглядят как упражнение студента первого курса в именовании подпрограмм. Приёмчики работы с массивами напоминают какой-то Фортран, а не язык, используемый в 21-м веке. Короче, скоро закрою бек-эндовую часть проекта и возьмусь за GUI. Там по крайней мере будет веселее в плане дебага - можно хоть на пустышках в браузере тренироваться.
Я тут потихоньку ваяю код для полноценного аггрегатора RSS, чтоб базировался на вебе, с мордой от Bootstrap. Мой древний самопал бежит строго на локальной машине, а это бардак и каменный век с точки зрения доступа. Про внешнее оформление в стиле Веб-1.0 вообще молчу. Уже сейчас имеется подкачка RSS-лент с сайтов по списку и умное хранение обновлений в базе, постраничное отображение статей, отметка прочитанного, редактирование кое-каких деталей имеющихся лент, поддержка клавиатурных шорткатов, плюс адаптивный дизайн под десктоп и смартфон.
Помимо всяких заморочек с базой данных, жабаскриптом и пе-ха-пе, приходится кое-где и велосипеды изобретать. В частности, задумал я накатать свой алгоритм для шифрования и передачи пароля (как нового, так и при логине). Сразу предупреждаю: мой проект не будет хранить никаких супер-пупер секретных или интимных личных данных. Просто мне надо разграничить доступ между пользователями, ну и предотвратить возможный вандализм с угоном аккаунта, порчей или замусориванием данных, вот это всё... Код хотелось бы сделать открытым (но не содержимое базы данных, естественно).
Итак, задача номер один: как секьюрно передать первоначальный пароль в систему, с учётом того, что хакеры могут прослушивать траффик. Идея состоит в том, что я вообще не собираюсь принимать от пользователя какой-то пароль при регистрации. Он оставляет на сайте свой запрос и получает от меня первоначальный пароль мейлом. При этом я не храню сам пароль в системе, а только его чексумму.
Вторая задача состоит в том чтобы передать пароль зарегистрированного пользователя (с учётом того, что на этот раз хакеры точно смогут прослушивать траффик). Решение выглядит так: сначала клиентская часть отправляет в систему запрос "пользователь такой-то хочет передать пароль". Система генерирует временный кусок "соли" и пересылает его клиенту обратно. После этого клиентский жабаскрипт считает чексумму пароля, на неё накладывает кусок "соли", и полученный результат возвращает в систему. Система убеждается, что это та самая сессия, накладывает свою "соль" на свою сохранённую чексумму пароля и сравнивает её с полученным от клиента кодом.
Если хакер перехватит сообщения в обоих направлениях, то всё равно повторить запрос на авторизацию он не сможет - та сессия уже стёрта, значит новая временная соль не даст тот же результат, что и у законного пользователя, ведь у него не будет из чего изготовить первую чексумму. Увы, менять пароль при этом не получится, потому что новый текст придётся передавать по тому же незащищённому каналу.
Фактически, я разрубил гордиев узел несекьюрного канала при помощи вспомогательного канала (мейл). Насколько мой сценарий опасен с точки зрения реальной жизни? Есть какие идеи?
Для тех, кто не в курсе: так программисты называют витиеватые способы, которыми программа может сделать себе больно.
Итак, был у меня замечательный код, просто конфетка: после выбора фильтра в верхнем меню он проходил по всем имеющимся объектам и помечал не прошедшие фильтрацию ноликом, а прошедшие - единичкой. После этого на сцену выходил его высочество AngularJS который показывал или прятал объект, в зависимости от того самого статуса. Но начальство резонно заметило, что прятать от пользователя объекты, пусть даже отфильтрованные, некрасиво. А красиво было бы объект показать, но в стиле "disabled" - сереньким, с выключенными действиями по клику мышки. Сказано - сделано: пошаманил с CSS, переставил вместо ng-hide вычисляемый класс ng-class зависимый от всё того же битового поля 0/1. И оно тоже прекрасно заработало, и увидел я что это хорошо, и сказал "да быть интеграции". Дело в том, что помимо этих визуальных чудес, я накрутил сложнючий код на PHP, который читал инфу из JSON-файла, объединял эту инфу с реальными объектами из базы данных, остатки разбивал на два подмножества (привет вычислительная математика)... Поэтому, чтобы немного облегчить мне жизнь, вопросами фронт-энда занялся совсем другой человек. Он просто заметил, что в моём жаба-скрипте есть что-то связанное с условием показывать/спрятать, и логично рассудив, что именно этого ему почему-то не хватает, понаставил в собственном цикле единички во все объекты. И вот, собрана бета-версия, начинаю тестировать и получаю полный игнор: что бы я ни фильтровал, ни черта не меняется. Начинаю дебажить жаба-скрипт - в нужные места программа заходит, нолики честно прописывает. Натравливаю на данные JSON.stringify и печатаю результат на консоль - та же картина, все нолики на месте. Но проклятый Angular продолжает игнорировать мои нолики! Уж не знаю, каким чудом я догадался заглянуть на несколько строчек ниже своего дампа: kurwa, вся моя фильтрация аккуратно идёт под нож. И ведь не упрекнёшь человека в том, что он мне данные попортил - надо было самому не лениться и переменную переименовать во что-то более self-explanatory.
Фоершванц сделали новогодний клип в своём стиле: с Крампусом и селянками.
Скачал их новый альбом "Memento Mori" и, как говорится "Моментально - в море". А если серьёзно, то ребята как-то однообразно кладут песню за песней. Надо бы над мелодиями поработать, а то эпичные морды кирпичом уже поднадоели.