/*---------------------------------------------------------------------- | PLT_DeviceData::SetDescription +---------------------------------------------------------------------*/ NPT_Result PLT_DeviceData::SetDescription(PLT_DeviceDataReference& root_device, NPT_TimeInterval leasetime, NPT_HttpUrl description_url, const char* description, const NPT_HttpRequestContext& context) { NPT_XmlParser parser; NPT_XmlNode* tree = NULL; NPT_Result res; NPT_XmlElementNode* root = NULL; NPT_String URLBase; // create new device if none passed if (root_device.IsNull()) { root_device = new PLT_DeviceData(description_url, "", leasetime); } res = parser.Parse(description, tree); NPT_CHECK_LABEL_SEVERE(res, cleanup); root = tree->AsElementNode(); if (!root || root->GetTag() != "root" || !root->GetNamespace() || *root->GetNamespace() != "urn:schemas-upnp-org:device-1-0") { NPT_LOG_INFO_1("root namespace is invalid: %s", (root&&root->GetNamespace())?root->GetNamespace()->GetChars():"null"); NPT_CHECK_LABEL_SEVERE(NPT_FAILURE, cleanup); } // look for optional URLBase element if (NPT_SUCCEEDED(PLT_XmlHelper::GetChildText(root, "URLBase", URLBase))) { NPT_HttpUrl url(URLBase); // Some devices like Connect360 try to be funny - not so if (url.GetHost().ToLowercase() == "localhost" || url.GetHost().ToLowercase() == "127.0.0.1") { url.SetHost(context.GetRemoteAddress().GetIpAddress().ToString()); } root_device->SetURLBase(url); } else { // No URLBase, derive from description url root_device->SetURLBase(description_url); } // at least one root device child element is required NPT_XmlElementNode* device; if (!(device = PLT_XmlHelper::GetChild(root, "device"))) { NPT_CHECK_LABEL_SEVERE(NPT_FAILURE, cleanup); } res = SetDescriptionDevice(root_device, device, context); cleanup: // delete the tree delete tree; return res; }
/*---------------------------------------------------------------------- | TestFinders +---------------------------------------------------------------------*/ static void TestFinders() { const char* xml = "<a b='foo' c='bar' ns:b='bla' ns:d='123' xmlns:ns='ns-uri' xmlns:ns1='ns1-uri' xmlns:ns2='ns2-uri' xmlns:ns3='ns3-uri'><b xmlns='ns4-uri' ba='123' ns2:bo='345'></b><b ba='123' ns2:bo='345'></b><ns2:b></ns2:b><ns1:b></ns1:b></a>"; NPT_XmlParser parser; NPT_XmlNode* root; CHECK(NPT_SUCCEEDED(parser.Parse(xml, root))); NPT_XmlElementNode* elem = root->AsElementNode(); const NPT_String* attr = elem->GetAttribute("d"); CHECK(attr == NULL); attr = elem->GetAttribute("b"); CHECK(attr != NULL && *attr == "foo"); attr = elem->GetAttribute("b", "ns-uri"); CHECK(attr != NULL && *attr == "bla"); attr = elem->GetAttribute("c", NPT_XML_ANY_NAMESPACE); CHECK(attr != NULL && *attr == "bar"); attr = elem->GetAttribute("b", NPT_XML_ANY_NAMESPACE); CHECK(attr != NULL && *attr == "foo"); attr = elem->GetAttribute("b", "boubou"); CHECK(attr == NULL); attr = elem->GetAttribute("d", NPT_XML_NO_NAMESPACE); CHECK(attr == NULL); NPT_XmlElementNode* child; child = elem->GetChild("b"); CHECK(child != NULL && *child->GetAttribute("ba") == "123"); child = elem->GetChild("b", "ns4-uri"); CHECK(child != NULL && child->GetAttribute("ba", "ns4-uri") == NULL); CHECK(child != NULL && *child->GetAttribute("bo", NPT_XML_ANY_NAMESPACE) == "345"); CHECK(child != NULL && child->GetAttribute("bo", NPT_XML_NO_NAMESPACE) == NULL); CHECK(child != NULL && child->GetAttribute("bo", "foo") == NULL); CHECK(child != NULL && *child->GetAttribute("bo", "ns2-uri") == "345"); child = elem->GetChild("b", NPT_XML_ANY_NAMESPACE); CHECK(child != NULL && *child->GetNamespace() == "ns4-uri"); child = elem->GetChild("b", "ns2-uri"); CHECK(child != NULL && *child->GetNamespace() == "ns2-uri"); child = elem->GetChild("b", "boubou"); CHECK(child == NULL); delete root; }
/*---------------------------------------------------------------------- | PLT_DeviceData::SetDescription +---------------------------------------------------------------------*/ NPT_Result PLT_DeviceData::SetDescription(const char* description, const NPT_IpAddress& local_iface_ip) { NPT_XmlParser parser; NPT_XmlNode* tree = NULL; NPT_Result res; res = parser.Parse(description, tree); if (NPT_FAILED(res)) { delete tree; return res; } NPT_XmlElementNode* root = tree->AsElementNode(); if (!root || root->GetTag() != "root" || !root->GetNamespace() || *root->GetNamespace() != "urn:schemas-upnp-org:device-1-0") { delete tree; return NPT_FAILURE; } // look for optional URLBase element NPT_String URLBase; if (NPT_SUCCEEDED(PLT_XmlHelper::GetChildText(root, "URLBase", URLBase))) { NPT_HttpUrl url(URLBase); if (!url.IsValid()) return NPT_FAILURE; SetURLBase(url); } // at least one root device child element is required NPT_XmlElementNode* device; if (!(device = PLT_XmlHelper::GetChild(root, "device"))) { delete tree; return NPT_FAILURE; } res = SetDescriptionDevice(device); // delete the tree delete tree; m_LocalIfaceIp = local_iface_ip; return res; }