1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
require 'base64'
class BasicMongrelHandler < Mongrel::HttpHandler
attr_accessor :content_type, :custom_headers, :response_body, :response_code, :preprocessor, :username, :password
def initialize
@content_type = "text/html"
@response_body = ""
@response_code = 200
@custom_headers = {}
end
def process(request, response)
instance_eval(&preprocessor) if preprocessor
reply_with(response, response_code, response_body)
end
def reply_with(response, code, response_body)
response.start(code) do |head, body|
head["Content-Type"] = content_type
custom_headers.each { |k, v| head[k] = v }
body.write(response_body)
end
end
end
class DeflateHandler < BasicMongrelHandler
def process(request, response)
accept_encoding = request.params["HTTP_ACCEPT_ENCODING"]
if accept_encoding.nil? || !accept_encoding.include?('deflate')
reply_with(response, 406, 'No deflate accept encoding found in request')
else
response.start do |head, body|
head['Content-Encoding'] = 'deflate'
body.write Zlib::Deflate.deflate(response_body)
end
end
end
end
class GzipHandler < BasicMongrelHandler
def process(request, response)
accept_encoding = request.params["HTTP_ACCEPT_ENCODING"]
if accept_encoding.nil? || !accept_encoding.include?('gzip')
reply_with(response, 406, 'No gzip accept encoding found in request')
else
response.start do |head, body|
head['Content-Encoding'] = 'gzip'
body.write gzip(response_body)
end
end
end
protected
def gzip(string)
sio = StringIO.new('', 'r+')
gz = Zlib::GzipWriter.new sio
gz.write string
gz.finish
sio.rewind
sio.read
end
end
module BasicAuthentication
def self.extended(base)
base.custom_headers["WWW-Authenticate"] = 'Basic Realm="Super Secret Page"'
end
def process(request, response)
if authorized?(request)
super
else
reply_with(response, 401, "Incorrect. You have 20 seconds to comply.")
end
end
def authorized?(request)
request.params["HTTP_AUTHORIZATION"] == "Basic " + Base64.encode64("#{@username}:#{@password}").strip
end
end
module DigestAuthentication
def self.extended(base)
base.custom_headers["WWW-Authenticate"] = 'Digest realm="testrealm@host.com",qop="auth,auth-int",nonce="nonce",opaque="opaque"'
end
def process(request, response)
if authorized?(request)
super
else
reply_with(response, 401, "Incorrect. You have 20 seconds to comply.")
end
end
def authorized?(request)
request.params["HTTP_AUTHORIZATION"] =~ /Digest.*uri=/
end
end
module DigestAuthenticationUsingMD5Sess
NONCE = 'nonce'
REALM = 'testrealm@host.com'
QOP = 'auth,auth-int'
def self.extended(base)
base.custom_headers["WWW-Authenticate"] = %(Digest realm="#{REALM}",qop="#{QOP}",algorithm="MD5-sess",nonce="#{NONCE}",opaque="opaque"')
end
def process(request, response)
if authorized?(request)
super
else
reply_with(response, 401, "Incorrect. You have 20 seconds to comply.")
end
end
def md5(str)
Digest::MD5.hexdigest(str)
end
def authorized?(request)
auth = request.params["HTTP_AUTHORIZATION"]
params = {}
auth.to_s.gsub(/(\w+)="(.*?)"/) { params[$1] = $2 }.gsub(/(\w+)=([^,]*)/) { params[$1] = $2 }
a1a = [@username,REALM,@password].join(':')
a1 = [md5(a1a),NONCE,params['cnonce'] ].join(':')
a2 = [ request.params["REQUEST_METHOD"], request.params["REQUEST_URI"] ] .join(':')
expected_response = md5( [md5(a1), NONCE, params['nc'], params['cnonce'], QOP, md5(a2)].join(':') )
expected_response == params['response']
end
end
def new_mongrel_redirector(target_url, relative_path = false)
target_url = "http://#{@host_and_port}#{target_url}" unless relative_path
Mongrel::RedirectHandler.new(target_url)
end
|