summaryrefslogtreecommitdiff
path: root/lib/xmlrpc/httpserver.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/xmlrpc/httpserver.rb')
-rw-r--r--lib/xmlrpc/httpserver.rb83
1 files changed, 39 insertions, 44 deletions
diff --git a/lib/xmlrpc/httpserver.rb b/lib/xmlrpc/httpserver.rb
index e4aa99f46a..f7185ff2dd 100644
--- a/lib/xmlrpc/httpserver.rb
+++ b/lib/xmlrpc/httpserver.rb
@@ -1,21 +1,19 @@
-#
-# Implements a simple HTTP-server by using John W. Small's (jsmall@laser.net)
-# ruby-generic-server.
-#
# Copyright (C) 2001, 2002, 2003 by Michael Neumann (mneumann@ntecs.de)
#
-# $Id: httpserver.rb,v 1.1 2003/07/19 10:05:54 matz Exp $
+# $Id$
#
require "gserver"
+# Implements a simple HTTP-server by using John W. Small's (jsmall@laser.net)
+# ruby-generic-server: GServer.
class HttpServer < GServer
##
- # handle_obj specifies the object, that receives calls to request_handler
- # and ip_auth_handler
- def initialize(handle_obj, port = 8080, host = DEFAULT_HOST, maxConnections = 4,
+ # +handle_obj+ specifies the object, that receives calls from +request_handler+
+ # and +ip_auth_handler+
+ def initialize(handle_obj, port = 8080, host = DEFAULT_HOST, maxConnections = 4,
stdlog = $stdout, audit = true, debug = true)
@handler = handle_obj
super(port, host, maxConnections, stdlog, audit, debug)
@@ -23,19 +21,16 @@ class HttpServer < GServer
private
- # Constants -----------------------------------------------
-
CRLF = "\r\n"
HTTP_PROTO = "HTTP/1.0"
SERVER_NAME = "HttpServer (Ruby #{RUBY_VERSION})"
+ # Default header for the server name
DEFAULT_HEADER = {
"Server" => SERVER_NAME
}
- ##
- # Mapping of status code and error message
- #
+ # Mapping of status codes and error messages
StatusCodeMapping = {
200 => "OK",
400 => "Bad Request",
@@ -45,28 +40,26 @@ private
500 => "Internal Server Error"
}
- # Classes -------------------------------------------------
-
class Request
attr_reader :data, :header, :method, :path, :proto
-
+
def initialize(data, method=nil, path=nil, proto=nil)
@header, @data = Table.new, data
@method, @path, @proto = method, path, proto
end
-
+
def content_length
len = @header['Content-Length']
return nil if len.nil?
- return len.to_i
+ return len.to_i
end
-
+
end
-
+
class Response
attr_reader :header
attr_accessor :body, :status, :status_message
-
+
def initialize(status=200)
@status = status
@status_message = nil
@@ -74,15 +67,12 @@ private
end
end
-
- ##
- # a case-insensitive Hash class for HTTP header
- #
+ # A case-insensitive Hash class for HTTP header
class Table
include Enumerable
def initialize(hash={})
- @hash = hash
+ @hash = hash
update(hash)
end
@@ -103,17 +93,17 @@ private
@hash.each {|k,v| yield k.capitalize, v }
end
+ # Output the Hash table for the HTTP header
def writeTo(port)
each { |k,v| port << "#{k}: #{v}" << CRLF }
end
end # class Table
- # Helper Methods ------------------------------------------
-
- def http_header(header=nil)
+ # Generates a Hash with the HTTP headers
+ def http_header(header=nil) # :doc:
new_header = Table.new(DEFAULT_HEADER)
- new_header.update(header) unless header.nil?
+ new_header.update(header) unless header.nil?
new_header["Connection"] = "close"
new_header["Date"] = http_date(Time.now)
@@ -121,13 +111,16 @@ private
new_header
end
- def http_date( aTime )
+ # Returns a string which represents the time as rfc1123-date of HTTP-date
+ def http_date( aTime ) # :doc:
aTime.gmtime.strftime( "%a, %d %b %Y %H:%M:%S GMT" )
end
- def http_resp(status_code, status_message=nil, header=nil, body=nil)
+ # Returns a string which includes the status code message as,
+ # http headers, and body for the response.
+ def http_resp(status_code, status_message=nil, header=nil, body=nil) # :doc:
status_message ||= StatusCodeMapping[status_code]
-
+
str = ""
str << "#{HTTP_PROTO} #{status_code} #{status_message}" << CRLF
http_header(header).writeTo(str)
@@ -136,10 +129,12 @@ private
str
end
- # Main Serve Loop -----------------------------------------
-
- def serve(io)
- # perform IP authentification
+ # Handles the HTTP request and writes the response back to the client, +io+.
+ #
+ # If an Exception is raised while handling the request, the client will receive
+ # a 500 "Internal Server Error" message.
+ def serve(io) # :doc:
+ # perform IP authentication
unless @handler.ip_auth_handler(io)
io << http_resp(403, "Forbidden")
return
@@ -149,28 +144,28 @@ private
if io.gets =~ /^(\S+)\s+(\S+)\s+(\S+)/
request = Request.new(io, $1, $2, $3)
else
- io << http_resp(400, "Bad Request")
+ io << http_resp(400, "Bad Request")
return
end
-
+
# parse HTTP headers
while (line=io.gets) !~ /^(\n|\r)/
if line =~ /^([\w-]+):\s*(.*)$/
- request.header[$1] = $2.strip
+ request.header[$1] = $2.strip
end
end
- io.binmode
+ io.binmode
response = Response.new
# execute request handler
@handler.request_handler(request, response)
-
+
# write response back to the client
io << http_resp(response.status, response.status_message,
- response.header, response.body)
+ response.header, response.body)
- rescue Exception => e
+ rescue Exception
io << http_resp(500, "Internal Server Error")
end