{"id":19419523,"url":"https://github.com/eexit/mirror-http-server","last_synced_at":"2026-03-04T12:03:51.958Z","repository":{"id":38984036,"uuid":"45647619","full_name":"eexit/mirror-http-server","owner":"eexit","description":"A dummy HTTP server that responds whatever you told it to","archived":false,"fork":false,"pushed_at":"2024-05-28T16:02:34.000Z","size":358,"stargazers_count":39,"open_issues_count":2,"forks_count":7,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-24T14:43:13.865Z","etag":null,"topics":["docker","docker-container","docker-image","dummy-server","http","http-mirror","http-server","mirroring"],"latest_commit_sha":null,"homepage":"https://mirror-http-server.web.app","language":"JavaScript","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/eexit.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":"2015-11-05T23:58:31.000Z","updated_at":"2025-03-16T11:47:32.000Z","dependencies_parsed_at":"2024-11-10T13:18:23.445Z","dependency_job_id":"895de8a2-826f-462f-b06d-6b230cd0459d","html_url":"https://github.com/eexit/mirror-http-server","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/eexit/mirror-http-server","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eexit%2Fmirror-http-server","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eexit%2Fmirror-http-server/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eexit%2Fmirror-http-server/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eexit%2Fmirror-http-server/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/eexit","download_url":"https://codeload.github.com/eexit/mirror-http-server/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eexit%2Fmirror-http-server/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30079565,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-04T11:57:42.557Z","status":"ssl_error","status_checked_at":"2026-03-04T11:56:10.793Z","response_time":59,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5: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":["docker","docker-container","docker-image","dummy-server","http","http-mirror","http-server","mirroring"],"created_at":"2024-11-10T13:18:06.925Z","updated_at":"2026-03-04T12:03:51.931Z","avatar_url":"https://github.com/eexit.png","language":"JavaScript","readme":"![logo](logo.png)\n\n# Mirror HTTP Server [![DockerHub](https://img.shields.io/docker/image-size/eexit/mirror-http-server?color=brightgreen)](https://hub.docker.com/r/eexit/mirror-http-server/) [![Firebase function](https://img.shields.io/badge/firebase-function-brightgreen)](https://mirror-http-server.web.app)\n\n*A dummy HTTP server that responds whatever you told it to.*\n\nTesting URL: \u003chttps://mirror-http-server.web.app\u003e\n\nBuilt to play with HTTP or test your API. Make a HTTP call to the dummy server with the specified headers you want the server responds with.\n\n## Usage\n\nPull the [Docker container](https://hub.docker.com/repository/docker/eexit/mirror-http-server):\n\n    docker pull eexit/mirror-http-server\n\nStart the container:\n\n    $ docker run -itp 8080:8080 eexit/mirror-http-server\n    2015-11-05T20:59:57.353Z]  INFO: mirror-http-server/17 on ccc867df5980: Listening on http://0.0.0.0:8080\n\nFor this README examples, I use the great [HTTPie](https://github.com/jkbrzt/httpie) tool.\n\nSend request against it:\n\n    http :8080\n\n```http\nHTTP/1.1 200 OK\nConnection: keep-alive\nContent-Length: 0\nDate: Wed, 13 Mar 2019 12:38:07 GMT\nX-Powered-By: Express\n```\n\nYou can use any [HTTP verbs](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods) with any path, any request body and any header.\n\n### Server behavioural request headers\n\nYou can change the server response code and body by setting specific `X-Mirror-*` headers to your request.\n\n### `X-Mirror-Code`\n\nChange the server response [status code](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes).\n\nExamples that simulates a `301` redirection and a `Content-Type` change:\n\n    http :8080 \\\n        X-Mirror-Code:301 \\\n        X-Mirror-Location:http://www.eexit.net \\\n        X-Mirror-Content-Type:\"text/plain; charset=ISO-8859-1\"\n\n```http\nHTTP/1.1 301 Moved Permanently\nConnection: keep-alive\nContent-Length: 0\nContent-Type: text/plain; charset=ISO-8859-1\nDate: Wed, 13 Mar 2019 12:41:35 GMT\nLocation: http://www.eexit.net\nX-Powered-By: Express\n```\n\nIf you add the `--follow` option, it will output my website HTML source.\n\nIf you check the container logs:\n\n```json\n[2019-03-13T12:41:35.567Z]  INFO: mirror-http-server/18 on f9c1a773d75a:\n    request: {\n      \"ip\": \"172.17.0.1\",\n      \"ips\": [],\n      \"method\": \"GET\",\n      \"url\": \"/\",\n      \"headers\": {\n        \"host\": \"localhost\",\n        \"user-agent\": \"HTTPie/1.0.2\",\n        \"accept-encoding\": \"gzip, deflate\",\n        \"accept\": \"*/*\",\n        \"connection\": \"keep-alive\",\n        \"x-mirror-code\": \"301\",\n        \"x-mirror-location\": \"http://www.eexit.net\",\n        \"x-mirror-content-type\": \"text/plain; charset=ISO-8859-1\"\n      },\n      \"body\": {}\n    }\n```\n\n### `X-Mirror-Delay`\n\nIf you need to test timeouts or errors handling like `503` HTTP responses, you can pass the\n`X-Mirror-Delay` header with a number in milliseconds before the server responds.\n\n```bash\ntime http :8080 X-Mirror-Code:503 X-Mirror-Delay:2000\nHTTP/1.1 503 Service Unavailable\nConnection: keep-alive\nContent-Length: 0\nDate: Fri, 20 May 2022 09:52:04 GMT\nKeep-Alive: timeout=5\nX-Powered-By: Express\n\n\n\nhttp :8080 X-Mirror-Code:503 X-Mirror-Delay:2000  0.12s user 0.03s system 7% cpu 2.163 total\n```\n\n### `X-Mirror-Request`\n\nIf you can't access to the container log or want to exploit what's logged under the hood, set the `X-Mirror-Request` to receive the logged entry (as JSON):\n\n    $ http POST :80/resource \\\n        X-Mirror-Code:201 \\\n        X-Mirror-Request:true \\\n        key1=value1 key2=value2\n\n```http\nHTTP/1.1 201 Created\nConnection: keep-alive\nContent-Length: 371\nContent-Type: application/json; charset=utf-8\nDate: Wed, 13 Mar 2019 12:43:02 GMT\nETag: W/\"173-rgXpQ/N7aKeAq+URc1y3vQypNZk\"\nX-Powered-By: Express\n\n{\n    \"request\": {\n        \"body\": {\n            \"key1\": \"value1\",\n            \"key2\": \"value2\"\n        },\n        \"headers\": {\n            \"accept\": \"application/json, */*\",\n            \"accept-encoding\": \"gzip, deflate\",\n            \"connection\": \"keep-alive\",\n            \"content-length\": \"36\",\n            \"content-type\": \"application/json\",\n            \"host\": \"localhost\",\n            \"user-agent\": \"HTTPie/1.0.2\",\n            \"x-mirror-code\": \"201\",\n            \"x-mirror-request\": \"true\"\n        },\n        \"ip\": \"172.17.0.1\",\n        \"ips\": [],\n        \"method\": \"POST\",\n        \"url\": \"/resource\"\n    }\n}\n```\n\nNote: if you don't specify the `true` value for the header, it'll ignored.\n\n### `X-Mirror-Body`\n\nInstead, if you wish the dummy server to return you the body you sent to it, set the `X-Mirror-Body` header.\n\nNote: the `X-Mirror-Request` header will override `X-Mirror-Body` header.\n\n    $ http PUT :80/resource \\\n        X-Mirror-Code:400 \\\n        X-Mirror-Body:true \\\n        key1=value1 key2=value2\n\n```http\nHTTP/1.1 400 Bad Request\nConnection: keep-alive\nContent-Length: 33\nContent-Type: application/json; charset=utf-8\nDate: Wed, 13 Mar 2019 12:43:45 GMT\nETag: W/\"21-SWsq4vawbQc/koBuf3CC1L6ssws\"\nX-Powered-By: Express\n\n{\n    \"key1\": \"value1\",\n    \"key2\": \"value2\"\n}\n```\n\nNote: if you don't specify the `true` value for the header, it'll ignored.\n\n### Works with any headers\n\nAside to the previous three special headers, you can set your wanted response header by prepending your header name by `X-Mirror-`.\n\nIn the request:\n\n```http\nContent-Type: application/json\nX-Mirror-Content-Type: text/html\n```\n\nYou'll get in your response:\n\n```http\nContent-Type: text/html\n```\n\nYou can even override Express headers or any other default header:\n\n```http\nX-Mirror-X-Powered-By: eexit-engine\nX-Mirror-Date: some date\n```\n\nWill turn into:\n\n```http\nX-Powered-By: eexit-engine\nDate: some date\n```\n\n## Development\n\nYou can either use Docker to run the server locally or emulate the function using Firebase CLI:\n\nIn one terminal, run this command:\n\n```\ncd functions\nyarn\nfirebase emulators:start --only functions\n```\n\nIn another terminal, test it:\n\n```\nhttp http://localhost:5001/mirror-http-server/us-central1/mirror X-Mirror-Body:true message=\"Hello world\\!\"\nHTTP/1.1 200 OK\nconnection: keep-alive\ncontent-length: 26\ncontent-type: application/json; charset=utf-8\ndate: Sun, 06 Nov 2022 10:56:21 GMT\netag: W/\"1a-T7vCLEZV7pLSyUzkr9XBdG32YU8\"\nkeep-alive: timeout=5\nx-powered-by: Express\n\n{\n    \"message\": \"Hello world!\"\n}\n```\n\n## Deployment\n\nThis service is host as [Google Clound Platform Cloud Function](https://firebase.google.com/docs/functions).\n\n```\nfirebase deploy --only functions\n```\n\n## Todo\n\n- Functional testing\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feexit%2Fmirror-http-server","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feexit%2Fmirror-http-server","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feexit%2Fmirror-http-server/lists"}