{"id":13878556,"url":"https://github.com/ronin-rb/ronin-web-server","last_synced_at":"2025-10-10T11:14:43.412Z","repository":{"id":66691455,"uuid":"436370595","full_name":"ronin-rb/ronin-web-server","owner":"ronin-rb","description":"A custom Ruby web server based on Sinatra.","archived":false,"fork":false,"pushed_at":"2025-02-15T06:25:41.000Z","size":464,"stargazers_count":4,"open_issues_count":4,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-09-05T18:45:57.536Z","etag":null,"topics":["infosec","ronin-rb","ruby","sinatra","webserver"],"latest_commit_sha":null,"homepage":"https://ronin-rb.dev","language":"Ruby","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/ronin-rb.png","metadata":{"files":{"readme":"README.md","changelog":"ChangeLog.md","contributing":null,"funding":null,"license":"COPYING.txt","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,"zenodo":null},"funding":{"open_collective":"ronin-rb","patreon":"roninrb"}},"created_at":"2021-12-08T19:38:39.000Z","updated_at":"2025-02-15T06:25:42.000Z","dependencies_parsed_at":"2024-11-05T22:04:14.431Z","dependency_job_id":"f24aaba8-5cea-4232-8526-4a807d9a4815","html_url":"https://github.com/ronin-rb/ronin-web-server","commit_stats":{"total_commits":456,"total_committers":2,"mean_commits":228.0,"dds":0.002192982456140302,"last_synced_commit":"41af9bedd1b341a3159f6bfcbf4e74b93a00eb95"},"previous_names":[],"tags_count":20,"template":false,"template_full_name":null,"purl":"pkg:github/ronin-rb/ronin-web-server","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ronin-rb%2Fronin-web-server","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ronin-rb%2Fronin-web-server/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ronin-rb%2Fronin-web-server/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ronin-rb%2Fronin-web-server/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ronin-rb","download_url":"https://codeload.github.com/ronin-rb/ronin-web-server/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ronin-rb%2Fronin-web-server/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279003726,"owners_count":26083610,"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","status":"online","status_checked_at":"2025-10-10T02:00:06.843Z","response_time":62,"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":["infosec","ronin-rb","ruby","sinatra","webserver"],"created_at":"2024-08-06T08:01:53.026Z","updated_at":"2025-10-10T11:14:43.395Z","avatar_url":"https://github.com/ronin-rb.png","language":"Ruby","funding_links":["https://opencollective.com/ronin-rb","https://patreon.com/roninrb"],"categories":["Ruby"],"sub_categories":[],"readme":"# ronin-web-server\n\n[![CI](https://github.com/ronin-rb/ronin-web-server/actions/workflows/ruby.yml/badge.svg)](https://github.com/ronin-rb/ronin-web-server/actions/workflows/ruby.yml)\n[![Code Climate](https://codeclimate.com/github/ronin-rb/ronin-web-server.svg)](https://codeclimate.com/github/ronin-rb/ronin-web-server)\n[![Gem Version](https://badge.fury.io/rb/ronin-web-server.svg)](https://badge.fury.io/rb/ronin-web-server)\n\n* [Website](https://ronin-rb.dev/)\n* [Source](https://github.com/ronin-rb/ronin-web-server)\n* [Issues](https://github.com/ronin-rb/ronin-web-server/issues)\n* [Documentation](https://ronin-rb.dev/docs/ronin-web-server/frames)\n* [Discord](https://discord.gg/6WAb3PsVX9) |\n  [Mastodon](https://infosec.exchange/@ronin_rb)\n\n## Description\n\nronin-web-server is a custom Ruby web server based on Sinatra tailored for\nsecurity research and development.\n\n## Features\n\n* Provides a [Sinatra][sinatra] based\n  {Ronin::Web::Server::Base web server base class}.\n* Supports additional routing helper methods:\n  * [any][docs-any] - matches any HTTP request method.\n  * [default][docs-default] - default response for the app.\n  * [basic_auth][docs-basic_auth] - enables Basic-Auth for the app.\n  * [redirect][docs-redirect] - adds a redirect to a given URL for the given\n    path.\n  * [file][docs-file] - mounts a local file to the given path.\n  * [directory][docs-directory] - mounts a local directory of files at the given\n    path.\n  * [public_dir][docs-public_dir] - mounts the files/directories within the\n    directory to the root of the app.\n  * [vhost][docs-vhost] - routes all requests for the given host to another app.\n  * [mount][docs-mount] - routes all requests for a given directory to another\n    app.\n* Supports additional routing conditions:\n  * [client_ip][docs-client_ip] - matches the client IP Address that sent the\n    request.\n  * [asn][docs-asn] - matches the AS number of the client's IP address.\n  * [country_code][docs-country_code] - matches the country code of the ASN\n    information for the client's IP address.\n  * [asn_name][docs-asn_name] - matches the company/ISP name of the ASN\n    information for the client's IP address.\n  * [host][docs-host] - matches the `Host` header.\n  * [referer][docs-referer] - matches the `Referer` header of the request.\n  * [user_agent][docs-user_agent] - matches the `User-Agent` header of the\n    request.\n  * [browser][docs-browser] - matches the browser name from the `User-Agent`\n    header of the request.\n  * [browser_vendor][docs-browser_vendor] - matches the browser vendor from the\n    `User-Agent` header of the request.\n  * [browser_version][docs-browser_version] - matches the browser version from\n    the `User-Agent` header of the request.\n  * [device_type][docs-device_type] - matches the device type of the\n    `User-Agent` header of the request.\n  * [os][docs-os] - matches the OS from the `User-Agent` header of the request.\n  * [os_version][docs-os_version] - matches the OS version from the `User-Agent`\n    header of the request.\n* Has 97% documentation coverage.\n* Has 90% test coverage.\n\n[docs-any]: https://ronin-rb.dev/docs/ronin-web-server/Ronin/Web/Server/Routing/ClassMethods.html#any-instance_method\n[docs-default]: https://ronin-rb.dev/docs/ronin-web-server/Ronin/Web/Server/Routing/ClassMethods.html#default-instance_method\n[docs-basic_auth]: https://ronin-rb.dev/docs/ronin-web-server/Ronin/Web/Server/Routing/ClassMethods.html#basic_auth-instance_method\n[docs-redirect]: https://ronin-rb.dev/docs/ronin-web-server/Ronin/Web/Server/Routing/ClassMethods.html#redirect-instance_method\n[docs-file]: https://ronin-rb.dev/docs/ronin-web-server/Ronin/Web/Server/Routing/ClassMethods.html#file-instance_method\n[docs-directory]: https://ronin-rb.dev/docs/ronin-web-server/Ronin/Web/Server/Routing/ClassMethods.html#directory-instance_method\n[docs-public_dir]: https://ronin-rb.dev/docs/ronin-web-server/Ronin/Web/Server/Routing/ClassMethods.html#public_dir-instance_method\n[docs-vhost]: https://ronin-rb.dev/docs/ronin-web-server/Ronin/Web/Server/Routing/ClassMethods.html#vhost-instance_method\n[docs-mount]: https://ronin-rb.dev/docs/ronin-web-server/Ronin/Web/Server/Routing/ClassMethods.html#mount-instance_method\n[docs-client_ip]: https://ronin-rb.dev/docs/ronin-web-server/Ronin/Web/Server/Conditions/ClassMethods.html#client_ip-instance_method\n[docs-asn]: https://ronin-rb.dev/docs/ronin-web-server/Ronin/Web/Server/Conditions/ClassMethods.html#asn-instance_method\n[docs-country_code]: https://ronin-rb.dev/docs/ronin-web-server/Ronin/Web/Server/Conditions/ClassMethods.html#country_code-instance_method\n[docs-asn_name]: https://ronin-rb.dev/docs/ronin-web-server/Ronin/Web/Server/Conditions/ClassMethods.html#asn_name-instance_method\n[docs-host]: https://ronin-rb.dev/docs/ronin-web-server/Ronin/Web/Server/Conditions/ClassMethods.html#host-instance_method\n[docs-referer]: https://ronin-rb.dev/docs/ronin-web-server/Ronin/Web/Server/Conditions/ClassMethods.html#referer-instance_method\n[docs-user_agent]: https://ronin-rb.dev/docs/ronin-web-server/Ronin/Web/Server/Conditions/ClassMethods.html#user_agent-instance_method\n[docs-browser]: https://ronin-rb.dev/docs/ronin-web-server/Ronin/Web/Server/Conditions/ClassMethods.html#browser-instance_method\n[docs-browser_vendor]: https://ronin-rb.dev/docs/ronin-web-server/Ronin/Web/Server/Conditions/ClassMethods.html#browser_vendor-instance_method\n[docs-browser_version]: https://ronin-rb.dev/docs/ronin-web-server/Ronin/Web/Server/Conditions/ClassMethods.html#browser_version-instance_method\n[docs-device_type]: https://ronin-rb.dev/docs/ronin-web-server/Ronin/Web/Server/Conditions/ClassMethods.html#device_type-instance_method\n[docs-os]: https://ronin-rb.dev/docs/ronin-web-server/Ronin/Web/Server/Conditions/ClassMethods.html#os-instance_method\n[docs-os_version]: https://ronin-rb.dev/docs/ronin-web-server/Ronin/Web/Server/Conditions/ClassMethods.html#os_version-instance_method\n\n## Examples\n\nCreate and run a simple web app:\n\n```ruby\nrequire 'ronin/web/server'\n\nclass App \u003c Ronin::Web::Server::Base\n\n  # mount a file\n  file '/sitemap.xml', './files/sitemap.xml'\n\n  # mount a directory\n  directory '/downloads/', '/tmp/downloads/'\n\n  get '/' do\n    # renders views/index.erb\n    erb :index\n  end\n\n  get '/test' do\n    \"raw string here\"\n  end\n\n  get '/exploit', asn: 13335 do\n    # route that only matches the AS13335 netblock\n  end\n\n  get '/exploit', asn_name: 'GOOGLE' do\n    # route that only matches GOOGLE netblocks\n  end\n\n  get '/exploit', country_code: 'US' do\n    # route that only matches US netblocks\n  end\n\n  get '/exploit', browser: :firefox do\n    # route that only matches firefox web browsers\n  end\n\n  get '/exploit', browser: :chrome, browser_version: /^99\\./ do\n    # route that only matches chrome 99.X.Y.Z web browsers\n  end\n\n  get '/exploit', os: :ios, os_version: '15.6' do\n    # route that only matches iOS 15.6 devices\n  end\n\n  # catchall route\n  get '/exploit' do\n    \"nothing to see here\"\n  end\n\nend\n\nApp.run!\n```\n\n**Note**: See {Ronin::Web::Server::Base} and [Sinatra's Intro][1] for additional\ndocumentation.\n\n[1]: http://sinatrarb.com/intro.html\n\n## Requirements\n\n* [Ruby] \u003e= 3.0.0\n* [webrick] ~\u003e 1.0\n* [rack] ~\u003e 2.2\n* [rack-user_agent] ~\u003e 0.5\n* [sinatra] ~\u003e 3.0\n* [ronin-support] ~\u003e 1.0\n\n## Install\n\n```shell\n$ gem install ronin-web-server\n```\n\n### Gemfile\n\n```shell\ngem 'ronin-web-server', '~\u003e 0.1'\n```\n\n## Development\n\n1. [Fork It!](https://github.com/ronin-rb/ronin-web-server/fork)\n2. Clone It!\n3. `cd ronin-web-server/`\n4. `bundle install`\n5. `git checkout -b my_feature`\n6. Code It!\n7. `bundle exec rake spec`\n8. `git push origin my_feature`\n\n## License\n\nronin-web-server - A custom Ruby web server based on Sinatra.\n\nCopyright (c) 2006-2025 Hal Brodigan (postmodern.mod3 at gmail.com)\n\nronin-web-server is free software: you can redistribute it and/or modify\nit under the terms of the GNU Lesser General Public License as published\nby the Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nronin-web-server is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU Lesser General Public License for more details.\n\nYou should have received a copy of the GNU Lesser General Public License\nalong with ronin-web-server.  If not, see \u003chttps://www.gnu.org/licenses/\u003e.\n\n[Ruby]: https://www.ruby-lang.org\n[webrick]: https://github.com/ruby/webrick#readme\n[rack]: https://github.com/rack/rack#readme\n[rack-user_agent]: https://github.com/k0kubun/rack-user_agent#readme\n[sinatra]: https://github.com/sinatra/sinatra#readme\n[ronin-support]: https://github.com/ronin-rb/ronin-support#readme\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fronin-rb%2Fronin-web-server","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fronin-rb%2Fronin-web-server","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fronin-rb%2Fronin-web-server/lists"}