culley harrelson <culley / fastmail.fm> skrev den Mon, 8 Sep 2003 10:50:07 +0900:

> I think you could run them on different ports then use apache for the virtual domains and mod_proxy to get each virtual domain to the correct port.  Just guessing but I think this should work...
>
Yeah, but if you wanna use pure-Ruby/webrick you can use my approach:

require 'webrick'
module WEBrick
  # A VHostServer is a HTTPServer that holds several mount tables.
  # Each mount table corresponds to a regexp. The mount table to use
  # for a request is the first one whose regexp matches the uri in the
  # request. This allows for easy "virtual hosting".
  class VHostServer < HTTPServer
    def initialize(*args)
      super
      @mount_tables = []     # holds [UriRE, MountTable] pairs
      @default_mount_table = @mount_tab
    end

    def vhost_mount(uriRegexp, dir, servlet, *options)
      @logger.debug(sprintf("%s is mounted on %s for %s.", servlet.inspect, dir, uriRegexp.inspect))
      re, mt = @mount_tables.detect {|re, mt| re == uriRegexp}
      unless mt
        mt = MountTable.new
        @mount_tables << [ uriRegexp, mt ]
      end
      mt[dir] = [ servlet, options ]
    end

    def service(req, res)
      if req.unparsed_uri == "*"
        if req.request_method == "OPTIONS"
          do_OPTIONS(req, res)
          raise HTTPStatus::OK
        end
        raise HTTPStatus::NotFound, "`#{req.unparsed_uri}' not found."
      end

      # Only change from HTTPServer#service:
      url = req.request_uri.to_s
      servlet, options, script_name, path_info = search_servlet(req.path, url)
      # ------------------------------------
      raise HTTPStatus::NotFound, "`#{req.path}' not found." unless servlet
      req.script_name = script_name
      req.path_info = path_info
      si = servlet.get_instance(self, *options)
      @logger.debug(format("%s is invoked.", si.class.name))
      si.service(req, res)
    end

    def search_servlet(path, url)
      mount_table = search_mount_table(url)
      script_name, path_info = mount_table.scan(path)
      servlet, options = mount_table[script_name]
      if servlet
        [ servlet, options, script_name, path_info ]
      end
    end

    def search_mount_table(url)
      re, mt = @mount_tables.detect {|re, mt| re.match(url) }
      mt || @default_mount_table
    end
  end
end

I just thought it was already in there...

Regards,

Robert