{"id":19110317,"url":"https://github.com/nxtrace/powclient","last_synced_at":"2026-06-20T22:31:01.790Z","repository":{"id":171542147,"uuid":"648069200","full_name":"nxtrace/powclient","owner":"nxtrace","description":null,"archived":false,"fork":false,"pushed_at":"2025-10-18T17:00:45.000Z","size":52,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-19T10:26:54.327Z","etag":null,"topics":["nexttrace","pow"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nxtrace.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-06-01T06:25:08.000Z","updated_at":"2025-10-18T17:00:49.000Z","dependencies_parsed_at":null,"dependency_job_id":"b6921014-5284-4eaf-8660-e79f400a4c0c","html_url":"https://github.com/nxtrace/powclient","commit_stats":null,"previous_names":["tsosunchia/powclient","nxtrace/powclient"],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/nxtrace/powclient","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nxtrace%2Fpowclient","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nxtrace%2Fpowclient/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nxtrace%2Fpowclient/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nxtrace%2Fpowclient/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nxtrace","download_url":"https://codeload.github.com/nxtrace/powclient/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nxtrace%2Fpowclient/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34587988,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-20T02:00:06.407Z","response_time":98,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["nexttrace","pow"],"created_at":"2024-11-09T04:24:37.902Z","updated_at":"2026-06-20T22:31:01.786Z","avatar_url":"https://github.com/nxtrace.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n\u003cimg src=\"https://github.com/nxtrace/NTrace-core/raw/main/assets/logo.png\" height=\"200px\" alt=\"NextTrace Logo\"/\u003e\n\n\u003c/div\u003e\n\n# POW CLIENT\n\nNEXTTRACE项目派生的仓库，用于实现POW反爬\n\nclient : https://github.com/tsosunchia/powclient\n\nserver : https://github.com/tsosunchia/powserver\n\n## 导出类型与函数\n```go\n// 获取 token 的主入口。\n// 成功返回 (token, nil)；失败返回 (\"\", err)。\nfunc RetToken(p *GetTokenParams) (string, error)\n\n// 参数：\ntype GetTokenParams struct {\n    TimeoutSec  time.Duration // 当 \u003e 0 时覆盖整个取 token 流程：获取 challenge、本地求解、提交 answer\n    BaseUrl     string        // 例如 \"https://example.com\"\n    RequestPath string        // 例如 \"/request_challenge\"\n    SubmitPath  string        // 例如 \"/submit_answer\"\n    UserAgent   string\n    SNI         string        // 可选：自定义 TLS SNI；不填则用默认的主机名\n    Host        string        // 可选：仅当非空时设置 req.Host\n    Proxy       *url.URL      // 可选：socks5:// 或 http://。不设置时默认走环境代理\n}\n\nfunc NewGetTokenParams() *GetTokenParams // 提供一份可用的默认值\n```\n\n## 错误模型（可用于精细化处理）\n```go\nvar (\n    ErrTooManyRequests  = errors.New(\"too many requests\")      // 429\n    ErrEmptyToken       = errors.New(\"empty token from server\") // 200 但 token 为空\n    ErrInvalidChallenge = errors.New(\"invalid challenge integer\") // challenge 非法、不可分解或不满足“恰好两个质因子”\n)\n\ntype HTTPStatusError struct {\n    Code int    // HTTP 状态码（非 200 且非 429）\n    Body string // 响应体前 2KB 片段（用于排错）\n}\n```  \n- 发生 429：返回 ErrTooManyRequests（可做重试/退避）\n- 发生其它非 200：返回 *HTTPStatusError（可通过 errors.As 拿到 Code/Body）\n- 发生 200 但 token 为空：返回 ErrEmptyToken\n- challenge 非法、不可分解、不是恰好两个质因子：返回 ErrInvalidChallenge（包含上下文）\n\n## DEMO\n```go\npackage main\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"log\"\n\t\"time\"\n\n\t\"github.com/tsosunchia/powclient\"\n)\n\nfunc main() {\n\tp := powclient.NewGetTokenParams()\n\tp.BaseUrl = \"https://pow.example.com\"\n\tp.TimeoutSec = 5 * time.Second\n\n\ttoken, err := powclient.RetToken(p)\n\tif err != nil {\n\t\t// 统一错误处理\n\t\tif errors.Is(err, powclient.ErrTooManyRequests) {\n\t\t\tlog.Println(\"rate limited, please retry later\")\n\t\t\treturn\n\t\t}\n\t\tvar he *powclient.HTTPStatusError\n\t\tif errors.As(err, \u0026he) {\n\t\t\tlog.Printf(\"http error: code=%d body=%q\\n\", he.Code, he.Body)\n\t\t\treturn\n\t\t}\n\t\tlog.Printf(\"get token failed: %v\\n\", err)\n\t\treturn\n\t}\n\n\tfmt.Println(\"token:\", token)\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnxtrace%2Fpowclient","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnxtrace%2Fpowclient","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnxtrace%2Fpowclient/lists"}