ryanuber/oaf

View on GitHub
lib/oaf/httphandler.rb

Summary

Maintainability
A
0 mins
Test Coverage
require 'oaf/util'
require 'oaf/httpserver'
require 'webrick'

module Oaf

  # Provides all required handlers to WEBrick for serving all basic HTTP
  # methods. WEBrick handles GET, POST, HEAD, and OPTIONS out of the box,
  # but to mock most RESTful applications we are going to want PUT and
  # DELETE undoubtedly.
  class HTTPHandler < WEBrick::HTTPServlet::AbstractServlet

    # Remove the predefined WEBrick methods. WEBrick comes with some defaults
    # for GET, POST, OPTIONS, and HEAD, but let's use our own instead.
    instance_methods.each do |method|
      undef_method method if method.to_s =~ /^do_[A-Z]+$/
    end

    # Creates a new abstract server object and allows passing in the root
    # path of the server via an argument.
    #
    # == Parameters:
    # server::
    #   A WEBrick::HTTPServer object
    # options::
    #   A hash of Oaf configuration options
    #
    def initialize server, options
      super server
      @options = options
    end

    # Main server method. Oaf does not really differentiate between different
    # HTTP methods, but needs to at least support passing them all.
    #
    # == Parameters:
    # req::
    #   A WEBrick::HTTPRequest object
    # res::
    #   A WEBrick::HTTPResponse object
    #
    def process_request req, res
      req_headers = req.header
      req_query = req.query
      req_body = Oaf::HTTPServer.get_request_body req
      file = Oaf::Util.get_request_file(@options[:path], req.path,
        req.request_method, @options[:default_response])
      out = Oaf::Util.get_output(file, req.path, req_headers, req_body,
        req_query)
      res_headers, res_status, res_body = Oaf::HTTPServer.parse_response out
      Oaf::HTTPServer.set_response! res, res_headers, res_body, res_status
    end

    # A magic respond_to? implementation to trick WEBrick into thinking that any
    # do_* methods are already defined. This allows method_missing to do its job
    # once WEBrick makes its call to the method.
    #
    # == Parameters:
    # method::
    #   The name of the class method being checked
    #
    # == Returns:
    # Boolean, true if the method name matches do_[A-Z]+, else super.
    #
    def respond_to? method
      method.to_s =~ /^do_[A-Z]+$/ ? true : super
    end

    # A magic method to handle any and all do_* methods. This allows Oaf to
    # claim some degree of support for any HTTP method, be it a known and
    # commonly used method such as PUT or DELETE, or custom methods.
    #
    # == Parameters:
    # method::
    #   The name of the method being called
    # *opt::
    #   A list of arguments to pass along to the processing method
    #
    def method_missing method, *opt
      method.to_s =~ /^do_[A-Z]+$/ ? process_request(*opt) : super
    end
  end
end