Shanraq.org Shanraq.org

Архив публикаций

воскресенье, 6 сентября 2026

воскресенье

сентябрь 2026
пнвтсрчтптсбвс
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30

Выделенные дни — те, в которые что-то опубликовано; их можно нажать.

IT

`context`: вовремя остановить запрос

Сорок третий урок курса по Go. Читатель закрыл вкладку — и обработчик узнаёт об этом сам: измерено, как он бросает работу через двести миллисекунд. Срок на запрос к базе, ключ своего типа вместо строки и обещанный переезд вошедшего человека в контекст запроса.

IT

Горутины и каналы: зачем они вебу

Сорок второй урок курса по Go. Сервер конкурентен с урока про HTTP, и вы этого не выбирали: каждый запрос — своя горутина. Измерено, как счётчик без замка сначала теряет один просмотр из пятисот, а потом роняет весь сервер, и как go test -race находит это заранее.

IT

Тесты: узнать, что сломалось при правке

Сорок первый урок курса по Go. Обещанная в уроке 10 таблица: случаи складывают в список, `t.Run` даёт каждому имя, и провал сразу говорит, какой именно случай сломался. Плюс проверка обработчика без запуска сервера и честный разговор о том, что показывает `-cover`.

IT

Загрузка изображений: чужой файл на вашем диске

Сороковой урок курса по Go. Форма, в которой едет файл, и четыре вещи, которые проверяют до того, как он ляжет на диск: размер, тип по содержимому, собственное имя вместо присланного и место, куда его класть. Заодно приводим /static в порядок: brand, css, images, js, uploads.

IT

CSRF и XSS: три защиты, которые ставят всем

Тридцать девятый урок курса по Go. Чужой скрипт на вашей странице и чужой сайт, отправляющий форму от имени вашего читателя. Измерено, как html/template экранирует по месту — в тексте, в ссылке и внутри script, — и как жетон отличает вашу форму от чужой.

IT

Права: кто что может менять

Тридцать восьмой урок курса по Go. Спрятать кнопку — не защита: измерено, как чужой человек правит вашу статью прямым запросом, пока кнопки он не видит. Проверка живёт в обработчике и в одном месте, а отказы отвечают по-разному: гостю — на вход, чужому — 403, несуществующему — 404.

IT

Сессии и cookie: как сервер помнит, кто вошёл

Тридцать седьмой урок курса по Go. HTTP не помнит ничего: каждый запрос приходит от незнакомца. Печенье с номером пользователя подделывается за секунду. Поэтому в браузер уходит случайный токен, а в базу его хеш, и всё закрывается тремя словами: HttpOnly, Secure, SameSite.

IT

Регистрация: что хранить вместо пароля

Тридцать шестой урок курса по Go. Пароль в базе не хранят — хранят bcrypt-хеш, у которого соль внутри, а стоимость снаружи. Измерено: sha256 даёт девять миллионов хешей в секунду, bcrypt десять. Плюс предел в 72 байта, о который казахский пароль спотыкается уже на тридцать седьмой букве.

IT

Макет: одна рамка на все страницы

Тридцать пятый урок курса по Go. Семь шаблонов блога держат семь копий одного и того же начала страницы. Сегодня остаётся одна рамка: base с блоками, папки pages и partials, семантическая разметка — и измеренная ловушка, из-за которой у людей все страницы вдруг показывают одну и ту же.

IT

Поиск: FTS5, и почему параметр спасает не от всего

Тридцать четвёртый урок курса по Go. Работающий поиск по блогу: виртуальная таблица FTS5, три триггера, ранжирование и подсветка найденного. И измеренный сюрприз: параметр защищает от инъекции, но не от того, что человек напечатал в строку поиска слово OR.

IT

Теги: третья таблица, которой не видно на странице

Тридцать третий урок курса по Go. У статьи много тегов, у тега много статей — и хранится это отдельной таблицей, а не списком в колонке. Составной ключ, on conflict ради id, каскад при удалении. И обещанный способ спросить у ошибки её код вместо того, чтобы читать её текст.

IT

Транзакции и SQL-инъекции: запрос — не строка, которую склеивают

Тридцать второй урок курса по Go. Два правила, на которых держится база. Данные не склеивают с текстом запроса: подстроенный адрес возвращает три строки вместо одной, а через параметр — ноль. Что должно случиться вместе — в транзакцию: без неё счётчик вырос за переезд, которого не было.

IT

Миграции: история базы, а не `create table if not exists`

Тридцать первый урок курса по Go. Схему перестаёт создавать программа при старте: появляются нумерованные файлы миграций, журнал применённого и правило «каждая ровно один раз». Плюс измеренная ловушка: колонку not null без значения по умолчанию пустая база примет, а рабочая откажется менять.

IT

CRUD: четыре действия над статьёй и жизнь без среза

Тридцатый урок курса по Go. Статьи переезжают из среза в базу и переживают перезапуск. Тип Store, который прячет базу от остального кода, четыре действия над статьёй и одна неочевидная вещь, стоящая целого раздела: обновить то, чего нет, — не ошибка, и узнать об этом можно только по RowsAffected.

IT

SQL: две таблицы, JOIN и внешние ключи

Двадцать восьмой урок курса по Go. У статьи появляются комментарии, и они не помещаются внутрь неё. Вторая таблица и ключ между ними, join против left join, каскадное удаление и ловушка SQLite, из-за которой внешние ключи молчат и оставляют строки сиротами.

IT

SQL: первая таблица, INSERT и SELECT

Двадцать седьмой урок курса по Go. Статьи наконец переживут перезапуск. Почему в курсе SQLite, а не Postgres, как создать таблицу и положить в неё строку: insert с returning, select с where и order by, update, у которого забыли where, и разница между = null и is null.

IT

SQLite и database/sql: первая строка из базы, а не из среза

Двадцать девятый урок курса по Go. Блог наконец читает статьи из файла базы. Пакет и драйвер, почему sql.Open ничего не открывает, что такое пул соединений и почему прагму про внешние ключи пишут в строку подключения, а не отдельным запросом. Плюс ErrNoRows и проверка ошибки после цикла.

IT

Конфигурация в Go: флаги, переменные окружения и пароль вне кода

Двадцать шестой урок курса по Go. Адрес, файл базы и ключ подписи уезжают из кода. Пакет flag и что даёт -h, почему переменную окружения удобно делать значением флага по умолчанию, чем пустая переменная отличается от незаданной и почему без обязательной настройки надо падать при старте.