Hi Tomas,

I did some additional debugging with a protocol analyzer (WireShark) and
writing to log files and am closer to understanding what is happening here.
As mentioned, by LuaCGI script is soap-service.lua, and the last lines say:

.
.
.
server.register_service_info("matricula2URL", path, script, nil, disco)
soap.server.export(matricula2URL_descr)
server.handle_request(cgilua.POST[1],cgilua.servervariable("QUERY_STRING"))


This works OK in the main dispatcher in soap.server.lua when called with
HTTP GET requests (for WSDL and DISCO):

---------------------------------------------------------------------
-- Handles the request received by the calling script.
-- @param postdata String with POST data from the server.
-- @param querystring String with the query string.
---------------------------------------------------------------------
function handle_request(postdata, querystring)
local namespace, func, arg_table
local header
if postdata then
namespace, func, arg_table = decodedata(postdata)
header = xml_header
else
if querystring == "wsdl" then -- WSDL service
func = function ()
return __service.wsdl or generate_wsdl()
end
elseif querystring == "disco" then -- discovery service
func = function ()
return __service.disco or generate_disco()
end
else
func = __methods["listMethods"]
header = xml_header
end
arg_table = {}
end

local ok, result = callfunc(func, namespace, arg_table)
respond(result, header)
end

However, it fails for POSTs. Note that the code above doesn't protect
against a combination of nil for both postdata and querystring, and I think
this is what's happening. It's crashing and burning because callfunc is
called with nil POST table data.

Now this is surprising because with WireShark, I do see POST requests being
received after the call to your client test routine (test-http.lua) and the
POST has plausible SOAP XML request packets in it. Yet when I look at my log
file of POST table data presented to handle_request, there is nothing. So
the code snippet you sent me:

server.handle_request(cgilua.POST[1],cgilua.servervariable("QUERY_STRING"))

is somehow incomplete or being called the wrong way for POST requests. The
input parameter 'cgilua.POST[1]' does not have valid table data to pass
along to handle_request.

--WHW



On Wed, Dec 23, 2009 at 9:11 PM, walter wilkinson <
[email protected]> wrote:

> Hello Tomas,
>
> I think it is all quite close to working now. When I access this URL with
> my Web browser,
>
>    http://localhost:8080/soap-service.lua?wsdl
>
> I get returned a beautiful page of WSDL code for my one existing service
> routine. Very encouraging! This means that the branch of
> handle_request(postdata, querystring) dealing with GET commands is in good
> shape.
>
> To test the POST branch I am trying to use the client test in
> test-http.lua, which works fine in its original state, where it accesses a
> site on the Internet dealing with SOAP tutorials. I have modified the client
> call to POST to my SOAP server:
>
>
> local soap_client = require"soap.client"
>
> ---------------------------------------------------------------------
> -- Call a remote method.
> -- @param args Table with the arguments which could be:
> -- url: String with the location of the server.
> -- soapaction: String with the value of the SOAPAction header.
> -- namespace: String with the namespace of the elements.
> -- method: String with the method's name.
> -- entries: Table of SOAP elements (LuaExpat's format).
> -- header: Table describing the header of the SOAP-ENV (optional).
> -- internal_namespace: String with the optional namespace used
> --  as a prefix for the method name (default = "").
> -- @return String with namespace, String with method's name and
> --    Table with SOAP elements (LuaExpat's format).
>
> local ns, meth, ent = soap_client.call {
>   url = "http://localhost:8080";,
>   soapaction = "/matricula2URL",
>   namespace = nil,
>   method = "matricula",
>   entries = {
>     {
>       tag = "occurrence",
>       { tag = "occurrence", attr = { "xsi:type", ["xsi:type"] =
> "xsd:string", }, "1"},
>     },
>   }}
>
> But honestly I was just guessing at correct values for some of these. The
> previous example data I got from you was:
>
>
> ----------------------------------------------------------------------
> -- Service Routine:
>
> function matricula2URL(namespace, args)
>
>        assert(args[1].tag == "matricula", "invalid tag")
>        local matricula = args[1][1]
>        assert(type(matricula) == "string", "invalid argument `matricula'
> (expected 'string', got '"..type(matricula).."')")
>
>        return {
>                {
>                        tag = "URL",
>                        'somestring',
>                },
>        }
> end
>
> ----------------------------------------------------------------------
> -- Service Descriptor:
>
> local matricula2URL_descr = {
>    name = "matricula2URL",
>    method = matricula2URL,
>    message = { name = "matricula2URL",
>                { name = "matricula", occurrence = 1, type = "string", },
>    },
>    response = { name = "matricula2URLResponse",
>                { name = "URL", occurrence = 1, type = "string", },
>    },
> }
>
> local disco = string.format([=[<?xml version="1.0" encoding="iso-8859-1" ?>
> <xdiscovery
>
>    xmlns:xsd="http://www.w3.org/2001/XMLSchema";
>    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
>    xmlns="http://schemas.xmlsoap.org/disco/";>
> <contractRef
>    ref="%s?wsdl"
>    docRef="%s"
>    xmlns="http://schemas.xmlsoap.org/disco/scl/"; />
> <soap
>    address="%s"
>    xmlns:q1="Matricula2URLSoapBind"
>    binding="q1:Matricula2URLSoapBind"
>    xmlns="http://schemas.xmlsoap.org/disco/soap/"; />
> </xdiscovery>]=], script, script, script)
>
> My code in soap-service.lua:
>
>
> server.register_service_info("matricula2URL", path, script, nil, disco)
> soap.server.export(matricula2URL_descr)
> server.handle_request(cgilua.POST[1],cgilua.servervariable("QUERY_STRING"))
>
> When running the client test I get an error in client.lua:
>
> .
> .
> .
> local err, code, headers, status = request(url)
>     local body = concat(tbody)
>     assert(tonumber(code) == 200, tostring(err or
> code).."\n\n"..tostring(body))
>
>     local ok, error_or_ns, method, result = pcall(soap.decode, body)
>     assert(ok, tostring(error_or_ns).."\n\n"..tostring(body))
>
>     return error_or_ns, method, result
>
> The unfired assertion for code == 200 indicates it's doing OK up until
> then. But there is an error in soap.decode:
>
> wa...@ubuntu:/usr/local/share/lua/5.1/soap$ sudo lua test-http.lua
> lua: /usr/local/share/lua/5.1/soap/client.lua:60: ./soap.lua:183: undefined
> entity
>
> <html><head><title>CGILua
> Error</title></head><body>.../.luarocks/rocks//cgilua/5.1.3-1/lua/cgilua/post.lua:289:
> wrong number of arguments to 'insert'<br>
> stack traceback:<br>
> &nbsp;&nbsp;[C]: in function 'tinsert'<br>
> &nbsp;&nbsp;.../.luarocks/rocks//cgilua/5.1.3-1/lua/cgilua/post.lua:289: in
> function 'parsedata'<br>
> &nbsp;&nbsp;...waldo/.luarocks/rocks//cgilua/5.1.3-1/lua/cgilua.lua:405: in
> function <...waldo/.luarocks/rocks//cgilua/5.1.3-1/lua/cgilua.lua:400><br>
> stack traceback:<br>
> &nbsp;&nbsp;...waldo/.luarocks/rocks//cgilua/5.1.3-1/lua/cgilua.lua:161: in
> function 'err'<br>
> &nbsp;&nbsp;/usr/local/rocks//coxpcall/cvs-2/lua/coxpcall.lua:24: in
> function </usr/local/rocks//coxpcall/cvs-2/lua/coxpcall.lua:22><br>
> &nbsp;&nbsp;(tail call): ?<br>
> &nbsp;&nbsp;(tail call): ?<br>
> &nbsp;&nbsp;(tail call): ?<br>
> &nbsp;&nbsp;(tail call): ?<br>
> &nbsp;&nbsp;...waldo/.luarocks/rocks//cgilua/5.1.3-1/lua/cgilua.lua:169: in
> function 'pcall'<br>
> &nbsp;&nbsp;...waldo/.luarocks/rocks//cgilua/5.1.3-1/lua/cgilua.lua:613: in
> function 'main'<br>
> &nbsp;&nbsp;...aldo/.luarocks/rocks//wsapi/1.1-2/lua/wsapi/sapi.lua:49: in
> function <...aldo/.luarocks/rocks//wsapi/1.1-2/lua/wsapi/sapi.lua:7><br>
> &nbsp;&nbsp;(tail call): ?</body></html>
> stack traceback:
>     [C]: in function 'assert'
>     /usr/local/share/lua/5.1/soap/client.lua:60: in function 'call'
>     test-http.lua:6: in main chunk
>     [C]: ?
>
> Does anything jump out at you (in the rhetorical sense) here?
>
> Thanks,
> --WHW
>
>
>
> On Wed, Dec 23, 2009 at 6:58 AM, Tomas Guisasola Gorham <
> [email protected]> wrote:
>
>>        Hi Walter
>>
>>
>>  Considering your sample server-side object descriptor:
>>>
>>> local matricula2URL_descr = {
>>>  name = "matricula2URL",
>>>  method = matricula2URL,
>>>  message = { name = "matricula2URL",
>>>              { name = "matricula", occurrence = 1, type = "string", },
>>>  },
>>>  response = { name = "matricula2URLResponse",
>>>              { name = "URL", occurrence = 1, type = "string", },
>>>  },
>>> }
>>>
>>> What server side function does this actually invoke? Something like:
>>>
>>> function (occurrence)
>>>  return 'somestring'
>>> end
>>>
>>        No, the function might be something like this:
>>
>> function matricula2URL(namespace, args)
>>        ...
>>        assert(args[1].tag == "matricula", "invalid tag")
>>        local matricula = args[1][1]
>>        assert(type(matricula) == "string", "invalid argument `matricula'
>> (expected 'string', got '"..type(matricula).."')")
>>        ...
>>        return {
>>                {
>>                        tag = "URL",
>>
>>                        'somestring',
>>                },
>>        }
>> end
>>
>>  Can this object description syntax be understood in terms of inputs and
>>> outputs?
>>>
>>        Sorry, I didn't understand what you mean.
>>
>>
>>  Also: when I try to call:
>>>
>>> soap.server.export(matricula2URL_descr)
>>>
>>> I get the error:
>>>
>>> /usr/local/share/lua/5.1//soap/server.lua:148: attempt to concatenate
>>> field
>>> 'soap_action' (a nil value)
>>> stack traceback:
>>>  /usr/local/share/lua/5.1//soap/server.lua:148: in function
>>> 'wsdl_gen_binding'
>>>  /usr/local/share/lua/5.1//soap/server.lua:273: in function 'export'
>>>  soap_service.lua:26: in main chunk
>>>
>>>
>>> 'export' calls  'wsdl_gen_binding' , which tries to reference
>>> __service.soap_action, which hasn't been set to anything. And it won't
>>> be,
>>> unless
>>> register_service_info is called beforehand--there is no other way for it
>>> to
>>> be set. In other words, it looks as though a prerequisite to doing
>>> the 'export' is setting up the WSDL registration before hand; so WSDL
>>> support isn't just an enhancement to be used if desired, it is a
>>> necessary
>>> precursor to 'export' anything (or it looks that way).
>>>
>>        I think it is a bug, sorry.  As I said, most of this code to
>> generate WSDL is a hack and is not well tested.  Anyway, I can try to
>> help you let it work...
>>
>>        Regards,
>>                Tomás
>> _______________________________________________
>> Kepler-Project mailing list
>> [email protected]
>> http://lists.luaforge.net/cgi-bin/mailman/listinfo/kepler-project
>> http://www.keplerproject.org/
>>
>
>
_______________________________________________
Kepler-Project mailing list
[email protected]
http://lists.luaforge.net/cgi-bin/mailman/listinfo/kepler-project
http://www.keplerproject.org/

Reply via email to