Page 1 of 1
Posting a SOAP request
Posted: Sun Jan 31, 2021 9:46 pm
by mrupp
Hi everybody
I'm trying to figure out how to post a SOAP request with Hollywood. I figured I should do this using the
hURL plugin. My overall goal is to write Sonos controller app for the Amiga, but let's take one step at a time, shall we?
This is want I'd like to achieve:
Method: POST
URL:
http://192.168.1.227:1400/MediaRenderer ... rt/Control
Headers:
Content-Type = text/xml
SOAPACTION = urn:schemas-upnp-org:service:AVTransport:1#Play
XML-Data:
Code: Select all
<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<s:Body>
<u:Play xmlns:u="urn:schemas-upnp-org:service:AVTransport:1">
<InstanceID>0</InstanceID>
<Speed>1</Speed>
</u:Play>
</s:Body>
</s:Envelope>
I testet this request with Postman (
https://www.postman.com/), where it works just as expected.
And this is what I tried with Hollywood:
Code: Select all
Function Play()
Local body$ = "<?xml version=\"1.0\" encoding=\"utf-8\"?><s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body><u:Play xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID><Speed>1</Speed></u:Play></s:Body></s:Envelope>"
form = hurl.Form();
form:addcontent("BODY", body$, "text/xml")
e = hurl.Easy()
e:setopt_url("http://192.168.1.227:1400/MediaRenderer/AVTransport/Control")
e:setopt_httpheader({ "SOAPACTION" = "urn:schemas-upnp-org:service:AVTransport:1#Play"});
e:setopt_httppost(form);
e:perform()
form:free();
EndFunction
Hopefully, somebody more experienced than me now just laughs and can point me to what I did wrong.

I'm new to Hollywood programming, so I'm not sure at all, if I did the right approach using
hurl.Easy() and
hurl.Form(), there might me another, better way to do this...
This piece of code does run without errors but doesn't show any effect on my Sonos device at 192.168.1.227.
I'm grateful for any advice anyone can give me.
Greetings,
Michael
Re: Posting a SOAP request
Posted: Mon Feb 01, 2021 4:31 pm
by mrupp
I might be a step further now... maybe... but have run into trouble again.
I figured I have to send raw data and not form data. Sending form data doesn't work with Postman either, the data is marked as raw there. The only method I found in the hURL doc to do so is
easy:Send(), therefore I tried this:
Code: Select all
Function Play()
Local body$ = "<?xml version=\"1.0\" encoding=\"utf-8\"?><s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body><u:Play xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID><Speed>1</Speed></u:Play></s:Body></s:Envelope>"
Local e = hurl.Easy()
e:setopt_url("http://192.168.1.227:1400/MediaRenderer/AVTransport/Control")
e:setopt_verbose(True)
e:setopt_post(1)
e:setopt_httpheader({ "SOAPACTION" = "urn:schemas-upnp-org:service:AVTransport:1#Play"});
e:send(body$)
e:close()
EndFunction
Unfortunately, when running this code, there's an error on "e:send(body$)" --> Unsupported protocol! (1)
Any ideas how to fix this?
Re: Posting a SOAP request
Posted: Mon Feb 01, 2021 10:37 pm
by p-OS
Maybe you could try sth. like this:
Code: Select all
url=http://192.168.1.227:1400/MediaRenderer/AVTransport/Control
mimetype="text/xml"
request=[[
<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<s:Body>
<u:Play xmlns:u="urn:schemas-upnp-org:service:AVTransport:1">
<InstanceID>0</InstanceID>
<Speed>1</Speed>
</u:Play>
</s:Body>
</s:Envelope>
]]
response=DownloadFile(url,{Post=request,PostType=mimetype})
Re: Posting a SOAP request
Posted: Tue Feb 02, 2021 7:57 pm
by mrupp
Thanks p-OS, that's a really good idea.
I tried excactly as you wrote (except to enclose the url in double quotes), but the code wouldn't run, the error output is:
Wrong usage/parameters for this command!
Read the documentation!
Hmm... I read the documentation for this command and can't see anything wrong with it.
Re: Posting a SOAP request
Posted: Tue Feb 02, 2021 9:29 pm
by airsoftsoftwair
mrupp wrote: ↑Tue Feb 02, 2021 7:57 pm
Hmm... I read the documentation for this command and can't see anything wrong with it.
Sorry, it's another Hollywood bug. It has been reported here already:
viewtopic.php?p=12409#p12409 
Re: Posting a SOAP request
Posted: Tue Feb 02, 2021 9:48 pm
by airsoftsoftwair
Coming back to your original problem, I know nothing about SOAP requests but if all you want to do is send a certain string using HTTP POST and add a custom header, it should be possible like this with hURL:
Code: Select all
Function p_Dump(v)
DebugPrint(v)
EndFunction
Function Play()
Local postdata$ = "<?xml version=\"1.0\" encoding=\"utf-8\"?><s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body><u:Play xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID><Speed>1</Speed></u:Play></s:Body></s:Envelope>"
Local e = hurl.Easy()
e:setopt_url("http://192.168.1.227:1400/MediaRenderer/AVTransport/Control")
e:setopt_verbose(True)
e:setopt_post(1)
e:setopt_postfields(postdata$)
e:setopt_httpheader({"SOAPAction: urn:schemas-upnp-org:service:AVTransport:1#Play"});
e:setopt_writefunction(p_Dump)
e:perform()
e:close()
EndFunction
You should definitely use
easy:Perform() instead of
easy:Send(). Also, I think you used
easy:SetOpt_HTTPHeader() in the wrong way. It needs a list of strings, so something like:
Code: Select all
easy:SetOpt_HTTPHeader({"Custom-Header1: Test", "Custom-Header2: Test"})
I've also added a call to
easy:SetOpt_WriteFunction() so that you can see the data you get back from the server.
Re: Posting a SOAP request
Posted: Tue Feb 02, 2021 10:26 pm
by mrupp
YES, IT WORKS!
Your code works just like that. By all the things I tried, in the end it was mostly the wrong formatting of the header.
THANKS!
One step closer to the Sonos conroller app for Amiga systems!
Maybe this or something similar would be a good example to add to the hURL docs, don't you think?
Also it would be nice to add an example for setopt_httpheader() in the docs, that would be very helpful.
Re: Posting a SOAP request
Posted: Sun Feb 07, 2021 11:28 am
by mrupp
Just in case somebody looks for this is in the future, here's my final solution to post a SOAP request and getting back the result. Thanks to everybody helping me with this:
Code: Select all
Function p_SoapRequest(host$, path$, soapBody$, soapAction$, timeout)
Local request$ = [[
<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<s:Body>]] .. soapBody$ .. [[</s:Body>
</s:Envelope>
]]
Local e = hurl.Easy()
Local result$ = ""
If Not IsNil(timeout)
e:setopt_timeout(timeout)
EndIf
e:setopt_url(host$ .. path$)
;e:setopt_verbose(True)
e:setopt_post(1)
e:setopt_postfields(request$)
e:setopt_httpheader({"CONTENT-TYPE: text/xml", "SOAPACTION: " .. soapAction$});
e:setopt_writefunction(Function(output$) result$ = result$ .. output$ EndFunction)
e:perform()
e:close()
;DebugPrint("result: " .. result$)
Return(result$)
EndFunction
Usage, following the example of the original thread:
Code: Select all
Function p_Play()
Local host$ = "http://192.168.1.227:1400"
Local soapPath$ = "/MediaRenderer/AVTransport/Control"
Local soapBody$ = [[
<u:Play xmlns:u="urn:schemas-upnp-org:service:AVTransport:1">
<InstanceID>0</InstanceID>
<Speed>1</Speed>
</u:Play>
]]
Local soapAction$ = "urn:schemas-upnp-org:service:AVTransport:1#Play"
Local result$ = p_SoapRequest(host$, soapPath$, soapBody$, soapAction$)
Return(result$)
EndFunction
Cheers,
Michael