{"id":21270728,"url":"https://github.com/explodingcamera/rust-http-server-from-scratch","last_synced_at":"2025-03-15T12:12:25.364Z","repository":{"id":129697263,"uuid":"405933957","full_name":"explodingcamera/rust-http-server-from-scratch","owner":"explodingcamera","description":null,"archived":false,"fork":false,"pushed_at":"2021-12-14T11:54:45.000Z","size":106,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-01-22T02:32:12.603Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","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/explodingcamera.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","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":"2021-09-13T10:50:57.000Z","updated_at":"2024-09-05T23:38:33.000Z","dependencies_parsed_at":null,"dependency_job_id":"f586648f-6a0d-48cd-832b-a5a87b3e036b","html_url":"https://github.com/explodingcamera/rust-http-server-from-scratch","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/explodingcamera%2Frust-http-server-from-scratch","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/explodingcamera%2Frust-http-server-from-scratch/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/explodingcamera%2Frust-http-server-from-scratch/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/explodingcamera%2Frust-http-server-from-scratch/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/explodingcamera","download_url":"https://codeload.github.com/explodingcamera/rust-http-server-from-scratch/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243725634,"owners_count":20337670,"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":[],"created_at":"2024-11-21T08:18:27.009Z","updated_at":"2025-03-15T12:12:25.357Z","avatar_url":"https://github.com/explodingcamera.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Creating a Webserver from scratch (in rust)\n\n# Getting Started\n\n## 1. Install Dependencies\n\n- [rust \u003e= 1.56.0](https://rustup.rs/)\n\n## 2. Run\n\n```bash\n$ cargo run --bin client\n$ cargo run --bin server\n```\n\n# TODO:\n\n- More Security Checks (Request Size limits)\n- Websockets\n  - [x] websocket middleware\n  - [x] websocket upgrade\n  - [x] websocket frame parser\n  - [x] websocket masking\n  - [ ] websocket chunked messages\n  - [ ] websocket frame builder\n- Partial request parsing\n- Stream Abstraction (Chunked encoding)\n- Revisit low level parallel processing of incoming sockets\n\n# Full Example\n\n```rust\nuse anyhow::Result;\nuse webserver_from_scratch::{middleware, router::Router, HTTPServer, LogLevel, StatusCode};\n\nfn main() -\u003e Result\u003c()\u003e {\n    let mut server = HTTPServer::new();\n    server.loglevel(LogLevel::Off);\n\n    let hello_world_handler = middleware!(|ctx| {\n        let resp = b\"\u003ch1\u003eHello World\u003c/h1\u003e\";\n        ctx.response.content_type(\"text/html\");\n        ctx.response.write(resp);\n        ctx.end();\n    });\n\n    let hello_handler = middleware!(|ctx| {\n        ctx.response.content_type(\"text/html\");\n        ctx.response.write(b\"\u003ch1\u003eHello \");\n\n        let params = ctx.params.clone();\n        let name = params.get(\":name\");\n        let name = if let Some(name) = name {\n            name.value.as_bytes()\n        } else {\n            b\"World\"\n        };\n\n        ctx.response.write(name);\n        ctx.response.write(b\"\u003c/h1\u003e\");\n        ctx.end();\n    });\n\n    server\n        .get(\"/\", hello_world_handler)\n        .get(\"/:name\", hello_handler);\n\n    server.any(\n        \"*\",\n        middleware!(|ctx| {\n            let resp = b\"404\";\n            ctx.response.status_code(StatusCode::NotFound);\n            ctx.response.write(resp);\n        }),\n    );\n\n    server.listen_blocking(\"[::1]:8080\".parse().unwrap())\n}\n```\n\n# Macro\n\n## Usage\n\n```rs\nmiddleware!(|ctx| {\n   // User Code (can use .await)\n})\n```\n\n## Resulting Code\n\n```rs\n{\n    let closure = |ctx: MiddlewareCtx| -\u003e HandlerFut {\n        Box::pin(async move {\n            // We have to use a mutex for the request context since the\n            // borrow checker doesn't recognize that an async function has finished running and\n            let mut ctx = ctx.lock(); // will be locked after `ctx` is dropped at the end of this block\n            /// {User code}\n            Ok(()) // enable error catching by returning a result (enables using `?` for catching errors)\n        })\n    };\n    closure // return closure from this block\n}\n```\n\n# Inspirations\n\n- Websocket\n  - https://github.com/1tgr/rust-websocket-lite\n  - https://github.com/snapview/tungstenite-rs\n- Http\n  - https://expressjs.com\n  - https://github.com/nickel-org/nickel.rs\n  - https://github.com/seanmonstar/httparse\n  - https://github.com/magic003/http-parser-rs\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fexplodingcamera%2Frust-http-server-from-scratch","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fexplodingcamera%2Frust-http-server-from-scratch","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fexplodingcamera%2Frust-http-server-from-scratch/lists"}