ronin-web 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. data.tar.gz.sig +0 -0
  2. data/History.txt +25 -0
  3. data/Manifest.txt +36 -4
  4. data/README.txt +67 -64
  5. data/Rakefile +12 -3
  6. data/bin/ronin-web +1 -1
  7. data/lib/ronin/network/helpers/web.rb +221 -0
  8. data/lib/ronin/web.rb +1 -2
  9. data/lib/ronin/web/extensions.rb +0 -2
  10. data/lib/ronin/web/extensions/nokogiri.rb +0 -23
  11. data/lib/ronin/web/proxy.rb +3 -103
  12. data/lib/ronin/web/proxy/app.rb +31 -0
  13. data/lib/ronin/web/proxy/base.rb +41 -0
  14. data/lib/ronin/web/proxy/web.rb +42 -0
  15. data/lib/ronin/web/server.rb +3 -530
  16. data/lib/ronin/web/server/app.rb +31 -0
  17. data/lib/ronin/web/server/base.rb +334 -0
  18. data/lib/ronin/web/server/files.rb +92 -0
  19. data/lib/ronin/web/server/helpers.rb +25 -0
  20. data/lib/ronin/web/server/helpers/files.rb +126 -0
  21. data/lib/ronin/web/server/helpers/hosts.rb +72 -0
  22. data/lib/ronin/web/server/helpers/proxy.rb +153 -0
  23. data/lib/ronin/web/server/helpers/rendering.rb +36 -0
  24. data/lib/ronin/web/server/hosts.rb +86 -0
  25. data/lib/ronin/web/server/proxy.rb +116 -0
  26. data/lib/ronin/web/server/web.rb +62 -0
  27. data/lib/ronin/web/spider.rb +53 -26
  28. data/lib/ronin/web/version.rb +1 -3
  29. data/lib/ronin/web/web.rb +253 -95
  30. data/spec/spec_helper.rb +1 -1
  31. data/spec/web/proxy/base_spec.rb +9 -0
  32. data/spec/web/server/base_spec.rb +86 -0
  33. data/spec/web/server/classes/files/dir/file.txt +1 -0
  34. data/spec/web/server/classes/files/dir/index.html +1 -0
  35. data/spec/web/server/classes/files/dir2/file2.txt +1 -0
  36. data/spec/web/server/classes/files/dir3/page.xml +4 -0
  37. data/spec/web/server/classes/files/file.txt +1 -0
  38. data/spec/web/server/classes/files_app.rb +27 -0
  39. data/spec/web/server/classes/hosts_app.rb +40 -0
  40. data/spec/web/server/classes/proxy_app.rb +45 -0
  41. data/spec/web/server/classes/public1/static1.txt +1 -0
  42. data/spec/web/server/classes/public2/static2.txt +1 -0
  43. data/spec/web/server/classes/sub_app.rb +13 -0
  44. data/spec/web/server/classes/test_app.rb +20 -0
  45. data/spec/web/server/files_spec.rb +74 -0
  46. data/spec/web/server/helpers/server.rb +42 -0
  47. data/spec/web/server/hosts_spec.rb +55 -0
  48. data/spec/web/server/proxy_spec.rb +49 -0
  49. data/tasks/spec.rb +1 -0
  50. data/tasks/yard.rb +13 -0
  51. metadata +76 -17
  52. metadata.gz.sig +0 -0
  53. data/TODO.txt +0 -7
  54. data/lib/ronin/sessions/web.rb +0 -80
  55. data/lib/ronin/web/fingerprint.rb +0 -76
  56. data/spec/web/server_spec.rb +0 -142
@@ -1,5 +1,4 @@
1
1
  #
2
- #--
3
2
  # Ronin Web - A Ruby library for Ronin that provides support for web
4
3
  # scraping and spidering functionality.
5
4
  #
@@ -18,13 +17,13 @@
18
17
  # You should have received a copy of the GNU General Public License
19
18
  # along with this program; if not, write to the Free Software
20
19
  # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
- #++
22
20
  #
23
21
 
24
22
  require 'ronin/web/extensions'
25
23
  require 'ronin/web/web'
26
24
  require 'ronin/web/spider'
27
25
  require 'ronin/web/server'
26
+ require 'ronin/web/proxy'
28
27
  require 'ronin/web/version'
29
28
  require 'ronin/config'
30
29
 
@@ -1,5 +1,4 @@
1
1
  #
2
- #--
3
2
  # Ronin Web - A Ruby library for Ronin that provides support for web
4
3
  # scraping and spidering functionality.
5
4
  #
@@ -18,7 +17,6 @@
18
17
  # You should have received a copy of the GNU General Public License
19
18
  # along with this program; if not, write to the Free Software
20
19
  # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
- #++
22
20
  #
23
21
 
24
22
  require 'ronin/web/extensions/nokogiri'
@@ -1,24 +1 @@
1
- #
2
- #--
3
- # Ronin Web - A Ruby library for Ronin that provides support for web
4
- # scraping and spidering functionality.
5
- #
6
- # Copyright (c) 2006-2009 Hal Brodigan (postmodern.mod3 at gmail.com)
7
- #
8
- # This program is free software; you can redistribute it and/or modify
9
- # it under the terms of the GNU General Public License as published by
10
- # the Free Software Foundation; either version 2 of the License, or
11
- # (at your option) any later version.
12
- #
13
- # This program is distributed in the hope that it will be useful,
14
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
15
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
- # GNU General Public License for more details.
17
- #
18
- # You should have received a copy of the GNU General Public License
19
- # along with this program; if not, write to the Free Software
20
- # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
- #++
22
- #
23
-
24
1
  require 'ronin/web/extensions/nokogiri/xml'
@@ -1,5 +1,4 @@
1
1
  #
2
- #--
3
2
  # Ronin Web - A Ruby library for Ronin that provides support for web
4
3
  # scraping and spidering functionality.
5
4
  #
@@ -18,107 +17,8 @@
18
17
  # You should have received a copy of the GNU General Public License
19
18
  # along with this program; if not, write to the Free Software
20
19
  # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
- #++
22
20
  #
23
21
 
24
- require 'ronin/web/server'
25
- require 'ronin/network/http'
26
-
27
- require 'net/http'
28
-
29
- module Ronin
30
- module Web
31
- class Proxy < Server
32
-
33
- # The default HTTP Request to use
34
- DEFAULT_HTTP_REQUEST = Net::HTTP::Get
35
-
36
- #
37
- # Creates a new Web Proxy using the given configuration _block_.
38
- #
39
- # _options_ may contain the following keys:
40
- # <tt>:host</tt>:: The host to bind to.
41
- # <tt>:port</tt>:: The port to listen on.
42
- # <tt>:config</tt>:: A +Hash+ of configurable variables to be used
43
- # in responses.
44
- #
45
- def initialize(options={},&block)
46
- super(options)
47
-
48
- @default = method(:proxy)
49
-
50
- instance_eval(&block) if block
51
- end
52
-
53
- #
54
- # Proxies the specified Rack _request_ and returns a corresponding
55
- # Rack response.
56
- #
57
- def proxy(request)
58
- server_response = http_response(request)
59
- server_headers = server_response.to_hash
60
- body = (server_response.body || '')
61
-
62
- return response(body,server_headers)
63
- end
64
-
65
- protected
66
-
67
- #
68
- # Returns the Net::HTTP Request class that represents the specified
69
- # HTTP _request_method_.
70
- #
71
- # http_class('POST')
72
- # # => Net::HTTP::Post
73
- #
74
- def http_class(request_method)
75
- http_method = request_method.downcase.capitalize
76
- http_class = DEFAULT_HTTP_REQUEST
77
-
78
- if Net::HTTP.const_defined?(http_method)
79
- http_class = Net::HTTP.const_get(http_method)
80
-
81
- unless http_class.kind_of?(Net::HTTPRequest)
82
- http_class = DEFAULT_HTTP_REQUEST
83
- end
84
- end
85
-
86
- return http_class
87
- end
88
-
89
- #
90
- # Converts the Rack headers within the specified _request_ to
91
- # Net::HTTP formatted HTTP headers.
92
- #
93
- def http_headers(request)
94
- client_headers = {}
95
-
96
- request.env.each do |name,value|
97
- if name =~ /^HTTP_/
98
- header_name = name.gsub(/^HTTP_/,'').split('_').map { |word|
99
- word.capitalize
100
- }.join('-')
101
-
102
- client_headers[header_name] = value
103
- end
104
- end
105
-
106
- return client_headers
107
- end
108
-
109
- #
110
- # Returns the Net::HTTP response for the specified Rack _request_.
111
- #
112
- def http_response(request)
113
- path = request.fullpath
114
- http_method = http_class(request.request_method)
115
- client_request = http_method.new(path,http_headers(request))
116
-
117
- Net.http_session(:host => request.host, :port => request.port) do |http|
118
- return http.request(client_request)
119
- end
120
- end
121
-
122
- end
123
- end
124
- end
22
+ require 'ronin/web/proxy/base'
23
+ require 'ronin/web/proxy/app'
24
+ require 'ronin/web/proxy/web'
@@ -0,0 +1,31 @@
1
+ #
2
+ # Ronin Web - A Ruby library for Ronin that provides support for web
3
+ # scraping and spidering functionality.
4
+ #
5
+ # Copyright (c) 2006-2009 Hal Brodigan (postmodern.mod3 at gmail.com)
6
+ #
7
+ # This program is free software; you can redistribute it and/or modify
8
+ # it under the terms of the GNU General Public License as published by
9
+ # the Free Software Foundation; either version 2 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # This program 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 General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with this program; if not, write to the Free Software
19
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
+ #
21
+
22
+ require 'ronin/web/proxy/base'
23
+
24
+ module Ronin
25
+ module Web
26
+ module Proxy
27
+ class App < Base
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,41 @@
1
+ #
2
+ # Ronin Web - A Ruby library for Ronin that provides support for web
3
+ # scraping and spidering functionality.
4
+ #
5
+ # Copyright (c) 2006-2009 Hal Brodigan (postmodern.mod3 at gmail.com)
6
+ #
7
+ # This program is free software; you can redistribute it and/or modify
8
+ # it under the terms of the GNU General Public License as published by
9
+ # the Free Software Foundation; either version 2 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # This program 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 General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with this program; if not, write to the Free Software
19
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
+ #
21
+
22
+ require 'ronin/web/server/base'
23
+
24
+ module Ronin
25
+ module Web
26
+ module Proxy
27
+ class Base < Server::Base
28
+
29
+ # The default port to run the Web Proxy on
30
+ DEFAULT_PORT = 8080
31
+
32
+ set :port, DEFAULT_PORT
33
+
34
+ default do
35
+ proxy
36
+ end
37
+
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,42 @@
1
+ #
2
+ # Ronin Web - A Ruby library for Ronin that provides support for web
3
+ # scraping and spidering functionality.
4
+ #
5
+ # Copyright (c) 2006-2009 Hal Brodigan (postmodern.mod3 at gmail.com)
6
+ #
7
+ # This program is free software; you can redistribute it and/or modify
8
+ # it under the terms of the GNU General Public License as published by
9
+ # the Free Software Foundation; either version 2 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # This program 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 General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with this program; if not, write to the Free Software
19
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
+ #
21
+
22
+ require 'ronin/web/proxy/app'
23
+
24
+ module Ronin
25
+ module Web
26
+ #
27
+ # Returns the Ronin Web Proxy. When called for the first time
28
+ # the proxy will be started in the background with the given
29
+ # _options_.
30
+ #
31
+ def Web.proxy(options={},&block)
32
+ unless class_variable_defined?('@@ronin_web_proxy')
33
+ @@ronin_web_proxy = Proxy::App
34
+ @@ronin_web_proxy.run!(options.merge(:background => true))
35
+ end
36
+
37
+ @@ronin_web_proxy.class_eval(&block)
38
+
39
+ return @@ronin_web_proxy
40
+ end
41
+ end
42
+ end
@@ -1,5 +1,4 @@
1
1
  #
2
- #--
3
2
  # Ronin Web - A Ruby library for Ronin that provides support for web
4
3
  # scraping and spidering functionality.
5
4
  #
@@ -18,534 +17,8 @@
18
17
  # You should have received a copy of the GNU General Public License
19
18
  # along with this program; if not, write to the Free Software
20
19
  # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
- #++
22
20
  #
23
21
 
24
- require 'uri'
25
- require 'cgi'
26
- require 'thread'
27
-
28
- begin
29
- require 'mongrel'
30
- rescue Gem::LoadError => e
31
- raise(e)
32
- rescue LoadError
33
- require 'webrick'
34
- end
35
-
36
- require 'rack'
37
-
38
- module Ronin
39
- module Web
40
- class Server
41
-
42
- # Default interface to run the Web Server on
43
- HOST = '0.0.0.0'
44
-
45
- # Default port to run the Web Server on
46
- PORT = 8080
47
-
48
- # Directory index files
49
- INDICES = ['index.htm', 'index.html']
50
-
51
- # The host to bind to
52
- attr_accessor :host
53
-
54
- # The port to listen on
55
- attr_accessor :port
56
-
57
- # The handler to run the server under
58
- attr_accessor :handler
59
-
60
- #
61
- # Creates a new Web Server using the given configuration _block_.
62
- #
63
- # _options_ may contain the following keys:
64
- # <tt>:host</tt>:: The host to bind to.
65
- # <tt>:port</tt>:: The port to listen on.
66
- # <tt>:handler</tt>:: The handler to run the server under.
67
- #
68
- def initialize(options={},&block)
69
- @host = options[:host]
70
- @port = options[:port]
71
- @handler = options[:handler]
72
-
73
- @default = method(:not_found)
74
-
75
- @vhost_patterns = {}
76
- @vhosts = {}
77
-
78
- @patterns = {}
79
- @paths = {}
80
- @directories = {}
81
-
82
- @default_mutex = Mutex.new
83
- @vhost_patterns_mutex = Mutex.new
84
- @vhosts_mutex = Mutex.new
85
- @patterns_mutex = Mutex.new
86
- @paths_mutex = Mutex.new
87
- @directories_mutex = Mutex.new
88
-
89
- block.call(self) if block
90
- end
91
-
92
- #
93
- # Returns the default host that the Web Server will be run on.
94
- #
95
- def Server.default_host
96
- @@default_host ||= HOST
97
- end
98
-
99
- #
100
- # Sets the default host that the Web Server will run on to the
101
- # specified _host_.
102
- #
103
- def Server.default_host=(host)
104
- @@default_host = host
105
- end
106
-
107
- #
108
- # Returns the default port that the Web Server will run on.
109
- #
110
- def Server.default_port
111
- @@default_port ||= PORT
112
- end
113
-
114
- #
115
- # Sets the default port the Web Server will run on to the specified
116
- # _port_.
117
- #
118
- def Server.default_port=(port)
119
- @@default_port = port
120
- end
121
-
122
- #
123
- # The Hash of the servers supported file extensions and their HTTP
124
- # Content-Types.
125
- #
126
- def Server.content_types
127
- @@content_types ||= {}
128
- end
129
-
130
- #
131
- # Registers a new content _type_ for the specified file _extensions_.
132
- #
133
- # Server.content_type 'text/xml', ['xml', 'xsl']
134
- #
135
- def Server.content_type(type,extensions)
136
- extensions.each { |ext| Server.content_types[ext] = type }
137
-
138
- return self
139
- end
140
-
141
- #
142
- # Creates a new Web Server object with the given _block_ and starts
143
- # it using the given _options_.
144
- #
145
- def self.start(options={},&block)
146
- self.new(options,&block).start
147
- end
148
-
149
- #
150
- # Returns the HTTP Content-Type for the specified file _extension_.
151
- #
152
- # server.content_type('html')
153
- # # => "text/html"
154
- #
155
- def content_type(extension)
156
- Server.content_types[extension] ||
157
- 'application/x-unknown-content-type'
158
- end
159
-
160
- #
161
- # Returns the HTTP Content-Type for the specified _file_.
162
- #
163
- # server.content_type_for('file.html')
164
- # # => "text/html"
165
- #
166
- def content_type_for(file)
167
- ext = File.extname(file).downcase
168
-
169
- return content_type(ext[1..-1])
170
- end
171
-
172
- #
173
- # Returns the index file contained within the _path_ of the specified
174
- # directory. If no index file can be found, +nil+ will be returned.
175
- #
176
- def index_of(path)
177
- path = File.expand_path(path)
178
-
179
- INDICES.each do |name|
180
- index = File.join(path,name)
181
-
182
- return index if File.file?(index)
183
- end
184
-
185
- return nil
186
- end
187
-
188
- #
189
- # Returns the HTTP 404 Not Found message for the requested path.
190
- #
191
- def not_found(request)
192
- path = request.path_info
193
- body = %{<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
194
- <html>
195
- <head>
196
- <title>404 Not Found</title>
197
- <body>
198
- <h1>Not Found</h1>
199
- <p>The requested URL #{CGI.escapeHTML(path)} was not found on this server.</p>
200
- <hr>
201
- </body>
202
- </html>}
203
-
204
- return response(body, :status => 404, :content_type => 'text/html')
205
- end
206
-
207
- #
208
- # Returns the contents of the file at the specified _path_. If the
209
- # _path_ points to a directory, the directory will be searched for
210
- # an index file. If no index file can be found or _path_ points to a
211
- # non-existant file, a "404 Not Found" response will be returned.
212
- #
213
- def return_file(path,request,content_type=nil)
214
- content_type ||= content_type_for(path)
215
-
216
- if !(File.exists?(path))
217
- return not_found(request)
218
- end
219
-
220
- if File.directory?(path)
221
- unless (path = index_of(path))
222
- return not_found(request)
223
- end
224
- end
225
-
226
- return response(File.new(path), :content_type => content_type)
227
- end
228
-
229
- #
230
- # Returns a Rack Response object with the specified _body_, the given
231
- # _options_ and the given _block_.
232
- #
233
- # _options_ may include the following keys:
234
- # <tt>:status</tt>:: The HTTP Response status code, defaults to 200.
235
- #
236
- # server.response("<data>lol</data>", :content_type => 'text/xml')
237
- #
238
- def response(body='',options={},&block)
239
- status = (
240
- options.delete(:status) ||
241
- options.delete('Status') ||
242
- 200
243
- )
244
- headers = {}
245
-
246
- options.each do |name,value|
247
- header_name = name.to_s.split('_').map { |word|
248
- word.capitalize
249
- }.join('-')
250
-
251
- headers[header_name] = value.to_s
252
- end
253
-
254
- return Rack::Response.new(body,status,headers,&block).finish
255
- end
256
-
257
- #
258
- # Returns the server that handles requests for the specified host
259
- # _name_.
260
- #
261
- def vhost(name)
262
- name = name.to_s
263
-
264
- @vhosts_mutex.synchronize do
265
- if @vhosts.has_key?(name)
266
- return @vhosts[name]
267
- end
268
- end
269
-
270
- @vhost_patterns_mutex.synchronize do
271
- @vhost_patterns.each do |pattern,server|
272
- return server if name.match(pattern)
273
- end
274
- end
275
-
276
- return nil
277
- end
278
-
279
- #
280
- # Use the given _server_ or _block_ as the default route for all
281
- # other requests.
282
- #
283
- # server.default do |request|
284
- # [200, {'Content-Type' => 'text/html'}, 'lol train']
285
- # end
286
- #
287
- def default(server=nil,&block)
288
- @default_mutex.synchronize do
289
- @default = (server || block)
290
- end
291
-
292
- return self
293
- end
294
-
295
- #
296
- # Registers the given _server_ or _block_ to be called when receiving
297
- # requests to host names which match the specified _pattern_.
298
- #
299
- # server.hosts_like(/^a[0-9]\./) do |vhost|
300
- # vhost.map('/download/') do |request|
301
- # ...
302
- # end
303
- # end
304
- #
305
- def hosts_like(pattern,server=nil,&block)
306
- server ||= self.class.new(&block)
307
-
308
- @vhost_patterns_mutex.synchronize do
309
- @vhost_patterns[pattern] = server
310
- end
311
-
312
- return server
313
- end
314
-
315
- #
316
- # Registers the given _server_ or _block_ to be called when receiving
317
- # requests for paths which match the specified _pattern_.
318
- #
319
- # server.paths_like(/\.xml$/) do |request|
320
- # ...
321
- # end
322
- #
323
- def paths_like(pattern,server=nil,&block)
324
- @patterns_mutex.synchronize do
325
- @patterns[pattern] = (server || block)
326
- end
327
-
328
- return self
329
- end
330
-
331
- #
332
- # Creates a new Server object using the specified _block_ and
333
- # connects it as a virtual host representing the specified host
334
- # _name_.
335
- #
336
- # server.host('cdn.evil.com') do |server|
337
- # ...
338
- # end
339
- #
340
- def host(name,server=nil,&block)
341
- server ||= self.class.new(&block)
342
-
343
- @vhosts_mutex.synchronize do
344
- @vhosts[name.to_s] = server
345
- end
346
-
347
- return server
348
- end
349
-
350
- #
351
- # Binds the specified URL _path_ to the given _server_ or _block_.
352
- #
353
- # server.bind '/secrets.xml' do |request|
354
- # [200, {'Content-Type' => 'text/xml'}, "Made you look."]
355
- # end
356
- #
357
- def bind(path,server=nil,&block)
358
- @paths_mutex.synchronize do
359
- @paths[path] = (server || block)
360
- end
361
-
362
- return self
363
- end
364
-
365
- #
366
- # Binds the specified URL directory _path_ to the given
367
- # _server_ or _block_.
368
- #
369
- # server.map '/downloads' do |request|
370
- # server.response(
371
- # "Your somewhere inside the downloads directory",
372
- # :content_type' => 'text/xml'
373
- # )
374
- # end
375
- #
376
- def map(path,server=nil,&block)
377
- @directories_mutex.synchronize do
378
- @directories[path] = (server || block)
379
- end
380
-
381
- return self
382
- end
383
-
384
- #
385
- # Binds the contents of the specified _file_ to the specified URL
386
- # _path_, using the given _options_.
387
- #
388
- # _options_ may contain the following keys:
389
- # <tt>content_type</tt>:: The content-type to use when serving
390
- # the file at the specified _path_.
391
- #
392
- # server.file '/robots.txt', '/path/to/my_robots.txt'
393
- #
394
- def file(path,file,options={})
395
- file = File.expand_path(file)
396
- content_type = options[:content_type]
397
-
398
- bind(path) do |request|
399
- if File.file?(file)
400
- return_file(file,request,content_type)
401
- else
402
- not_found(request)
403
- end
404
- end
405
- end
406
-
407
- #
408
- # Binds the contents of the specified _directory_ to the given
409
- # prefix _path_.
410
- #
411
- # server.directory '/download/', '/tmp/files/'
412
- #
413
- def directory(path,directory)
414
- sub_dirs = path.split('/')
415
- directory = File.expand_path(directory)
416
-
417
- map(path) do |request|
418
- http_path = File.expand_path(request.path_info)
419
- http_dirs = http_path.split('/')
420
-
421
- sub_path = http_dirs[sub_dirs.length..-1].join('/')
422
- absolute_path = File.join(directory,sub_path)
423
-
424
- return_file(absolute_path,request)
425
- end
426
- end
427
-
428
- #
429
- # Starts the server. Mongrel will be used to run the server, if it
430
- # is installed, otherwise WEBrick will be used.
431
- #
432
- def start
433
- rack_handler = [@handler, 'Mongrel', 'WEBrick'].find do |name|
434
- name && Rack::Handler.const_defined?(name)
435
- end
436
-
437
- unless rack_handler
438
- raise(StandardError,"unable to find any Rack handlers",caller)
439
- end
440
-
441
- rack_options = {
442
- 'Host' => (@host || Server.default_host),
443
- 'Port' => (@port || Server.default_port)
444
- }
445
-
446
- Rack::Handler.const_get(rack_handler).run(self,rack_options)
447
- return self
448
- end
449
-
450
- #
451
- # The method which receives all requests.
452
- #
453
- def call(env)
454
- http_host = env['HTTP_HOST']
455
- http_path = File.expand_path(env['PATH_INFO'])
456
- request = Rack::Request.new(env)
457
-
458
- if http_host
459
- if (server = vhost(http_host))
460
- return server.call(env)
461
- end
462
- end
463
-
464
- if http_path
465
- @paths_mutex.synchronize do
466
- if (block = @paths[http_path])
467
- return block.call(request)
468
- end
469
- end
470
-
471
- @patterns_mutex.synchronize do
472
- @patterns.each do |pattern,block|
473
- if http_path.match(pattern)
474
- return block.call(request)
475
- end
476
- end
477
- end
478
-
479
- http_dirs = http_path.split('/')
480
-
481
- @directories_mutex.synchronize do
482
- sub_dir = @directories.keys.select { |path|
483
- dirs = path.split('/')
484
-
485
- http_dirs[0...dirs.length] == dirs
486
- }.sort.last
487
-
488
- if (sub_dir && (block = @directories[sub_dir]))
489
- return block.call(request)
490
- end
491
- end
492
- end
493
-
494
- resp = nil
495
-
496
- @default_mutex.synchronize do
497
- resp = @default.call(request)
498
- end
499
-
500
- return resp
501
- end
502
-
503
- #
504
- # Routes the specified _url_ to the call method.
505
- #
506
- def route(url)
507
- url = URI(url.to_s)
508
-
509
- return call(
510
- 'HTTP_HOST' => url.host,
511
- 'HTTP_PORT' => url.port,
512
- 'SERVER_PORT' => url.port,
513
- 'PATH_INFO' => url.path,
514
- 'QUERY_STRING' => url.query
515
- )
516
- end
517
-
518
- #
519
- # Routes the specified _path_ to the call method.
520
- #
521
- def route_path(path)
522
- path, query = URI.decode(path.to_s).split('?',2)
523
-
524
- return route(URI::HTTP.build(
525
- :host => @host,
526
- :port => @port,
527
- :path => path,
528
- :query => query
529
- ))
530
- end
531
-
532
- protected
533
-
534
- content_type 'text/html', ['html', 'htm', 'xhtml']
535
- content_type 'text/css', ['css']
536
- content_type 'text/gif', ['gif']
537
- content_type 'text/jpeg', ['jpeg', 'jpg']
538
- content_type 'text/png', ['png']
539
- content_type 'image/x-icon', ['ico']
540
- content_type 'text/javascript', ['js']
541
- content_type 'text/xml', ['xml', 'xsl']
542
- content_type 'application/rss+xml', ['rss']
543
- content_type 'application/rdf+xml', ['rdf']
544
- content_type 'application/pdf', ['pdf']
545
- content_type 'application/doc', ['doc']
546
- content_type 'application/zip', ['zip']
547
- content_type 'text/plain', ['txt', 'conf', 'rb', 'py', 'h', 'c', 'hh', 'cc', 'hpp', 'cpp']
548
-
549
- end
550
- end
551
- end
22
+ require 'ronin/web/server/base'
23
+ require 'ronin/web/server/app'
24
+ require 'ronin/web/server/web'