colouringcode-passenger 0.1 → 0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/NEWS +129 -0
- data/Rakefile +2 -2
- data/bin/passenger-install-apache2-module +1 -0
- data/bin/passenger-install-nginx-module +4 -2
- data/ext/apache2/Hooks.cpp +4 -2
- data/ext/common/ApplicationPoolServer.h +1 -1
- data/ext/common/ApplicationPoolServerExecutable.cpp +1 -1
- data/ext/common/MessageChannel.h +48 -4
- data/ext/common/StandardApplicationPool.h +4 -2
- data/ext/common/Version.h +1 -1
- data/ext/nginx/Configuration.c +1 -1
- data/ext/nginx/HttpStatusExtractor.h +1 -0
- data/ext/nginx/ScgiRequestParser.h +1 -0
- data/ext/oxt/system_calls.cpp +11 -0
- data/ext/oxt/system_calls.hpp +2 -1
- data/ext/oxt/thread.hpp +97 -1
- data/ext/phusion_passenger/native_support.c +30 -1
- data/lib/phusion_passenger/constants.rb +1 -1
- data/lib/phusion_passenger/dependencies.rb +32 -0
- data/lib/phusion_passenger/message_channel.rb +45 -3
- data/lib/phusion_passenger/platform_info.rb +1 -1
- data/lib/phusion_passenger/rack/application_spawner.rb +10 -4
- data/lib/phusion_passenger/rack/request_handler.rb +2 -5
- data/lib/phusion_passenger/railz/application_spawner.rb +59 -7
- data/lib/phusion_passenger/utils.rb +70 -16
- data/{vendor/rack-1.0.0-git/lib/rack → lib/phusion_passenger/utils}/rewindable_input.rb +34 -9
- data/test/ApplicationPoolTest.cpp +1 -1
- data/test/MessageChannelTest.cpp +9 -1
- data/test/stub/message_channel.rb +1 -1
- data/test/stub/message_channel_2.rb +1 -1
- data/test/stub/message_channel_3.rb +2 -2
- metadata +43 -155
- data/doc/Architectural overview.html +0 -1
- data/doc/rdoc/classes/ConditionVariable.html +0 -194
- data/doc/rdoc/classes/Exception.html +0 -120
- data/doc/rdoc/classes/GC.html +0 -113
- data/doc/rdoc/classes/IO.html +0 -169
- data/doc/rdoc/classes/PhusionPassenger.html +0 -238
- data/doc/rdoc/classes/PhusionPassenger/AbstractInstaller.html +0 -153
- data/doc/rdoc/classes/PhusionPassenger/AbstractRequestHandler.html +0 -517
- data/doc/rdoc/classes/PhusionPassenger/AbstractServer.html +0 -719
- data/doc/rdoc/classes/PhusionPassenger/AbstractServer/ServerAlreadyStarted.html +0 -97
- data/doc/rdoc/classes/PhusionPassenger/AbstractServer/ServerError.html +0 -96
- data/doc/rdoc/classes/PhusionPassenger/AbstractServer/ServerNotStarted.html +0 -97
- data/doc/rdoc/classes/PhusionPassenger/AbstractServer/UnknownMessage.html +0 -96
- data/doc/rdoc/classes/PhusionPassenger/AbstractServerCollection.html +0 -598
- data/doc/rdoc/classes/PhusionPassenger/AdminTools.html +0 -140
- data/doc/rdoc/classes/PhusionPassenger/AdminTools/ControlProcess.html +0 -317
- data/doc/rdoc/classes/PhusionPassenger/AdminTools/ControlProcess/Instance.html +0 -138
- data/doc/rdoc/classes/PhusionPassenger/AppInitError.html +0 -154
- data/doc/rdoc/classes/PhusionPassenger/Application.html +0 -283
- data/doc/rdoc/classes/PhusionPassenger/ConsoleTextTemplate.html +0 -172
- data/doc/rdoc/classes/PhusionPassenger/FrameworkInitError.html +0 -145
- data/doc/rdoc/classes/PhusionPassenger/HTMLTemplate.html +0 -181
- data/doc/rdoc/classes/PhusionPassenger/InitializationError.html +0 -141
- data/doc/rdoc/classes/PhusionPassenger/InvalidPath.html +0 -92
- data/doc/rdoc/classes/PhusionPassenger/MessageChannel.html +0 -489
- data/doc/rdoc/classes/PhusionPassenger/NativeSupport.html +0 -350
- data/doc/rdoc/classes/PhusionPassenger/Rack.html +0 -91
- data/doc/rdoc/classes/PhusionPassenger/Rack/ApplicationSpawner.html +0 -188
- data/doc/rdoc/classes/PhusionPassenger/Rack/RequestHandler.html +0 -199
- data/doc/rdoc/classes/PhusionPassenger/Railz.html +0 -95
- data/doc/rdoc/classes/PhusionPassenger/Railz/ApplicationSpawner.html +0 -438
- data/doc/rdoc/classes/PhusionPassenger/Railz/ApplicationSpawner/Error.html +0 -98
- data/doc/rdoc/classes/PhusionPassenger/Railz/CGIFixed.html +0 -200
- data/doc/rdoc/classes/PhusionPassenger/Railz/FrameworkSpawner.html +0 -436
- data/doc/rdoc/classes/PhusionPassenger/Railz/FrameworkSpawner/Error.html +0 -98
- data/doc/rdoc/classes/PhusionPassenger/Railz/RequestHandler.html +0 -155
- data/doc/rdoc/classes/PhusionPassenger/SpawnManager.html +0 -402
- data/doc/rdoc/classes/PhusionPassenger/UnknownError.html +0 -125
- data/doc/rdoc/classes/PhusionPassenger/Utils.html +0 -803
- data/doc/rdoc/classes/PhusionPassenger/Utils/PseudoIO.html +0 -169
- data/doc/rdoc/classes/PhusionPassenger/VersionNotFound.html +0 -140
- data/doc/rdoc/classes/PhusionPassenger/WSGI.html +0 -89
- data/doc/rdoc/classes/PhusionPassenger/WSGI/ApplicationSpawner.html +0 -188
- data/doc/rdoc/classes/PlatformInfo.html +0 -866
- data/doc/rdoc/classes/RakeExtensions.html +0 -197
- data/doc/rdoc/classes/Signal.html +0 -131
- data/doc/rdoc/created.rid +0 -1
- data/doc/rdoc/files/DEVELOPERS_TXT.html +0 -255
- data/doc/rdoc/files/README.html +0 -175
- data/doc/rdoc/files/ext/phusion_passenger/native_support_c.html +0 -92
- data/doc/rdoc/files/lib/phusion_passenger/abstract_installer_rb.html +0 -129
- data/doc/rdoc/files/lib/phusion_passenger/abstract_request_handler_rb.html +0 -129
- data/doc/rdoc/files/lib/phusion_passenger/abstract_server_collection_rb.html +0 -126
- data/doc/rdoc/files/lib/phusion_passenger/abstract_server_rb.html +0 -128
- data/doc/rdoc/files/lib/phusion_passenger/admin_tools/control_process_rb.html +0 -130
- data/doc/rdoc/files/lib/phusion_passenger/admin_tools_rb.html +0 -122
- data/doc/rdoc/files/lib/phusion_passenger/application_rb.html +0 -127
- data/doc/rdoc/files/lib/phusion_passenger/console_text_template_rb.html +0 -126
- data/doc/rdoc/files/lib/phusion_passenger/constants_rb.html +0 -122
- data/doc/rdoc/files/lib/phusion_passenger/dependencies_rb.html +0 -134
- data/doc/rdoc/files/lib/phusion_passenger/events_rb.html +0 -122
- data/doc/rdoc/files/lib/phusion_passenger/exceptions_rb.html +0 -122
- data/doc/rdoc/files/lib/phusion_passenger/html_template_rb.html +0 -126
- data/doc/rdoc/files/lib/phusion_passenger/message_channel_rb.html +0 -120
- data/doc/rdoc/files/lib/phusion_passenger/packaging_rb.html +0 -122
- data/doc/rdoc/files/lib/phusion_passenger/platform_info_rb.html +0 -127
- data/doc/rdoc/files/lib/phusion_passenger/rack/application_spawner_rb.html +0 -133
- data/doc/rdoc/files/lib/phusion_passenger/rack/request_handler_rb.html +0 -125
- data/doc/rdoc/files/lib/phusion_passenger/railz/application_spawner_rb.html +0 -140
- data/doc/rdoc/files/lib/phusion_passenger/railz/cgi_fixed_rb.html +0 -126
- data/doc/rdoc/files/lib/phusion_passenger/railz/framework_spawner_rb.html +0 -145
- data/doc/rdoc/files/lib/phusion_passenger/railz/request_handler_rb.html +0 -125
- data/doc/rdoc/files/lib/phusion_passenger/simple_benchmarking_rb.html +0 -122
- data/doc/rdoc/files/lib/phusion_passenger/spawn_manager_rb.html +0 -159
- data/doc/rdoc/files/lib/phusion_passenger/utils_rb.html +0 -174
- data/doc/rdoc/files/lib/phusion_passenger/wsgi/application_spawner_rb.html +0 -129
- data/doc/rdoc/files/misc/rake/extensions_rb.html +0 -130
- data/doc/rdoc/fr_class_index.html +0 -91
- data/doc/rdoc/fr_file_index.html +0 -76
- data/doc/rdoc/fr_method_index.html +0 -205
- data/doc/rdoc/index.html +0 -26
- data/doc/rdoc/rdoc-style.css +0 -187
- data/vendor/README +0 -13
- data/vendor/README_FOR_PACKAGERS +0 -1
- data/vendor/rack-1.0.0-git/COPYING +0 -18
- data/vendor/rack-1.0.0-git/KNOWN-ISSUES +0 -18
- data/vendor/rack-1.0.0-git/README +0 -353
- data/vendor/rack-1.0.0-git/Rakefile +0 -164
- data/vendor/rack-1.0.0-git/lib/rack.rb +0 -90
- data/vendor/rack-1.0.0-git/lib/rack/adapter/camping.rb +0 -22
- data/vendor/rack-1.0.0-git/lib/rack/auth/abstract/handler.rb +0 -37
- data/vendor/rack-1.0.0-git/lib/rack/auth/abstract/request.rb +0 -37
- data/vendor/rack-1.0.0-git/lib/rack/auth/basic.rb +0 -58
- data/vendor/rack-1.0.0-git/lib/rack/auth/digest/md5.rb +0 -124
- data/vendor/rack-1.0.0-git/lib/rack/auth/digest/nonce.rb +0 -51
- data/vendor/rack-1.0.0-git/lib/rack/auth/digest/params.rb +0 -55
- data/vendor/rack-1.0.0-git/lib/rack/auth/digest/request.rb +0 -40
- data/vendor/rack-1.0.0-git/lib/rack/auth/openid.rb +0 -487
- data/vendor/rack-1.0.0-git/lib/rack/builder.rb +0 -63
- data/vendor/rack-1.0.0-git/lib/rack/cascade.rb +0 -41
- data/vendor/rack-1.0.0-git/lib/rack/chunked.rb +0 -49
- data/vendor/rack-1.0.0-git/lib/rack/commonlogger.rb +0 -52
- data/vendor/rack-1.0.0-git/lib/rack/conditionalget.rb +0 -47
- data/vendor/rack-1.0.0-git/lib/rack/content_length.rb +0 -29
- data/vendor/rack-1.0.0-git/lib/rack/content_type.rb +0 -23
- data/vendor/rack-1.0.0-git/lib/rack/deflater.rb +0 -96
- data/vendor/rack-1.0.0-git/lib/rack/directory.rb +0 -153
- data/vendor/rack-1.0.0-git/lib/rack/file.rb +0 -88
- data/vendor/rack-1.0.0-git/lib/rack/handler.rb +0 -69
- data/vendor/rack-1.0.0-git/lib/rack/handler/cgi.rb +0 -61
- data/vendor/rack-1.0.0-git/lib/rack/handler/evented_mongrel.rb +0 -8
- data/vendor/rack-1.0.0-git/lib/rack/handler/fastcgi.rb +0 -88
- data/vendor/rack-1.0.0-git/lib/rack/handler/lsws.rb +0 -55
- data/vendor/rack-1.0.0-git/lib/rack/handler/mongrel.rb +0 -84
- data/vendor/rack-1.0.0-git/lib/rack/handler/scgi.rb +0 -59
- data/vendor/rack-1.0.0-git/lib/rack/handler/swiftiplied_mongrel.rb +0 -8
- data/vendor/rack-1.0.0-git/lib/rack/handler/thin.rb +0 -18
- data/vendor/rack-1.0.0-git/lib/rack/handler/webrick.rb +0 -67
- data/vendor/rack-1.0.0-git/lib/rack/head.rb +0 -19
- data/vendor/rack-1.0.0-git/lib/rack/lint.rb +0 -537
- data/vendor/rack-1.0.0-git/lib/rack/lobster.rb +0 -65
- data/vendor/rack-1.0.0-git/lib/rack/lock.rb +0 -16
- data/vendor/rack-1.0.0-git/lib/rack/methodoverride.rb +0 -27
- data/vendor/rack-1.0.0-git/lib/rack/mime.rb +0 -204
- data/vendor/rack-1.0.0-git/lib/rack/mock.rb +0 -184
- data/vendor/rack-1.0.0-git/lib/rack/recursive.rb +0 -57
- data/vendor/rack-1.0.0-git/lib/rack/reloader.rb +0 -106
- data/vendor/rack-1.0.0-git/lib/rack/request.rb +0 -248
- data/vendor/rack-1.0.0-git/lib/rack/response.rb +0 -183
- data/vendor/rack-1.0.0-git/lib/rack/session/abstract/id.rb +0 -142
- data/vendor/rack-1.0.0-git/lib/rack/session/cookie.rb +0 -91
- data/vendor/rack-1.0.0-git/lib/rack/session/memcache.rb +0 -109
- data/vendor/rack-1.0.0-git/lib/rack/session/pool.rb +0 -100
- data/vendor/rack-1.0.0-git/lib/rack/showexceptions.rb +0 -349
- data/vendor/rack-1.0.0-git/lib/rack/showstatus.rb +0 -106
- data/vendor/rack-1.0.0-git/lib/rack/static.rb +0 -38
- data/vendor/rack-1.0.0-git/lib/rack/urlmap.rb +0 -55
- data/vendor/rack-1.0.0-git/lib/rack/utils.rb +0 -522
@@ -1,63 +0,0 @@
|
|
1
|
-
module Rack
|
2
|
-
# Rack::Builder implements a small DSL to iteratively construct Rack
|
3
|
-
# applications.
|
4
|
-
#
|
5
|
-
# Example:
|
6
|
-
#
|
7
|
-
# app = Rack::Builder.new {
|
8
|
-
# use Rack::CommonLogger
|
9
|
-
# use Rack::ShowExceptions
|
10
|
-
# map "/lobster" do
|
11
|
-
# use Rack::Lint
|
12
|
-
# run Rack::Lobster.new
|
13
|
-
# end
|
14
|
-
# }
|
15
|
-
#
|
16
|
-
# Or
|
17
|
-
#
|
18
|
-
# app = Rack::Builder.app do
|
19
|
-
# use Rack::CommonLogger
|
20
|
-
# lambda { |env| [200, {'Content-Type' => 'text/plain'}, 'OK'] }
|
21
|
-
# end
|
22
|
-
#
|
23
|
-
# +use+ adds a middleware to the stack, +run+ dispatches to an application.
|
24
|
-
# You can use +map+ to construct a Rack::URLMap in a convenient way.
|
25
|
-
|
26
|
-
class Builder
|
27
|
-
def initialize(&block)
|
28
|
-
@ins = []
|
29
|
-
instance_eval(&block) if block_given?
|
30
|
-
end
|
31
|
-
|
32
|
-
def self.app(&block)
|
33
|
-
self.new(&block).to_app
|
34
|
-
end
|
35
|
-
|
36
|
-
def use(middleware, *args, &block)
|
37
|
-
@ins << lambda { |app| middleware.new(app, *args, &block) }
|
38
|
-
end
|
39
|
-
|
40
|
-
def run(app)
|
41
|
-
@ins << app #lambda { |nothing| app }
|
42
|
-
end
|
43
|
-
|
44
|
-
def map(path, &block)
|
45
|
-
if @ins.last.kind_of? Hash
|
46
|
-
@ins.last[path] = self.class.new(&block).to_app
|
47
|
-
else
|
48
|
-
@ins << {}
|
49
|
-
map(path, &block)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
def to_app
|
54
|
-
@ins[-1] = Rack::URLMap.new(@ins.last) if Hash === @ins.last
|
55
|
-
inner_app = @ins.last
|
56
|
-
@ins[0...-1].reverse.inject(inner_app) { |a, e| e.call(a) }
|
57
|
-
end
|
58
|
-
|
59
|
-
def call(env)
|
60
|
-
to_app.call(env)
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
@@ -1,41 +0,0 @@
|
|
1
|
-
module Rack
|
2
|
-
# Rack::Cascade tries an request on several apps, and returns the
|
3
|
-
# first response that is not 404 (or in a list of configurable
|
4
|
-
# status codes).
|
5
|
-
|
6
|
-
class Cascade
|
7
|
-
NotFound = [404, {}, []]
|
8
|
-
|
9
|
-
attr_reader :apps
|
10
|
-
|
11
|
-
def initialize(apps, catch=404)
|
12
|
-
@apps = []; @has_app = {}
|
13
|
-
apps.each { |app| add app }
|
14
|
-
|
15
|
-
@catch = {}
|
16
|
-
[*catch].each { |status| @catch[status] = true }
|
17
|
-
end
|
18
|
-
|
19
|
-
def call(env)
|
20
|
-
result = NotFound
|
21
|
-
|
22
|
-
@apps.each do |app|
|
23
|
-
result = app.call(env)
|
24
|
-
break unless @catch.include?(result[0].to_i)
|
25
|
-
end
|
26
|
-
|
27
|
-
result
|
28
|
-
end
|
29
|
-
|
30
|
-
def add app
|
31
|
-
@has_app[app] = true
|
32
|
-
@apps << app
|
33
|
-
end
|
34
|
-
|
35
|
-
def include? app
|
36
|
-
@has_app.include? app
|
37
|
-
end
|
38
|
-
|
39
|
-
alias_method :<<, :add
|
40
|
-
end
|
41
|
-
end
|
@@ -1,49 +0,0 @@
|
|
1
|
-
require 'rack/utils'
|
2
|
-
|
3
|
-
module Rack
|
4
|
-
|
5
|
-
# Middleware that applies chunked transfer encoding to response bodies
|
6
|
-
# when the response does not include a Content-Length header.
|
7
|
-
class Chunked
|
8
|
-
include Rack::Utils
|
9
|
-
|
10
|
-
def initialize(app)
|
11
|
-
@app = app
|
12
|
-
end
|
13
|
-
|
14
|
-
def call(env)
|
15
|
-
status, headers, body = @app.call(env)
|
16
|
-
headers = HeaderHash.new(headers)
|
17
|
-
|
18
|
-
if env['HTTP_VERSION'] == 'HTTP/1.0' ||
|
19
|
-
STATUS_WITH_NO_ENTITY_BODY.include?(status) ||
|
20
|
-
headers['Content-Length'] ||
|
21
|
-
headers['Transfer-Encoding']
|
22
|
-
[status, headers.to_hash, body]
|
23
|
-
else
|
24
|
-
dup.chunk(status, headers, body)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def chunk(status, headers, body)
|
29
|
-
@body = body
|
30
|
-
headers.delete('Content-Length')
|
31
|
-
headers['Transfer-Encoding'] = 'chunked'
|
32
|
-
[status, headers.to_hash, self]
|
33
|
-
end
|
34
|
-
|
35
|
-
def each
|
36
|
-
term = "\r\n"
|
37
|
-
@body.each do |chunk|
|
38
|
-
size = bytesize(chunk)
|
39
|
-
next if size == 0
|
40
|
-
yield [size.to_s(16), term, chunk, term].join
|
41
|
-
end
|
42
|
-
yield ["0", term, "", term].join
|
43
|
-
end
|
44
|
-
|
45
|
-
def close
|
46
|
-
@body.close if @body.respond_to?(:close)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
@@ -1,52 +0,0 @@
|
|
1
|
-
module Rack
|
2
|
-
# Rack::CommonLogger forwards every request to an +app+ given, and
|
3
|
-
# logs a line in the Apache common log format to the +logger+, or
|
4
|
-
# rack.errors by default.
|
5
|
-
class CommonLogger
|
6
|
-
# Common Log Format: http://httpd.apache.org/docs/1.3/logs.html#common
|
7
|
-
# lilith.local - - [07/Aug/2006 23:58:02] "GET / HTTP/1.1" 500 -
|
8
|
-
# %{%s - %s [%s] "%s %s%s %s" %d %s\n} %
|
9
|
-
FORMAT = %{%s - %s [%s] "%s %s%s %s" %d %s %0.4f\n}
|
10
|
-
|
11
|
-
def initialize(app, logger=nil)
|
12
|
-
@app = app
|
13
|
-
@logger = logger
|
14
|
-
end
|
15
|
-
|
16
|
-
def call(env)
|
17
|
-
began_at = Time.now
|
18
|
-
status, header, body = @app.call(env)
|
19
|
-
log(env, status, header, began_at)
|
20
|
-
[status, header, body]
|
21
|
-
end
|
22
|
-
|
23
|
-
private
|
24
|
-
|
25
|
-
def log(env, status, header, began_at)
|
26
|
-
now = Time.now
|
27
|
-
length = extract_content_length(header)
|
28
|
-
|
29
|
-
logger = @logger || env['rack.errors']
|
30
|
-
logger.write FORMAT % [
|
31
|
-
env['HTTP_X_FORWARDED_FOR'] || env["REMOTE_ADDR"] || "-",
|
32
|
-
env["REMOTE_USER"] || "-",
|
33
|
-
now.strftime("%d/%b/%Y %H:%M:%S"),
|
34
|
-
env["REQUEST_METHOD"],
|
35
|
-
env["PATH_INFO"],
|
36
|
-
env["QUERY_STRING"].empty? ? "" : "?"+env["QUERY_STRING"],
|
37
|
-
env["HTTP_VERSION"],
|
38
|
-
status.to_s[0..3],
|
39
|
-
length,
|
40
|
-
now - began_at ]
|
41
|
-
end
|
42
|
-
|
43
|
-
def extract_content_length(headers)
|
44
|
-
headers.each do |key, value|
|
45
|
-
if key.downcase == 'content-length'
|
46
|
-
return value.to_s == '0' ? '-' : value
|
47
|
-
end
|
48
|
-
end
|
49
|
-
'-'
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
@@ -1,47 +0,0 @@
|
|
1
|
-
require 'rack/utils'
|
2
|
-
|
3
|
-
module Rack
|
4
|
-
|
5
|
-
# Middleware that enables conditional GET using If-None-Match and
|
6
|
-
# If-Modified-Since. The application should set either or both of the
|
7
|
-
# Last-Modified or Etag response headers according to RFC 2616. When
|
8
|
-
# either of the conditions is met, the response body is set to be zero
|
9
|
-
# length and the response status is set to 304 Not Modified.
|
10
|
-
#
|
11
|
-
# Applications that defer response body generation until the body's each
|
12
|
-
# message is received will avoid response body generation completely when
|
13
|
-
# a conditional GET matches.
|
14
|
-
#
|
15
|
-
# Adapted from Michael Klishin's Merb implementation:
|
16
|
-
# http://github.com/wycats/merb-core/tree/master/lib/merb-core/rack/middleware/conditional_get.rb
|
17
|
-
class ConditionalGet
|
18
|
-
def initialize(app)
|
19
|
-
@app = app
|
20
|
-
end
|
21
|
-
|
22
|
-
def call(env)
|
23
|
-
return @app.call(env) unless %w[GET HEAD].include?(env['REQUEST_METHOD'])
|
24
|
-
|
25
|
-
status, headers, body = @app.call(env)
|
26
|
-
headers = Utils::HeaderHash.new(headers)
|
27
|
-
if etag_matches?(env, headers) || modified_since?(env, headers)
|
28
|
-
status = 304
|
29
|
-
headers.delete('Content-Type')
|
30
|
-
headers.delete('Content-Length')
|
31
|
-
body = []
|
32
|
-
end
|
33
|
-
[status, headers, body]
|
34
|
-
end
|
35
|
-
|
36
|
-
private
|
37
|
-
def etag_matches?(env, headers)
|
38
|
-
etag = headers['Etag'] and etag == env['HTTP_IF_NONE_MATCH']
|
39
|
-
end
|
40
|
-
|
41
|
-
def modified_since?(env, headers)
|
42
|
-
last_modified = headers['Last-Modified'] and
|
43
|
-
last_modified == env['HTTP_IF_MODIFIED_SINCE']
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
end
|
@@ -1,29 +0,0 @@
|
|
1
|
-
require 'rack/utils'
|
2
|
-
|
3
|
-
module Rack
|
4
|
-
# Sets the Content-Length header on responses with fixed-length bodies.
|
5
|
-
class ContentLength
|
6
|
-
include Rack::Utils
|
7
|
-
|
8
|
-
def initialize(app)
|
9
|
-
@app = app
|
10
|
-
end
|
11
|
-
|
12
|
-
def call(env)
|
13
|
-
status, headers, body = @app.call(env)
|
14
|
-
headers = HeaderHash.new(headers)
|
15
|
-
|
16
|
-
if !STATUS_WITH_NO_ENTITY_BODY.include?(status) &&
|
17
|
-
!headers['Content-Length'] &&
|
18
|
-
!headers['Transfer-Encoding'] &&
|
19
|
-
(body.respond_to?(:to_ary) || body.respond_to?(:to_str))
|
20
|
-
|
21
|
-
body = [body] if body.respond_to?(:to_str) # rack 0.4 compat
|
22
|
-
length = body.to_ary.inject(0) { |len, part| len + bytesize(part) }
|
23
|
-
headers['Content-Length'] = length.to_s
|
24
|
-
end
|
25
|
-
|
26
|
-
[status, headers, body]
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
require 'rack/utils'
|
2
|
-
|
3
|
-
module Rack
|
4
|
-
|
5
|
-
# Sets the Content-Type header on responses which don't have one.
|
6
|
-
#
|
7
|
-
# Builder Usage:
|
8
|
-
# use Rack::ContentType, "text/plain"
|
9
|
-
#
|
10
|
-
# When no content type argument is provided, "text/html" is assumed.
|
11
|
-
class ContentType
|
12
|
-
def initialize(app, content_type = "text/html")
|
13
|
-
@app, @content_type = app, content_type
|
14
|
-
end
|
15
|
-
|
16
|
-
def call(env)
|
17
|
-
status, headers, body = @app.call(env)
|
18
|
-
headers = Utils::HeaderHash.new(headers)
|
19
|
-
headers['Content-Type'] ||= @content_type
|
20
|
-
[status, headers.to_hash, body]
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
@@ -1,96 +0,0 @@
|
|
1
|
-
require "zlib"
|
2
|
-
require "stringio"
|
3
|
-
require "time" # for Time.httpdate
|
4
|
-
require 'rack/utils'
|
5
|
-
|
6
|
-
module Rack
|
7
|
-
class Deflater
|
8
|
-
def initialize(app)
|
9
|
-
@app = app
|
10
|
-
end
|
11
|
-
|
12
|
-
def call(env)
|
13
|
-
status, headers, body = @app.call(env)
|
14
|
-
headers = Utils::HeaderHash.new(headers)
|
15
|
-
|
16
|
-
# Skip compressing empty entity body responses and responses with
|
17
|
-
# no-transform set.
|
18
|
-
if Utils::STATUS_WITH_NO_ENTITY_BODY.include?(status) ||
|
19
|
-
headers['Cache-Control'].to_s =~ /\bno-transform\b/
|
20
|
-
return [status, headers, body]
|
21
|
-
end
|
22
|
-
|
23
|
-
request = Request.new(env)
|
24
|
-
|
25
|
-
encoding = Utils.select_best_encoding(%w(gzip deflate identity),
|
26
|
-
request.accept_encoding)
|
27
|
-
|
28
|
-
# Set the Vary HTTP header.
|
29
|
-
vary = headers["Vary"].to_s.split(",").map { |v| v.strip }
|
30
|
-
unless vary.include?("*") || vary.include?("Accept-Encoding")
|
31
|
-
headers["Vary"] = vary.push("Accept-Encoding").join(",")
|
32
|
-
end
|
33
|
-
|
34
|
-
case encoding
|
35
|
-
when "gzip"
|
36
|
-
headers['Content-Encoding'] = "gzip"
|
37
|
-
headers.delete('Content-Length')
|
38
|
-
mtime = headers.key?("Last-Modified") ?
|
39
|
-
Time.httpdate(headers["Last-Modified"]) : Time.now
|
40
|
-
[status, headers, GzipStream.new(body, mtime)]
|
41
|
-
when "deflate"
|
42
|
-
headers['Content-Encoding'] = "deflate"
|
43
|
-
headers.delete('Content-Length')
|
44
|
-
[status, headers, DeflateStream.new(body)]
|
45
|
-
when "identity"
|
46
|
-
[status, headers, body]
|
47
|
-
when nil
|
48
|
-
message = "An acceptable encoding for the requested resource #{request.fullpath} could not be found."
|
49
|
-
[406, {"Content-Type" => "text/plain", "Content-Length" => message.length.to_s}, [message]]
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
class GzipStream
|
54
|
-
def initialize(body, mtime)
|
55
|
-
@body = body
|
56
|
-
@mtime = mtime
|
57
|
-
end
|
58
|
-
|
59
|
-
def each(&block)
|
60
|
-
@writer = block
|
61
|
-
gzip =::Zlib::GzipWriter.new(self)
|
62
|
-
gzip.mtime = @mtime
|
63
|
-
@body.each { |part| gzip << part }
|
64
|
-
@body.close if @body.respond_to?(:close)
|
65
|
-
gzip.close
|
66
|
-
@writer = nil
|
67
|
-
end
|
68
|
-
|
69
|
-
def write(data)
|
70
|
-
@writer.call(data)
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
class DeflateStream
|
75
|
-
DEFLATE_ARGS = [
|
76
|
-
Zlib::DEFAULT_COMPRESSION,
|
77
|
-
# drop the zlib header which causes both Safari and IE to choke
|
78
|
-
-Zlib::MAX_WBITS,
|
79
|
-
Zlib::DEF_MEM_LEVEL,
|
80
|
-
Zlib::DEFAULT_STRATEGY
|
81
|
-
]
|
82
|
-
|
83
|
-
def initialize(body)
|
84
|
-
@body = body
|
85
|
-
end
|
86
|
-
|
87
|
-
def each
|
88
|
-
deflater = ::Zlib::Deflate.new(*DEFLATE_ARGS)
|
89
|
-
@body.each { |part| yield deflater.deflate(part) }
|
90
|
-
@body.close if @body.respond_to?(:close)
|
91
|
-
yield deflater.finish
|
92
|
-
nil
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|
@@ -1,153 +0,0 @@
|
|
1
|
-
require 'time'
|
2
|
-
require 'rack/utils'
|
3
|
-
require 'rack/mime'
|
4
|
-
|
5
|
-
module Rack
|
6
|
-
# Rack::Directory serves entries below the +root+ given, according to the
|
7
|
-
# path info of the Rack request. If a directory is found, the file's contents
|
8
|
-
# will be presented in an html based index. If a file is found, the env will
|
9
|
-
# be passed to the specified +app+.
|
10
|
-
#
|
11
|
-
# If +app+ is not specified, a Rack::File of the same +root+ will be used.
|
12
|
-
|
13
|
-
class Directory
|
14
|
-
DIR_FILE = "<tr><td class='name'><a href='%s'>%s</a></td><td class='size'>%s</td><td class='type'>%s</td><td class='mtime'>%s</td></tr>"
|
15
|
-
DIR_PAGE = <<-PAGE
|
16
|
-
<html><head>
|
17
|
-
<title>%s</title>
|
18
|
-
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
19
|
-
<style type='text/css'>
|
20
|
-
table { width:100%%; }
|
21
|
-
.name { text-align:left; }
|
22
|
-
.size, .mtime { text-align:right; }
|
23
|
-
.type { width:11em; }
|
24
|
-
.mtime { width:15em; }
|
25
|
-
</style>
|
26
|
-
</head><body>
|
27
|
-
<h1>%s</h1>
|
28
|
-
<hr />
|
29
|
-
<table>
|
30
|
-
<tr>
|
31
|
-
<th class='name'>Name</th>
|
32
|
-
<th class='size'>Size</th>
|
33
|
-
<th class='type'>Type</th>
|
34
|
-
<th class='mtime'>Last Modified</th>
|
35
|
-
</tr>
|
36
|
-
%s
|
37
|
-
</table>
|
38
|
-
<hr />
|
39
|
-
</body></html>
|
40
|
-
PAGE
|
41
|
-
|
42
|
-
attr_reader :files
|
43
|
-
attr_accessor :root, :path
|
44
|
-
|
45
|
-
def initialize(root, app=nil)
|
46
|
-
@root = F.expand_path(root)
|
47
|
-
@app = app || Rack::File.new(@root)
|
48
|
-
end
|
49
|
-
|
50
|
-
def call(env)
|
51
|
-
dup._call(env)
|
52
|
-
end
|
53
|
-
|
54
|
-
F = ::File
|
55
|
-
|
56
|
-
def _call(env)
|
57
|
-
@env = env
|
58
|
-
@script_name = env['SCRIPT_NAME']
|
59
|
-
@path_info = Utils.unescape(env['PATH_INFO'])
|
60
|
-
|
61
|
-
if forbidden = check_forbidden
|
62
|
-
forbidden
|
63
|
-
else
|
64
|
-
@path = F.join(@root, @path_info)
|
65
|
-
list_path
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
def check_forbidden
|
70
|
-
return unless @path_info.include? ".."
|
71
|
-
|
72
|
-
body = "Forbidden\n"
|
73
|
-
size = Rack::Utils.bytesize(body)
|
74
|
-
return [403, {"Content-Type" => "text/plain","Content-Length" => size.to_s}, [body]]
|
75
|
-
end
|
76
|
-
|
77
|
-
def list_directory
|
78
|
-
@files = [['../','Parent Directory','','','']]
|
79
|
-
glob = F.join(@path, '*')
|
80
|
-
|
81
|
-
Dir[glob].sort.each do |node|
|
82
|
-
stat = stat(node)
|
83
|
-
next unless stat
|
84
|
-
basename = F.basename(node)
|
85
|
-
ext = F.extname(node)
|
86
|
-
|
87
|
-
url = F.join(@script_name, @path_info, basename)
|
88
|
-
size = stat.size
|
89
|
-
type = stat.directory? ? 'directory' : Mime.mime_type(ext)
|
90
|
-
size = stat.directory? ? '-' : filesize_format(size)
|
91
|
-
mtime = stat.mtime.httpdate
|
92
|
-
url << '/' if stat.directory?
|
93
|
-
basename << '/' if stat.directory?
|
94
|
-
|
95
|
-
@files << [ url, basename, size, type, mtime ]
|
96
|
-
end
|
97
|
-
|
98
|
-
return [ 200, {'Content-Type'=>'text/html; charset=utf-8'}, self ]
|
99
|
-
end
|
100
|
-
|
101
|
-
def stat(node, max = 10)
|
102
|
-
F.stat(node)
|
103
|
-
rescue Errno::ENOENT, Errno::ELOOP
|
104
|
-
return nil
|
105
|
-
end
|
106
|
-
|
107
|
-
# TODO: add correct response if not readable, not sure if 404 is the best
|
108
|
-
# option
|
109
|
-
def list_path
|
110
|
-
@stat = F.stat(@path)
|
111
|
-
|
112
|
-
if @stat.readable?
|
113
|
-
return @app.call(@env) if @stat.file?
|
114
|
-
return list_directory if @stat.directory?
|
115
|
-
else
|
116
|
-
raise Errno::ENOENT, 'No such file or directory'
|
117
|
-
end
|
118
|
-
|
119
|
-
rescue Errno::ENOENT, Errno::ELOOP
|
120
|
-
return entity_not_found
|
121
|
-
end
|
122
|
-
|
123
|
-
def entity_not_found
|
124
|
-
body = "Entity not found: #{@path_info}\n"
|
125
|
-
size = Rack::Utils.bytesize(body)
|
126
|
-
return [404, {"Content-Type" => "text/plain", "Content-Length" => size.to_s}, [body]]
|
127
|
-
end
|
128
|
-
|
129
|
-
def each
|
130
|
-
show_path = @path.sub(/^#{@root}/,'')
|
131
|
-
files = @files.map{|f| DIR_FILE % f }*"\n"
|
132
|
-
page = DIR_PAGE % [ show_path, show_path , files ]
|
133
|
-
page.each_line{|l| yield l }
|
134
|
-
end
|
135
|
-
|
136
|
-
# Stolen from Ramaze
|
137
|
-
|
138
|
-
FILESIZE_FORMAT = [
|
139
|
-
['%.1fT', 1 << 40],
|
140
|
-
['%.1fG', 1 << 30],
|
141
|
-
['%.1fM', 1 << 20],
|
142
|
-
['%.1fK', 1 << 10],
|
143
|
-
]
|
144
|
-
|
145
|
-
def filesize_format(int)
|
146
|
-
FILESIZE_FORMAT.each do |format, size|
|
147
|
-
return format % (int.to_f / size) if int >= size
|
148
|
-
end
|
149
|
-
|
150
|
-
int.to_s + 'B'
|
151
|
-
end
|
152
|
-
end
|
153
|
-
end
|