summaryrefslogtreecommitdiffstats
path: root/lib/puppet/network/http
diff options
context:
space:
mode:
authorChristian Hofstaedtler <hofstaedtler@inqnet.at>2009-04-28 12:29:20 +0000
committerJames Turnbull <james@lovedthanlost.net>2009-05-02 09:13:29 +1000
commitd6be4e1206e9285dee9fc4d8cde9608c029d4001 (patch)
tree8027f46a38089b893faa8d9e342cacec65333dfb /lib/puppet/network/http
parent6e01e7ab403d090f29f13c938ca5b19930c4b408 (diff)
downloadpuppet-d6be4e1206e9285dee9fc4d8cde9608c029d4001.tar.gz
puppet-d6be4e1206e9285dee9fc4d8cde9608c029d4001.tar.xz
puppet-d6be4e1206e9285dee9fc4d8cde9608c029d4001.zip
Add XMLRPC compatibility for Rack
Diffstat (limited to 'lib/puppet/network/http')
-rw-r--r--lib/puppet/network/http/rack.rb19
-rw-r--r--lib/puppet/network/http/rack/xmlrpc.rb65
2 files changed, 83 insertions, 1 deletions
diff --git a/lib/puppet/network/http/rack.rb b/lib/puppet/network/http/rack.rb
index 58f49416b..aa81b45f7 100644
--- a/lib/puppet/network/http/rack.rb
+++ b/lib/puppet/network/http/rack.rb
@@ -2,6 +2,7 @@
require 'rack'
require 'puppet/network/http'
require 'puppet/network/http/rack/rest'
+require 'puppet/network/http/rack/xmlrpc'
# An rack application, for running the Puppet HTTP Server.
class Puppet::Network::HTTP::Rack
@@ -14,6 +15,14 @@ class Puppet::Network::HTTP::Rack
@rest_http_handler = Puppet::Network::HTTP::RackREST.new()
protocols.delete :rest
+ # Prepare the XMLRPC handler, for backward compatibility (if requested)
+ if args[:protocols].include?(:xmlrpc)
+ raise ArgumentError, "XMLRPC was requested, but no handlers were given" if !args.include?(:xmlrpc_handlers)
+
+ @xmlrpc_http_handler = Puppet::Network::HTTP::RackXMLRPC.new(args[:xmlrpc_handlers])
+ protocols.delete :xmlrpc
+ end
+
raise ArgumentError, "there were unknown :protocols specified." if !protocols.empty?
end
@@ -27,8 +36,16 @@ class Puppet::Network::HTTP::Rack
response = Rack::Response.new()
Puppet.debug 'Handling request: %s %s' % [request.request_method, request.fullpath]
+ # if we shall serve XMLRPC, have /RPC2 go to the xmlrpc handler
+ if @xmlrpc_http_handler and request.path_info.start_with?('/RPC2')
+ handler = @xmlrpc_http_handler
+ else
+ # everything else is handled by the new REST handler
+ handler = @rest_http_handler
+ end
+
begin
- @rest_http_handler.process(request, response)
+ handler.process(request, response)
rescue => detail
# Send a Status 500 Error on unhandled exceptions.
response.status = 500
diff --git a/lib/puppet/network/http/rack/xmlrpc.rb b/lib/puppet/network/http/rack/xmlrpc.rb
new file mode 100644
index 000000000..ef686cd4f
--- /dev/null
+++ b/lib/puppet/network/http/rack/xmlrpc.rb
@@ -0,0 +1,65 @@
+require 'puppet/network/http/rack/httphandler'
+require 'puppet/network/xmlrpc/server'
+require 'resolv'
+
+class Puppet::Network::HTTP::RackXMLRPC < Puppet::Network::HTTP::RackHttpHandler
+ def initialize(handlers)
+ @xmlrpc_server = Puppet::Network::XMLRPCServer.new
+ handlers.each do |name|
+ Puppet.debug " -> register xmlrpc namespace %s" % name
+ unless handler = Puppet::Network::Handler.handler(name)
+ raise ArgumentError, "Invalid XMLRPC handler %s" % name
+ end
+ @xmlrpc_server.add_handler(handler.interface, handler.new({}))
+ end
+ super()
+ end
+
+ def process(request, response)
+ # errors are sent as text/plain
+ response['Content-Type'] = 'text/plain'
+ if not request.post? then
+ response.status = 405
+ response.write 'Method Not Allowed'
+ return
+ end
+ if request.media_type() != "text/xml" then
+ response.status = 400
+ response.write 'Bad Request'
+ return
+ end
+
+ # get auth/certificate data
+ client_request = build_client_request(request)
+
+ response_body = @xmlrpc_server.process(request.body, client_request)
+
+ response.status = 200
+ response['Content-Type'] = 'text/xml; charset=utf-8'
+ response.write response_body
+ end
+
+ def build_client_request(request)
+ ip = request.ip
+
+ # if we find SSL info in the headers, use them to get a hostname.
+ # try this with :ssl_client_header, which defaults should work for
+ # Apache with StdEnvVars.
+ if dn = request.env[Puppet[:ssl_client_header]] and dn_matchdata = dn.match(/^.*?CN\s*=\s*(.*)/)
+ node = dn_matchdata[1].to_str
+ authenticated = (request.env[Puppet[:ssl_client_verify_header]] == 'SUCCESS')
+ else
+ begin
+ node = Resolv.getname(ip)
+ rescue => detail
+ Puppet.err "Could not resolve %s: %s" % [ip, detail]
+ node = "unknown"
+ end
+ authenticated = false
+ end
+
+ Puppet::Network::ClientRequest.new(node, ip, authenticated)
+ end
+
+end
+