v0.1.35: query-mode XML-ответы, TOCTOU receive, валидации AWS, purge 60s, сужение локов

This commit is contained in:
“Naeel”
2026-08-14 15:53:08 +04:00
parent 8c40ca592f
commit ec10acc99e
15 changed files with 919 additions and 172 deletions
+54
View File
@@ -465,3 +465,57 @@ DeleteQueue всегда успешен; NextSequenceNumber пересоздаё
PurgeQueueInProgress (LastPurgeTime); FIFO MissingParameter; SendMessage пустое тело/размер — AWS-коды.
10. NumberOfReceives инкремент при выдаче.
После: 25-цикловая проверка целостности, smoke, повторный 30-мин нагрузочный тест.
---
## v0.1.35 — реализация фиксов по итогам нагрузочного теста (14.08.2026)
**Изменённые файлы** (правки с подробными комментариями каждой функции и логики):
1. `app/router/router.go`:
- `resolveProtocol`: заголовок `x-amzn-query-mode: true` (AWS CLI v2/boto3) →
принудительно Query-протокол (XML-ответы). Раньше query-mode запросы получали
JSON-ошибки → botocore Code=None («сырые 400/404»).
- `extractAction`: Action берётся сначала из `X-Amz-Target` (JSON и query-mode
клиенты), затем из form `Action` — для query-mode раньше Action не находился.
- `encodeResponse` (JSON): ошибки — в формате AWS-JSON
`{"__type":"com.amazonaws.sqs#<Code>","message":"..."}` (раньше голый ErrorResult).
- `actionHandler`: неизвестный Action → GeneralError в формате протокола клиента
(раньше текст "Bad Request"). Убран импорт `io`.
2. `app/gosqs/receive_message.go`:
- TOCTOU устранён: проверка готовности И пометка in-flight — под одним Lock
(`receiveMessagesUnderLock`). Раньше два параллельных receive видели одно
сообщение, второй получал пусто → «потери».
- MaxNumberOfMessages: 110, выход → InvalidParameterValue (был clamp).
- Проверка существования очереди — под RLock (была гонка чтения map).
- `msg.NumberOfReceives++` при выдаче (счётчик доставок).
3. `app/gosqs/send_message.go`:
- FIFO без MessageGroupId → MissingParameter (было: принималось).
- Док-схема функции; Redis-записи асинхронны, под Lock только marshal.
4. `app/gosqs/gosqs.go`:
- `PeriodicTasks`: снапшот указателей под RLock + обработка каждой очереди под
отдельным Lock (раньше глобальный Lock на весь обход всех очередей).
5. `app/models/models.go`:
- `LockGroup`/`NextSequenceNumber`: map больше НЕ пересоздаётся (терялись
блокировки/счётчики остальных групп).
- Новое поле `Queue.LastPurgeTime`.
6. `app/gosqs/queue_attributes.go` + `set_queue_attributes.go` + `create_queue.go`:
- Применяются только явно переданные атрибуты (!= 0) — раньше zero-value
обнулял непереданные атрибуты.
- Bounds-check → InvalidParameterValue (был clamp).
- Whitelist имён → InvalidAttributeName (Query-протокол).
7. `app/gosqs/purge_queue.go`: повторный purge < 60 с → PurgeQueueInProgress.
8. `app/gosqs/delete_queue.go`: удаление несуществующей очереди → QueueNotFound.
9. `app/models/errors.go`: добавлены `InvalidAttributeName`, `PurgeQueueInProgress`.
**Проверки**: go build OK (v0.1.35), go vet чистый (кроме известной некомпиляции
тестов gosqs — пакет fixtures), go test app/models OK.