{"id":19285681,"url":"https://github.com/wklken/echo","last_synced_at":"2025-11-16T13:05:19.149Z","repository":{"id":147861564,"uuid":"189574755","full_name":"wklken/echo","owner":"wklken","description":"An server will echo the requests detail into response. For api testing / benchmark for your proxies like APIGateway/ReverseProxy/nginx/traefik.","archived":false,"fork":false,"pushed_at":"2023-10-22T01:35:02.000Z","size":132,"stargazers_count":1,"open_issues_count":2,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-05T18:35:57.337Z","etag":null,"topics":["apigateway","golang","nginx","proxy","reverseproxy","test","testing-tools","traefik"],"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/wklken.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}},"created_at":"2019-05-31T10:20:31.000Z","updated_at":"2024-12-22T04:24:37.000Z","dependencies_parsed_at":null,"dependency_job_id":"40a30169-f27a-4f98-88d8-c31f7d952194","html_url":"https://github.com/wklken/echo","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wklken%2Fecho","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wklken%2Fecho/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wklken%2Fecho/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wklken%2Fecho/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wklken","download_url":"https://codeload.github.com/wklken/echo/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240390717,"owners_count":19793782,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["apigateway","golang","nginx","proxy","reverseproxy","test","testing-tools","traefik"],"created_at":"2024-11-09T21:46:21.599Z","updated_at":"2025-11-16T13:05:19.107Z","avatar_url":"https://github.com/wklken.png","language":"Go","readme":"# echo\n\nEcho server will echo the requests detail into response.\n\nFor api testing or benchmarking for your proxies like APIGateway/ReverseProxy/nginx/traefik.\n\nBuild on [chi](https://github.com/go-chi/chi) with simple logical, so the performance is good enough.\n\n\n# run\n\n```\nmake build\n\n./echo 9001\n```\n\n# apis\n\n### /ping/\n\n- AllowedMethods: all\n- return 200 with pong\n\n```shell\n$ curl -XPOST http://127.0.0.1:9001/ping/\n\n\u003e POST /ping/ HTTP/1.1\n\u003e Host: 127.0.0.1:9001\n\u003e User-Agent: curl/7.54.0\n\u003e Accept: */*\n\u003e\n\u003c HTTP/1.1 200 OK\n\u003c Date: Sun, 02 Jun 2019 00:19:19 GMT\n\u003c Content-Length: 4\n\u003c Content-Type: text/plain; charset=utf-8\n\npong\n```\n\n### /sleep/{sleep}/\n\n- AllowedMethods: all\n- will sleep for `{sleep}` ms\n- return 200 with ok\n\n```shell\n$ curl -XPOST http://127.0.0.1:9001/sleep/10/\n\n\u003e POST /sleep/10/ HTTP/1.1\n\u003e Host: 127.0.0.1:9001\n\u003e User-Agent: curl/7.54.0\n\u003e Accept: */*\n\u003e\n\u003c HTTP/1.1 200 OK\n\u003c Date: Sun, 02 Jun 2019 00:20:16 GMT\n\u003c Content-Length: 2\n\u003c Content-Type: text/plain; charset=utf-8\n\nok\n```\n\nand do the benchmark\n\n```shell\n$ wrk -t8 -c1000 -d10s http://127.0.0.1:9000/sleep/10/\nRunning 10s test @ http://127.0.0.1:9000/sleep/10/\n  8 threads and 1000 connections\n  Thread Stats   Avg      Stdev     Max   +/- Stdev\n    Latency    11.84ms   18.96ms 266.92ms   91.97%\n    Req/Sec     8.79k     2.04k   14.77k    64.38%\n  699458 requests in 10.04s, 117.40MB read\n  Socket errors: connect 0, read 916, write 0, timeout 0\n  Non-2xx or 3xx responses: 699458\nRequests/sec:  69640.30\nTransfer/sec:     11.69MB\n```\n\n### /status/{status}/\n\n- AllowedMethods: all\n- return `{status}`\n\n```\n$ curl -XPOST http://127.0.0.1:9001/status/500/\n\n\u003e POST /status/500/ HTTP/1.1\n\u003e Host: 127.0.0.1:9001\n\u003e User-Agent: curl/7.54.0\n\u003e Accept: */*\n\u003e\n\u003c HTTP/1.1 500 Internal Server Error\n\u003c Content-Type: text/plain; charset=utf-8\n\u003c X-Content-Type-Options: nosniff\n\u003c Date: Sun, 02 Jun 2019 00:21:01 GMT\n\u003c Content-Length: 22\n\nInternal Server Error\n```\n\n### /echo/\n\n- AllowedMethods: all\n- return 200, with the request contents in json\n\n```shell\n$ curl -XPOST http://127.0.0.1:9001/echo/\\?a\\=1\\\u0026b\\=2\n\n\u003e POST /echo/?a=1\u0026b=2 HTTP/1.1\n\u003e Host: 127.0.0.1:9001\n\u003e User-Agent: curl/7.54.0\n\u003e Accept: */*\n\u003e\n\u003c HTTP/1.1 200 OK\n\u003c Content-Type: application/json; charset=UTF-8\n\u003c Date: Sun, 02 Jun 2019 00:17:57 GMT\n\u003c Content-Length: 140\n\n{\n    \"body\": \"\",\n    \"form\":\n    {},\n    \"headers\":\n    {\n        \"Accept\": [\"*/*\"],\n        \"User-Agent\": [\"curl/7.54.0\"]\n    },\n    \"method\": \"POST\",\n    \"query\":\n    {\n        \"a\": [\"1\"],\n        \"b\": [\"2\"]\n    },\n    \"url\": \"/echo/\"\n}\n```\n\n### websocket\n\n- /ws/index/ the websocket test page\n- /ws/       the websocket api, will broadcast the message to all client\n\n### file upload/download\n\n- /file/download/{size}/   the size unit is KB\n\n```shell\n$ curl -XGET http://127.0.0.1:9001/file/download/1024/ -vv \u003e a.txt\n\n\u003e GET /file/download/1024/ HTTP/1.1\n\u003e Host: 127.0.0.1:3000\n\u003e User-Agent: curl/7.54.0\n\u003e Accept: */*\n\u003e\n\u003c HTTP/1.1 200 OK\n\u003c Accept-Ranges: bytes\n\u003c Content-Control: private, no-transform, no-store, must-revalidate\n\u003c Content-Disposition: attachment; filename=data.txt\n\u003c Content-Length: 1048576\n\u003c Content-Transfer-Encoding: binary\n\u003c Content-Type: text/plain; charset=utf-8\n\u003c Expires: 0\n\u003c Last-Modified: Tue, 02 Jul 2019 08:23:20 GMT\n\u003c Date: Tue, 02 Jul 2019 08:23:20 GMT\n\n$ du -h a.txt\n1M\n```\n\n\n- /file/upload/{filename}/\n\n```\n$ curl -XPOST \\\n  'http://127.0.0.1:9001/file/upload/data.txt/' \\\n  -H 'Content-Type: multipart/form-data' \\\n  -F data.txt=@/Downloads/data.txt -v\n\n\u003e POST /file/upload/data.txt/ HTTP/1.1\n\u003e Host: 127.0.0.1:3000\n\u003e User-Agent: curl/7.54.0\n\u003e Accept: */*\n\u003e Content-Length: 10430\n\u003e Expect: 100-continue\n\u003e Content-Type: multipart/form-data; boundary=------------------------1fb40c77823315c2\n\u003e\n\u003c HTTP/1.1 100 Continue\n\u003c HTTP/1.1 204 No Content\n\u003c Date: Tue, 02 Jul 2019 08:25:48 GMT\n```\n\n# TODO\n\n- [ ] httpbin apis\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwklken%2Fecho","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwklken%2Fecho","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwklken%2Fecho/lists"}