Неверный запрос от вызова Soap к UPNP TV

Я играл с отправкой команд на мой телевизор с поддержкой Upnp. Я написал некоторый код C # для запроса устройств UPNP в сети, а затем отправлял команды на телевизор через мыло. Однако, когда я делаю запросы к телевизору, я получаю 400 неверных запросов. Я смотрел в Fiddler, и это, кажется, запрос RAW.

POST http://192.168.1.4:52323/upnp/control/RenderingControl HTTP/1.1 SOAPACTION: urn:schemas-upnp-org:service:RenderingControl:1#SetVolume Content-Type: text/xml;charset="utf-8" Accept: text/xml Host:
192.168.1.4:52323 Content-Length: 418 Expect: 100-continue Connection: Keep-Alive

<?xml version="1.0" encoding="utf-8"?> <s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">   <s:Body>
    <ns0:SetVolume xmlns:ns0="urn:schemas-upnp-org:service:RenderingControl:1">
      <InstanceId>0</InstanceId>
      <Channel>Master</Channel>
      <DesiredVolume>70</DesiredVolume>
    </ns0:SetVolume>   </s:Body> </s:Envelope>

Кто-нибудь видит что-то плохое в этом запросе?

Вот как я создаю WebRequest на С#:

HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
webRequest.Headers.Add("SOAPACTION", action);
webRequest.ContentType = "text/xml;charset=\"utf-8\"";
webRequest.Accept = "text/xml";
webRequest.Method = "POST";
return webRequest;

ОБНОВЛЕНО

Я пытался вообще удалить код и просто сформировать запрос через fiddler. В данный момент телевизор не подключен к моей сети, поэтому я пытаюсь проверить вызовы на свой маршрутизатор. Это мой недавно построенный вызов через скрипача:

POST http://10.0.0.1:49153/upnp/control/Layer3Forwarding HTTP/1.1
SOAPACTION: urn:schemas-upnp-org:service:Layer3Forwarding:1#GetDefaultConnectionService
Content-Type: text/xml;charset="utf-8"
Host: 10.0.0.1:49153
Content-Length: 345

<?xml version="1.0" encoding="utf-8"?>
<s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Body>
    <ns0:GetDefaultConnectionService xmlns:ns0="urn:schemas-upnp-org:service:Layer3Forwarding:1">
    </ns0:GetDefaultConnectionService>
  </s:Body>
</s:Envelope>

Однако я продолжаю получать либо недопустимые действия, либо неправильный xml, например, этот ответ ниже:

HTTP/1.1 500 Internal Server Error
CONTENT-LENGTH: 413
CONTENT-TYPE: text/xml; charset="utf-8"
DATE: Tue, 14 Mar 2017 21:55:49 GMT
EXT: 
SERVER: Linux/3.12.14, UPnP/1.0, Portable SDK for UPnP devices/1.6.18
X-User-Agent: redsonic

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<s:Body>
<s:Fault>
<faultcode>s:Client</faultcode>
<faultstring>UPnPError</faultstring>
<detail>
<UPnPError xmlns="urn:schemas-upnp-org:control-1-0">
<errorCode>-111</errorCode>
<errorDescription>Invalid Action</errorDescription>
</UPnPError>
</detail>
</s:Fault>
</s:Body>
</s:Envelope>

Любые идеи о том, как мой запрос может потерпеть неудачу?


person user1496741    schedule 12.03.2017    source источник
comment
как насчет замены control/Layer3Forwarding на Layer3Forwarding/control в строке POST? Вот как это выглядит на моем устройстве.   -  person Stefan Hegny    schedule 15.03.2017
comment
Спасибо за совет, я думаю, моя проблема заключалась в том, что мой SOAPACTION не был в кавычках. Кажется, сейчас я получаю ответы в скрипаче. Device Spy очень помог в отслеживании разницы между моим запросом и запросом в правильном формате.   -  person user1496741    schedule 15.03.2017


Ответы (1)


В спецификации архитектуры UPnP указано, что формат вызова действия

POST path of control URL HTTP/1.1
HOST: host of control URL:port of control URL
CONTENT-LENGTH: bytes in body
CONTENT-TYPE: text/xml; charset="utf-8"
SOAPACTION: "urn:schemas-upnp-org:service:serviceType:v#actionName"

<?xml version="1.0"?>
< s:Envelope
  xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"
  s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
  <s:Body>
    <u:actionName xmlns:u="urn:schemas-upnp-org:service:serviceType:v">
      <argumentName>in arg value</argumentName>
       other in args and their values go here, if any
    </u:actionName>
  </s:Body>
</s:Envelope>

Ваш код отличается от этого несколькими способами:

  • Нет новых строк (\r\n) между заголовками HTTP (если это не ошибка форматирования в вашем вопросе)
  • Путь в заголовке POST не должен содержать схему, хост или порт. то есть удалить http://192.168.1.4:52323

Вы также можете рассмотреть возможность удаления использования заголовка Expect. Кажется, нет никакой пользы в его добавлении (вы не должны ожидать появления каких-либо серверов/прокси в локальной сети, которые поддерживают этот заголовок, но не могут справиться с накладными расходами в несколько сотен байтов тела запроса). И наоборот, вполне возможно, что вы столкнетесь с примитивными HTTP-серверами, которые не знают, как обрабатывать этот заголовок, поэтому отклоните запрос.

person simonc    schedule 13.03.2017
comment
Спасибо за информацию! Я думаю, что между заголовками есть новые строки, и это была просто проблема форматирования из-за копирования его из скрипача. Я отредактировал исходный пост, чтобы показать, как я создаю webRequest на C#. Я могу попробовать удалить ожидаемый заголовок и исправить значение POST. - person user1496741; 13.03.2017