{"id":19564282,"url":"https://github.com/ronenness/serverito","last_synced_at":"2025-04-27T00:32:54.727Z","repository":{"id":82588262,"uuid":"116529190","full_name":"RonenNess/Serverito","owner":"RonenNess","description":"Http framework for C# web apps.","archived":false,"fork":false,"pushed_at":"2018-01-09T23:20:00.000Z","size":85,"stargazers_count":10,"open_issues_count":1,"forks_count":0,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-15T16:36:14.301Z","etag":null,"topics":["csharp","csharp-li","http","http-server","httplistener","webapp"],"latest_commit_sha":null,"homepage":null,"language":"C#","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/RonenNess.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":"2018-01-07T01:47:51.000Z","updated_at":"2025-02-06T04:52:20.000Z","dependencies_parsed_at":"2023-04-21T17:19:26.943Z","dependency_job_id":null,"html_url":"https://github.com/RonenNess/Serverito","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RonenNess%2FServerito","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RonenNess%2FServerito/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RonenNess%2FServerito/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RonenNess%2FServerito/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RonenNess","download_url":"https://codeload.github.com/RonenNess/Serverito/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251073336,"owners_count":21532005,"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":["csharp","csharp-li","http","http-server","httplistener","webapp"],"created_at":"2024-11-11T05:21:10.828Z","updated_at":"2025-04-27T00:32:54.721Z","avatar_url":"https://github.com/RonenNess.png","language":"C#","readme":"# Serverito\n\nHttp framework for C# web apps.\n\n## Why\n\nSometimes you want to build simple web apps in C# without using the extensive ASP.net or IIS frameworks. \nFor that purpose, .Net provide a very useful class, [HttpListener](https://msdn.microsoft.com/en-us/library/system.net.httplistener.aspx).\n\nWhile its quite easy to use, the problem with ```HttpListener``` is that you need to implement a lot of basic things on your own: serving static files, mapping URLs, writing output to responses, etc.\n\nTo solve that, *Serverito* implement a wrapping layer around ```HttpListener``` that provide a very easy API, and do most of the tedious work for you.\n\n**It takes minutes to build web apps with *Serverito*!**\n\n## Install\n\nInstall Serverito via NuGet:\n\n```\nInstall-Package Serverito\n```\n\nOr check it out on [nuget.org](https://www.nuget.org/packages/Serverito/).\n\n## Using Serverito\n\nLets create a *Serverito* server on localhost, add a test URL, and start listening:\n\n```cs\n// don't forget to add 'using Serverito;'\n\n// create server\nServeritoListener server = new ServeritoListener(\"http://localhost:8000/\");\n\n// add a test url\nserver.AddView(new URL(\"/\"), (ServeritoContext context) =\u003e\n{\n\tUtils.WriteToResponse(context.Context, \"Hello World!\");\n});\n\n// start listening\nserver.Start();\n```\n\nIn the example above we created a server, added a 'view' to it (mapping between URL and a function to handle it), and started listening to incoming requests.\n\nIf you run your app you'll see that its blocking on the ```server.Start()``` line. This means your listener is working and ready to handle incoming requests. \n\nIf you open a browser and go to URL ```http://localhost:8000/```, you should now see ```Hello World!``` printed on the screen.\n\n### Urls and Views\n\nAs you saw in previous example, to use *Serverito* you need to map different URLs to handling functions (aka 'Views') which are responsible to render the response.\n\nWhen *Serverito* receive an incoming request, the listener will iterate over all the views you previously defined and use the first one that the request URL matches its pattern (this means that the order you put them is important). \n\nIn the example above the URL pattern was quite simple, only accepting '/', but URLs can be more sophisticated than that. For example, the following view:\n\n```cs\nserver.AddView(new URL(\"/post/\", HttpMethods.POST, UrlMatchingType.StartsWith), (ServeritoContext context) =\u003e\n{\n\tUtils.WriteToResponse(context.Context, \"Hello World!\");\n});\n```\n\nWill run only for POST requests if URL starts with \"/post/\". \nYou can also use Regex in URLs:\n\n```cs\nserver.AddView(new URL(@\"/number/\\d+/\", matchType: UrlMatchingType.RegEx), (ServeritoContext context) =\u003e\n{\n\tUtils.WriteToResponse(context.Context, \"Hello World!\");\n});\n```\n\nThe example above will match any http request type, for all URLs that match the pattern of '/number/\u003cnumber\u003e/' (\u003cnumber\u003e can be any length number).\n\n### Serving Static Files\n\nUsually in production you want to serve static files from your web server layer (eg nginx, apache, etc.) and not from your app. However, if you want to serve static files from *Serverito*, its easy to do (useful for development process).\n\nTo serve static files automatically, you only need to set two properties in your server:\n\n```\nserver.StaticFilesRootUrl = \"/static/\";\nserver.StaticFilesPath = \"../../static_files\";\n```\n\n```StaticFilesRootUrl``` is the root URL used to serve static files. In the example above, whenever someone enters a URL like '/static/something/', the server will understand he's looking for a file and will try to serve him the content of 'something'.\n\n```StaticFilesPath``` is the path on your machine of the static files. When the server need to serve a static file, it will search for it under this path.\n\nSo if we look at the example above, if a user goes to URL ```/static/hello.txt```, the server will look for file ```../../static_files/hello.txt``` (relative to current working directory) and try to serve it.\n\nIf file not found, 404 error code will be returned.\n\n#### Mime Types\n\n*Serverito* handle mime-types automatically by setting the content-type header based on file extension. To disable this behavior, set:\n\n```\nserver.SetMimeContentType = false;\n```\n\n#### Encoding\n\nTo choose what encoding type to use with static files, you can set the `StaticFilesEncodingType` property:\n\n```cs\nserver.StaticFilesEncodingType = EncodingType.UTF8;\n```\n\nThis will set the 'charset' property in the content-type header.\n\n#### Smarter File Handling\n\nBy default whenever *Serverito* need to serve a file, it just reads the file bytes and write them to response. If you want to use caching mechanisms or have a more sophisticated logic, you can override the function that reads a file:\n\n```cs\nserver.StaticFilesReader = SmartReadingFunc;\n```\n\n\n### Rendering Html\n\nTo serve an HTML page use ```server.ServeHtmlPage```:\n\n```cs\nserver.AddView(new URL(\"/\"), (ServeritoContext context) =\u003e\n{\n\tserver.ServeHtmlPage(context, \"test.html\");\n});\n```\n\nNote that this uses the static files mechanism, which means that you have to set ```StaticFilesPath``` for it to work (the server will look for `test.html` under the path you defined as StaticFilesPath).\n\n### Useful Config\n\nThe *Serverito* server comes with some useful config properties you should know:\n\n##### server.UseThreads [default: false]\n\nWhen true, the server will open a new thread for every incoming request.\n\n##### CloseRequests [default: true]\n\nWhen true, the server will close responses automatically whenever its most fitting. Closing the response is what actually fires it back to client.\n\nIf you want to control when to close the responses, set this to false.\n\n##### UseChunks [default: true]\n\nIf true, will send data in chunks.\n\n##### SetMimeContentType [default: true]\n\nIf true, will set content-type automatically for known file types whenever serving static files.\n\n##### StaticFilesEncodingType [default: EncodingType.UTF8]\n\nWhat encoding type to use for files we serve.\n\n### Utils\n\n```Utils``` is a static class with useful utilities to help you handle requests and setup the server. It has lots of useful stuff, but the following are the most important functions you should know:\n\n##### Utils.FileToBytes\n\nRead a file into bytes buffer.\n\n##### Utils.GetIp\n\nGet IP address (as string) from request.\n\n##### Utils.ReadRequestInput\n\nRead request input stream and return it as string. If you're using JSON with your APIs you need a JSON lib to convert to objects.\n\n##### Utils.WriteToResponse\n\nWrite string directly to response.\n\n##### Utils.ForceTrailingSlash\n\nMake your server force users to use URLs with trailing slashes (except for static files).\n\n##### Utils.DumpExceptionsToResponse\n\nMake your server dump all exceptions to response.\n\n### Events\n\nTo make the server more flexible, it features a set of events you can register and use to process requests while they go through the pipes.\n\nYou can listen to the following events:\n\n- OnException: called whenever an exception occurs.\n- OnFinishedProcessingView: called right after a view successfully runs.\n- OnFinishHandlingRequest: called after a request is fully handled and ready to be closed.\n- OnNewRawRequest: called when we get a new request, before we start processing it.\n- OnPassingRequestToView: called before we pass the request to the matching view.\n- OnServingFile: called whenever a static file is served.\n- OnUndefinedURL: called whenever we can't find a matching view for a request URL.\n- OnMissingFile: called whenever we can't find a static file we need to serve.\n- OnUrlMatching: called before we start matching URLs for a new request (eg before we decide which view to use).\n\nAll the events above get the ```ServeritoContext``` as their param. You can use ```ServeritoContext.UserData``` to pass data between them.\n\n#### Controlling Flow\n\nThe callbacks you register can control the flow of the request by throwing some special exceptions:\n\n- BreakCallbacks: throwing this exception will skip the following event handlers for this specific event.\n- AbortRequest: will abort the request and stop processing it.\n- StopProcessingRequest: will stop processing request, but won't abort it. if you close request manually, it will be a valid response.\n\n## Example\n\nIf you clone this repository and build the project as a console application instead of a class library, you will get a simple example app that renders a test page and defines some test views.\n\n## Changes\n\n#### 1.0.0.1\n\nInitial release.\n\n#### 1.0.0.2\n\n- Fixed bug in setting mime-type automatically.\n- Added support in changing static files encoding type.\n- Added charset header to static files we serve.\n\n#### 1.0.0.3\n\n- Improved the way we read requests input to support POST data.\n- Added some tests to the example HTML.\n- Improved function(s) to get source IP as string from request.\n- Closing listener on destructor.\n- Added 'Abort()'.\n\n\n## Contact\n\nFor bug report, questions or feature requests, please use the [GitHub Issues](https://github.com/RonenNess/Serverito/issues/) section.\n\nFor anything else, feel free to contact me directly at [ronenness@gmail.com](mailto:ronenness@gmail.com).\n\n\n## License\n\n*Serverito* is distributed under the permissive MIT license.","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fronenness%2Fserverito","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fronenness%2Fserverito","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fronenness%2Fserverito/lists"}