{"id":51784675,"url":"https://github.com/faustbrian/go-http-middleware","last_synced_at":"2026-07-20T16:31:20.870Z","repository":{"id":371968149,"uuid":"1304160397","full_name":"faustbrian/go-http-middleware","owner":"faustbrian","description":"Composable server-side HTTP middleware with explicit ordering and transport-safe behavior.","archived":false,"fork":false,"pushed_at":"2026-07-18T02:51:32.000Z","size":136,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-18T03:17:09.290Z","etag":null,"topics":["compression","cors","go","golang","http","microservices","middleware","net-http","security-headers","trusted-proxy"],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/faustbrian.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":"NOTICE","maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-07-17T15:59:13.000Z","updated_at":"2026-07-18T02:51:35.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/faustbrian/go-http-middleware","commit_stats":null,"previous_names":["faustbrian/go-http-middleware"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/faustbrian/go-http-middleware","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/faustbrian%2Fgo-http-middleware","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/faustbrian%2Fgo-http-middleware/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/faustbrian%2Fgo-http-middleware/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/faustbrian%2Fgo-http-middleware/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/faustbrian","download_url":"https://codeload.github.com/faustbrian/go-http-middleware/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/faustbrian%2Fgo-http-middleware/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35693381,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-07-20T02:08:10.276Z","status":"ssl_error","status_checked_at":"2026-07-20T02:08:09.736Z","response_time":111,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["compression","cors","go","golang","http","microservices","middleware","net-http","security-headers","trusted-proxy"],"created_at":"2026-07-20T16:31:20.078Z","updated_at":"2026-07-20T16:31:20.858Z","avatar_url":"https://github.com/faustbrian.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# go-http-middleware\n\n[![CI](https://github.com/faustbrian/go-http-middleware/actions/workflows/ci.yml/badge.svg)](https://github.com/faustbrian/go-http-middleware/actions/workflows/ci.yml)\n[![Release](https://github.com/faustbrian/go-http-middleware/actions/workflows/release.yml/badge.svg)](https://github.com/faustbrian/go-http-middleware/actions/workflows/release.yml)\n[![Go Reference](https://pkg.go.dev/badge/github.com/faustbrian/go-http-middleware.svg)](https://pkg.go.dev/github.com/faustbrian/go-http-middleware)\n[![Go Report Card](https://goreportcard.com/badge/github.com/faustbrian/go-http-middleware)](https://goreportcard.com/report/github.com/faustbrian/go-http-middleware)\n\nExplicit, bounded server-side HTTP middleware built on `net/http`. The root\npackage composes only the middleware supplied by the caller. There is no\nregistry, router, server runtime, service container, background process, or\nglobal default chain.\n\n## Five-minute chain\n\n```go\nmust := func(value middleware.Middleware, err error) middleware.Middleware {\n    if err != nil {\n        panic(err) // Fail startup on invalid transport policy.\n    }\n    return value\n}\n\nids := must(requestid.New(requestid.Policy{}))\nrecoverPanics := must(recovery.New(recovery.Policy{}))\nlimitBodies := must(bodylimit.New(bodylimit.Policy{MaxBytes: 1 \u003c\u003c 20}))\nsecurity := must(secureheader.New(secureheader.APIDefaults()))\n\nchain, err := middleware.New(\n    recoverPanics,\n    ids,\n    limitBodies,\n    security,\n)\nif err != nil {\n    panic(err)\n}\nhandler, err := chain.Handler(application)\nif err != nil {\n    panic(err)\n}\nif err := http.ListenAndServe(\":8080\", handler); err != nil {\n    panic(err)\n}\n```\n\nThe first middleware receives the request first. The response returns through\nthe list in reverse. `Handler` rejects nil terminals, invalid descriptors, and\nmiddleware that returns nil.\n\n## Independently importable middleware\n\nEvery subpackage returns the standard `func(http.Handler) http.Handler` shape:\n\n```go\nlimit, err := bodylimit.New(bodylimit.Policy{MaxBytes: 8 \u003c\u003c 20})\nif err != nil {\n    return err\n}\nhandler := limit(uploadHandler)\n```\n\nImporting the root does not import codecs, telemetry SDKs, authentication,\nauthorization, rate limiting, idempotency, routing, or server lifecycle.\n\n## Packages\n\n| Package | Owns | Important boundary |\n|---|---|---|\n| root | chains, descriptors, conditions | 256-layer maximum |\n| `requestid` | request/correlation IDs | inbound values untrusted by default |\n| `recovery` | panic containment | never rewrites committed responses |\n| `bodylimit` | encoded request byte limit | no payload decoding |\n| `deadline` | context and buffered handler timeouts | no arbitrary-code interruption |\n| `proxy` | effective peer/host/scheme/prefix | explicit trusted networks only |\n| `cors` | server CORS responses and preflights | not authentication or CSRF |\n| `secureheader` | explicit response headers | HSTS requires acknowledgement |\n| `compress` | bounded gzip negotiation | buffered mode is not streaming |\n| `observe` | bounded completion events | no raw path, query, body, or headers |\n| `content` | 406/415 media guards | no encoder or decoder |\n| `admission` | local in-flight bounds | not distributed rate limiting |\n| `responsepolicy` | no-store and readiness admission | no response cache |\n| `adapter` | ownership names and overlap checks | no sibling policy reimplementation |\n| `middlewaretest` | deterministic fixtures | test-only behavior helpers |\n\n## Recommended API order\n\n`recovery -\u003e trusted proxy -\u003e request ID -\u003e observe -\u003e CORS -\u003e security\nheaders -\u003e admission -\u003e deadline/body limit -\u003e owning-package policies -\u003e\ncompression -\u003e application`\n\nOrder is application-specific. Compression must remain outside handlers whose\nalready-encoded responses it should observe, and recovery must surround every\nlayer whose panic it should contain. See [the ordering reference](docs/ordering.md).\n\n## Security posture\n\nDefaults deny forwarding and inbound identifier trust. All configured header\nvalues reject controls. Parsing and retained buffers have explicit limits.\nThese controls complement, but do not replace, ingress validation, server\ntimeouts, TLS, request-header limits, authentication, authorization, CSRF\ndefenses, or application validation.\n\nRead [SECURITY.md](SECURITY.md), [the threat model](docs/threat-model.md), and\n[deployment guidance](docs/security.md) before production use.\n\n## Compatibility\n\nThe minimum toolchain is Go 1.26.5. Normal tracking and header wrappers preserve\nthe exact `Flusher`, `Hijacker`, `Pusher`, and `ReaderFrom` set of the underlying\nwriter. Buffered timeout and compression intentionally do not expose streaming\ninterfaces. See [the complete matrix](docs/responsewriter.md).\n\n## Development\n\n```sh\nmake check\n```\n\nEvery blocking CI command has a local target. `make nilaway` is advisory.\nHosted release publication remains separate from local verification.\n\nThe CI badge covers the blocking `quality`, `lint`, `staticcheck`, and\n`vulnerability` jobs. Release verification repeats `make check` before a\nsigned provenance attestation and release assets are published.\n\n## License\n\nMIT. See [LICENSE](LICENSE) and [NOTICE](NOTICE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffaustbrian%2Fgo-http-middleware","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffaustbrian%2Fgo-http-middleware","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffaustbrian%2Fgo-http-middleware/lists"}