{"id":18204461,"url":"https://github.com/3p3r/fakettp","last_synced_at":"2026-01-31T02:02:50.324Z","repository":{"id":204643077,"uuid":"709978483","full_name":"3p3r/fakettp","owner":"3p3r","description":"sandbox node core http module in a service worker.","archived":false,"fork":false,"pushed_at":"2024-06-29T17:16:01.000Z","size":469,"stargazers_count":1,"open_issues_count":3,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-06-04T22:12:21.035Z","etag":null,"topics":["http-server","mocking","node","service-worker","testing","webpack"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/3p3r.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":"2023-10-25T18:56:29.000Z","updated_at":"2024-09-18T23:22:36.000Z","dependencies_parsed_at":null,"dependency_job_id":"6acd3c79-0bdc-40ca-b221-e3cf83d6da35","html_url":"https://github.com/3p3r/fakettp","commit_stats":null,"previous_names":["3p3r/fakettp"],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/3p3r/fakettp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/3p3r%2Ffakettp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/3p3r%2Ffakettp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/3p3r%2Ffakettp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/3p3r%2Ffakettp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/3p3r","download_url":"https://codeload.github.com/3p3r/fakettp/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/3p3r%2Ffakettp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28926630,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-30T22:32:35.345Z","status":"online","status_checked_at":"2026-01-31T02:00:09.179Z","response_time":128,"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-server","mocking","node","service-worker","testing","webpack"],"created_at":"2024-11-03T11:04:25.456Z","updated_at":"2026-01-31T02:02:50.310Z","avatar_url":"https://github.com/3p3r.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# fakettp\n\nsandbox node core http module in a service worker.\n\n- [disclaimer](#disclaimer)\n- [motivation](#motivation)\n- [usage](#usage)\n- [demo](#demo)\n- [development](#development)\n- [compatibility](#compatibility)\n- [limitations](#limitations)\n\n## disclaimer\n\n\u003e this is part of a security focused research project I am currently working on.\n\u003e as it usually goes for security software, this can be used for good or evil.\n\u003e this can also harm your computer or browser and cause you inconvenience.\n\u003e **I do not take any responsibility for any damages caused by this software.**\n\u003e proceed at your own risk. absolutely no warranty is provided. you may brick\n\u003e your browser if you do not know how to use this library properly.\n\nif you are new, it is not all hopeless. make sure you understand the intricacies\nof [service workers][2] and its security implications before using this library.\n\n## motivation\n\nin building progressive web apps and performing client side testing and caching,\nit is immensely helpful to have something like express or socket.io available in\norder to reuse packages on npm made for various http interaction needs.\n\nusing this library in a bundler allows reuse of applications made for node.js in\nterms of interaction with the core http module.\n\ncreating the http server this way does not involve a network adapter and is thus\naccessible where environment is restricted. sending requests in browsers is also\nlocal and does not involve any network adapter (including loopback).\n\n## usage\n\nthis library is designed to be used in a bundler like [webpack](webpack.js.org).\nfakettp is a drop in replacement for node's http module. two requirements should\nbe met to use it in a bundler successfully:\n\n1. alias `http` to `fakettp` in your bundler config.\n2. provide fallbacks for anything else that your code may use from node core.\n\nexample webpack config:\n\n```sh\nnpm install fakettp --save-dev\n```\n\n```js\nmodule.exports = {\n  resolve: {\n    plugins: [\n      new webpack.ProvidePlugin({\n        process: \"process/browser\",\n        Buffer: [\"buffer\", \"Buffer\"],\n        URL: [\"url\", \"URL\"],\n      }),\n    ],\n    fallback: {\n      http: require.resolve(\"fakettp\"),\n      util: require.resolve(\"util/\"),\n      events: require.resolve(\"events/\"),\n      buffer: require.resolve(\"buffer/\"),\n      assert: require.resolve(\"assert/\"),\n      stream: require.resolve(\"stream-browserify\"),\n    }\n  },\n};\n```\n\nyou can use [configuration of this repository](webpack.config.ts) as reference.\n\n## demo\n\ncheck out the examples that are known to work in [samples](./ext/samples) folder\nand the [webpack config](./webpack.config.ts) for this repository.\n\n![demo](./ext/demo.png)\n\nyou can create a server and listen like so:\n\n```js\nconst server = FAKETTP.createServer().on(\"request\", (req, res) =\u003e {\n  req.on('data', (chunk) =\u003e {\n    console.log(`Received ${chunk.length} bytes of data in request body.`);\n    console.log(`Request chunk: ${chunk.toString()}`);\n  });\n  req.on('end', () =\u003e {\n    console.log('No more data in request body.');\n  });\n  res.writeHead(200, { 'Content-Type': 'text/plain' });\n  res.end('{\"yo\":\"nice\"}');\n}).listen(443, \"google.com\");\n```\n\n![listen](./ext/listen.png)\n\nafter that all requests will be intercepted and handled by the service worker.\nthe host and port to watch for can be configured by passing options to `listen`.\n\nyou can for example send a request to the server like so:\n\n```js\nasync function postData(data = {}, url = \"https://google.com/fake.html\") {\n  const response = await fetch(url, {\n    method: \"POST\",\n    headers: {\n      \"Content-Type\": \"application/json\",\n    },\n    body: JSON.stringify(data),\n  });\n  return response.json();\n}\n\npostData({ answer: \"browser\" }).then((data) =\u003e {\n  console.log(data);\n});\n```\n\n![response](./ext/response.png)\n\nyou can also close the server like so:\n\n```js\nserver.close();\n```\n\nand if you attempt to send a request after that, you will get an error:\n\n![close](./ext/close.png)\n\n## development\n\n- `npm test` to run tests.\n- `npm run build` to build the project.\n- `npm run serve` to start webpack dev server.\n- `npm run watch` to watch for changes and rebuild.\n- `npx http-serve --cors dist` to run production build.\n\n## compatibility\n\nworking samples:\n\n- `ext/samples/express.ts`: express app with a dynamic route.\n- `ext/samples/express-post.ts`: express app with a post route.\n- `ext/samples/express-static.ts`: express app with static files.\n- `ext/samples/socket-io.ts`: express app with socket io.\n- `ext/samples/remote-context`: shows the usage of `fakettp.html`.\n\nthis is what is known to work good enough for most use cases:\n\n- `http.createServer([options][, requestListener])` *one instance per session*\n- `http.METHODS` through [stream-http][1]\n- `http.STATUS_CODES` through [stream-http][1]\n- `http.get(options[, callback])` through [stream-http][1]\n- `http.get(url[, options][, callback])` through [stream-http][1]\n- `http.request(options[, callback])` through [stream-http][1]\n- `http.request(url[, options][, callback])` through [stream-http][1]\n- class: `http.ClientRequest` through [stream-http][1]\n- class: `http.Server`\n  - event: `'close'`\n  - event: `'connection'`\n  - event: `'request'`\n  - `server.close([callback])`\n  - `server.listen()`\n  - `server.listen(port[, host][, callback])`\n  - `server.listening`\n- class: `http.ServerResponse`\n  - event: `'close'`\n  - event: `'finish'`\n  - `response.end([data][, encoding][, callback])`\n  - `response.finished`\n  - `response.getHeader(name)`\n  - `response.getHeaderNames()`\n  - `response.getHeaders()`\n  - `response.hasHeader(name)`\n  - `response.headersSent`\n  - `response.removeHeader(name)`\n  - `response.setHeader(name, value)`\n  - `response.socket`\n  - `response.statusCode`\n  - `response.statusMessage`\n  - `response.write(chunk[, encoding][, callback])`\n  - `response.writeHead(statusCode[, statusMessage][, headers])`\n- class: `http.IncomingMessage`\n  - event: `'close'`\n  - `message.complete`\n  - `message.destroy([error])`\n  - `message.headers`\n  - `message.httpVersion`\n  - `message.method`\n  - `message.rawHeaders`\n  - `message.socket`\n  - `message.statusCode`\n  - `message.statusMessage`\n  - `message.url`\n  - `message.connection`\n- class: `net.Socket`\n  - event: `'close'`\n  - event: `'data'`\n  - event: `'drain'`\n  - event: `'end'`\n  - event: `'error'`\n  - `socket.address()`\n  - `socket.remoteAddress`\n  - `socket.remoteFamily`\n  - `socket.remotePort`\n  - `socket.bufferSize`\n  - `socket.bytesRead`\n  - `socket.bytesWritten`\n  - `socket.destroy([exception])`\n  - `socket.destroyed`\n  - `socket.end([data][, encoding][, callback])`\n  - `socket.write(data[, encoding][, callback])`\n\n## limitations\n\n- fakettp cannot be hosted on a cdn and must be served from the same origin.\n- fakettp works best in chromium based browsers due to support discrepancies.\n- fakettp only works in secure contexts and localhost for development purposes.\n- fakettp does not support history navigations that result in crossing origins.\n- fakettp listening on root domain is not advised due to history complications.\n- fakettp can currently have only one instance active and listening at a time.\n\n[1]: https://www.npmjs.com/package/stream-http\n[2]: https://www.chromium.org/Home/chromium-security/security-faq/service-worker-security-faq/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F3p3r%2Ffakettp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F3p3r%2Ffakettp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F3p3r%2Ffakettp/lists"}