{"id":51014485,"url":"https://github.com/gechandesu/httest","last_synced_at":"2026-06-21T08:31:21.399Z","repository":{"id":366063909,"uuid":"1274918184","full_name":"gechandesu/httest","owner":"gechandesu","description":"HTTP test server","archived":false,"fork":false,"pushed_at":"2026-06-20T04:44:39.000Z","size":28,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-06-20T06:10:57.610Z","etag":null,"topics":["http-mocking","http-server","mock-server","testing","testing-tool","vlang"],"latest_commit_sha":null,"homepage":"","language":"V","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/gechandesu.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"COPYING","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":"2026-06-20T03:19:12.000Z","updated_at":"2026-06-20T04:44:42.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/gechandesu/httest","commit_stats":null,"previous_names":["gechandesu/httest"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/gechandesu/httest","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gechandesu%2Fhttest","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gechandesu%2Fhttest/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gechandesu%2Fhttest/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gechandesu%2Fhttest/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gechandesu","download_url":"https://codeload.github.com/gechandesu/httest/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gechandesu%2Fhttest/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34603546,"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-21T02:00:05.568Z","response_time":54,"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":["http-mocking","http-server","mock-server","testing","testing-tool","vlang"],"created_at":"2026-06-21T08:31:20.629Z","updated_at":"2026-06-21T08:31:21.355Z","avatar_url":"https://github.com/gechandesu.png","language":"V","funding_links":[],"categories":[],"sub_categories":[],"readme":"# httest\n\nA configurable HTTP test server written in V. Use it to mock backends, inspect\nrequests, simulate delays and errors, or run CGI scripts during integration testing.\n\n## Build\n\nInstall the [V compiler](https://github.com/vlang/v#installing-v-from-source), then run:\n\n```\nv install\nv .\n```\n\nThe binary is written to the current directory as `httest`. Pre-built binaries\ncan be found on the [releases](https://github.com/gechandesu/httest/releases/latest) page.\n\n## Usage\n\n```bash\nhttest [OPTION]... [ADDR]\n```\n\n`ADDR` is optional. It may be an IPv4/IPv6 address, hostname, or UNIX socket path.\nWhen omitted, the server listens on port 9000 on all interfaces.\n\n### Examples\n\nReturn a fixed response:\n\n```\nhttest -respond 201 -respond-body 'created' -H 'X-Custom: yes'\n```\n\nServe a file as the response body:\n\n```\nhttest -respond-file ./fixture.json -H 'Content-Type: application/json'\n```\n\nSimulate a slow backend:\n\n```\nhttest -response-delay 2s # constant 2 second delay\nhttest -response-delay 400-700 # random delay in milliseconds in range\n```\n\nRun a CGI script for every request:\n\n```\nchmod +x examples/hello.cgi\nhttest -cgi-script examples/hello.cgi\n```\n\nThen:\n\n```\ncurl 'http://127.0.0.1:9000/test?name=world' -d 'payload'\n```\n\n## Synopsis\n\n```\nUsage: httest [OPTION]... [ADDR]\n\nADDR may be an IPv4 or IPv6 IP-address, domain name or UNIX-socket path.\n\nOptions:\n  -help                     print this help message and exit.\n  -version                  print version info and exit.\n  -ipv4                     enable IPv4-only mode.\n  -ipv6                     enable IPv6-only mode.\n  -backlog \u003cint\u003e            max number of parallel connections on socket,\n                            defaults to 128.\n  -log-level \u003cstring\u003e       log level, one of: none, fatal, error, warn,\n                            info, debug, trace.\n  -log-output \u003cstring\u003e      where to write logs: stdout, stderr (default) or\n                            filepath.\n  -F, -log-fields \u003cstring\u003e  See Log fields control below.\n  -request-id-header \u003cstring\u003e\n                            read request ID from header.\n  -respond \u003cint\u003e            response HTTP status code, 200 by default.\n  -H, -respond-header \u003cstring\u003e (allowed multiple times)\n                            response header as 'key: value' pair.\n  -respond-body \u003cstring\u003e    response body as string.\n  -respond-file \u003cstring\u003e    read response body from file.\n  -response-delay \u003cstring\u003e  response delay e.g 1s, 3m, 100-900ms, 300 (in\n                            milliseconds by default).\n  -cgi-script \u003cstring\u003e      path to CGI script to execute for each request.\n\nWhen -cgi-script is set, the script handles the request instead of the static\n-respond* options.\n\nLog fields control:\n\nBelow are listed all available log fields in the order they appear in the logs.\nFields marked by * are non-defaults.\n\n  id          auto-generated or passed through -request-id-header request ID.\n  method      used HTTP method.\n  path        request path.\n  status      HTTP response status code as integer.\n  recv        size of request body in bytes.\n  sent        size of response body in bytes.\n  elapsed     request processing time excluding HTTP parsing time.\n  remote*     remote address from Remote-Addr header.\n  user_agent* request User-Agent header value.\n  headers*    all request headers separated by `;`.\n  body*       request body text as is.\n\nYou can add or remove fields from the HTTP request log using the -log-fields\n(-F) option. To add a field, specify its name without a prefix or with a `+`\nprefix. For example `-F +body` enables request body logging. You can list\nmultiple fields separated by commas. `-` prefix disables the log field. There\nis also two special values `all` and `default` (for default set). Examples:\n  httest -F +headers,body,-id\n  httest -F +all\n  httest -F -default,+id,method,path,status,elapsed\n```\n\n## CGI support\n\nWith `-cgi-script`, `httest` runs the given executable once per HTTP request.\n\nThe server:\n\n1. Builds a [CGI/1.1](https://datatracker.ietf.org/doc/html/rfc3875) environment from the request (`REQUEST_METHOD`, `QUERY_STRING`, `PATH_INFO`, `CONTENT_*`, `HTTP_*`, and related variables).\n2. Writes the request body to the script's standard input.\n3. Reads the script's standard output and parses CGI-style headers (if present) followed by the response body.\n4. Returns 502 Bad Gateway if the script is missing, exits with a non-zero status, or fails to run.\n\nThe script must be executable (typically with a shebang line). Example:\n\n```bash\n#!/usr/bin/env python3\nimport os\nprint(\"Content-Type: text/plain\")\nprint()\nprint(os.environ[\"REQUEST_METHOD\"], os.environ[\"PATH_INFO\"])\n```\n\nSupported CGI response headers include:\n\n- `Status: 404 Not Found` — sets the HTTP status code\n- `Content-Type: ...` — response content type\n- `Location: ...` — redirect (status 302)\n\nIf the script prints no header block, the entire output is returned as the body\nwith status 200.\n\n## Logging\n\nEach processed request is logged as a structured line. Default fields:\n\n`id`, `method`, `path`, `status`, `recv`, `sent`, `elapsed`\n\nUse `-F` to add or remove fields. Enable logging the request body and headers:\n\n```\nhttest -F +headers,body\n```\n\nEnable all available log fields:\n\n```\nhttest -F +all\n```\n\nSee Synopsis above or `httest -help` for details.\n\n## License\n\nSPDX identifier: `GPL-3.0-or-later`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgechandesu%2Fhttest","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgechandesu%2Fhttest","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgechandesu%2Fhttest/lists"}