# = Webrick Servlet. # # code: # George Moschovitis # # (c) 2004 Navel, all rights reserved. # $Id: webrick-servlet.rb 87 2004-10-19 17:27:45Z gmosx $ require "drb" require "singleton" require "webrick" require "n/logger" require "n/utils/cache" require "n/app/request" require "n/app/request" require "n/app/handlers" require "n/app/session" # Override WEBrick to suit our needs. module WEBrick class HTTPRequest alias_method :old_parse_uri, :parse_uri def parse_uri(str, scheme="http") old_parse_uri(__rewrite(str.dup), scheme) end # gmosx, FIXME: temp hack! # def __rewrite(uri) # FIXME: scan for first ONLY. realm = uri.scan(/^\/(.*?)\//) realm = realm[0][0] unless realm.empty? if rules = $rewrites[realm] for rule in rules return uri if uri.gsub!(rule[0], rule[1]) end end return uri end end class HTTPResponse attr_writer :header attr_writer :cookies end end module N; module App # = WebrickServlet # class WebrickServlet < WEBrick::HTTPServlet::AbstractServlet include WEBrick def do_GET(wreq, wres) request = create_request(wreq) request.session = create_session(request) extension = N::StringUtils.extension_from_path(request.path) handler = $srv_extension_map[extension][1] begin fragment, script = handler.process(request) if fragment request.out["Content-Type"] = "text/html" unless request.out["Content-Type"] request.out_buffer = fragment.body end unless request.expires? request.expires!(Time.now()) end rescue Exception, StandardError => e $log.error "error while handling the request #{request.uri}" $log.error pp_exception(e) if $error_page_url # internal redirect to error page. # gmosx: reset handler for .rx pages. handler = $srv_extension_map["sx"][1] request.path = $error_page_url retry else # no custom error page defined. Presen a simple yet # useful error screen. request.out["Content-Type"] = "text/html" body = %{

ERROR

Click here to return to the previous page.

} if request.error_log body << %{

Request error log

#{request.error_log.join("\n")}
} end body << %{

Exception

#{pp_exception(e)}
} request.out_buffer = body end end # gmosx: optimize me, do something more clever!!! request.session.synchronize! wres.status = request.status wres.header = request.out wres.cookies = request.out_cookies.values() wres.body = request.out_buffer end def do_POST(wreq, wres) do_GET(wreq, wres) end #------------------------------------------------------------------------------- private # Convert a webrick request to an engine request # FIXME: this is UNOPTIMIZED code! # def create_request(wreq) # FIXME: use a resource pool! request = N::App::Request.new request.uri = wreq.unparsed_uri request.translated_uri = wreq.path_info request.path = wreq.path # request.path_info = wreq.path_info request.query_string = wreq.query_string request.method = wreq.request_method # request.remote_addr = wreq["REMOTE_ADDR"] # gmosx: we use an apache proxy for the moment. request.remote_addr = wreq["X-FORWARDED-FOR"] # gmosx: remove this ?? request.in = {} wreq.header.each { |k, v| # gmosx: upcase to make compatible with n2 codebase. request.in[k.upcase] = v[0] } request.parts = {} request.parameters = {} wreq.query.each { |k, v| if v.filename request.parts[k] = N::App::RequestPart.new(v.filename, v) else request.parameters[k] = v end } request.in_cookies = {} wreq.cookies.each { |c| request.in_cookies[c.name] = c } # gmosx: is this STILL needed?? # # INVESTIGATE, FIXME: this is a hack! # apache prepends $srv_url and fucks up msie. # FIXME: add unit test for this! if ref = request.in["REFERER"] split_re = Regexp.new($srv_url) unless split_re xref = ref.split(split_re).last if N::StringUtils.valid?(xref) request.in["REFERER"] = xref end end return request end # Create session # def create_session(request) session = nil session_id = nil # gmosx: i have to fix the get_cookie method to return a # full cookie object. if session_id = request.get_cookie(N::App::Session::COOKIE_NAME) session = $sessions[session_id] $log.debug "Stale session cookie: #{session_id}" unless session # FIXME: remove cookie if stale! else session_id = N::App::Session.calculate_id() cookie = N::App::Cookie.new(N::App::Session::COOKIE_NAME, session_id) request.out_cookies[N::App::Session::COOKIE_NAME] = cookie end # session not found and must be created unless session session = N::App::Session.new(session_id) end return session end end end; end # module