ruby-changes:35105
From: hsbt <ko1@a...>
Date: Fri, 15 Aug 2014 10:21:23 +0900 (JST)
Subject: [ruby-changes:35105] hsbt:r47187 (trunk): * lib/gserver.rb: removed unmaintained code.
hsbt 2014-08-15 10:21:18 +0900 (Fri, 15 Aug 2014) New Revision: 47187 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=47187 Log: * lib/gserver.rb: removed unmaintained code. [ruby-core:40313][Feature #5480] * lib/xmlrpc/httpserver.rb: ditto. Removed files: trunk/lib/gserver.rb trunk/lib/xmlrpc/httpserver.rb Modified files: trunk/ChangeLog trunk/NEWS Index: ChangeLog =================================================================== --- ChangeLog (revision 47186) +++ ChangeLog (revision 47187) @@ -1,3 +1,9 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Fri Aug 15 10:13:37 2014 SHIBATA Hiroshi <shibata.hiroshi@g...> + + * lib/gserver.rb: removed unmaintained code. + [ruby-core:40313][Feature #5480] + * lib/xmlrpc/httpserver.rb: ditto. + Fri Aug 15 09:22:12 2014 Eric Wong <e@8...> * vm_core.h (rb_thread_struct): reorder to pack Index: lib/gserver.rb =================================================================== --- lib/gserver.rb (revision 47186) +++ lib/gserver.rb (revision 47187) @@ -1,310 +0,0 @@ https://github.com/ruby/ruby/blob/trunk/lib/gserver.rb#L0 -# -# Copyright (C) 2001 John W. Small All Rights Reserved -# -# Author:: John W. Small -# Documentation:: Gavin Sinclair -# Licence:: Ruby License - -require "socket" -require "thread" - -# -# GServer implements a generic server, featuring thread pool management, -# simple logging, and multi-server management. See HttpServer in -# <tt>xmlrpc/httpserver.rb</tt> in the Ruby standard library for an example of -# GServer in action. -# -# Any kind of application-level server can be implemented using this class. -# It accepts multiple simultaneous connections from clients, up to an optional -# maximum number. Several _services_ (i.e. one service per TCP port) can be -# run simultaneously, and stopped at any time through the class method -# <tt>GServer.stop(port)</tt>. All the threading issues are handled, saving -# you the effort. All events are optionally logged, but you can provide your -# own event handlers if you wish. -# -# == Example -# -# Using GServer is simple. Below we implement a simple time server, run it, -# query it, and shut it down. Try this code in +irb+: -# -# require 'gserver' -# -# # -# # A server that returns the time in seconds since 1970. -# # -# class TimeServer < GServer -# def initialize(port=10001, *args) -# super(port, *args) -# end -# def serve(io) -# io.puts(Time.now.to_i) -# end -# end -# -# # Run the server with logging enabled (it's a separate thread). -# server = TimeServer.new -# server.audit = true # Turn logging on. -# server.start -# -# # *** Now point your browser to http://localhost:10001 to see it working *** -# -# # See if it's still running. -# GServer.in_service?(10001) # -> true -# server.stopped? # -> false -# -# # Shut the server down gracefully. -# server.shutdown -# -# # Alternatively, stop it immediately. -# GServer.stop(10001) -# # or, of course, "server.stop". -# -# All the business of accepting connections and exception handling is taken -# care of. All we have to do is implement the method that actually serves the -# client. -# -# === Advanced -# -# As the example above shows, the way to use GServer is to subclass it to -# create a specific server, overriding the +serve+ method. You can override -# other methods as well if you wish, perhaps to collect statistics, or emit -# more detailed logging. -# -# * #connecting -# * #disconnecting -# * #starting -# * #stopping -# -# The above methods are only called if auditing is enabled, via #audit=. -# -# You can also override #log and #error if, for example, you wish to use a -# more sophisticated logging system. -# -class GServer - - DEFAULT_HOST = "127.0.0.1" - - def serve(io) - end - - @@services = {} # Hash of opened ports, i.e. services - @@servicesMutex = Mutex.new - - # Stop the server running on the given port, bound to the given host - # - # +port+:: port, as a Fixnum, of the server to stop - # +host+:: host on which to find the server to stop - def GServer.stop(port, host = DEFAULT_HOST) - @@servicesMutex.synchronize { - @@services[host][port].stop - } - end - - # Check if a server is running on the given port and host - # - # +port+:: port, as a Fixnum, of the server to check - # +host+:: host on which to find the server to check - # - # Returns true if a server is running on that port and host. - def GServer.in_service?(port, host = DEFAULT_HOST) - @@services.has_key?(host) and - @@services[host].has_key?(port) - end - - # Stop the server - def stop - @connectionsMutex.synchronize { - if @tcpServerThread - @tcpServerThread.raise "stop" - end - } - end - - # Returns true if the server has stopped. - def stopped? - @tcpServerThread == nil - end - - # Schedule a shutdown for the server - def shutdown - @shutdown = true - end - - # Return the current number of connected clients - def connections - @connections.size - end - - # Join with the server thread - def join - @tcpServerThread.join if @tcpServerThread - end - - # Port on which to listen, as a Fixnum - attr_reader :port - # Host on which to bind, as a String - attr_reader :host - # Maximum number of connections to accept at a time, as a Fixnum - attr_reader :maxConnections - # IO Device on which log messages should be written - attr_accessor :stdlog - # Set to true to cause the callbacks #connecting, #disconnecting, #starting, - # and #stopping to be called during the server's lifecycle - attr_accessor :audit - # Set to true to show more detailed logging - attr_accessor :debug - - # Called when a client connects, if auditing is enabled. - # - # +client+:: a TCPSocket instance representing the client that connected - # - # Return true to allow this client to connect, false to prevent it. - def connecting(client) - addr = client.peeraddr - log("#{self.class} #{@host}:#{@port} client:#{addr[1]} " + - "#{addr[2]}<#{addr[3]}> connect") - true - end - - - # Called when a client disconnects, if audition is enabled. - # - # +clientPort+:: the port of the client that is connecting - def disconnecting(clientPort) - log("#{self.class} #{@host}:#{@port} " + - "client:#{clientPort} disconnect") - end - - protected :connecting, :disconnecting - - # Called when the server is starting up, if auditing is enabled. - def starting() - log("#{self.class} #{@host}:#{@port} start") - end - - # Called when the server is shutting down, if auditing is enabled. - def stopping() - log("#{self.class} #{@host}:#{@port} stop") - end - - protected :starting, :stopping - - # Called if #debug is true whenever an unhandled exception is raised. - # This implementation simply logs the backtrace. - # - # +detail+:: the Exception that was caught - def error(detail) - log(detail.backtrace.join("\n")) - end - - # Log a message to #stdlog, if it's defined. This implementation - # outputs the timestamp and message to the log. - # - # +msg+:: the message to log - def log(msg) - if @stdlog - @stdlog.puts("[#{Time.new.ctime}] %s" % msg) - @stdlog.flush - end - end - - protected :error, :log - - # Create a new server - # - # +port+:: the port, as a Fixnum, on which to listen - # +host+:: the host to bind to - # +maxConnections+:: the maximum number of simultaneous connections to - # accept - # +stdlog+:: IO device on which to log messages - # +audit+:: if true, lifecycle callbacks will be called. See #audit - # +debug+:: if true, error messages are logged. See #debug - def initialize(port, host = DEFAULT_HOST, maxConnections = 4, - stdlog = $stderr, audit = false, debug = false) - @tcpServerThread = nil - @port = port - @host = host - @maxConnections = maxConnections - @connections = [] - @connectionsMutex = Mutex.new - @connectionsCV = ConditionVariable.new - @stdlog = stdlog - @audit = audit - @debug = debug - end - - # Start the server if it isn't already running - # - # +maxConnections+:: - # override +maxConnections+ given to the constructor. A negative - # value indicates that the value from the constructor should be used. - def start(maxConnections = -1) - raise "server is already running" if !stopped? - @shutdown = false - @maxConnections = maxConnections if maxConnections > 0 - @@servicesMutex.synchronize { - if GServer.in_service?(@port,@host) - raise "Port already in use: #{host}:#{@port}!" - end - @tcpServer = TCPServer.new(@host,@port) - @port = @tcpServer.addr[1] - @@services[@host] = {} unless @@services.has_key?(@host) - @@services[@host][@port] = self; - } - @tcpServerThread = Thread.new { - begin - starting if @audit - while !@shutdown - @connectionsMutex.synchronize { - while @connections.size >= @maxConnections - @connectionsCV.wait(@connectionsMutex) - end - } - client = @tcpServer.accept - Thread.new(client) { |myClient| - @connections << Thread.current - begin - myPort = myClient.peeraddr[1] - serve(myClient) if !@audit or connecting(myClient) - rescue => detail - error(detail) if @debug - ensure - begin - myClient.close - rescue - end - @connectionsMutex.synchronize { - @connections.delete(Thread.current) - @connectionsCV.signal - } - disconnecting(myPort) if @audit - end - } - end - rescue => detail - error(detail) if @debug - ensure - begin - @tcpServer.close - rescue - end - if @shutdown - @connectionsMutex.synchronize { - while @connections.size > 0 - @connectionsCV.wait(@connectionsMutex) - end - } - else - @connections.each { |c| c.raise "stop" } - end - @tcpServerThread = nil - @@servicesMutex.synchronize { - @@services[@host].delete(@port) - } - stopping if @audit - end - } - self - end - -end Index: lib/xmlrpc/httpserver.rb =================================================================== --- lib/xmlrpc/httpserver.rb (revision 47186) +++ lib/xmlrpc/httpserver.rb (revision 47187) @@ -1,173 +0,0 @@ https://github.com/ruby/ruby/blob/trunk/lib/xmlrpc/httpserver.rb#L0 -# Copyright (C) 2001, 2002, 2003 by Michael Neumann (mneumann@n...) -# -# $Id$ -# - - -require "gserver" - -# Implements a simple HTTP-server by using John W. Small's (jsmall@l...) -# ruby-generic-server: GServer. -class HttpServer < GServer - - ## - # +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) - end - -private - - 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 codes and error messages - StatusCodeMapping = { - 200 => "OK", - 400 => "Bad Request", - 403 => "Forbidden", - 405 => "Method Not Allowed", - 411 => "Length Required", - 500 => "Internal Server Error" - } - - 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 - end - - end - - class Response - attr_reader :header - attr_accessor :body, :status, :status_message - - def initialize(status=200) - @status = status - @status_message = nil - @header = Table.new - end - end - - # A case-insensitive Hash class for HTTP header - class Table - include Enumerable - - def initialize(hash={}) - @hash = hash - update(hash) - end - - def [](key) - @hash[key.to_s.capitalize] - end - - def []=(key, value) - @hash[key.to_s.capitalize] = value - end - - def update(hash) - hash.each {|k,v| self[k] = v} - self - end - - def each - @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 - - - # 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["Connection"] = "close" - new_header["Date"] = http_date(Time.now) - - new_header - end - - # 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 - - # 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) - str << CRLF - str << body unless body.nil? - str - end - - # 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 - end - - # parse first line - if io.gets =~ /^(\S+)\s+(\S+)\s+(\S+)/ - request = Request.new(io, $1, $2, $3) - else - 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 - end - end - - 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) - - rescue Exception - io << http_resp(500, "Internal Server Error") - end - -end # class HttpServer - Index: NEWS =================================================================== --- NEWS (revision 47186) +++ NEWS (revision 47187) @@ -144,6 +144,9 @@ with all sufficient information, see the https://github.com/ruby/ruby/blob/trunk/NEWS#L144 * lib/uri * support RFC 3986. [Feature #2542] +* GServer + * GServer is extracted to gserver gem. It's unmaintain code. + * Logger * Logger::Application is extracted to logger-application gem. It's unmaintain code. -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/