ronin-web-server 0.1.0.beta1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.document +5 -0
- data/.github/workflows/ruby.yml +41 -0
- data/.gitignore +13 -0
- data/.rspec +1 -0
- data/.rubocop.yml +154 -0
- data/.ruby-version +1 -0
- data/.yardopts +1 -0
- data/COPYING.txt +165 -0
- data/ChangeLog.md +38 -0
- data/Gemfile +35 -0
- data/README.md +177 -0
- data/Rakefile +34 -0
- data/gemspec.yml +31 -0
- data/lib/ronin/web/server/app.rb +33 -0
- data/lib/ronin/web/server/base.rb +214 -0
- data/lib/ronin/web/server/conditions.rb +443 -0
- data/lib/ronin/web/server/helpers.rb +67 -0
- data/lib/ronin/web/server/request.rb +78 -0
- data/lib/ronin/web/server/response.rb +36 -0
- data/lib/ronin/web/server/reverse_proxy/request.rb +230 -0
- data/lib/ronin/web/server/reverse_proxy/response.rb +35 -0
- data/lib/ronin/web/server/reverse_proxy.rb +265 -0
- data/lib/ronin/web/server/routing.rb +261 -0
- data/lib/ronin/web/server/version.rb +28 -0
- data/lib/ronin/web/server.rb +62 -0
- data/ronin-web-server.gemspec +59 -0
- data/spec/base_spec.rb +73 -0
- data/spec/classes/public1/static1.txt +1 -0
- data/spec/classes/public2/static2.txt +1 -0
- data/spec/classes/sub_app.rb +13 -0
- data/spec/classes/test_app.rb +20 -0
- data/spec/helpers/rack_app.rb +24 -0
- data/spec/request_spec.rb +58 -0
- data/spec/response_spec.rb +8 -0
- data/spec/reverse_proxy/request_spec.rb +200 -0
- data/spec/reverse_proxy/response_spec.rb +8 -0
- data/spec/reverse_proxy_spec.rb +223 -0
- data/spec/spec_helper.rb +9 -0
- metadata +180 -0
data/gemspec.yml
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
name: ronin-web-server
|
2
|
+
summary: A custom Ruby web server based on Sinatra.
|
3
|
+
description: |
|
4
|
+
ronin-web-server is a custom Ruby web server based on Sinatra tailored for
|
5
|
+
security research and development.
|
6
|
+
|
7
|
+
license: LGPL-3.0
|
8
|
+
authors: Postmodern
|
9
|
+
email: postmodern.mod3@gmail.com
|
10
|
+
homepage: https://ronin-rb.dev/
|
11
|
+
has_yard: true
|
12
|
+
|
13
|
+
metadata:
|
14
|
+
documentation_uri: https://rubydoc.info/gems/ronin-web-server
|
15
|
+
source_code_uri: https://github.com/postmodern/ronin-web-server
|
16
|
+
bug_tracker_uri: https://github.com/postmodern/ronin-web-server/issues
|
17
|
+
changelog_uri: https://github.com/postmodern/ronin-web-server/blob/master/ChangeLog.md
|
18
|
+
rubygems_mfa_required: 'true'
|
19
|
+
|
20
|
+
required_ruby_version: ">= 3.0.0"
|
21
|
+
|
22
|
+
dependencies:
|
23
|
+
webrick: ~> 1.0
|
24
|
+
rack: ~> 2.2
|
25
|
+
rack-user_agent: ~> 0.5
|
26
|
+
sinatra: ~> 3.0
|
27
|
+
# Ronin dependencies:
|
28
|
+
ronin-support: ~> 1.0.0.beta1
|
29
|
+
|
30
|
+
development_dependencies:
|
31
|
+
bundler: ~> 2.0
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
#
|
3
|
+
# ronin-web-server - A custom Ruby web server based on Sinatra.
|
4
|
+
#
|
5
|
+
# Copyright (c) 2006-2022 Hal Brodigan (postmodern.mod3 at gmail.com)
|
6
|
+
#
|
7
|
+
# ronin-web-server is free software: you can redistribute it and/or modify
|
8
|
+
# it under the terms of the GNU Lesser General Public License as published
|
9
|
+
# by the Free Software Foundation, either version 3 of the License, or
|
10
|
+
# (at your option) any later version.
|
11
|
+
#
|
12
|
+
# ronin-web-server is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU Lesser General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU Lesser General Public License
|
18
|
+
# along with ronin-web-server. If not, see <https://www.gnu.org/licenses/>.
|
19
|
+
#
|
20
|
+
|
21
|
+
require 'ronin/web/server/base'
|
22
|
+
|
23
|
+
module Ronin
|
24
|
+
module Web
|
25
|
+
module Server
|
26
|
+
#
|
27
|
+
# The main Web Server class used by {Web.server}.
|
28
|
+
#
|
29
|
+
class App < Base
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,214 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
#
|
3
|
+
# ronin-web-server - A custom Ruby web server based on Sinatra.
|
4
|
+
#
|
5
|
+
# Copyright (c) 2006-2022 Hal Brodigan (postmodern.mod3 at gmail.com)
|
6
|
+
#
|
7
|
+
# ronin-web-server is free software: you can redistribute it and/or modify
|
8
|
+
# it under the terms of the GNU Lesser General Public License as published
|
9
|
+
# by the Free Software Foundation, either version 3 of the License, or
|
10
|
+
# (at your option) any later version.
|
11
|
+
#
|
12
|
+
# ronin-web-server is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU Lesser General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU Lesser General Public License
|
18
|
+
# along with ronin-web-server. If not, see <https://www.gnu.org/licenses/>.
|
19
|
+
#
|
20
|
+
|
21
|
+
require 'ronin/web/server/request'
|
22
|
+
require 'ronin/web/server/response'
|
23
|
+
require 'ronin/web/server/routing'
|
24
|
+
require 'ronin/web/server/helpers'
|
25
|
+
require 'ronin/web/server/conditions'
|
26
|
+
|
27
|
+
require 'rack'
|
28
|
+
require 'sinatra/base'
|
29
|
+
require 'rack/user_agent'
|
30
|
+
|
31
|
+
module Ronin
|
32
|
+
module Web
|
33
|
+
module Server
|
34
|
+
#
|
35
|
+
# The base-class for all Ronin Web Servers. Extends
|
36
|
+
# [Sinatra::Base](http://rubydoc.info/gems/sinatra/Sinatra/Base)
|
37
|
+
# with additional {Routing routing methods}, {Helpers helper methods} and
|
38
|
+
# Sinatra {Conditions conditions}.
|
39
|
+
#
|
40
|
+
# ## Routing Methods
|
41
|
+
#
|
42
|
+
# * {Routing::ClassMethods#any any}: registers a route that responds to
|
43
|
+
# `GET`, `POST`, `PUT`, `PATCH`, `DELETE` and `OPTIONS` requests.
|
44
|
+
# * {Routing::ClassMethods#default default}: registers the default route.
|
45
|
+
# * {Routing::ClassMethods#basic_auth basic_auth}: enables Basic-Auth
|
46
|
+
# authentication for the whole app.
|
47
|
+
# * {Routing::ClassMethods#redirect redirect}: adds a route that simply
|
48
|
+
# redirects to another URL.
|
49
|
+
# * {Routing::ClassMethods#file file}: mounts a file at the given path.
|
50
|
+
# a given file.
|
51
|
+
# * {Routing::ClassMethods#directory directory}: mounts a directory at
|
52
|
+
# the given path.
|
53
|
+
# * {Routing::ClassMethods#public_dir public_dir}: mounts a directory
|
54
|
+
# at the root.
|
55
|
+
# * {Routing::ClassMethods#vhost vhost}: mounts a Rack app for the given
|
56
|
+
# vhost.
|
57
|
+
# * {Routing::ClassMethods#mount mount}: mounts a Rack app at the given
|
58
|
+
# path.
|
59
|
+
#
|
60
|
+
# ## Helper Methods
|
61
|
+
#
|
62
|
+
# * {Helpers#h h}: escapes HTML entities.
|
63
|
+
# * {Helpers#file file}: sends a file.
|
64
|
+
# * {Helpers#mime_type_for mime_type_for}: returns the MIME type for the
|
65
|
+
# file.
|
66
|
+
# * {Helpers#content_type_for content_type_for}: sets the `Content-Type`
|
67
|
+
# for the file.
|
68
|
+
#
|
69
|
+
# ## Routing Conditions
|
70
|
+
#
|
71
|
+
# * {Conditions::ClassMethods#client_ip client_ip}: filters requests
|
72
|
+
# based on their client IP address.
|
73
|
+
# * {Conditions::ClassMethods#asn asn}: filters requests by the client
|
74
|
+
# IP's ASN number.
|
75
|
+
# * {Conditions::ClassMethods#country_code country_code}: filters requests
|
76
|
+
# by the client IP's ASN country code.
|
77
|
+
# * {Conditions::ClassMethods#asn_name asn_name}: filters requests by the
|
78
|
+
# client IP's ASN company/ISP name.
|
79
|
+
# * {Conditions::ClassMethods#host host}: filters requests based on the
|
80
|
+
# `Host` header.
|
81
|
+
# * {Conditions::ClassMethods#referer referer}: filters requests based on
|
82
|
+
# the `Referer` header.
|
83
|
+
# * {Conditions::ClassMethods#user_agent user_agent}: filters requests
|
84
|
+
# based on the `User-Agent` header.
|
85
|
+
# * {Conditions::ClassMethods#browser browser}: filters requests based on
|
86
|
+
# the browser name within the `User-Agent` header.
|
87
|
+
# * {Conditions::ClassMethods#browser_version browser_version}: filters
|
88
|
+
# requests based on the browser version within the `User-Agent` header.
|
89
|
+
# * {Conditions::ClassMethods#device_type device_type}: filters requests
|
90
|
+
# based on the device type within the `User-Agent` header.
|
91
|
+
# * {Conditions::ClassMethods#os os}: filters requests based on the OS
|
92
|
+
# within the `User-Agent` header.
|
93
|
+
# * {Conditions::ClassMethods#os_version os_version}: filters requests
|
94
|
+
# based on the OS version within the `User-Agent` header.
|
95
|
+
#
|
96
|
+
# ## Examples
|
97
|
+
#
|
98
|
+
# require 'ronin/web/server'
|
99
|
+
#
|
100
|
+
# class App < Ronin::Web::Server::Base
|
101
|
+
#
|
102
|
+
# # mount a file
|
103
|
+
# file '/sitemap.xml', './files/sitemap.xml'
|
104
|
+
#
|
105
|
+
# # mount a directory
|
106
|
+
# directory '/downloads/', '/tmp/downloads/'
|
107
|
+
#
|
108
|
+
# get '/' do
|
109
|
+
# # renders views/index.erb
|
110
|
+
# erb :index
|
111
|
+
# end
|
112
|
+
#
|
113
|
+
# get '/test' do
|
114
|
+
# "raw text here"
|
115
|
+
# end
|
116
|
+
#
|
117
|
+
# end
|
118
|
+
#
|
119
|
+
# App.run!
|
120
|
+
#
|
121
|
+
class Base < Sinatra::Base
|
122
|
+
|
123
|
+
include Server::Routing
|
124
|
+
include Server::Helpers
|
125
|
+
include Server::Conditions
|
126
|
+
|
127
|
+
# Default interface to run the Web Server on
|
128
|
+
DEFAULT_HOST = '0.0.0.0'
|
129
|
+
|
130
|
+
# Default port to run the Web Server on
|
131
|
+
DEFAULT_PORT = 8000
|
132
|
+
|
133
|
+
use Rack::UserAgent
|
134
|
+
|
135
|
+
set :host, DEFAULT_HOST
|
136
|
+
set :port, DEFAULT_PORT
|
137
|
+
|
138
|
+
before do
|
139
|
+
@request = Request.new(@env)
|
140
|
+
@response = Response.new
|
141
|
+
end
|
142
|
+
|
143
|
+
not_found { [404, {'Content-Type' => 'text/html'}, ['']] }
|
144
|
+
|
145
|
+
#
|
146
|
+
# Run the web server.
|
147
|
+
#
|
148
|
+
# @param [Hash] options Additional options.
|
149
|
+
#
|
150
|
+
# @option options [String] :host
|
151
|
+
# The host the server will listen on.
|
152
|
+
#
|
153
|
+
# @option options [Integer] :port
|
154
|
+
# The port the server will bind to.
|
155
|
+
#
|
156
|
+
# @option options [String] :server
|
157
|
+
# The Web Server to run on.
|
158
|
+
#
|
159
|
+
# @option options [Boolean] :background (false)
|
160
|
+
# Specifies wether the server will run in the background or run
|
161
|
+
# in the foreground.
|
162
|
+
#
|
163
|
+
# @api public
|
164
|
+
#
|
165
|
+
def self.run!(options={})
|
166
|
+
set(options)
|
167
|
+
|
168
|
+
handler = detect_rack_handler
|
169
|
+
handler_name = handler.name.gsub(/.*::/, '')
|
170
|
+
|
171
|
+
# rubocop:disable Lint/ShadowingOuterLocalVariable
|
172
|
+
runner = lambda { |handler,server|
|
173
|
+
begin
|
174
|
+
handler.run(server,Host: bind, Port: port) do |server|
|
175
|
+
trap(:INT) { quit!(server,handler_name) }
|
176
|
+
trap(:TERM) { quit!(server,handler_name) }
|
177
|
+
|
178
|
+
set :running, true
|
179
|
+
end
|
180
|
+
rescue Errno::EADDRINUSE
|
181
|
+
warn "ronin-web-server: address is already in use: #{bind}:#{port}"
|
182
|
+
end
|
183
|
+
}
|
184
|
+
# rubocop:enable Lint/ShadowingOuterLocalVariable
|
185
|
+
|
186
|
+
if options[:background]
|
187
|
+
Thread.new(handler,self,&runner)
|
188
|
+
else
|
189
|
+
runner.call(handler,self)
|
190
|
+
end
|
191
|
+
|
192
|
+
return self
|
193
|
+
end
|
194
|
+
|
195
|
+
#
|
196
|
+
# Stops the web server.
|
197
|
+
#
|
198
|
+
# @param [#call] server
|
199
|
+
# The Rack Handler server.
|
200
|
+
#
|
201
|
+
# @param [String] handler_name
|
202
|
+
# The name of the handler.
|
203
|
+
#
|
204
|
+
# @api semipublic
|
205
|
+
#
|
206
|
+
def self.quit!(server,handler_name)
|
207
|
+
# Use thins' hard #stop! if available, otherwise just #stop
|
208
|
+
server.respond_to?(:stop!) ? server.stop! : server.stop
|
209
|
+
end
|
210
|
+
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|