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
@@ -0,0 +1,200 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'ronin/web/server/reverse_proxy/request'
|
3
|
+
|
4
|
+
describe Ronin::Web::Server::ReverseProxy::Request do
|
5
|
+
it "must provide the same methods as Ronin::Web::Server::Request" do
|
6
|
+
expect(described_class).to be < Ronin::Web::Server::Request
|
7
|
+
end
|
8
|
+
|
9
|
+
let(:env) { {} }
|
10
|
+
|
11
|
+
subject { described_class.new(env) }
|
12
|
+
|
13
|
+
describe "#host=" do
|
14
|
+
let(:host) { 'example.com' }
|
15
|
+
let(:new_host) { 'evil.com' }
|
16
|
+
let(:env) do
|
17
|
+
{'HTTP_HOST' => host}
|
18
|
+
end
|
19
|
+
|
20
|
+
before { subject.host = new_host }
|
21
|
+
|
22
|
+
it "must set HTTP_HOST" do
|
23
|
+
expect(env['HTTP_HOST']).to eq(new_host)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "#port=" do
|
28
|
+
let(:port) { 80 }
|
29
|
+
let(:new_port) { 8080 }
|
30
|
+
let(:env) do
|
31
|
+
{'SERVER_PORT' => port}
|
32
|
+
end
|
33
|
+
|
34
|
+
before { subject.port = new_port }
|
35
|
+
|
36
|
+
it "must set SERVER_PORT" do
|
37
|
+
expect(env['SERVER_PORT']).to eq(new_port)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "#scheme=" do
|
42
|
+
let(:scheme) { 'https' }
|
43
|
+
let(:new_scheme) { 'http' }
|
44
|
+
let(:env) do
|
45
|
+
{'rack.url_scheme' => scheme}
|
46
|
+
end
|
47
|
+
|
48
|
+
before { subject.scheme = new_scheme }
|
49
|
+
|
50
|
+
it "must set rack.url_scheme" do
|
51
|
+
expect(env['rack.url_scheme']).to eq(new_scheme)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "#ssl=" do
|
56
|
+
context "when given true" do
|
57
|
+
before { subject.ssl = true }
|
58
|
+
|
59
|
+
it "must set #port to 443" do
|
60
|
+
expect(subject.port).to eq(443)
|
61
|
+
end
|
62
|
+
|
63
|
+
it "must set #scheme to 'https'" do
|
64
|
+
expect(subject.scheme).to eq('https')
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context "when given false" do
|
69
|
+
before { subject.ssl = false }
|
70
|
+
|
71
|
+
it "must set #port to 80" do
|
72
|
+
expect(subject.port).to eq(80)
|
73
|
+
end
|
74
|
+
|
75
|
+
it "must set #scheme to 'http'" do
|
76
|
+
expect(subject.scheme).to eq('http')
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe "#request_method=" do
|
82
|
+
let(:request_method) { 'GET' }
|
83
|
+
let(:new_request_method) { 'POST' }
|
84
|
+
let(:env) do
|
85
|
+
{'REQUEST_METHOD' => request_method}
|
86
|
+
end
|
87
|
+
|
88
|
+
before { subject.request_method = new_request_method }
|
89
|
+
|
90
|
+
it "must set REQUEST_METHOD" do
|
91
|
+
expect(env['REQUEST_METHOD']).to eq(new_request_method)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
describe "#query_string=" do
|
96
|
+
let(:query_string) { 'GET' }
|
97
|
+
let(:new_query_string) { 'POST' }
|
98
|
+
let(:env) do
|
99
|
+
{'QUERY_STRING' => query_string}
|
100
|
+
end
|
101
|
+
|
102
|
+
before { subject.query_string = new_query_string }
|
103
|
+
|
104
|
+
it "must set QUERY_STRING" do
|
105
|
+
expect(env['QUERY_STRING']).to eq(new_query_string)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
describe "#xhr=" do
|
110
|
+
context "when given true" do
|
111
|
+
before { subject.xhr = true }
|
112
|
+
|
113
|
+
it "must set HTTP_X_REQUESTED_WITH to 'XMLHttpRequest'" do
|
114
|
+
expect(env['HTTP_X_REQUESTED_WITH']).to eq('XMLHttpRequest')
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
context "when given false" do
|
119
|
+
let(:env) do
|
120
|
+
{'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest'}
|
121
|
+
end
|
122
|
+
|
123
|
+
before { subject.xhr = false }
|
124
|
+
|
125
|
+
it "must delete the HTTP_X_REQUESTED_WITH header" do
|
126
|
+
expect(env['HTTP_X_REQUESTED_WITH']).to be(nil)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
describe "#content_type=" do
|
132
|
+
let(:content_type) { 'text/html' }
|
133
|
+
let(:new_content_type) { 'text/xml' }
|
134
|
+
let(:env) do
|
135
|
+
{'CONTENT_TYPE' => content_type}
|
136
|
+
end
|
137
|
+
|
138
|
+
before { subject.content_type = new_content_type }
|
139
|
+
|
140
|
+
it "must set CONTENT_TYPE" do
|
141
|
+
expect(env['CONTENT_TYPE']).to eq(new_content_type)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
describe "#accept_encoding=" do
|
146
|
+
let(:accept_encoding) { 'gzip' }
|
147
|
+
let(:new_accept_encoding) { '*' }
|
148
|
+
let(:env) do
|
149
|
+
{'HTTP_ACCEPT_ENCODING' => accept_encoding}
|
150
|
+
end
|
151
|
+
|
152
|
+
before { subject.accept_encoding = new_accept_encoding }
|
153
|
+
|
154
|
+
it "must set HTTP_ACCEPT_ENCODING" do
|
155
|
+
expect(env['HTTP_ACCEPT_ENCODING']).to eq(new_accept_encoding)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
describe "#user_agent=" do
|
160
|
+
let(:user_agent) { 'FireFox' }
|
161
|
+
let(:new_user_agent) { 'Chrome' }
|
162
|
+
let(:env) do
|
163
|
+
{'HTTP_USER_AGENT' => user_agent}
|
164
|
+
end
|
165
|
+
|
166
|
+
before { subject.user_agent = new_user_agent }
|
167
|
+
|
168
|
+
it "must set HTTP_USER_AGENT" do
|
169
|
+
expect(env['HTTP_USER_AGENT']).to eq(new_user_agent)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
describe "#referer=" do
|
174
|
+
let(:referer) { 'http://example.com/' }
|
175
|
+
let(:new_referer) { 'http://evil.com/' }
|
176
|
+
let(:env) do
|
177
|
+
{'HTTP_REFERER' => referer}
|
178
|
+
end
|
179
|
+
|
180
|
+
before { subject.referer = new_referer }
|
181
|
+
|
182
|
+
it "must set HTTP_REFERER" do
|
183
|
+
expect(env['HTTP_REFERER']).to eq(new_referer)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
describe "#body=" do
|
188
|
+
let(:body) { '<html><body>test</body></html>' }
|
189
|
+
let(:new_body) { '<html><body>rewritten!</body></html>' }
|
190
|
+
let(:env) do
|
191
|
+
{'rack.input' => body}
|
192
|
+
end
|
193
|
+
|
194
|
+
before { subject.body = new_body }
|
195
|
+
|
196
|
+
it "must set rack.input" do
|
197
|
+
expect(env['rack.input']).to eq(new_body)
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'ronin/web/server/reverse_proxy/response'
|
3
|
+
|
4
|
+
describe Ronin::Web::Server::ReverseProxy::Response do
|
5
|
+
it "must provide the same methods as Ronin::Web::Server::Response" do
|
6
|
+
expect(described_class).to be < Ronin::Web::Server::Response
|
7
|
+
end
|
8
|
+
end
|
@@ -0,0 +1,223 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'ronin/web/server/reverse_proxy'
|
3
|
+
|
4
|
+
require 'webmock/rspec'
|
5
|
+
|
6
|
+
describe Ronin::Web::Server::ReverseProxy do
|
7
|
+
describe "#initialize" do
|
8
|
+
context "when given a block" do
|
9
|
+
it "must pass the newly created reverse proxy object" do
|
10
|
+
expect { |b|
|
11
|
+
described_class.new(&b)
|
12
|
+
}.to yield_with_args(described_class)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "#call" do
|
18
|
+
let(:request_method) { 'GET' }
|
19
|
+
let(:path) { '/' }
|
20
|
+
let(:port) { 80 }
|
21
|
+
let(:host) { 'example.com' }
|
22
|
+
let(:body) { '' }
|
23
|
+
let(:env) do
|
24
|
+
{
|
25
|
+
'REQUEST_METHOD' => request_method,
|
26
|
+
'REQUEST_PATH' => path,
|
27
|
+
'PATH_INFO' => path,
|
28
|
+
'HTTP_HOST' => host,
|
29
|
+
'SERVER_PORT' => port,
|
30
|
+
'rack.input' => StringIO.new(body)
|
31
|
+
}
|
32
|
+
end
|
33
|
+
|
34
|
+
let(:http_request_method) { request_method.downcase.to_sym }
|
35
|
+
let(:http_request_uri) do
|
36
|
+
URI::HTTP.build(host: host, port: port, path: path)
|
37
|
+
end
|
38
|
+
|
39
|
+
let(:http_response_status) { 200 }
|
40
|
+
let(:http_response_headers) do
|
41
|
+
{'X-Foo' => 'bar'}
|
42
|
+
end
|
43
|
+
let(:http_response_body) { nil }
|
44
|
+
|
45
|
+
before do
|
46
|
+
stub_request(:get,http_request_uri).to_return(
|
47
|
+
status: http_response_status,
|
48
|
+
headers: http_response_headers,
|
49
|
+
body: http_response_body
|
50
|
+
)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "must return a #{described_class::Response} object" do
|
54
|
+
expect(subject.call(env)).to be_kind_of(described_class::Response)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "must make an HTTP request for the requested Host header and path" do
|
58
|
+
subject.call(env)
|
59
|
+
|
60
|
+
expect(WebMock).to have_requested(http_request_method,http_request_uri)
|
61
|
+
end
|
62
|
+
|
63
|
+
it "must return all HTTP response headers in the respones object" do
|
64
|
+
response = subject.call(env)
|
65
|
+
|
66
|
+
expect(response.headers).to include(http_response_headers)
|
67
|
+
end
|
68
|
+
|
69
|
+
it "must default the response body to an empty String" do
|
70
|
+
response = subject.call(env)
|
71
|
+
|
72
|
+
expect(response.body).to eq([''])
|
73
|
+
end
|
74
|
+
|
75
|
+
context "when the #on_request callback is set" do
|
76
|
+
it "must pass the request object to the #on_request callback" do
|
77
|
+
yielded_request = nil
|
78
|
+
|
79
|
+
reverse_proxy = described_class.new do |proxy|
|
80
|
+
proxy.on_request do |request|
|
81
|
+
yielded_request = request
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
reverse_proxy.call(env)
|
86
|
+
|
87
|
+
expect(yielded_request).to be_kind_of(described_class::Request)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
context "when the #on_response callback is set" do
|
92
|
+
it "must pass the response object to the #on_response callback" do
|
93
|
+
yielded_response = nil
|
94
|
+
|
95
|
+
reverse_proxy = described_class.new do |proxy|
|
96
|
+
proxy.on_response do |response|
|
97
|
+
yielded_response = response
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
reverse_proxy.call(env)
|
102
|
+
|
103
|
+
expect(yielded_response).to be_kind_of(described_class::Response)
|
104
|
+
end
|
105
|
+
|
106
|
+
context "when the #on_response callback accepts two arguments" do
|
107
|
+
it "must pass both the request and the response objects" do
|
108
|
+
yielded_request = nil
|
109
|
+
yielded_response = nil
|
110
|
+
|
111
|
+
reverse_proxy = described_class.new do |proxy|
|
112
|
+
proxy.on_response do |request,response|
|
113
|
+
yielded_request = request
|
114
|
+
yielded_response = response
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
reverse_proxy.call(env)
|
119
|
+
|
120
|
+
expect(yielded_request).to be_kind_of(described_class::Request)
|
121
|
+
expect(yielded_response).to be_kind_of(described_class::Response)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
describe "#connection_for" do
|
128
|
+
let(:host) { 'example.com' }
|
129
|
+
let(:port) { 443 }
|
130
|
+
let(:ssl) { true }
|
131
|
+
|
132
|
+
context "when there is no connection for the host/port/ssl combination" do
|
133
|
+
it "must return a new Ronin::Support::Network::HTTP instance for the host/port/ssl combination" do
|
134
|
+
http = subject.connection_for(host,port,ssl: ssl)
|
135
|
+
|
136
|
+
expect(http).to be_kind_of(Ronin::Support::Network::HTTP)
|
137
|
+
expect(http.host).to eq(host)
|
138
|
+
expect(http.port).to eq(port)
|
139
|
+
expect(http.ssl?).to eq(ssl)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
context "when there is an existing connection for the host/port/ssl combination" do
|
144
|
+
it "must return the existing Ronin::Support::Network::HTTP instance for the host/port/ssl combination" do
|
145
|
+
expect(subject.connection_for(host,port,ssl: ssl)).to be(
|
146
|
+
subject.connection_for(host,port,ssl: ssl)
|
147
|
+
)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
describe "#reverse_proxy" do
|
153
|
+
let(:request_method) { 'GET' }
|
154
|
+
let(:path) { '/' }
|
155
|
+
let(:port) { 80 }
|
156
|
+
let(:host) { 'example.com' }
|
157
|
+
let(:body) { '' }
|
158
|
+
let(:env) do
|
159
|
+
{
|
160
|
+
'REQUEST_METHOD' => request_method,
|
161
|
+
'REQUEST_PATH' => path,
|
162
|
+
'PATH_INFO' => path,
|
163
|
+
'HTTP_HOST' => host,
|
164
|
+
'SERVER_PORT' => port,
|
165
|
+
'rack.input' => StringIO.new(body)
|
166
|
+
}
|
167
|
+
end
|
168
|
+
let(:request) { described_class::Request.new(env) }
|
169
|
+
|
170
|
+
let(:http_request_method) { request_method.downcase.to_sym }
|
171
|
+
let(:http_request_uri) do
|
172
|
+
URI::HTTP.build(host: host, port: port, path: path)
|
173
|
+
end
|
174
|
+
|
175
|
+
let(:http_response_status) { 200 }
|
176
|
+
let(:http_response_headers) do
|
177
|
+
{'X-Foo' => 'bar'}
|
178
|
+
end
|
179
|
+
let(:http_response_body) { nil }
|
180
|
+
|
181
|
+
before do
|
182
|
+
stub_request(:get,http_request_uri).to_return(
|
183
|
+
status: http_response_status,
|
184
|
+
headers: http_response_headers,
|
185
|
+
body: http_response_body
|
186
|
+
)
|
187
|
+
end
|
188
|
+
|
189
|
+
it "must return a #{described_class::Response} object" do
|
190
|
+
expect(subject.reverse_proxy(request)).to be_kind_of(described_class::Response)
|
191
|
+
end
|
192
|
+
|
193
|
+
it "must make an HTTP request for the requested Host header and path" do
|
194
|
+
subject.reverse_proxy(request)
|
195
|
+
|
196
|
+
expect(WebMock).to have_requested(http_request_method,http_request_uri)
|
197
|
+
end
|
198
|
+
|
199
|
+
it "must return all HTTP response headers in the respones object" do
|
200
|
+
response = subject.reverse_proxy(request)
|
201
|
+
|
202
|
+
expect(response.headers).to include(http_response_headers)
|
203
|
+
end
|
204
|
+
|
205
|
+
it "must default the response body to an empty String" do
|
206
|
+
response = subject.reverse_proxy(request)
|
207
|
+
|
208
|
+
expect(response.body).to eq([''])
|
209
|
+
end
|
210
|
+
|
211
|
+
context "when the response contains the 'Transfer-Encoding' header" do
|
212
|
+
let(:http_response_headers) do
|
213
|
+
{'Transfer-Encoding' => 'chunked'}
|
214
|
+
end
|
215
|
+
|
216
|
+
it "must omit the 'Transfer-Encoding' header from the response" do
|
217
|
+
response = subject.reverse_proxy(request)
|
218
|
+
|
219
|
+
expect(response.headers).to_not have_key('Transfer-Encoding')
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,180 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ronin-web-server
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0.beta1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Postmodern
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2023-01-01 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: webrick
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rack
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '2.2'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '2.2'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rack-user_agent
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.5'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.5'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: sinatra
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: ronin-support
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 1.0.0.beta1
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 1.0.0.beta1
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: bundler
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '2.0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '2.0'
|
97
|
+
description: |
|
98
|
+
ronin-web-server is a custom Ruby web server based on Sinatra tailored for
|
99
|
+
security research and development.
|
100
|
+
email: postmodern.mod3@gmail.com
|
101
|
+
executables: []
|
102
|
+
extensions: []
|
103
|
+
extra_rdoc_files:
|
104
|
+
- COPYING.txt
|
105
|
+
- ChangeLog.md
|
106
|
+
- README.md
|
107
|
+
files:
|
108
|
+
- ".document"
|
109
|
+
- ".github/workflows/ruby.yml"
|
110
|
+
- ".gitignore"
|
111
|
+
- ".rspec"
|
112
|
+
- ".rubocop.yml"
|
113
|
+
- ".ruby-version"
|
114
|
+
- ".yardopts"
|
115
|
+
- COPYING.txt
|
116
|
+
- ChangeLog.md
|
117
|
+
- Gemfile
|
118
|
+
- README.md
|
119
|
+
- Rakefile
|
120
|
+
- gemspec.yml
|
121
|
+
- lib/ronin/web/server.rb
|
122
|
+
- lib/ronin/web/server/app.rb
|
123
|
+
- lib/ronin/web/server/base.rb
|
124
|
+
- lib/ronin/web/server/conditions.rb
|
125
|
+
- lib/ronin/web/server/helpers.rb
|
126
|
+
- lib/ronin/web/server/request.rb
|
127
|
+
- lib/ronin/web/server/response.rb
|
128
|
+
- lib/ronin/web/server/reverse_proxy.rb
|
129
|
+
- lib/ronin/web/server/reverse_proxy/request.rb
|
130
|
+
- lib/ronin/web/server/reverse_proxy/response.rb
|
131
|
+
- lib/ronin/web/server/routing.rb
|
132
|
+
- lib/ronin/web/server/version.rb
|
133
|
+
- ronin-web-server.gemspec
|
134
|
+
- spec/base_spec.rb
|
135
|
+
- spec/classes/public1/static1.txt
|
136
|
+
- spec/classes/public2/static2.txt
|
137
|
+
- spec/classes/sub_app.rb
|
138
|
+
- spec/classes/test_app.rb
|
139
|
+
- spec/helpers/rack_app.rb
|
140
|
+
- spec/request_spec.rb
|
141
|
+
- spec/response_spec.rb
|
142
|
+
- spec/reverse_proxy/request_spec.rb
|
143
|
+
- spec/reverse_proxy/response_spec.rb
|
144
|
+
- spec/reverse_proxy_spec.rb
|
145
|
+
- spec/spec_helper.rb
|
146
|
+
homepage: https://ronin-rb.dev/
|
147
|
+
licenses:
|
148
|
+
- LGPL-3.0
|
149
|
+
metadata:
|
150
|
+
documentation_uri: https://rubydoc.info/gems/ronin-web-server
|
151
|
+
source_code_uri: https://github.com/postmodern/ronin-web-server
|
152
|
+
bug_tracker_uri: https://github.com/postmodern/ronin-web-server/issues
|
153
|
+
changelog_uri: https://github.com/postmodern/ronin-web-server/blob/master/ChangeLog.md
|
154
|
+
rubygems_mfa_required: 'true'
|
155
|
+
post_install_message:
|
156
|
+
rdoc_options: []
|
157
|
+
require_paths:
|
158
|
+
- lib
|
159
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
160
|
+
requirements:
|
161
|
+
- - ">="
|
162
|
+
- !ruby/object:Gem::Version
|
163
|
+
version: 3.0.0
|
164
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
165
|
+
requirements:
|
166
|
+
- - ">="
|
167
|
+
- !ruby/object:Gem::Version
|
168
|
+
version: '0'
|
169
|
+
requirements: []
|
170
|
+
rubygems_version: 3.3.26
|
171
|
+
signing_key:
|
172
|
+
specification_version: 4
|
173
|
+
summary: A custom Ruby web server based on Sinatra.
|
174
|
+
test_files:
|
175
|
+
- spec/base_spec.rb
|
176
|
+
- spec/request_spec.rb
|
177
|
+
- spec/response_spec.rb
|
178
|
+
- spec/reverse_proxy/request_spec.rb
|
179
|
+
- spec/reverse_proxy/response_spec.rb
|
180
|
+
- spec/reverse_proxy_spec.rb
|