On Jul 18, 2006, at 11:35 PM, Timothy J.Wood wrote:
>
> I''m working on a rails app where I''d like to have a
session-based
> SOAP API. That is, I''d like to connect via SSL and have a
''login''
> method followed by one or more other methods.
>
> I''m using the ActionWebService::Client::Soap class to connect to
> my app, but each method invocation results in a new session on the
> server (WEBrick, at the moment). I''ve tracked down an example at
> <http://www.zimbra.com/forums/showthread.php?t=428> of how I might
> add a session id cookie header via some direct access to the SOAP
> driver. But, @driver isn''t exposed in
> ActionWebService::Client::Soap, so I can''t get at it.
>
> Is there a simpler way to do this? I could use the Ruby SOAP API
> directly, but then I''d not get the advantage of using the API
> object to do the method creation on the driver.
To answer my own question and to make sure it gets into google for
others... :)
I now use vanilla Ruby SOAP instead of the AWS wrapper and create
using the WSDL driver (which parses the .wsdl file automatically
vended by the app):
BASE_URL = "http://0.0.0.0:3000/xxx"
soap = SOAP::WSDLDriverFactory.new("#{BASE_URL}/
service.wsdl").create_rpc_driver
Then, I can do a login. My login method returns the session id
which I record in a global for the moment:
SESSION_ID = soap.Login("some user name", "some password")
To get the _session_id cookie passed back to the app, I do:
client = soap.proxy.streamhandler.client
OLD_METHOD = client.method(:post)
class << client
def post(url, req_body, header = {})
if header
header = header.dup
else
header = {}
end
header["Cookie"] = "_session_id=#{SESSION_ID}"
OLD_METHOD.call(url, req_body, header)
end
end
I can then call the rest of the methods in my API using the same
session identifier. This is kind of gross, but it seems to work so
far. It would be nicer if I could get at the cookies returned from
the last SOAP message (so the login call wouldn''t need to return the
session id and could just return true/false). Also, it would be
nicer if I could figure out a way to write the instance-specific
override of :post so that I didn''t use globals (maybe with a block).
-tim