История изменений
Технические изменения в Quickmock — фичи, фиксы, ужесточения безопасности. Источник правды — git-история; эта страница — собранный «человеко-читаемый» срез для разработчиков.
2026-10-17 — Защита от злоупотреблений
Безопасность
- Значения заголовков с управляющими символами отклоняются. Если значение заголовка мока содержит перенос строки или другой управляющий символ (попытка подсунуть лишний заголовок), валидация теперь возвращает понятную ошибку — везде, где задаются заголовки: основной ответ, варианты, маршруты, шаги последовательности и ответ-ошибка. В самом ответе такие значения и раньше обезвреживались.
- Моки, которые притворяются LLM-API, чтобы ИИ-агент выполнил shell-команды, блокируются. Антиспам-фильтр теперь отклоняет вызовы инструментов для запуска команд (OpenAI
tool_calls / function_call, Anthropic tool_use) и разведку сети внутри песочницы. Обычные моки с вызовами инструментов вроде get_weather работают как раньше.
2026-10-02 — Облегчённая начинка; очистка логов обнуляет счётчик
Изменено
- robots.txt стал одной группой правил вместо одинаковых правил, повторённых для 23 краулеров по именам, — все боты, включая ИИ-краулеры, получают ровно тот же доступ. Списки гайдов и шаблонов в
llms.txt теперь собираются из того же реестра, что страницы и sitemap, и больше не могут устареть.
- Защита создания моков от межсайтовых запросов теперь на встроенной CSRF-защите Go. Браузерные запросы с чужого сайта — в том числе с соседнего поддомена — отклоняются; curl, CI и другие небраузерные клиенты не затронуты. Эндпоинт переключателя языка принимает только свою форму, JSON-тело больше не поддерживается.
- Внутренняя чистка: около 700 строк самописного кода заменены стандартной библиотекой Go и драйвером базы данных — API и поведение моков не изменились.
Исправлено
- Очистка логов мока теперь обнуляет и счётчик запросов. Раньше список логов пустел, а в сводке оставались прежнее число запросов и время последнего запроса.
GET /api/mocks/:id/logs для мока без запросов возвращает "logs": [], а не null.
- Живой инспектор запросов работает в реальном времени с первого захода. На приватном моке страница открывала live-соединение раньше, чем появлялась сессия инспектора, получала отказ и молча переходила на опрос сервера каждые 2 секунды; теперь соединение открывается, когда сессия готова, а закрытый инспектор вообще не опрашивает сервер. «Очистить логи» сразу обновляет список, а страница больше не пишет ошибку htmx при каждой загрузке.
2026-09-26 — Без платёжных запросов; исправлен опрос в инспекторе
Безопасность
- Quickmock больше не размещает x402-запросы на оплату в реальных сетях. Мок не может проверить платёж, поэтому ответ
402 с требованием настоящих стейблкоинов был ловушкой для любого агента, который по нему заплатит, — и такие моки уже начали выставлять в каталог x402-сервисов. Создание или правка мока с x402-требованием оплаты в mainnet (Base, Ethereum, Solana…) теперь завершается ошибкой 422 payment_blocked. x402 в тестнетах вроде base-sepolia по-прежнему разрешён, как и обычный статус 402.
Исправлено
- Вкладка инспектора, оставленная открытой на удалённом или истёкшем моке, больше не опрашивает сервер бесконечно. Список запросов и счётчик раньше запрашивали сервер каждые 2–5 секунд и молча игнорировали ответ 404 — одна забытая вкладка за несколько дней сделала больше двух тысяч запросов. Теперь сервер говорит странице остановить опрос, а страница сообщает, что мока больше нет.
2026-09-20 — Достоверные IP клиентов
Безопасность
- Origin теперь принимает веб-трафик только от Cloudflare, на двух независимых уровнях: список разрешённых диапазонов Cloudflare в фаерволе, который еженедельно обновляет таймер, и Authenticated Origin Pulls, где веб-сервер требует клиентский TLS-сертификат Cloudflare. Именно это делает адрес посетителя достоверным: Cloudflare перезаписывает несущий его заголовок, но только для трафика, который реально идёт через Cloudflare. Пока прямой путь был открыт, любой, кто нашёл origin, мог подключиться к нему и объявить себя произвольным IP.
Исправлено
- Лимит активных моков на IP, rate limit и блок-лист оператора опирались на внутренний адрес вместо адреса посетителя — три механизма, завязанных на IP, схлопывались в один общий счётчик: блок-лист не совпадал ни с кем, а один клиент мог израсходовать квоту всех. В логах запросов стоял тот же бесполезный адрес. Теперь везде резолвится настоящий IP клиента.
- Команды внутри развёрнутых секций гайда выводились обычным текстом абзаца — без оформления кодом и без кнопки копирования, хотя это ровно те строки, которые читателю предлагается ввести. Теперь они выглядят как остальные блоки кода на странице и копируются в один клик.
Добавлено
- Скрипты и подробный разбор лежат в репозитории в
deploy/cloudflare/: зачем нужен каждый уровень, в каком порядке их включать, чтобы не уронить сайт, как еженедельная синхронизация падает безопасно и какие есть подводные камни, если вы сами держите что-то за CDN.
2026-09-19 — Фильтрация по статусу и новые локали
Добавлено
- Фильтр по статусу: Инспектор запросов теперь сохраняет реальный HTTP статус ответа для каждого запроса и позволяет фильтровать логи по коду статуса. Экспорт логов также включает это новое поле.
- Локали: Добавлены полные переводы на испанский, португальский и упрощенный китайский, чтобы сделать Quickmock удобнее для глобальной аудитории на основе трендов трафика.
- Публичный API и CLI:
go install .../cmd/quickmock@latest даёт команду quickmock create, которая печатает публичный URL мока и его одноразовый admin-токен — CI-задача получает одноразовый эндпоинт без браузера. Новый гайд Публичный API и CLI разбирает установку, флаги и curl-эквивалент для пайплайнов, которые не хотят ставить ничего лишнего.
Исправлено
- У фильтрации по статусу было три шероховатости, теперь убранных: у бейджа статуса не было определено цветов, поэтому 500 выглядел ровно как 200; статус вне короткого списка выпадашки оставлял контрол в положении все статусы над уже отфильтрованным списком; а
?status= в экспорте логов молча проглатывал мусор вместо 422, который ?method= отдавал и раньше.
- Self-hosting: колонка
response_status, добавленная в этом релизе, была nullable — из-за этого любое чтение логов падало на запросах, записанных до обновления. Теперь это NOT NULL DEFAULT 0, а отдельная миграция чинит инстанс, который успел применить первый вариант.
2026-09-18 — Тело ответа, которое может сослаться на себя
Добавлено
- Новый токен
{{mock.url}} раскрывается в собственный базовый URL мока — https://quickmock.dev/m/<slug> — так что тело ответа может указать на себя. Раньше это было невозможно: слаг появляется только после создания мока, и автор шаблона не может вписать его заранее.
- Новый эхо-токен
{{request.host}} возвращает Host, на который был адресован запрос. Go держит это значение вне карты заголовков, поэтому {{request.header.host}} его никогда не заменял.
Изменено
2026-09-08 — Развёрнутые гайды и глубина шаблонов
Добавлено
- Три гайда — мок REST-эндпоинта, тест приёмника вебхуков и тест ретраев и back-off — стали полноценными разборами вместо сниппета с подписью: прямой ответ в начале, заголовки в форме вопроса, с которым вы пришли, раздел о том, что обычно идёт не так, и FAQ.
- Каждая страница шаблона теперь начинается с прямого ответа, для чего шаблон нужен и чего он сознательно не делает, и заканчивается ссылками на документацию вендора или RFC, которые он воспроизводит — Stripe, Slack, GitHub, Shopify, Telegram, RFC 6749, RFC 7517, RFC 9457 — вместо упоминаний вскользь.
- Страницы гайдов и шаблонов несут разметку
FAQPage, а разметка шаблона ссылается на источники, из которых он собран.
Изменено
- Страницы гайдов и шаблонов показывают дату последнего обновления и публикуют её же как
dateModified.
- В гайдах про ретраи и приёмник вебхуков появились разделы о том, когда прекращать повторы и как строить ключ идемпотентности на идентификаторе доставки.
2026-09-08 — Внутренняя перелинковка и разметка хабов
Добавлено
- Каждая страница гайда и шаблона теперь заканчивается ссылками на соседние страницы, а гайд ссылается на построенные на нём шаблоны — оба раздела связаны в обе стороны, а не только с собственным хабом.
- С главной страницы теперь ведут прямые ссылки на пять гайдов и пять шаблонов, а не только на хаб.
- Страницы гайдов, документации и чейнджлога получили разметку schema.org —
ItemList, TechArticle и SoftwareApplication с версией и release notes.
Изменено
- Заголовки индексных страниц гайдов и шаблонов теперь начинаются с того, что на них собрано, а не с общего названия раздела.
- В
/llms.txt появилась секция Documentation: справочник API, OpenAPI-контракт и чейнджлог собраны там, где их ищет AI-ассистент, а не посреди списка фактов.
2026-09-05 — Доверенный IP клиента и редиректы только на относительные пути
Безопасность
- IP-адрес клиента, от которого зависят лимит моков на IP, блок-лист IP и белый список анти-спам фильтра, больше не берётся из заголовка
X-Forwarded-For, который проставляет сам клиент. Теперь используется заголовок ближайшего обратного прокси (в проде — CF-Connecting-IP), и только если этому прокси можно доверять; подделки через список значений через запятую полностью игнорируются.
- Ломающее изменение: заголовок ответа
Location у мока теперь должен быть простым относительным путём (например, /m/abc123) — проверка действует одинаково для основного ответа, именованных вариантов, маршрутов, шагов последовательности и error_response. Абсолютные адреса, протокол-независимые //host и варианты с обратным слэшем отклоняются с ошибкой 422 validation_failed при создании и обновлении, а у уже существующей записи с таким значением заголовок просто не выставляется при отдаче.
- Ответы моков на
/m/:slug теперь отправляют заголовок Cross-Origin-Resource-Policy: same-origin, поэтому мок больше нельзя подгрузить как скрипт, картинку или iframe с чужого сайта. Переопределить этот заголовок сам мок не может.
- Встроенный анти-спам фильтр пополнился паттернами: чтение flag-файлов, поиск секретов через переменные окружения, однострочники-загрузчики и reverse-shell, пути облачных метаданных, а также два приёма перехвата вкладки в браузере.
Изменено
- Admin-токен теперь обязателен для всех операций изменения мока — редактирования, удаления, продления, а также экспорта и очистки логов — без исключения для моков, созданных ещё до появления токенов.
2026-08-22 — Go 1.27 и обновление CI
Изменено
- Бэкенд и production-образ теперь собираются на Go 1.27.0; полный набор тестов с race detector продолжает проходить на новом toolchain.
- GitHub Actions переведён на совместимые с Node.js 24 версии checkout и setup-go, а версия Go теперь читается прямо из
go.mod, чтобы CI и production не расходились.
2026-08-19 — Детерминированные сценарии, API-workspace и приватные логи
Добавлено
- Появились именованные варианты ответа: нужный edge case можно явно выбрать через
X-Quickmock-Variant или __quickmock_variant и стабильно воспроизводить в тестах.
- Упорядоченные условные правила выбирают вариант по методу, пути, query, заголовкам или JSON-телу запроса; доступны операторы
equals, not_equals, contains и exists.
- Один мок теперь может отдавать до 50 маршрутов method + path. В конструктор можно вставить OpenAPI 3.x в JSON или YAML, чтобы получить маршруты workspace и примеры ответов.
- Новые документация API и машиночитаемый контракт OpenAPI 3.1 описывают создание, варианты, правила, workspace и приватность инспектора.
Безопасность
- Логи запросов новых моков по умолчанию приватны. Admin-токен открывает ограниченную путём HttpOnly-сессию инспектора; сохранение тел запросов и IP отправителей можно отключить отдельно.
Изменено
- SEO/GEO-метаданные теперь публикуют взаимные языковые записи sitemap, включают страницу документации и актуальную дату обновления, а URL моков, workspace, шаринга и инспектора помечены как неиндексируемые.
2026-08-15 — Защита от злоупотреблений и безопасные ответы моков
Безопасность
- У fallback-поллинга инспектора запросов появился отдельный per-IP лимит: автоматические всплески ограничиваются, а обычные живые обновления продолжают работать.
- Ответ мока больше не может расширить область действия Service Worker, а редиректы принимают только относительные, HTTP- или HTTPS-адреса.
- Встроенный фильтр злоупотреблений теперь отклоняет типичные SSRF-примитивы, конфигурации исполняемых обработчиков и известные шаблоны backlink-страниц. В self-hosted установке также можно задать denylist IP/CIDR.
Исправлено
- Логи контейнеров теперь ротируются по умолчанию, а при штатной остановке закрытая очередь больше не порождает пустые записи журнала запросов.
2026-08-10 — Защита создания моков из браузера
Безопасность
- Создание мока с сайта — через форму на главной и кнопкой в один клик на странице шаблона — теперь отклоняется, если запрос инициировал в вашем браузере посторонний сайт. Программный доступ это не задевает:
curl, задачи CI и публичный API не шлют браузерных заголовков происхождения и работают ровно как раньше.
- У этих же двух действий появился собственный лимит запросов, отдельный от того, что обслуживает обращения к самим мокам, — сорвавшийся скрипт больше не израсходует вашу квоту активных моков.
Изменено
- Шапка больше не разъезжается на телефоне: с разделом Шаблоны шести ссылок стало слишком много для одной строки, поэтому ссылка на GitHub переехала в подвал к остальным ссылкам автора, а оставшаяся навигация переносится на свою строку вместо того, чтобы уезжать за край экрана.
- Для своего инстанса: сервер теперь предупреждает при старте о переменных окружения, оставшихся от старого префикса
MOCKAPI_. После переименования их никто не читает, так что до сих пор устаревший ключ молча оставлял значение по умолчанию — включая QUICKMOCK_BASE_URL, на который опирается новая проверка происхождения запроса.
2026-08-09 — Галерея готовых шаблонов моков
Добавлено
- Новый раздел /templates: десять готовых конфигураций моков в четырёх категориях (платежи, инструменты разработчика, авторизация и идентификация, общего назначения) — вебхуки Stripe и Shopify, push-события GitHub, хендшейк
url_verification из Slack, discovery для OAuth2/OIDC и JWKS, тела ошибок по RFC 9457 и другое.
- У каждого шаблона кнопка «Создать этот мок» создаёт его в один клик, а ссылка «Открыть в конструкторе моков и сначала поправить» открывает ту же конфигурацию в обычной форме мока, где можно подправить поля, заголовки или код ответа перед сохранением.
- На каждой странице шаблона разобраны ключевые поля payload'а и честно перечислены отличия мока от настоящего сервиса, который он имитирует — без выдавания статичного мока за настоящий API.
Исправлено
- Баннер «вы упёрлись в лимит активных моков» на главной странице показывал лимит размера тела запроса вместо реального лимита количества моков, да ещё с мусорным хвостом
%!(EXTRA int=…). Теперь показывает верное число без лишнего хвоста.
2026-07-26 — Потолок TTL, продление мока, выгрузка логов
Добавлено
- Срок жизни мока теперь ограничен:
ttl_seconds не может превышать 30 дней (настраивается на сервере) — ни при создании, ни при последующем изменении.
- На странице мока появилась кнопка «Продлить» — она отодвигает срок истечения дальше, но не больше чем на те же 30 дней от даты создания мока; требует admin-токен, как и редактирование или удаление мока.
- В шаблонах тела ответа появились четыре новых токена:
{{random.pick:a|b|c}} выбирает один вариант на каждое обращение, {{seq}} считает обращения, плюс {{faker.price}} и {{faker.lorem}}.
- Инспектор запросов теперь фильтруется по HTTP-методу, а ссылка «Скачать JSON» выгружает полную историю захваченных запросов и ответов (включая IP отправителей) — требует admin-токен, в отличие от экспорта конфига.
2026-07-17 — Admin-токен для мока
Добавлено
- Теперь при создании мока в ответе приходит одноразовый admin-токен — он показывается один раз, в баннере на странице мока с кнопкой копирования; сохрани его, второй раз он не покажется.
- Редактирование мока, удаление или очистка его логов теперь требуют этот токен: передавай его в заголовке
Authorization: Bearer <токен>. Чтение мока, его логов и живой инспектор по-прежнему работают только по slug, без токена.
- Моки, созданные до этого релиза, продолжают работать без токена до истечения срока. Новый гайд: Управляй моками с любого устройства.
2026-07-05 — Живой инспектор, экспорт и импорт, антиспам
Добавлено
- Инспектор запросов работает через Server-Sent Events: новые запросы появляются мгновенно, без поллинга; там, где SSE недоступен, страница автоматически возвращается к поллингу.
- Конфиг мока можно выгрузить в JSON со страницы мока (без логов и IP) и импортировать на форме создания — из файла или вставкой текста, целиком в браузере. Формат совпадает с
POST /api/mocks, так что экспорт можно проиграть через API.
- Антиспам-фильтр блокирует создание мошеннических моков. Встроенный список паттернов можно заменить (
QUICKMOCK_SPAM_PATTERNS_FILE), выключить или добавить IP в список исключений (QUICKMOCK_SPAM_ALLOW_IPS).
2026-06-19 — Переключатель CORS
Добавлено
- Один чекбокс на форме создания включает разрешающий CORS-пресет без credentials (
Access-Control-Allow-Origin: * и др.) и отвечает на preflight OPTIONS кодом 204 — вызывайте мок из браузерного JS с любого origin, без прокси.
- Новый гайд: Замокать API с CORS.
2026-06-13 — Гайды по сценариям
Добавлено
- Новый раздел /guide: сценарные лендинги под частые задачи — замокать REST API, протестировать ретраи, имитировать нестабильный или медленный API, ловить вебхуки, отдавать фейковые данные, отразить запрос. На каждой странице готовый curl-пример; все они в sitemap.
- На каждом гайде теперь есть кнопка копировать у curl-примеров и CTA Создать мок в один клик: она открывает форму на главной, заранее заполненную конфигом этого рецепта — метод, тело, задержка, доля ошибок, последовательность — остаётся отправить.
2026-06-11 — Симуляция нестабильного API
Добавлено
- Последовательности ответов: мок может хранить упорядоченный список до 10 дополнительных ответов (у каждого свои статус, тело и заголовки), отдаваемых по кругу — 1-й вызов → основной ответ, 2-й → шаг 2, … затем заново. Классический тест retry-логики. Позиция — общий для мока счётчик (Redis, с запасным вариантом в памяти процесса), так что все вызывающие двигаются по одной последовательности.
- Доля ошибок и джиттер задержки: настраиваемая доля запросов (0–100%, бросок на каждый запрос) может отвечать альтернативным статусом/телом, а задержку можно задать диапазоном мин–макс для случайного разброса вместо фиксированного значения. Все три настройки сочетаются, а новый заголовок ответа
X-Mockapi-Variant (default, error или seq-i/n) показывает, какая ветка обслужила вызов. Настраивается в форме создания (новая секция «Симуляция нестабильности») и через API.
- Блок «Кто это сделал» на главной теперь ссылается на личный сайт автора (deadsquirrel.dev), с учётом языка локали.
2026-06-10 — Эхо-токены запроса
Добавлено
- Новые динамические токены
request.* возвращают части входящего запроса прямо в тело ответа: {{request.method}}, {{request.path}}, {{request.ip}}, {{request.query.id}}, {{request.header.x-request-id}}, {{request.body}} и JSON-пути через точку вроде {{request.body.user.name}}. Значения вставляются как есть, ничего дополнительно не сохраняется — статический мок теперь может отвечать данными из самого запроса.
Исправлено
- Запись от 2026-05-20 ниже показывала Go-template экранирование (
{{`…`}}) вокруг каждого токена вместо самого токена — след копирования разметки из HTML-шаблона. Теперь отображается обычный {{faker.uuid}} и компания.
2026-06-08 — Ссылка на автора
Добавлено
- Имя автора в подвале теперь ведёт на личный сайт мейнтейнера (deadsquirrel.dev) — с языковым маппингом под локаль и атрибутом
rel="me" как identity-сигналом.
2026-05-25 — Контент на главной
Добавлено
- Сама эта /changelog страница, на EN и RU, с hreflang и записью в
sitemap.xml.
- На главной — секция Краткий глоссарий (Mock API, Эндпоинт, TTL, Faker-токен, Content-Type) для тех, кто пришёл сюда без контекста.
- На главной — блок Кто это сделал с био автора и прямыми ссылками на GitHub, LinkedIn, Telegram; плюс секция Зачем я это сделал с историей создания — чтобы страница не выглядела «безымянной утилитой».
- Видимая отметка Обновлено внизу главной;
dateModified продублирован в WebApplication JSON-LD, чтобы AI-краулеры видели свежесть.
Исправлено
?lang=<code> в URL теперь действительно отдаёт указанный язык. Раньше canonical / hreflang ссылались на ?lang=ru, но резолвер читал только cookie и Accept-Language, поэтому бот, идущий по hreflang, видел английский контент — мультиязычный сигнал был обманом.
Безопасность
- Усиление origin для
/m/*: публичный mock-router теперь вырезает заголовки, через которые злоумышленник мог запутать downstream-прокси; slug-и стали длиннее (больше энтропии); внутренние сообщения об ошибках редактируются перед отдачей наружу — никаких фрагментов DSN, никаких стек-фреймов.
- Переключение языка (
POST /language) теперь принимает same-origin абсолютные Referer-ы — редирект «обратно» работает за reverse-прокси, которые переписывают Referer. Cross-origin Referer-ы по-прежнему отбрасываются.
Исправлено
- Middleware RealIP теперь доверяет
X-Forwarded-For / X-Real-IP, когда непосредственный peer — loopback или private / link-local адрес. Раньше XFF принимался только от loopback, поэтому за Docker Compose все запросы атрибутировались bridge-шлюзу (например, 172.18.0.1) — creator_ip и request_ip становились бесполезными, а лимит «50 моков на IP» превращался в глобальный.
- Mock router теперь сохраняет ключи входящих заголовков в нижнем регистре, чтобы
request_headers->>'user-agent' работал независимо от регистра в проводе.
- UI: примеры slug-ов обновлены на новый 12-символьный формат; кнопка «Copy URL» на странице мока починена.
2026-05-21 — Дисклеймер UGC
Добавлено
- Дисклеймер в подвале и модалка с условиями использования: содержимое моков — UGC, явно перечислены запрещённые категории (вредоносное ПО, фишинг, CSAM, инфраструктура для атак), опубликован канал для жалоб.
- Модалка в футере остаётся юзабельной на маленьких экранах — кнопка закрытия больше не уезжает за край на мобильных.
2026-05-20 — Динамические токены
Добавлено
- Подстановка faker / now токенов в теле ответа:
{{faker.uuid}}, {{faker.email}}, {{faker.name}}, {{now.iso8601}} и ещё 18 других (люди, ID, сеть, текст, время). Мок хранит шаблон как есть и подставляет свежие случайные значения на каждый запрос — один мок отдаёт разные данные в разных вызовах. Полный список — в разделе Динамические токены на форме создания.
2026-05-18 — Усиление и удобство
Исправлено
- Docker Compose деплой теперь ждёт
--wait healthcheck вместо опроса /healthz в shell-цикле — деплои больше не печатают косметический curl: (52) Empty reply в момент, когда прокси и Go-процесс заканчивают «гонку».
- Пример
POSTGRES_PASSWORD в .env.example теперь предупреждает против base64 — pgx DSN-парсер ломается на + / = в пароле.
2026-05-17 — Первый публичный релиз
Добавлено
- Ядро mock-движка: создание, просмотр, редактирование, удаление; все HTTP-методы, включая
ANY.
- Публичный роутер
/m/:slug с настраиваемыми статусом, телом, заголовками, задержкой ответа (0–30 с) и TTL.
- Живой инспектор запросов: HTMX-опрос раз в 2 секунды, счётчик попаданий, очистка лога.
- Импорт из cURL — вставь команду
curl …, и форма создания заполнится сама.
- Сниппеты кода на странице мока для JavaScript, Python, Go, PHP.
- Превью только для чтения по
/share/:slug с Open Graph тегами.
- Per-IP rate limit (5000 хитов / 8 часов) и потолок активных моков на IP (50).
- Максимальный размер тела ответа — 512 КБ, обеспечивается handler-ом и DB
CHECK-констрейнтом.
- Docker Compose стек (app + Postgres + Redis + one-shot миграционный контейнер) и bare-metal путь через systemd.
- EN + RU локализация, переключатель языка (cookie + Accept-Language).
- Privacy by design: никакого стороннего JS, никакой аналитики, никакого CDN-шрифтов; CI это проверяет на каждом билде.
Полная git-история на GitHub →
← На главную