Class | SOAP::RPC::Router |
In: |
lib/soap/rpc/router.rb
|
Parent: | Object |
actor | [R] | |
external_ces | [RW] | |
generate_explicit_type | [RW] | |
literal_mapping_registry | [RW] | |
mapping_registry | [RW] |
# File lib/soap/rpc/router.rb, line 33 33: def initialize(actor) 34: @actor = actor 35: @mapping_registry = nil 36: @headerhandler = Header::HandlerSet.new 37: @literal_mapping_registry = ::SOAP::Mapping::WSDLLiteralRegistry.new 38: @generate_explicit_type = true 39: @external_ces = nil 40: @operation_by_soapaction = {} 41: @operation_by_qname = {} 42: @headerhandlerfactory = [] 43: end
Alias for add_document_operation
# File lib/soap/rpc/router.rb, line 119 119: def add_document_operation(receiver, soapaction, name, param_def, opt = {}) 120: # 121: # adopt workaround for doc/lit wrapper method 122: # (you should consider to simply use rpc/lit service) 123: # 124: #unless soapaction 125: # raise RPCRoutingError.new("soapaction is a must for document method") 126: #end 127: ensure_styleuse_option(opt, :document, :literal) 128: op = ApplicationScopeOperation.new(soapaction, receiver, name, param_def, 129: opt) 130: if opt[:request_style] != :document 131: raise RPCRoutingError.new("illegal request_style given") 132: end 133: assign_operation(soapaction, first_input_part_qname(param_def), op) 134: end
# File lib/soap/rpc/router.rb, line 137 137: def add_document_request_operation(factory, soapaction, name, param_def, opt = {}) 138: # 139: # adopt workaround for doc/lit wrapper method 140: # (you should consider to simply use rpc/lit service) 141: # 142: #unless soapaction 143: # raise RPCRoutingError.new("soapaction is a must for document method") 144: #end 145: ensure_styleuse_option(opt, :document, :literal) 146: op = RequestScopeOperation.new(soapaction, receiver, name, param_def, opt) 147: if opt[:request_style] != :document 148: raise RPCRoutingError.new("illegal request_style given") 149: end 150: assign_operation(soapaction, first_input_part_qname(param_def), op) 151: end
# File lib/soap/rpc/router.rb, line 55 55: def add_headerhandler(handler) 56: @headerhandler.add(handler) 57: end
header handler interface
# File lib/soap/rpc/router.rb, line 48 48: def add_request_headerhandler(factory) 49: unless factory.respond_to?(:create) 50: raise TypeError.new("factory must respond to 'create'") 51: end 52: @headerhandlerfactory << factory 53: end
operation definition interface
# File lib/soap/rpc/router.rb, line 96 96: def add_rpc_operation(receiver, qname, soapaction, name, param_def, opt = {}) 97: ensure_styleuse_option(opt, :rpc, :encoded) 98: opt[:request_qname] = qname 99: op = ApplicationScopeOperation.new(soapaction, receiver, name, param_def, 100: opt) 101: if opt[:request_style] != :rpc 102: raise RPCRoutingError.new("illegal request_style given") 103: end 104: assign_operation(soapaction, qname, op) 105: end
# File lib/soap/rpc/router.rb, line 109 109: def add_rpc_request_operation(factory, qname, soapaction, name, param_def, opt = {}) 110: ensure_styleuse_option(opt, :rpc, :encoded) 111: opt[:request_qname] = qname 112: op = RequestScopeOperation.new(soapaction, factory, name, param_def, opt) 113: if opt[:request_style] != :rpc 114: raise RPCRoutingError.new("illegal request_style given") 115: end 116: assign_operation(soapaction, qname, op) 117: end
servant definition interface
# File lib/soap/rpc/router.rb, line 62 62: def add_rpc_request_servant(factory, namespace) 63: unless factory.respond_to?(:create) 64: raise TypeError.new("factory must respond to 'create'") 65: end 66: obj = factory.create # a dummy instance for introspection 67: ::SOAP::RPC.defined_methods(obj).each do |name| 68: begin 69: qname = XSD::QName.new(namespace, name) 70: param_def = ::SOAP::RPC::SOAPMethod.derive_rpc_param_def(obj, name) 71: opt = create_styleuse_option(:rpc, :encoded) 72: add_rpc_request_operation(factory, qname, nil, name, param_def, opt) 73: rescue SOAP::RPC::MethodDefinitionError => e 74: p e if $DEBUG 75: end 76: end 77: end
# File lib/soap/rpc/router.rb, line 79 79: def add_rpc_servant(obj, namespace) 80: ::SOAP::RPC.defined_methods(obj).each do |name| 81: begin 82: qname = XSD::QName.new(namespace, name) 83: param_def = ::SOAP::RPC::SOAPMethod.derive_rpc_param_def(obj, name) 84: opt = create_styleuse_option(:rpc, :encoded) 85: add_rpc_operation(obj, qname, nil, name, param_def, opt) 86: rescue SOAP::RPC::MethodDefinitionError => e 87: p e if $DEBUG 88: end 89: end 90: end
Create fault response string.
# File lib/soap/rpc/router.rb, line 183 183: def create_fault_response(e) 184: env = SOAPEnvelope.new(SOAPHeader.new, SOAPBody.new(fault(e))) 185: opt = {} 186: opt[:external_content] = nil 187: response_string = Processor.marshal(env, opt) 188: conn_data = StreamHandler::ConnectionData.new(response_string) 189: conn_data.is_fault = true 190: if ext = opt[:external_content] 191: mimeize(conn_data, ext) 192: end 193: conn_data 194: end
# File lib/soap/rpc/router.rb, line 153 153: def route(conn_data) 154: # we cannot set request_default_encodingsyle before parsing the content. 155: env = unmarshal(conn_data) 156: if env.nil? 157: raise ArgumentError.new("illegal SOAP marshal format") 158: end 159: op = lookup_operation(conn_data.soapaction, env.body) 160: headerhandler = @headerhandler.dup 161: @headerhandlerfactory.each do |f| 162: headerhandler.add(f.create) 163: end 164: receive_headers(headerhandler, env.header) 165: soap_response = default_encodingstyle = nil 166: begin 167: soap_response = 168: op.call(env.body, @mapping_registry, @literal_mapping_registry, 169: create_mapping_opt) 170: default_encodingstyle = op.response_default_encodingstyle 171: rescue Exception 172: soap_response = fault($!) 173: default_encodingstyle = nil 174: end 175: conn_data.is_fault = true if soap_response.is_a?(SOAPFault) 176: header = call_headers(headerhandler) 177: body = SOAPBody.new(soap_response) 178: env = SOAPEnvelope.new(header, body) 179: marshal(conn_data, env, default_encodingstyle) 180: end
# File lib/soap/rpc/router.rb, line 222 222: def assign_operation(soapaction, qname, op) 223: assigned = false 224: if soapaction and !soapaction.empty? 225: @operation_by_soapaction[soapaction] = op 226: assigned = true 227: end 228: if qname 229: @operation_by_qname[qname] = op 230: assigned = true 231: end 232: unless assigned 233: raise RPCRoutingError.new("cannot assign operation") 234: end 235: end
# File lib/soap/rpc/router.rb, line 253 253: def call_headers(headerhandler) 254: headers = headerhandler.on_outbound 255: if headers.empty? 256: nil 257: else 258: h = ::SOAP::SOAPHeader.new 259: headers.each do |header| 260: h.add(header.elename.name, header) 261: end 262: h 263: end 264: end
# File lib/soap/rpc/router.rb, line 330 330: def create_mapping_opt 331: { :external_ces => @external_ces } 332: end
# File lib/soap/rpc/router.rb, line 208 208: def create_styleuse_option(style, use) 209: opt = {} 210: opt[:request_style] = opt[:response_style] = style 211: opt[:request_use] = opt[:response_use] = use 212: opt 213: end
# File lib/soap/rpc/router.rb, line 215 215: def ensure_styleuse_option(opt, style, use) 216: opt[:request_style] ||= style 217: opt[:response_style] ||= style 218: opt[:request_use] ||= use 219: opt[:response_use] ||= use 220: end
Create fault response.
# File lib/soap/rpc/router.rb, line 321 321: def fault(e) 322: detail = Mapping::SOAPException.new(e) 323: SOAPFault.new( 324: SOAPString.new('Server'), 325: SOAPString.new(e.to_s), 326: SOAPString.new(@actor), 327: Mapping.obj2soap(detail, @mapping_registry)) 328: end
# File lib/soap/rpc/router.rb, line 198 198: def first_input_part_qname(param_def) 199: param_def.each do |inout, paramname, typeinfo| 200: if inout == SOAPMethod::IN 201: klass, nsdef, namedef = typeinfo 202: return XSD::QName.new(nsdef, namedef) 203: end 204: end 205: nil 206: end
# File lib/soap/rpc/router.rb, line 237 237: def lookup_operation(soapaction, body) 238: if op = @operation_by_soapaction[soapaction] 239: return op 240: end 241: qname = body.root_node.elename 242: if op = @operation_by_qname[qname] 243: return op 244: end 245: if soapaction 246: raise RPCRoutingError.new( 247: "operation: #{soapaction} #{qname} not supported") 248: else 249: raise RPCRoutingError.new("operation: #{qname} not supported") 250: end 251: end
# File lib/soap/rpc/router.rb, line 295 295: def marshal(conn_data, env, default_encodingstyle = nil) 296: opt = {} 297: opt[:external_content] = nil 298: opt[:default_encodingstyle] = default_encodingstyle 299: opt[:generate_explicit_type] = @generate_explicit_type 300: response_string = Processor.marshal(env, opt) 301: conn_data.send_string = response_string 302: if ext = opt[:external_content] 303: mimeize(conn_data, ext) 304: end 305: conn_data 306: end
# File lib/soap/rpc/router.rb, line 308 308: def mimeize(conn_data, ext) 309: mime = MIMEMessage.new 310: ext.each do |k, v| 311: mime.add_attachment(v.data) 312: end 313: mime.add_part(conn_data.send_string + "\r\n") 314: mime.close 315: conn_data.send_string = mime.content_str 316: conn_data.send_contenttype = mime.headers['content-type'].str 317: conn_data 318: end
# File lib/soap/rpc/router.rb, line 266 266: def receive_headers(headerhandler, headers) 267: headerhandler.on_inbound(headers) if headers 268: end
# File lib/soap/rpc/router.rb, line 270 270: def unmarshal(conn_data) 271: opt = {} 272: contenttype = conn_data.receive_contenttype 273: if /#{MIMEMessage::MultipartContentType}/i =~ contenttype 274: opt[:external_content] = {} 275: mime = MIMEMessage.parse("Content-Type: " + contenttype, 276: conn_data.receive_string) 277: mime.parts.each do |part| 278: value = Attachment.new(part.content) 279: value.contentid = part.contentid 280: obj = SOAPAttachment.new(value) 281: opt[:external_content][value.contentid] = obj if value.contentid 282: end 283: opt[:charset] = 284: StreamHandler.parse_media_type(mime.root.headers['content-type'].str) 285: env = Processor.unmarshal(mime.root.content, opt) 286: else 287: opt[:charset] = ::SOAP::StreamHandler.parse_media_type(contenttype) 288: env = Processor.unmarshal(conn_data.receive_string, opt) 289: end 290: charset = opt[:charset] 291: conn_data.send_contenttype = "text/xml; charset=\"#{charset}\"" 292: env 293: end