PageRenderTime 79ms CodeModel.GetById 60ms app.highlight 16ms RepoModel.GetById 1ms app.codeStats 0ms

/tools/Ruby/lib/ruby/1.8/soap/rpc/cgistub.rb

http://github.com/agross/netopenspace
Ruby | 206 lines | 151 code | 40 blank | 15 comment | 6 complexity | 2a7d6c8ef02db032ac36434f9e2539a3 MD5 | raw file
  1# SOAP4R - CGI/mod_ruby stub library
  2# Copyright (C) 2001, 2003-2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
  3
  4# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
  5# redistribute it and/or modify it under the same terms of Ruby's license;
  6# either the dual license version in 2003, or any later version.
  7
  8
  9require 'soap/streamHandler'
 10require 'webrick/httpresponse'
 11require 'webrick/httpstatus'
 12require 'logger'
 13require 'soap/rpc/soaplet'
 14
 15
 16module SOAP
 17module RPC
 18
 19
 20###
 21# SYNOPSIS
 22#   CGIStub.new
 23#
 24# DESCRIPTION
 25#   To be written...
 26#
 27class CGIStub < Logger::Application
 28  include SOAP
 29  include WEBrick
 30
 31  class SOAPRequest
 32    attr_reader :body
 33
 34    def [](var); end
 35
 36    def meta_vars; end
 37  end
 38
 39  class SOAPStdinRequest < SOAPRequest
 40    attr_reader :body
 41
 42    def initialize(stream)
 43      size = ENV['CONTENT_LENGTH'].to_i || 0
 44      @body = stream.read(size)
 45    end
 46
 47    def [](var)
 48      ENV[var.gsub(/-/, '_').upcase]
 49    end
 50
 51    def meta_vars
 52      {
 53        'HTTP_SOAPACTION' => ENV['HTTP_SOAPAction']
 54      }
 55    end
 56  end
 57
 58  class SOAPFCGIRequest < SOAPRequest
 59    attr_reader :body
 60
 61    def initialize(request)
 62      @request = request
 63      @body = @request.in.read
 64    end
 65
 66    def [](var)
 67      @request.env[var.gsub(/-/, '_').upcase]
 68    end
 69
 70    def meta_vars
 71      {
 72        'HTTP_SOAPACTION' => @request.env['HTTP_SOAPAction']
 73      }
 74    end
 75  end
 76
 77  def initialize(appname, default_namespace)
 78    super(appname)
 79    set_log(STDERR)
 80    self.level = ERROR
 81    @default_namespace = default_namespace
 82    @remote_host = ENV['REMOTE_HOST'] || ENV['REMOTE_ADDR'] || 'unknown'
 83    @router = ::SOAP::RPC::Router.new(self.class.name)
 84    @soaplet = ::SOAP::RPC::SOAPlet.new(@router)
 85    on_init
 86  end
 87  
 88  def on_init
 89    # do extra initialization in a derived class if needed.
 90  end
 91
 92  def mapping_registry
 93    @router.mapping_registry
 94  end
 95
 96  def mapping_registry=(value)
 97    @router.mapping_registry = value
 98  end
 99
100  def generate_explicit_type
101    @router.generate_explicit_type
102  end
103
104  def generate_explicit_type=(generate_explicit_type)
105    @router.generate_explicit_type = generate_explicit_type
106  end
107
108  # servant entry interface
109
110  def add_rpc_servant(obj, namespace = @default_namespace)
111    @router.add_rpc_servant(obj, namespace)
112  end
113  alias add_servant add_rpc_servant
114
115  def add_headerhandler(obj)
116    @router.add_headerhandler(obj)
117  end
118  alias add_rpc_headerhandler add_headerhandler
119
120  # method entry interface
121
122  def add_rpc_method(obj, name, *param)
123    add_rpc_method_with_namespace_as(@default_namespace, obj, name, name, *param)
124  end
125  alias add_method add_rpc_method
126
127  def add_rpc_method_as(obj, name, name_as, *param)
128    add_rpc_method_with_namespace_as(@default_namespace, obj, name, name_as, *param)
129  end
130  alias add_method_as add_rpc_method_as
131
132  def add_rpc_method_with_namespace(namespace, obj, name, *param)
133    add_rpc_method_with_namespace_as(namespace, obj, name, name, *param)
134  end
135  alias add_method_with_namespace add_rpc_method_with_namespace
136
137  def add_rpc_method_with_namespace_as(namespace, obj, name, name_as, *param)
138    qname = XSD::QName.new(namespace, name_as)
139    soapaction = nil
140    param_def = SOAPMethod.derive_rpc_param_def(obj, name, *param)
141    @router.add_rpc_operation(obj, qname, soapaction, name, param_def)
142  end
143  alias add_method_with_namespace_as add_rpc_method_with_namespace_as
144
145  def add_rpc_operation(receiver, qname, soapaction, name, param_def, opt = {})
146    @router.add_rpc_operation(receiver, qname, soapaction, name, param_def, opt)
147  end
148
149  def add_document_operation(receiver, soapaction, name, param_def, opt = {})
150    @router.add_document_operation(receiver, soapaction, name, param_def, opt)
151  end
152
153  def set_fcgi_request(request)
154    @fcgi = request
155  end
156
157private
158
159  HTTPVersion = WEBrick::HTTPVersion.new('1.0')       # dummy; ignored
160
161  def run
162    res = WEBrick::HTTPResponse.new({:HTTPVersion => HTTPVersion})
163    begin
164      @log.info { "received a request from '#{ @remote_host }'" }
165      if @fcgi
166        req = SOAPFCGIRequest.new(@fcgi)
167      else
168        req = SOAPStdinRequest.new($stdin)
169      end
170      @soaplet.do_POST(req, res)
171    rescue HTTPStatus::EOFError, HTTPStatus::RequestTimeout => ex
172      res.set_error(ex)
173    rescue HTTPStatus::Error => ex
174      res.set_error(ex)
175    rescue HTTPStatus::Status => ex
176      res.status = ex.code
177    rescue StandardError, NameError => ex # for Ruby 1.6
178      res.set_error(ex, true)
179    ensure
180      if defined?(MOD_RUBY)
181        r = Apache.request
182        r.status = res.status
183        r.content_type = res.content_type
184        r.send_http_header
185        buf = res.body
186      else
187        buf = ''
188        res.send_response(buf)
189        buf.sub!(/^[^\r]+\r\n/, '')       # Trim status line.
190      end
191      @log.debug { "SOAP CGI Response:\n#{ buf }" }
192      if @fcgi
193        @fcgi.out.print buf
194        @fcgi.finish
195        @fcgi = nil
196      else
197        print buf
198      end
199    end
200    0
201  end
202end
203
204
205end
206end