From: "Hartin, Brian" Date: 2006-11-01T01:56:42+09:00 Subject: Re: How can I populate header values in SOAP document? I was able to get the namespace abbreviations right by returning a hash from on_simple_outbound instead of a string, letting the API handle the conversion to XML. # A handler to add authentication parameters to the SOAP header. class AutheticationHeaderHandler < SOAP::Header::SimpleHandler @@HEADER_NAME = 'WSAuthHeader' def initialize(namespace, username, password) super(XSD::QName.new(namespace, @@HEADER_NAME)) @user_element = XSD::QName.new(namespace, 'User') @password_element = XSD::QName.new(namespace, 'Password') @username, @password = username, password end def on_simple_outbound # Seems to result in the creation of elements with the proper namespace # abbreviation, e.g. 'JohnDoe' {@user_element => @username, @password_element => @password} end end # ... As before ... ws.headerhandler << AutheticationHeaderHandler.new(namespace, user, password) Of course, this could be generalized to handle an arbitrary set of child data, as in your example below. Thanks again! Brian Hartin -----Original Message----- From: Hartin, Brian Sent: Friday, October 27, 2006 4:28 PM To: 'ruby-talk@ruby-lang.org' Cc: Hartin, Brian Subject: RE: How can I populate header values in SOAP document? Thanks Jeremy! This worked pretty well. I still have to hardcode the namespace abbreviation for the attributes, e.g.: xml.puts("ns1:<#{key}>#{value}") #Bad, but OK for now Thanks again, Brian Hartin -----Original Message----- From: Jeremy Hinegardner [mailto:jeremy@hinegardner.org] Sent: Thursday, October 26, 2006 10:04 PM To: ruby-talk ML Subject: Re: How can I populate header values in SOAP document? I'm not sure if it can be done dynamically, but you can create a ClientSimpleHeader which hooks into the inbound and outbound stream. I've only hooked into the outbound and it looked something like the code below. The code is untested and extrapolated from my case to yours, so take the general idea and see where it gets you. And if you didn't know, driver.wiredump_dev is your friend. Good Luck. enjoy, -jeremy ----- customer_header.rb ----- require 'soap/header/simplehandler' require 'stringio' class CustomSimpleHeader < SOAP::Header::SimpleHandler # encapsulate outbound only headers, this is set once and never # touched again. # def initialize(itemname,namespace,childdata) super(XSD::QName.new(namespace,name)) case childdate # other classes if you want # Or do something with XML::Mappging when Hash xml = StringIO.new childdata.each_pair do |key,value| xml.puts("<#{key}>#{value}") end @item = xml.string else @item = childdata.to_s end end def on_simple_outbound @item if @item end def on_simple_inbound end end ---- possible soaptest.rb ----- require 'customer_header' # assuming this works with a dynamic proxy ws = SOAP::WSDLDriverFactor.new("http://foo.com/foo.wsdl").create_rpc_driver ws.wiredump_dev = STDERR ws.generate_explicit_type = true user = "my user" password = "my password" ws.headerhandler << CustomSimpleHeader.new("WSAuthHeader", { "User" => user, "Password" => password }) ----- -- ======================================================================== Jeremy Hinegardner jeremy@hinegardner.org On Fri, Oct 27, 2006 at 04:52:54AM +0900, Hartin, Brian wrote: > Hi all, > > Got a question about the Ruby SOAP library. I've generated a proxy > using the SOAP::WSDLDriverFactory as follows: > > ws = > SOAP::WSDLDriverFactory.new('http://foo.com/foo.wsdl').create_rpc_driver > > I can see that this generates methods for each defined operation, and I > use them thusly: > > ws.WSGetResults(:maxRecords => 1, ...) > > The method and parameters are translated to the appropriate XML in the > SOAP message body. However, some operations require a 'User' and > 'Password' to be in the message _header_. I've looked through the > documentation and mailing lists with no luck. How can one achieve this? > > My code is listed below. > > Thanks! > > Brian Hartin > > ---- soaptest.rb ---- > require 'soap/wsdlDriver' > require 'date' > > ws = > SOAP::WSDLDriverFactory.new('http://foo.com/foo.wsdl').create_rpc_driver > ws.generate_explicit_type = true > r = ws.WSHeartbeat({}) # Works because it doesn't require authentication > r = g.WSGetXmlResults(:recordId => 123, :recordLimit => 200) # Doesn't > work > > ---- Example SOAP request, according to vendor ---- > > xmlns:xsd="http://www.w3.org/2001/XMLSchema" > xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> > > > > string > string > > > > > int > int > > > > ************************************************************************ **** > This email may contain confidential material. > If you were not an intended recipient, > Please notify the sender and delete all copies. > We may monitor email to and from our network. > ************************************************************************ **** > **************************************************************************** This email may contain confidential material. If you were not an intended recipient, Please notify the sender and delete all copies. We may monitor email to and from our network. ****************************************************************************