{"id":13764103,"url":"https://github.com/codemodus/chain","last_synced_at":"2026-01-12T13:55:36.398Z","repository":{"id":32061492,"uuid":"35633280","full_name":"codemodus/chain","owner":"codemodus","description":"Composable chains of nested http.Handler instances.","archived":false,"fork":false,"pushed_at":"2018-08-25T20:35:40.000Z","size":41,"stargazers_count":61,"open_issues_count":0,"forks_count":3,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-05-10T17:41:38.325Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","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/codemodus.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-05-14T19:52:58.000Z","updated_at":"2025-03-04T10:42:21.000Z","dependencies_parsed_at":"2022-06-26T17:39:28.195Z","dependency_job_id":null,"html_url":"https://github.com/codemodus/chain","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/codemodus/chain","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codemodus%2Fchain","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codemodus%2Fchain/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codemodus%2Fchain/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codemodus%2Fchain/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/codemodus","download_url":"https://codeload.github.com/codemodus/chain/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codemodus%2Fchain/sbom","scorecard":{"id":296884,"data":{"date":"2025-08-11","repo":{"name":"github.com/codemodus/chain","commit":"bb99cd2071affdfe6242b2655c84ebdb82363ea0"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"checks":[{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}}]},"last_synced_at":"2025-08-17T19:46:32.284Z","repository_id":32061492,"created_at":"2025-08-17T19:46:32.284Z","updated_at":"2025-08-17T19:46:32.284Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28339969,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-12T12:22:26.515Z","status":"ssl_error","status_checked_at":"2026-01-12T12:22:10.856Z","response_time":98,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: 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":[],"created_at":"2024-08-03T15:01:13.888Z","updated_at":"2026-01-12T13:55:36.363Z","avatar_url":"https://github.com/codemodus.png","language":"Go","readme":"# chain\n\n    go get github.com/codemodus/chain\n\nPackage chain aids the composition of nested http.Handler instances.\n\nNesting functions is a simple concept.  If your nested handler order does not \nneed to be composable, please do not use this or any similar package and avoid \nadding a dependency to your project.\n\n## Usage\n\n```go\ntype Chain\n    func New(handlers ...func(http.Handler) http.Handler) *Chain\n    func (c *Chain) Append(handlers ...func(http.Handler) http.Handler) *Chain\n    func (c *Chain) Copy(chain *Chain)\n    func (c *Chain) End(handler http.Handler) http.Handler\n    func (c *Chain) EndFn(handlerFunc http.HandlerFunc) http.Handler\n    func (c *Chain) Merge(chains ...*Chain) *Chain\n```\n\n### Setup\n\n```go\nimport (\n    // ...\n\n    \"github.com/codemodus/chain\"\n)\n\nfunc main() {\n    // ...\n\n  \t// Nested handlers write either \"0\" or \"1\" to the response body before\n\t// and after ServeHTTP() is called.\n\t//\n\t// endHandler writes \"_END_\" to the response body.\n\n\tch00 := New(nestedHandler0, nestedHandler0)\n\tch001 := ch00.Append(nestedHandler1)\n\n\tch1 := New(nestedHandler1)\n\tch1001 := ch1.Merge(ch001)\n\n\tmux := http.NewServeMux()\n\tmux.Handle(\"/00_End\", ch00.EndFn(endHandler))     // Resp Body: \"00_END_00\"\n\tmux.Handle(\"/001_End\", ch001.EndFn(endHandler))   // Resp Body: \"001_END_100\"\n\tmux.Handle(\"/1001_End\", ch1001.EndFn(endHandler)) // Resp Body: \"1001_END_1001\"\n\n    // ...\n}\n```\n\n### Nestable http.Handler\n\n```go\nfunc nestableHandler(next http.Handler) http.Handler {\n    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n        // ...\n        \n        next.ServeHTTP(w, r)\n    \t\n        // ...\n    })\n}\n```\n\n## More Info\n\n### Changes in go1.7+/chain2.0+\n\nAs of Go 1.7, the http package's Request type includes a field (accessed via \nthe Context() method) which holds an implementation of context.Context. Further, \nthe context package has been added to the standard library. There is now no need \nfor the custom Handler defined in previous versions of chain. Please refer to \nthe following command to ease the process of updating your source.\n\n    sed -r -e 's/chain\\.Handler/http.Handler/g' \\\n        -e 's/[a-zA-Z0-9]+ context\\.Context, ([a-zA-Z0-9]+) (http\\.ResponseWriter)/\\1 \\2/' \\\n        -e 's/ServeHTTPContext\\([a-zA-Z0-9]+, /ServeHTTP(/'\n\nBeyond this, any usage of chain.Set(context.Context) will need to be modified\nmanually. Adding the affected logic as a nested handler is a simple and \neffective alternative. Don't forget to run gofmt/goimports.\n\n## Documentation\n\nView the [GoDoc](http://godoc.org/github.com/codemodus/chain)\n\n## Benchmarks\n\nThese results are for comparison of normally nested functions, and chained \nfunctions.  Each benchmark includes 10 functions prior to the final handler.\n\n    go1.7\n    benchmark             iter      time/iter   bytes alloc         allocs\n    ---------             ----      ---------   -----------         ------\n    BenchmarkChain10     20000    61.01 μs/op     3684 B/op   51 allocs/op\n    BenchmarkChain10-4   20000    68.62 μs/op     3691 B/op   51 allocs/op\n    BenchmarkChain10-8   20000    69.33 μs/op     3696 B/op   51 allocs/op\n    BenchmarkNest10      20000    60.36 μs/op     3684 B/op   51 allocs/op\n    BenchmarkNest10-4    20000    70.82 μs/op     3692 B/op   51 allocs/op\n    BenchmarkNest10-8    20000    71.03 μs/op     3697 B/op   51 allocs/op\n","funding_links":[],"categories":["Web Frameworks","XML","Web框架","中间件### 中间件","中间件","Libraries for creating HTTP middlewares"],"sub_categories":["Middlewares","中间件","创建http中间件的代码库","Fail injection","中間件"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodemodus%2Fchain","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcodemodus%2Fchain","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodemodus%2Fchain/lists"}