{"id":13429642,"url":"https://github.com/unosquare/embedio","last_synced_at":"2025-05-13T00:21:51.501Z","repository":{"id":15109605,"uuid":"17836469","full_name":"unosquare/embedio","owner":"unosquare","description":"A tiny, cross-platform, module based web server for .NET","archived":false,"fork":false,"pushed_at":"2025-03-13T20:41:19.000Z","size":14477,"stargazers_count":1504,"open_issues_count":55,"forks_count":178,"subscribers_count":66,"default_branch":"master","last_synced_at":"2025-04-23T18:53:06.795Z","etag":null,"topics":["dotnet","dotnetcore","embedded","http","http-api","http-request","http-requests","http-response","http-rest-api","http-server","mono","raspberry-pi","raspberry-pi-3","routing-strategies","tiny","url-segment","webserver","websocket","websockets"],"latest_commit_sha":null,"homepage":"http://unosquare.github.io/embedio","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/unosquare.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","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":"2014-03-17T17:17:07.000Z","updated_at":"2025-04-23T06:01:24.000Z","dependencies_parsed_at":"2024-01-02T22:40:12.036Z","dependency_job_id":"1ca1c9a3-88eb-447d-a87a-60795f26b544","html_url":"https://github.com/unosquare/embedio","commit_stats":null,"previous_names":[],"tags_count":70,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unosquare%2Fembedio","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unosquare%2Fembedio/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unosquare%2Fembedio/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unosquare%2Fembedio/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/unosquare","download_url":"https://codeload.github.com/unosquare/embedio/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253843988,"owners_count":21972989,"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":["dotnet","dotnetcore","embedded","http","http-api","http-request","http-requests","http-response","http-rest-api","http-server","mono","raspberry-pi","raspberry-pi-3","routing-strategies","tiny","url-segment","webserver","websocket","websockets"],"created_at":"2024-07-31T02:00:43.011Z","updated_at":"2025-05-13T00:21:51.455Z","avatar_url":"https://github.com/unosquare.png","language":"C#","readme":" [![Analytics](https://ga-beacon.appspot.com/UA-8535255-2/unosquare/embedio/)](https://github.com/igrigorik/ga-beacon)\n [![Build status](https://ci.appveyor.com/api/projects/status/w59t7sct3a8ir96t?svg=true)](https://ci.appveyor.com/project/geoperez/embedio)\n ![Buils status](https://github.com/unosquare/embedio/workflows/.NET%20Core%20CI/badge.svg)\n [![NuGet version](https://badge.fury.io/nu/embedio.svg)](https://www.nuget.org/packages/embedio)\n [![NuGet](https://img.shields.io/nuget/dt/embedio.svg)](https://www.nuget.org/packages/embedio)\n[![BuiltWithDotnet](https://builtwithdot.net/project/105/embedio/badge)](https://builtwithdot.net/project/105/embedio)\n[![Slack](https://img.shields.io/badge/chat-slack-blue.svg)](https://join.slack.com/t/embedio/shared_invite/enQtNjcwMjgyNDk4NzUzLWQ4YTE2MDQ2MWRhZGIyMTRmNTU0YmY4MmE3MTJmNTY4MmZiZDAzM2M4MTljMmVmNjRiZDljM2VjYjI5MjdlM2U)\n\n![EmbedIO](https://raw.githubusercontent.com/unosquare/embedio/master/images/embedio.png)\n\n*:star: Please star this project if you find it useful!*\n\n**This README is for EmbedIO v3.x. Click [here](https://github.com/unosquare/embedio/tree/v2.X) if you are still using EmbedIO v2.x.**\n\n- [Overview](#overview)\n    - [EmbedIO 3.0 - What's new](#embedio-30---whats-new)\n    - [Some usage scenarios](#some-usage-scenarios)\n- [Installation](#installation)\n- [Usage](#usage)\n    - [WebServer Setup](#webserver-setup)\n    - [Reading from a POST body as a dictionary (application/x-www-form-urlencoded)](#reading-from-a-post-body-as-a-json-payload-applicationjson)\n    - [Reading from a POST body as a JSON payload (application/json)](#reading-from-a-post-body-as-a-json-payload-applicationjson)\n    - [Reading from a POST body as a FormData (multipart/form-data)](#reading-from-a-post-body-as-a-formdata-multipartform-data)\n    - [Writing a binary stream](#writing-a-binary-stream)\n    - [WebSockets Example](#websockets-example)\n- [Support for SSL](#support-for-ssl)\n- [Related Projects and Nugets](#related-projects-and-nugets)\n- [Special Thanks](#special-thanks)\n\n## Overview\n\nA tiny, cross-platform, module based, MIT-licensed web server for .NET Framework and .NET Core.\n\n* Written entirely in C#, using our helpful library [SWAN](https://github.com/unosquare/swan)\n* Network operations use the async/await pattern: Responses are handled asynchronously\n* Multiple implementations support: EmbedIO can use Microsoft `HttpListener` or internal Http Listener based on [Mono](https://www.mono-project.com/)/[websocket-sharp](https://github.com/sta/websocket-sharp/) projects\n* Cross-platform: tested on multiple OS and runtimes. From Windows .NET Framework to Linux MONO.\n* Extensible: Write your own modules -- For example, video streaming, UPnP, etc. Check out [EmbedIO Extras](https://github.com/unosquare/embedio-extras) for additional modules\n* Small memory footprint\n* Create REST APIs quickly with the out-of-the-box Web API module\n* Serve static or embedded files with 1 line of code (also out-of-the-box)\n* Handle sessions with the built-in LocalSessionWebModule\n* WebSockets support\n* CORS support. Origin, Header and Method validation with OPTIONS preflight\n* HTTP 206 Partial Content support\n* Support [Xamarin Forms](https://github.com/unosquare/embedio/tree/master/src/EmbedIO.Forms.Sample)\n* And many more options in the same package\n\n### EmbedIO 3.0 - What's new\n\nThe major version 3.0 includes a lot of changes in how the webserver process the incoming request and the pipeline of the Web Modules. You can check a complete list of changes and a upgrade guide for v2 users [here](https://github.com/unosquare/embedio/wiki/Upgrade-from-v2).\n\n### Some usage scenarios:\n\n* Write a cross-platform GUI entirely using React/AngularJS/Vue.js or any Javascript framework\n* Write a game using Babylon.js and make EmbedIO your serve your code and assets\n* Create GUIs for Windows services or Linux daemons\n* Works well with [LiteLib](https://github.com/unosquare/litelib) - add SQLite support in minutes!\n* Write client applications with real-time communication between them using WebSockets\n* Write internal web server for [Xamarin Forms](https://github.com/unosquare/embedio/tree/master/src/EmbedIO.Forms.Sample) applications\n\n## Installation:\n\nYou can start using EmbedIO by just downloading the nuget.\n\n### Package Manager\n\n```\nPM\u003e Install-Package EmbedIO\n```\n\n### .NET CLI\n\n```\n\u003e dotnet add package EmbedIO\n```\n\n## Usage\n\nWorking with EmbedIO is pretty simple, check the follow sections to start coding right away. You can find more useful recipes and implementation details in the [Cookbook](https://github.com/unosquare/embedio/wiki/Cookbook).\n\n### WebServer Setup\n\nPlease note the comments are the important part here. More info is available in the samples.\n\n```csharp\nnamespace Unosquare\n{\n    using System;\n    using EmbedIO;\n    using EmbedIO.WebApi;\n\n    class Program\n    {\n        /// \u003csummary\u003e\n        /// Defines the entry point of the application.\n        /// \u003c/summary\u003e\n        /// \u003cparam name=\"args\"\u003eThe arguments.\u003c/param\u003e\n        static void Main(string[] args)\n        {\n            var url = \"http://localhost:9696/\";\n            if (args.Length \u003e 0)\n                url = args[0];\n\n            // Our web server is disposable.\n            using (var server = CreateWebServer(url))\n            {\n                // Once we've registered our modules and configured them, we call the RunAsync() method.\n                server.RunAsync();\n\n                var browser = new System.Diagnostics.Process()\n                {\n                    StartInfo = new System.Diagnostics.ProcessStartInfo(url) { UseShellExecute = true }\n                };\n                browser.Start();\n                // Wait for any key to be pressed before disposing of our web server.\n                // In a service, we'd manage the lifecycle of our web server using\n                // something like a BackgroundWorker or a ManualResetEvent.\n                Console.ReadKey(true);\n            }\n        }\n\t\n\t// Create and configure our web server.\n        private static WebServer CreateWebServer(string url)\n        {\n            var server = new WebServer(o =\u003e o\n                    .WithUrlPrefix(url)\n                    .WithMode(HttpListenerMode.EmbedIO))\n\t\t // First, we will configure our web server by adding Modules.\n                .WithLocalSessionManager()\n                .WithWebApi(\"/api\", m =\u003e m\n                    .WithController\u003cPeopleController\u003e())\n                .WithModule(new WebSocketChatModule(\"/chat\"))\n                .WithModule(new WebSocketTerminalModule(\"/terminal\"))\n                .WithStaticFolder(\"/\", HtmlRootPath, true, m =\u003e m\n                    .WithContentCaching(UseFileCache)) // Add static files after other modules to avoid conflicts\n                .WithModule(new ActionModule(\"/\", HttpVerbs.Any, ctx =\u003e ctx.SendDataAsync(new { Message = \"Error\" })));\n\n            // Listen for state changes.\n            server.StateChanged += (s, e) =\u003e $\"WebServer New State - {e.NewState}\".Info();\n\n            return server;\n        }\n    }\n}\n```\n\n### Reading from a POST body as a dictionary (application/x-www-form-urlencoded)\n\nFor reading a dictionary from an HTTP Request body inside a WebAPI method you can add an argument to your method with the attribute `FormData`.\n\n```csharp\n    [Route(HttpVerbs.Post, \"/data\")]\n    public async Task PostData([FormData] NameValueCollection data) \n    {\n        // Perform an operation with the data\n        await SaveData(data);\n    }\n```\n\n### Reading from a POST body as a JSON payload (application/json)\n\nFor reading a JSON payload and deserialize it to an object from an HTTP Request body you can use [GetRequestDataAsync\u003cT\u003e](#). This method works directly from `IHttpContext` and returns an object of the type specified in the generic type.\n\n```csharp\n    [Route(HttpVerbs.Post, \"/data\")]\n    public async Task PostJsonData() \n    {\n        var data = HttpContext.GetRequestDataAsync\u003cMyData\u003e();\n\t\n        // Perform an operation with the data\n        await SaveData(data);\n    }\n```\n\n### Reading from a POST body as a FormData (multipart/form-data)\n\nEmbedIO doesn't provide the functionality to read from a Multipart FormData stream. But you can check the [HttpMultipartParser Nuget](https://www.nuget.org/packages/HttpMultipartParser/) and connect the Request input directly to the HttpMultipartParser, very helpful and small library.\n\nA sample code using the previous library:\n\n```csharp\n    [Route(HttpVerbs.Post, \"/upload\")]\n    public async Task UploadFile()\n    {\n        var parser = await MultipartFormDataParser.ParseAsync(Request.InputStream);\n        // Now you can access parser.Files\n    }\n```\n\nThere is [another solution](http://stackoverflow.com/questions/7460088/reading-file-input-from-a-multipart-form-data-post) but it requires this [Microsoft Nuget](https://www.nuget.org/packages/Microsoft.AspNet.WebApi.Client).\n\n### Writing a binary stream\n\nYou can open the Response Output Stream with the extension [OpenResponseStream]().\n\n```csharp\n    [Route(HttpVerbs.Get, \"/binary\")]\n    public async Task GetBinary() \n    {\n\t// Call a fictional external source\n\tusing (var stream = HttpContext.OpenResponseStream())\n                await stream.WriteAsync(dataBuffer, 0, 0);\n    }\n```\n\n### WebSockets Example\n\nWorking with WebSocket is pretty simple, you just need to implement the abstract class `WebSocketModule` and register the module to your Web server as follow:\n\n```csharp\nserver..WithModule(new WebSocketChatModule(\"/chat\"));\n```\n\nAnd our web sockets server class looks like:\n\n```csharp\nnamespace Unosquare\n{\n    using EmbedIO.WebSockets;\n\n    /// \u003csummary\u003e\n    /// Defines a very simple chat server.\n    /// \u003c/summary\u003e\n    public class WebSocketsChatServer : WebSocketModule\n    {\n        public WebSocketsChatServer(string urlPath)\n            : base(urlPath, true)\n        {\n            // placeholder\n        }\n\n        /// \u003cinheritdoc /\u003e\n        protected override Task OnMessageReceivedAsync(\n            IWebSocketContext context,\n            byte[] rxBuffer,\n            IWebSocketReceiveResult rxResult)\n            =\u003e SendToOthersAsync(context, Encoding.GetString(rxBuffer));\n\n        /// \u003cinheritdoc /\u003e\n        protected override Task OnClientConnectedAsync(IWebSocketContext context)\n            =\u003e Task.WhenAll(\n                SendAsync(context, \"Welcome to the chat room!\"),\n                SendToOthersAsync(context, \"Someone joined the chat room.\"));\n\n        /// \u003cinheritdoc /\u003e\n        protected override Task OnClientDisconnectedAsync(IWebSocketContext context)\n            =\u003e SendToOthersAsync(context, \"Someone left the chat room.\");\n\n        private Task SendToOthersAsync(IWebSocketContext context, string payload)\n            =\u003e BroadcastAsync(payload, c =\u003e c != context);\n    }\n}\n\n```\n\n## Support for SSL\n\nBoth HTTP listeners (Microsoft and Unosquare) can open a web server using SSL. This support is for Windows only (for now) and you need to manually register your certificate or use the `WebServerOptions` class to initialize a new `WebServer` instance. This section will provide some examples of how to use SSL but first a brief explanation of how SSL works on Windows.\n\nFor Windows Vista or better, Microsoft provides Network Shell (`netsh`). This command line tool allows to map an IP-port to a certificate, so incoming HTTP request can upgrade the connection to a secure stream using the provided certificate. EmbedIO can read or register certificates to a default store (My/LocalMachine) and use them against a netsh `sslcert` for binding the first `https` prefix registered.\n\nFor Windows XP and Mono, you can use manually the `httpcfg` for registering the binding.\n\n### Using a PFX file and AutoRegister option\n\nThe more practical case to use EmbedIO with SSL is the `AutoRegister` option. You need to create a `WebServerOptions` instance with the path to a PFX file and the `AutoRegister` flag on. This options will try to get or register the certificate to the default certificate store. Then it will use the certificate thumbprint to register with `netsh` the FIRST `https` prefix registered on the options.\n\n### Using AutoLoad option\n\nIf you already have a certificate on the default certificate store and the binding is also registered in `netsh`, you can use `Autoload` flag and optionally provide a certificate thumbprint. If the certificate thumbprint is not provided, EmbedIO will read the data from `netsh`. After getting successfully the certificate from the store, the raw data is passed to the WebServer.\n\n## Related Projects and Nugets\n\nName | Author | Description\n-----|--------|--------------\n[Butterfly.EmbedIO](https://www.nuget.org/packages/Butterfly.EmbedIO/) | Fireshark Studios, LLC | Implementation of Butterfly.Core.Channel and Butterfly.Core.WebApi using the EmbedIO server\n[embedio-cli](https://github.com/unosquare/embedio-cli) | Unosquare | A dotnet global tool that enables start any web folder or EmbedIO assembly (WebAPI or WebSocket) from command line.\n[EmbedIO.BearerToken](https://www.nuget.org/packages/EmbedIO.BearerToken/)  | Unosquare | Allow to authenticate with a Bearer Token. It uses a Token endpoint (at /token path) and with a defined validation delegate create a JsonWebToken. The module can check all incoming requests or a paths\n[EmbedIO.LiteLibWebApi](https://www.nuget.org/packages/EmbedIO.LiteLibWebApi/) | Unosquare | Allow to expose a sqlite database as REST api using EmbedIO WebApi and LiteLib libraries\n[EmbedIO.OWIN](https://www.nuget.org/packages/EmbedIO.OWIN/) | Unosquare | EmbedIO can use the OWIN platform in two different approach: You can use EmbedIO as OWIN server and use all OWIN framework with EmbedIO modules.\n[Microsoft.AspNetCore.Server.EmbedIO](https://www.nuget.org/packages/Microsoft.AspNetCore.Server.EmbedIO/) | Dju  | EmbedIO web server support for ASP.NET Core, as a drop-in replacement for Kestrel\n[SambaFetcher](https://github.com/nddipiazza/SambaFetcher/) | nddipiazza  | A .NET tool to connect a web server with Samba\n\n## Special Thanks\n\n [![YourKit](https://www.yourkit.com/images/yklogo.png)](https://www.yourkit.com)\n\n To YourKit for supports open source projects with its full-featured [.NET Profiler](https://www.yourkit.com/.net/profiler/), an amazing tool to profile CPU and Memory!\n","funding_links":[],"categories":["Frameworks, Libraries and Tools","C# #","C#","Web Servers","框架, 库和工具","Web服务器","Application Frameworks","NET Conf"],"sub_categories":["Application Frameworks","应用程序框架","GUI - other"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Funosquare%2Fembedio","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Funosquare%2Fembedio","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Funosquare%2Fembedio/lists"}