Help us shape the future of Go! Take the 2026 Go Developer Survey

httpcodec

package module
v0.0.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 30, 2026 License: MIT Imports: 6 Imported by: 0

README

httpcodec 🚀

Высокопроизводительный, потокобезопасный Open-Source пакет для Go 1.24+ (с поддержкой Go 1.26.1), обеспечивающий симметричное кодирование/декодирование HTTP с нулевыми аллокациями (Zero-Allocation I/O) и защитой периметра для финтех и highload систем (версия v0.0.2 использует модульную архитектуру и Functional Options).

✨ Ключевые особенности v0.0.2

  • Модульная архитектура: Разделение на options.go, codec.go, reader.go, writer.go, middleware.go.
  • Functional Options: Тонкий тюнинг буферов и лимитов.
  • Zero-Allocation I/O: Оптимизация через sync.Pool.
  • OOM Protection: Автоматическая утилизация раздутых буферов.
  • Fail-Safe Keep-Alive: Очистка до 64 KB в io.Discard для сохранения соединений.
  • Data Bleed Protection: Зануление через clear() для изоляции данных.
  • Drop-in JIT JSON: Использование goccy/go-json.

🏗 Технологический стек

  • Среда выполнения: Go 1.24 – 1.26.1+
  • Базовый парсер: github.com/goccy/go-json
  • Совместимость: Полная совместимость со стандартным пакетом net/http и любыми роутерами (chi, gin, gorilla/mux).

⚡ Результаты бенчмарков (v0.0.2)

Тестирование производительности ядра пакета на процессоре AMD Ryzen 5 5600X (12 потоков) с флагами -benchtime=2s -count=10 продемонстрировало следующие чистые показатели эффективности утилизации памяти (метрики очищены от оверхеда пакета httptest):

Метод / Компонент Скорость выполнения Потребление памяти (B/op) Аллокации (allocs/op)
ReadBytes_Optimized 125.0 – 129.8 ns/op 0 B/op 0 allocs/op
ReadJSON_Optimized 249.4 – 263.3 ns/op 88 B/op 1 allocs/op
WriteJSON_Optimized (Light) 145.3 – 151.2 ns/op 16 B/op 1 allocs/op¹
WriteHeavyJSON_Optimized (1K Batch) 33.1 – 35.4 µs/op 17 – 34 B/op 1 allocs/op¹

¹ Важное примечание по аллокациям на запись: Единичная аллокация (1 allocs/op) и сопутствующие 16–34 B/op возникают исключительно из-за вызова стандартного метода w.Header().Set("Content-Type", "application/json") пакета net/http, который неявно выделяет кучевую память под срез строк заголовка ([]string). Сама сериализация JSON и утилизация пулов внутри кодека происходят с абсолютным нулем аллокаций.

📊 Сравнительный Highload-анализ с Legacy подходом:
  • Истинный Zero-Allocation на чтении: Метод ReadBytes при чистом проходе рантайма гарантирует честные 0 B/op и 0 allocs/op, полностью исключая нагрузку на Garbage Collector .
  • Экстремальное сжатие кучи (Heavy JSON): На тяжелых батчах из 1000 элементов кодек расходует всего ~25 байт памяти и отрабатывает за ~33 µs . Стандартный легаси-подход (json.Marshal) на том же процессоре требует 141.5 KB памяти на операцию и выполняется на 44% медленнее (48.5 µs).
  • OOM и Data Bleed защита: Накладные расходы включают в себя сквозную верификацию buf.Cap() для предотвращения деградации памяти из-за раздувания пулов и зануление буферов через clear().

📦 Установка

go get github.com/ioncode/httpcodec

🚀 Быстрый старт

1. Инициализация и защита периметра (main.go)

Настройте кодек с использованием функциональных опций для ограничения входящего тела, очистки сокета Keep-Alive и управления пулом буферов. Подключите встроенное Middleware в роутер:

package main

import (
	"net/http"
	"time"

	"github.com/ioncode/httpcodec"
	"github.com/go-chi/chi/v5"
)

func main() {
	r := chi.NewRouter()

	codec := httpcodec.New(
		8192,
		httpcodec.WithMaxTrashRead(64*1024),
		httpcodec.WithInitJSONBufferCap(4*1024),
		httpcodec.WithMaxJSONBufferCap(256*1024),
	)

	r.Use(codec.Middleware())
	r.Post("/api/v1/batch", APIPostBatchHandler(codec))

	server := &http.Server{
		Addr:         ":8080",
		Handler:      r,
		ReadTimeout:  5 * time.Second,
		WriteTimeout: 5 * time.Second,
	}
	_ = server.ListenAndServe()
}
2. Использование в хендлерах (handler.go)

Чтение и отправка данных выполняются через методы кодека, скрывающие управление памятью:

package main

import (
	"net/http"
	"github.com/ioncode/httpcodec"
)

type RequestItem struct {
	CorrelationID string `json:"correlation_id"`
	Payload       string `json:"payload"`
}

type ResponseDTO struct {
	Status string   `json:"status"`
	IDs    []string `json:"processed_ids"`
}

func APIPostBatchHandler(codec *httpcodec.Codec) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		var items []RequestItem

		if !codec.ReadJSON(w, r, &items) {
			return 
		}

		processedIDs := make([]string, len(items))
		for i, item := range items {
			processedIDs[i] = item.CorrelationID
		}

		response := ResponseDTO{
			Status: "success",
			IDs:    processedIDs,
		}

		codec.WriteJSON(w, http.StatusCreated, &response)
	}
}

📜 Лицензия

MIT License. См. файл LICENSE для подробностей.

Documentation

Overview

Package httpcodec предоставляет высокопроизводительные инструменты для кодирования и декодирования HTTP-данных с нулевыми аллокациями и защитой периметра.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Codec

type Codec struct {
	// contains filtered or unexported fields
}

Codec объединяет высокопроизводительные и потокобезопасные инструменты для симметричного кодирования и декодирования HTTP-данных.

Структура инкапсулирует лимиты сетевого периметра и управляет двумя независимыми пулами переиспользования памяти (sync.Pool). Это позволяет минимизировать аллокации в куче (heap) и свести нагрузку на Garbage Collector (GC) к абсолютному минимуму (0 B/op).

func New

func New(maxBodySize int64, opts ...Option) *Codec

New создает и настраивает новый экземпляр Codec с поддержкой пулов памяти.

func (*Codec) Middleware

func (c *Codec) Middleware() func(http.Handler) http.Handler

Middleware возвращает стандартный перехватчик (http.Handler middleware), который аппаратно ограничивает размер тела входящего запроса на уровне TCP-сокета.

Метод полностью оптимизирован под рантайм Go 1.26.1 и использует лимит maxBodySize, заданный при инициализации кодека через конструктор New(). Для модифицирующих методов (POST, PUT, PATCH) поток r.Body оборачивается в http.MaxBytesReader.

Это гарантирует автоматическую синхронизацию лимитов сетевого периметра и пулов памяти, предотвращая атаки класса Slowloris DoS и переполнение буферов.

func (*Codec) ReadBytes

func (c *Codec) ReadBytes(w http.ResponseWriter, r *http.Request, processor func(payload []byte) bool) bool

ReadBytes выполняет оптимизированное чтение тела HTTP-запроса в виде сырых байт с использованием переиспользуемых буферов памяти из sync.Pool.

Метод полностью спроектирован под требования Highload-систем:

  1. Исключает аллокации в куче (heap) на этапе сетевого ввода-вывода (0 B/op).
  2. Принудительно зануляет память буфера через встроенную функцию clear(), гарантируя изоляцию данных и защиту от утечек (Data Bleed) между запросами клиентов.
  3. Полностью совместим с поведением постоянных соединений (Keep-Alive) и протоколом HTTP/2.
  4. Содержит автономный защитный контур DoS-защиты, который при превышении лимита maxBodySize безопасно вычитывает оставшийся хвост мусора в io.Discard (в пределах лимита maxTrashRead), что позволяет сохранить сокет чистым и переиспользовать TCP-соединение без TLS-хендшейков.

Если тело запроса пустое, повреждено или превышает допустимый размер, метод автоматически отправляет клиенту соответствующий HTTP-статус (400 или 413) и возвращает false. В случае успешного чтения управление передается в функцию-коллбэк processor.

func (*Codec) ReadJSON

func (c *Codec) ReadJSON(w http.ResponseWriter, r *http.Request, dst any) bool

ReadJSON выполняет оптимизированный, строго типизированный парсинг тела JSON-запроса.

Метод повторно использует оперативную память из внутреннего пула sync.Pool через вызов ReadBytes, полностью исключая аллокации в куче на этапе сетевого ввода-вывода (I/O). Десериализация данных в целевой объект dst производится с помощью высокопроизводительного кодировщика 'goccy/go-json'.

Если входящий JSON поврежден, содержит невалидные типы данных или неизвестные поля, метод автоматически отправляет клиенту ошибку HTTP 400 Bad Request и прерывает обработку.

func (*Codec) WriteJSON

func (c *Codec) WriteJSON(w http.ResponseWriter, statusCode int, data any)

WriteJSON выполняет высокопроизводительную потоковую сериализацию данных в JSON и отправку в сетевой сокет с защитой от OOM (Capacity Check). Полный исходный код доступен в документации.

type Option added in v0.0.2

type Option func(*Codec)

Option определяет сигнатуру функции для гибкого конфигурирования Кодека.

func WithInitJSONBufferCap added in v0.0.2

func WithInitJSONBufferCap(bytes int) Option

WithInitJSONBufferCap настраивает начальную емкость (pre-allocated capacity) для каждого нового bytes.Buffer, создаваемого внутри пула jsonPool.

func WithMaxJSONBufferCap added in v0.0.2

func WithMaxJSONBufferCap(bytes int) Option

WithMaxJSONBufferCap задает верхнюю границу емкости буфера ответа. Если буфер при маршалинге раздуется сильнее этого лимита, он утилизируется GC (защита от OOM).

func WithMaxTrashRead added in v0.0.2

func WithMaxTrashRead(bytes int64) Option

WithMaxTrashRead настраивает лимит вычитки «мусора» в пустоту для спасения Keep-Alive. Позволяет сохранить прогретое соединение, если клиент слегка превысил maxBodySize.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL