Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HTTPClient::KeepAliveDisconnected on ONVIF unsubscribe request #969

Open
migalenkom opened this issue Apr 26, 2022 · 2 comments
Open

HTTPClient::KeepAliveDisconnected on ONVIF unsubscribe request #969

migalenkom opened this issue Apr 26, 2022 · 2 comments

Comments

@migalenkom
Copy link

Bug report

I am generating SOAP requests to IP cameras to use ONVIF API. When generating a request through Savon it doesn't work.
However, when generating via the official tool request passes OK.

Current behavior:
Here is the request generated through Savon and I am getting HTTPClient::KeepAliveDisconnected

[2022-04-26 21:29:16 +0000] SOAP request: http://192.168.0.89/onvif/Subscription?Idx=77
[2022-04-26 21:29:16 +0000] Content-Type: application/soap+xml; charset=utf-8, SOAPAction: "http://docs.oasis-open.org/wsn/bw-2/PausableSubscriptionManager/UnsubscribeRequest", Content-Length: 1709
[2022-04-26 21:29:16 +0000] <?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:wsdl="http://www.onvif.org/ver10/events/wsdl" xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope">
  <SOAP-ENV:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
    <wsa:Action>http://docs.oasis-open.org/wsn/bw-2/PausableSubscriptionManager/UnsubscribeRequest</wsa:Action>
    <wsa:To>http://192.168.0.89/onvif/Subscription?Idx=77</wsa:To>
    <wsa:MessageID xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing">urn:uuid:b4742513-fd62-44b5-a9d9-3db005e1a330</wsa:MessageID>
    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
      <wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="UsernameToken-1">
        <wsse:Username>admin</wsse:Username>
        <wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">M2M0NGJhMGI1Y2ZjMWYxYTRjMTkyYTg1NmFjNzg4ZDliOGIzNjkyOA==</wsse:Nonce>
        <wsu:Created>2022-04-26T21:29:16Z</wsu:Created>
        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">h+WeEanGY2sFUhBbhcd5Oi1ZHhw=</wsse:Password>
      </wsse:UsernameToken>
      <wsu:Timestamp xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="Timestamp-2">
        <wsu:Created>2022-04-26T21:29:16Z</wsu:Created>
        <wsu:Expires>2022-04-26T21:30:16Z</wsu:Expires>
      </wsu:Timestamp>
    </wsse:Security>
  </SOAP-ENV:Header>
  <SOAP-ENV:Body>
    <wsdl:Unsubscribe/>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

[2022-04-26 21:29:16 +0000] HTTPI /none POST request to 192.168.0.89 (httpclient)
/data/deployer/onvif/vendor/bundle/ruby/3.1.0/gems/httpclient-2.8.3/lib/httpclient/session.rb:808:in `block in parse_header': HTTPClient::KeepAliveDisconnected:  (HTTPClient::KeepAliveDisconnected)
/data/deployer/onvif/vendor/bundle/ruby/3.1.0/gems/httpclient-2.8.3/lib/httpclient/session.rb:808:in `block in parse_header': HTTPClient::KeepAliveDisconnected:  `(HTTPClient::KeepAliveDisconnected)

Request generated via the official tool:


POST /onvif/Subscription?Idx=87 HTTP/1.1
Host: 192.168.0.89
Content-Type: application/soap+xml; charset=utf-8
Authorization: Digest username="admin",realm="Login to 2L05ABCPAA00246",qop="auth",algorithm=MD5,uri="/onvif/Subscription?Idx=87",nonce="b252aWYtZGlnZXN0OjQyOTc3MDM4Njcw",nc=00000001,cnonce="AA1E66694E8FDFD77C29FC359DAA0C15",opaque="",response="9a6aa57108955142ddb522698d20c274"
Content-Length: 713

<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
  <s:Header>
    <a:Action s:mustUnderstand="1">http://docs.oasis-open.org/wsn/bw-2/SubscriptionManager/UnsubscribeRequest</a:Action>
    <a:MessageID>urn:uuid:bf921174-c408-48f7-97c8-f5f64ee3462e</a:MessageID>
    <a:ReplyTo>
      <a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
    </a:ReplyTo>
    <a:To s:mustUnderstand="1">http://192.168.0.89/onvif/Subscription?Idx=87</a:To>
  </s:Header>
  <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <Unsubscribe xmlns="http://docs.oasis-open.org/wsn/b-2" />
  </s:Body>
</s:Envelope>

Steps to reproduce current behavior:

require 'savon'

@ip.           = 'ip'
@user        = 'user'
@pass.      = 'pass'
@wsdl        = 'http://www.onvif.org/ver10/events/wsdl/event.wsdl'
@endpoint = 'http://192.168.0.89/onvif/event_service'
      
@soap_client = Savon.client do |c|
  c.wsdl wsdl
  c.endpoint @endpoint
  c.wsse_auth(user, pass, :digest)
  c.use_wsa_headers true
  c.wsse_timestamp true
  c.convert_request_keys_to :none
  c.env_namespace 'SOAP-ENV'
  c.open_timeout 60
  c.read_timeout 60
  c.soap_version 2
  c.headers 'Content-Type' => 'application/soap+xml; charset=utf-8'
  c.pretty_print_xml true
end
@soap_client.call(:create_pull_point_subscription)
...
@soap_client.call(:unsubscribe)

Expected behavior:

Generated request passes OK

System information:

  • ruby version: 3.1
  • savon version: 2.12.1
@olleolleolle
Copy link
Contributor

To me, by just looking at the thing, the top one seems to use the wsse type of authentication, which is a Web Service description of authentication. The lower one seems to have a Digest header only.

Could it be that the service authenticates requests in some other way than the wsse thing?

@migalenkom
Copy link
Author

@olleolleolle Hi thanks for the suggestion.
I tried different types of auth but ONVIF cameras support both wsse and digest so it should not be auth issue.
The next thing that I tried is changing namespaces and that made a request to work.
HTTPClient::KeepAliveDisconnected doesn't look like a correct error in this case.

The Official tool adds xmlns="http://docs.oasis-open.org/wsn/b-2" straight to the Unsubscribe tag.

<Unsubscribe xmlns="http://docs.oasis-open.org/wsn/b-2" />

Savon builds requests in a different way and adds a namespace wsdl:Unsubscribe with namespace declaration with wrong namespace xmlns:wsdl="http://www.onvif.org/ver10/events/wsdl"

 <wsdl:Unsubscribe/>

I did not manage to add xmlns="http://docs.oasis-open.org/wsn/b-2" or remove wsdl namespace from Unsubscribe tag but managed to override it namespaces: { 'xmlns:wsdl' => "http://docs.oasis-open.org/wsn/b-2" }

Is there a way I can build the same request with savon as the official tools offer?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants