{"id":32287723,"url":"https://github.com/masonfrykman/rbws","last_synced_at":"2026-05-21T03:32:18.242Z","repository":{"id":245771846,"uuid":"816362436","full_name":"masonfrykman/rbws","owner":"masonfrykman","description":"really bad web server aka another generic HTTP/1.1 impl","archived":false,"fork":false,"pushed_at":"2026-02-07T04:21:42.000Z","size":108,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-07T14:57:47.010Z","etag":null,"topics":["dart","http","web","webserver"],"latest_commit_sha":null,"homepage":"https://pub.dev/packages/rbws","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/masonfrykman.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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":"ROADMAP.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-06-17T15:34:14.000Z","updated_at":"2026-01-27T17:58:24.000Z","dependencies_parsed_at":"2024-07-05T13:27:17.921Z","dependency_job_id":"49d64d29-feeb-4b59-8b15-cad6e0fcd6bb","html_url":"https://github.com/masonfrykman/rbws","commit_stats":null,"previous_names":["masonfrykman/rbws"],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/masonfrykman/rbws","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/masonfrykman%2Frbws","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/masonfrykman%2Frbws/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/masonfrykman%2Frbws/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/masonfrykman%2Frbws/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/masonfrykman","download_url":"https://codeload.github.com/masonfrykman/rbws/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/masonfrykman%2Frbws/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33287441,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-21T02:57:32.698Z","status":"ssl_error","status_checked_at":"2026-05-21T02:57:31.990Z","response_time":62,"last_error":"SSL_read: 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":["dart","http","web","webserver"],"created_at":"2025-10-23T02:16:45.141Z","updated_at":"2026-05-21T03:32:18.236Z","avatar_url":"https://github.com/masonfrykman.png","language":"Dart","funding_links":[],"categories":[],"sub_categories":[],"readme":"# RBWS\n\n*really bad web server*\n\nAnother generic HTTP/1.1 web server implementation using ```dart:io```.\n\n## Features :D\n\n- Matches request paths to files from a defined document root.\n    - **To enable:** Set the ```storage``` property on an ```HTTPServerInstance``` to be a ```RootedAutoreleasingStore``` object.\n- Stores files loaded from filesystem in a cache that will clear the file after an arbitrary amount of time.\n    - The amount of time defaults to a day. The duration can be changed by setting ```defaultStorageDuration``` on an ```AutoreleasingStore``` object.\n- Matches request paths to static handler functions.\n    - **To enable:** Populate the ```staticRoutes``` map on an ```HTTPServerInstance```.\n- Redirects insecure requests to a secure version.\n    - **To enable:** Set ```referralToSecureServer``` on an ```HTTPServerInstance``` where ```securityContext == null```.\n    - **Caveat:** Requests will only be upgraded if they have the header ```Upgrade-Insecure-Requests: 1```\n\n## A note on the License\n\nThe RBWS package is licensed under the [GNU Lesser General Public License v3.0](https://www.gnu.org/licenses/lgpl-3.0.txt) (you can also find it in the LICENSE file of the GitHub repo)\n\n**What this means for you:** you can use the pub utility to get the package, import it into another application, and release that code built on this library under whatever license your heart desires.\n\nHowever, if any of the source code of this library is changed or reused, that subsequent source code must be released and be easily accessible under the LGPL or GPL. Thats it! :)\n\n## Synopsis\n\nThis package provides a framework for programmatically building an HTTP server application by providing classes that handle the nitty-gritty of HTTP/1.1—TCP connections, request parsing, response synthesis—yet still allow for customization when necessary. Said classes often go even further than basic HTTP management by accomodating common tasks and use cases that may appear when building an application.\n\n## Examples\n\n### Basic usage\n\nThe following is a really basic web server that simply loads files from the disk and logs the responses.\n\n```dart\nimport 'package:rbws/rbws.dart';\nimport 'dart:io';\n\nvoid main() async {\n    HTTPServerInstance server = HTTPServerInstance(InternetAddress.anyIPv4, 80, generalServeRoot: \"/path/to/webroot\");\n    server.onResponse = (response) {\n        print(\"${DateTime.now()} ${response.toRequest?.path} [${response.status}]\");\n    };\n\n    server.start();\n}\n```\n\nWe could build on top of that by also providing static routes, which will match before trying to load a file.\nThe following code is the same as last time, but we have a super secret webpage that checks for a password as a cookie.\n\n```dart\nimport 'package:rbws/rbws.dart';\nimport 'dart:io';\nimport 'dart:convert';\n\nvoid main() async {\n    HTTPServerInstance server = HTTPServerInstance(InternetAddress.anyIPv4, 80, generalServeRoot: \"/path/to/webroot\");\n    server.onResponse = (response) {\n        print(\"${DateTime.now()} ${response.toRequest?.path} [${response.status}]\");\n    };\n\n    // This can also be defined as an optional parameter in the constructor!\n    server.staticRoutes = {\n        (RBWSMethod.get, \"/super-secret-webpage\"): (request) {\n            if(!request.headers.containsKey[\"Cookie\"]) {\n                return RBWSResponse(401, data: utf8.encode(\"401 Unauthorized\"), headers: {\"Content-Type\": \"text/plain\"});\n            }\n\n            List\u003cString\u003e cookies = request.headers[\"Cookie\"].split(\" \");\n            if(cookies.isEmpty) {\n                return RBWSResponse(401, data: utf8.encode(\"401 Unauthorized\"), headers: {\"Content-Type\": \"text/plain\"});\n            }\n\n            for(String cookie in cookies) {\n                if(cookie.startsWith(\"password\") \u0026\u0026 cookie.trim().split(\"=\").last == \"ImNotTheFBI\") {\n                    return RBWSResponse(200, data: utf8.encode(\"\u003ch1\u003eEVIDENCE:\u003c/h1\u003e\u003cimg src='evidence.jpeg' /\u003e\"), headers: {\"Content-Type\": \"text/html\"});\n                }\n            }\n            return RBWSResponse(401, data: utf8.encode(\"401 Unauthorized\"), headers: {\"Content-Type\": \"text/plain\"});\n        }\n    };\n\n    server.start();\n}\n```\n\n### Insecure -\u003e Secure upgrader\n\nThe following is the same as the last example, but the insecure version offers to upgrade HTTP to HTTPS and only offers the \"/super-secret-webpage\" over HTTPS.\n\n```dart\nimport 'package:rbws/rbws.dart';\nimport 'dart:io';\nimport 'dart:convert';\n\nvoid main() async {\n    HTTPServerInstance secureServer = HTTPServerInstance(InternetAddress.anyIPv4, 443, generalServeRoot: \"/path/to/webroot\", securityContext: SecurityContext.defaultContext);\n    secureServer.securityContext!.useCertificateChain(\"/path/to/certificate\");\n    secureServer.securityContext!.usePrivateKey(\"/path/to/private/key\");\n\n    HTTPServerInstance server = HTTPServerInstance(InternetAddress.anyIPv4, 80, generalServeRoot: \"/path/to/webroot\");  \n    server.referralToSecureServer = \"https://${secureServer.host.address}:${secureServer.port}\"; // This will trigger Upgrade-Insecure-Requests: 1\n\n    var onResponse = (response) {\n        print(\"${DateTime.now()} ${response.toRequest?.path} [${response.status}]\");\n    };\n\n    server.onResponse = onResponse;\n    secureServer.onResponse = onResponse;\n\n    // This can also be defined as an optional parameter in the constructor!\n    secureServer.staticRoutes = {\n        (RBWSMethod.get, \"/super-secret-webpage\"): (request) {\n            if(!request.headers.containsKey[\"Cookie\"]) {\n                return RBWSResponse(401, data: utf8.encode(\"401 Unauthorized\"), headers: {\"Content-Type\": \"text/plain\"});\n            }\n\n            List\u003cString\u003e cookies = request.headers[\"Cookie\"].split(\" \");\n            if(cookies.isEmpty) {\n                return RBWSResponse(401, data: utf8.encode(\"401 Unauthorized\"), headers: {\"Content-Type\": \"text/plain\"});\n            }\n\n            for(String cookie in cookies) {\n                if(cookie.startsWith(\"password\") \u0026\u0026 cookie.trim().split(\"=\").last == \"ImNotTheFBI\") {\n                    return RBWSResponse(200, data: utf8.encode(\"\u003ch1\u003eEVIDENCE:\u003c/h1\u003e\u003cimg src='evidence.jpeg' /\u003e\"), headers: {\"Content-Type\": \"text/html\"});\n                }\n            }\n            return RBWSResponse(401, data: utf8.encode(\"401 Unauthorized\"), headers: {\"Content-Type\": \"text/plain\"});\n        }\n    };\n\n    secureServer.start();\n    server.start();\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmasonfrykman%2Frbws","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmasonfrykman%2Frbws","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmasonfrykman%2Frbws/lists"}