Implement HTTP timeout configurations and enhance API documentation

- Added optional HTTP server timeout configurations (`HNHMAP_READ_TIMEOUT`, `HNHMAP_WRITE_TIMEOUT`, `HNHMAP_IDLE_TIMEOUT`) to `.env.example` and updated the server initialization in `main.go` to utilize these settings.
- Enhanced API documentation for the `rebuildZooms` endpoint to clarify its background processing and polling mechanism for status updates.
- Updated `configuration.md` to include new timeout environment variables for better configuration guidance.
- Improved error handling in the client for large request bodies, ensuring appropriate responses for oversized payloads.
This commit is contained in:
2026-03-04 11:59:28 +03:00
parent a3a4c0e896
commit dda35baeca
17 changed files with 396 additions and 73 deletions

View File

@@ -12,6 +12,9 @@ import (
"github.com/andyleap/hnh-map/internal/app/services"
)
// maxClientBodySize is the maximum size for position and marker update request bodies.
const maxClientBodySize = 2 * 1024 * 1024 // 2 MB
var clientPath = regexp.MustCompile(`client/([^/]+)/(.*)`)
// ClientRouter handles /client/* requests with token-based auth.
@@ -112,12 +115,16 @@ func (h *Handlers) clientGridUpload(rw http.ResponseWriter, req *http.Request) {
func (h *Handlers) clientPositionUpdate(rw http.ResponseWriter, req *http.Request) {
defer req.Body.Close()
buf, err := io.ReadAll(req.Body)
buf, err := io.ReadAll(io.LimitReader(req.Body, maxClientBodySize+1))
if err != nil {
slog.Error("error reading position update", "error", err)
JSONError(rw, http.StatusBadRequest, "failed to read body", "BAD_REQUEST")
return
}
if len(buf) > maxClientBodySize {
JSONError(rw, http.StatusRequestEntityTooLarge, "request body too large", "PAYLOAD_TOO_LARGE")
return
}
if err := h.Client.UpdatePositions(req.Context(), buf); err != nil {
slog.Error("position update failed", "error", err)
HandleServiceError(rw, err)
@@ -126,12 +133,16 @@ func (h *Handlers) clientPositionUpdate(rw http.ResponseWriter, req *http.Reques
func (h *Handlers) clientMarkerUpdate(rw http.ResponseWriter, req *http.Request) {
defer req.Body.Close()
buf, err := io.ReadAll(req.Body)
buf, err := io.ReadAll(io.LimitReader(req.Body, maxClientBodySize+1))
if err != nil {
slog.Error("error reading marker update", "error", err)
JSONError(rw, http.StatusBadRequest, "failed to read body", "BAD_REQUEST")
return
}
if len(buf) > maxClientBodySize {
JSONError(rw, http.StatusRequestEntityTooLarge, "request body too large", "PAYLOAD_TOO_LARGE")
return
}
if err := h.Client.UploadMarkers(req.Context(), buf); err != nil {
slog.Error("marker update failed", "error", err)
HandleServiceError(rw, err)