QDomNodeList QDomDocumentProto::elementsByTagNameNS(const QString& nsURI, const QString& localName) { QDomDocument *item = qscriptvalue_cast<QDomDocument*>(thisObject()); if (item) return item->elementsByTagNameNS(nsURI, localName); return QDomNodeList(); }
void OwnCloudService::loadDirectory(QString &data) { QDomDocument doc; doc.setContent(data, true); if (data.isEmpty()) { showOwnCloudServerErrorMessage("", false); } QStringList pathList; QDomNodeList responseNodes = doc.elementsByTagNameNS(NS_DAV, "response"); for (int i = 0; i < responseNodes.count(); i++) { QDomNode responseNode = responseNodes.at(i); if (responseNode.isElement()) { QDomElement elem = responseNode.toElement(); bool isFolder = false; QDomNodeList resourceTypeNodes = elem.elementsByTagNameNS(NS_DAV, "resourcetype"); if (resourceTypeNodes.length()) { QDomNodeList typeNodes = resourceTypeNodes.at(0).childNodes(); for (int j = 0; j < typeNodes.length(); ++j) { QDomNode typeNode = typeNodes.at(j); QString typeString = typeNode.toElement().tagName(); if (typeString == "collection") { isFolder = true; break; } } } if (!isFolder) { continue; } // check if we have an url QDomNodeList urlPartNodes = elem.elementsByTagNameNS(NS_DAV, "href"); if (urlPartNodes.length()) { QString urlPart = urlPartNodes.at(0).toElement().text(); QRegularExpression re( QRegularExpression::escape(webdavPath) + "\\/(.+)\\/$"); QRegularExpressionMatch match = re.match(urlPart); QString folderString = match.hasMatch() ? match.captured(1) : ""; if (!folderString.isEmpty()) { pathList << QUrl::fromPercentEncoding( folderString.toUtf8()); } } } } settingsDialog->setNoteFolderRemotePathList(pathList); }
void Config::editResponse(QDomDocument &rpc, size_t) { const QDomNodeList &errors(rpc.elementsByTagNameNS(netconfUri, "rpc-error")); if (errors.size()) { const QString &text(errors.at(0).namedItem("error-message").toElement().text()); QMessageBox::warning(this, "RPC error", text); } // Get the new version of config. It may have changed. downloadButton->click(); }
QStringList OwnCloudService::parseCalendarHrefList(QString &data) { QStringList resultList; QDomDocument doc; doc.setContent(data, true); // loop all response blocks QDomNodeList responseNodes = doc.elementsByTagNameNS(NS_DAV, "response"); for (int i = 0; i < responseNodes.length(); ++i) { QDomNode responseNode = responseNodes.at(i); if (responseNode.isElement()) { QDomElement elem = responseNode.toElement(); QDomNodeList resourceTypeNodes = elem.elementsByTagNameNS(NS_DAV, "resourcetype"); if (resourceTypeNodes.length()) { QDomNodeList typeNodes = resourceTypeNodes.at(0).childNodes(); for (int j = 0; j < typeNodes.length(); ++j) { QDomNode typeNode = typeNodes.at(j); QString typeString = typeNode.toElement().tagName(); // did we find a calendar? // ideally we should check the // "supported-calendar-component-set" for "VTODO" if (typeString == "calendar") { // add the href to our result list QDomNodeList hrefNodes = elem.elementsByTagNameNS( NS_DAV, "href"); if (hrefNodes.length()) { const QString href = hrefNodes.at( 0).toElement().text(); resultList << href; } QDomNodeList displayNameNodes = elem.elementsByTagNameNS(NS_DAV, "displayname"); if (displayNameNodes.length()) { // TODO(pbek): we want to use this display name in // the future! const QString displayName = displayNameNodes.at( 0).toElement().text(); qDebug() << __func__ << " - 'displayName': " << displayName; } } } } } } return resultList; }
int QgsWFSProvider::readAttributesFromSchema( QDomDocument& schemaDoc, QString& geometryAttribute, QgsFields& fields, QGis::WkbType& geomType ) { //get the <schema> root element QDomNodeList schemaNodeList = schemaDoc.elementsByTagNameNS( QgsWFSConstants::XMLSCHEMA_NAMESPACE, "schema" ); if ( schemaNodeList.length() < 1 ) { return 1; } QDomElement schemaElement = schemaNodeList.at( 0 ).toElement(); mApplicationNamespace = schemaElement.attribute( "targetNamespace" ); QDomElement complexTypeElement; //the <complexType> element corresponding to the feature type //find out, on which lines the first <element> or the first <complexType> occur. If <element> occurs first (mapserver), read the type of the relevant <complexType> tag. If <complexType> occurs first (geoserver), search for information about the feature type directly under this first complexType element int firstElementTagPos = schemaElement.elementsByTagNameNS( QgsWFSConstants::XMLSCHEMA_NAMESPACE, "element" ).at( 0 ).toElement().columnNumber(); int firstComplexTypeTagPos = schemaElement.elementsByTagNameNS( QgsWFSConstants::XMLSCHEMA_NAMESPACE, "complexType" ).at( 0 ).toElement().columnNumber(); if ( firstComplexTypeTagPos < firstElementTagPos ) { //geoserver complexTypeElement = schemaElement.elementsByTagNameNS( QgsWFSConstants::XMLSCHEMA_NAMESPACE, "complexType" ).at( 0 ).toElement(); } else { //UMN mapserver QString complexTypeType; QDomNodeList typeElementNodeList = schemaElement.elementsByTagNameNS( QgsWFSConstants::XMLSCHEMA_NAMESPACE, "element" ); QDomElement typeElement = typeElementNodeList.at( 0 ).toElement(); complexTypeType = typeElement.attribute( "type" ); if ( complexTypeType.isEmpty() ) { return 3; } //remove the namespace on complexTypeType if ( complexTypeType.contains( ':' ) ) { complexTypeType = complexTypeType.section( ':', 1, 1 ); } //find <complexType name=complexTypeType QDomNodeList complexTypeNodeList = schemaElement.elementsByTagNameNS( QgsWFSConstants::XMLSCHEMA_NAMESPACE, "complexType" ); for ( int i = 0; i < complexTypeNodeList.size(); ++i ) { if ( complexTypeNodeList.at( i ).toElement().attribute( "name" ) == complexTypeType ) { complexTypeElement = complexTypeNodeList.at( i ).toElement(); break; } } } if ( complexTypeElement.isNull() ) { return 4; } //we have the relevant <complexType> element. Now find out the geometry and the thematic attributes QDomNodeList attributeNodeList = complexTypeElement.elementsByTagNameNS( QgsWFSConstants::XMLSCHEMA_NAMESPACE, "element" ); if ( attributeNodeList.size() < 1 ) { return 5; } bool foundGeometryAttribute = false; for ( int i = 0; i < attributeNodeList.size(); ++i ) { QDomElement attributeElement = attributeNodeList.at( i ).toElement(); //attribute name QString name = attributeElement.attribute( "name" ); //attribute type QString type = attributeElement.attribute( "type" ); //is it a geometry attribute? //MH 090428: sometimes the <element> tags for geometry attributes have only attribute ref="gml:polygonProperty" and no name QRegExp gmlPT( "gml:(.*)PropertyType" ); // the GeometryAssociationType has been seen in #11785 if ( type.indexOf( gmlPT ) == 0 || type == "gml:GeometryAssociationType" || name.isEmpty() ) { foundGeometryAttribute = true; geometryAttribute = name; geomType = geomTypeFromPropertyType( geometryAttribute, gmlPT.cap( 1 ) ); } else //todo: distinguish between numerical and non-numerical types { QVariant::Type attributeType = QVariant::String; //string is default type if ( type.contains( "double", Qt::CaseInsensitive ) || type.contains( "float", Qt::CaseInsensitive ) || type.contains( "decimal", Qt::CaseInsensitive ) ) { attributeType = QVariant::Double; } else if ( type.contains( "int", Qt::CaseInsensitive ) ) { attributeType = QVariant::Int; } else if ( type.contains( "long", Qt::CaseInsensitive ) ) { attributeType = QVariant::LongLong; } fields.append( QgsField( name, attributeType, type ) ); } } if ( !foundGeometryAttribute ) { geomType = QGis::WKBNoGeometry; } return 0; }
void QgsWFSCapabilities::capabilitiesReplyFinished() { QNetworkReply *reply = mCapabilitiesReply; reply->deleteLater(); mCapabilitiesReply = 0; // handle network errors if ( reply->error() != QNetworkReply::NoError ) { mErrorCode = QgsWFSCapabilities::NetworkError; mErrorMessage = reply->errorString(); emit gotCapabilities(); return; } // handle HTTP redirects QVariant redirect = reply->attribute( QNetworkRequest::RedirectionTargetAttribute ); if ( !redirect.isNull() ) { QgsDebugMsg( "redirecting to " + redirect.toUrl().toString() ); QNetworkRequest request( redirect.toUrl() ); setAuthorization( request ); request.setAttribute( QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferNetwork ); request.setAttribute( QNetworkRequest::CacheSaveControlAttribute, true ); mCapabilitiesReply = QgsNetworkAccessManager::instance()->get( request ); connect( mCapabilitiesReply, SIGNAL( finished() ), this, SLOT( capabilitiesReplyFinished() ) ); return; } QByteArray buffer = reply->readAll(); QgsDebugMsg( "parsing capabilities: " + buffer ); // parse XML QString capabilitiesDocError; QDomDocument capabilitiesDocument; if ( !capabilitiesDocument.setContent( buffer, true, &capabilitiesDocError ) ) { mErrorCode = QgsWFSCapabilities::XmlError; mErrorMessage = capabilitiesDocError; emit gotCapabilities(); return; } QDomElement doc = capabilitiesDocument.documentElement(); // hangle exceptions if ( doc.tagName() == "ExceptionReport" ) { QDomNode ex = doc.firstChild(); QString exc = ex.toElement().attribute( "exceptionCode", "Exception" ); QDomElement ext = ex.firstChild().toElement(); mErrorCode = QgsWFSCapabilities::ServerExceptionError; mErrorMessage = exc + ": " + ext.firstChild().nodeValue(); emit gotCapabilities(); return; } mCaps.clear(); //test wfs version QString version = capabilitiesDocument.documentElement().attribute( "version" ); if ( version != "1.0.0" && version != "1.0" ) { mErrorCode = WFSVersionNotSupported; mErrorMessage = tr( "Either the WFS server does not support WFS version 1.0.0 or the WFS url is wrong" ); emit gotCapabilities(); return; } // get the <FeatureType> elements QDomNodeList featureTypeList = capabilitiesDocument.elementsByTagNameNS( WFS_NAMESPACE, "FeatureType" ); for ( unsigned int i = 0; i < featureTypeList.length(); ++i ) { FeatureType featureType; QDomElement featureTypeElem = featureTypeList.at( i ).toElement(); //Name QDomNodeList nameList = featureTypeElem.elementsByTagNameNS( WFS_NAMESPACE, "Name" ); if ( nameList.length() > 0 ) { featureType.name = nameList.at( 0 ).toElement().text(); } //Title QDomNodeList titleList = featureTypeElem.elementsByTagNameNS( WFS_NAMESPACE, "Title" ); if ( titleList.length() > 0 ) { featureType.title = titleList.at( 0 ).toElement().text(); } //Abstract QDomNodeList abstractList = featureTypeElem.elementsByTagNameNS( WFS_NAMESPACE, "Abstract" ); if ( abstractList.length() > 0 ) { featureType.abstract = abstractList.at( 0 ).toElement().text(); } //DefaultSRS is always the first entry in the feature srs list QDomNodeList defaultCRSList = featureTypeElem.elementsByTagNameNS( WFS_NAMESPACE, "DefaultSRS" ); if ( defaultCRSList.length() > 0 ) { featureType.crslist.append( defaultCRSList.at( 0 ).toElement().text() ); } //OtherSRS QDomNodeList otherCRSList = featureTypeElem.elementsByTagNameNS( WFS_NAMESPACE, "OtherSRS" ); for ( unsigned int i = 0; i < otherCRSList.length(); ++i ) { featureType.crslist.append( otherCRSList.at( i ).toElement().text() ); } //Support <SRS> for compatibility with older versions QDomNodeList srsList = featureTypeElem.elementsByTagNameNS( WFS_NAMESPACE, "SRS" ); for ( unsigned int i = 0; i < srsList.length(); ++i ) { featureType.crslist.append( srsList.at( i ).toElement().text() ); } mCaps.featureTypes.append( featureType ); } emit gotCapabilities(); }
void QgsSOAPRequestHandler::parseInput() { QString inputString = readPostBody(); //QgsDebugMsg("input string is: " + inputString) //inputString to QDomDocument QDomDocument inputXML; QString errorMsg; if ( !inputXML.setContent( inputString, true, &errorMsg ) ) { QgsDebugMsg( "soap request parse error" ); QgsDebugMsg( "error message: " + errorMsg ); QgsDebugMsg( "the xml string was:" ); QgsDebugMsg( inputString ); throw QgsMapServiceException( "InvalidXML", "XML error: " + errorMsg ); } // if xml reading was successfull, save the inputXML in a file QFile soapFile; QTextStream soapStream; //go through soap envelope->soap body, search for either GetCapabilities or GetMap QDomNodeList envelopeNodeList = inputXML.elementsByTagNameNS( "http://schemas.xmlsoap.org/soap/envelope/", "Envelope" ); if ( envelopeNodeList.size() < 1 ) { QgsDebugMsg( "Envelope element not found" ); throw QgsMapServiceException( "SOAPError", "Element <Envelope> not found" ); } QDomNodeList bodyNodeList = envelopeNodeList.item( 0 ).toElement().elementsByTagNameNS( "http://schemas.xmlsoap.org/soap/envelope/", "Body" ); if ( bodyNodeList.size() < 1 ) { QgsDebugMsg( "body node not found" ); throw QgsMapServiceException( "SOAPError", "Element <Body> not found" ); } QDomElement bodyElement = bodyNodeList.item( 0 ).toElement(); QDomElement firstChildElement = bodyElement.firstChild().toElement(); QString serviceString = firstChildElement.attribute( "service" ); if ( serviceString == "MS" ) { QgsDebugMsg( "service = MS " ); mParameterMap.insert( "SERVICE", "MS" ); mService = "MS"; } else if ( serviceString == "WMS" ) { mParameterMap.insert( "SERVICE", "WMS" ); mService = "WMS"; } else if ( serviceString == "MDS" ) { mParameterMap.insert( "SERVICE", "MDS" ); mService = "MDS"; } else if ( serviceString == "MAS" ) { mParameterMap.insert( "SERVICE", "MAS" ); mService = "MAS"; } else { mParameterMap.insert( "SERVICE", "DISCOVERY" ); mService = "DISCOVERY"; } //GetCapabilities request //if(firstChildElement.localName().compare("getCapabilities", Qt::CaseInsensitive) == 0) if ( firstChildElement.localName() == "GetCapabilities" || firstChildElement.localName() == "getCapabilities" ) { mParameterMap.insert( "REQUEST", "GetCapabilities" ); } //GetMap request //else if(firstChildElement.tagName().compare("getMap",Qt::CaseInsensitive) == 0) else if ( firstChildElement.localName() == "GetMap" || firstChildElement.localName() == "getMap" ) { mParameterMap.insert( "REQUEST", "GetMap" ); parseGetMapElement( mParameterMap, firstChildElement ); } //GetDiagram request //else if(firstChildElement.tagName().compare("getDiagram", Qt::CaseInsensitive) == 0) else if ( firstChildElement.localName() == "GetDiagram" ) { mParameterMap.insert( "REQUEST", "GetDiagram" ); parseGetMapElement( mParameterMap, firstChildElement ); //reuse the method for GetMap } //GetFeatureInfo request else if ( firstChildElement.localName() == "GetFeatureInfo" ) { mParameterMap.insert( "REQUEST", "GetFeatureInfo" ); parseGetFeatureInfoElement( mParameterMap, firstChildElement ); } //set mFormat QString formatString = mParameterMap.value( "FORMAT" ); if ( !formatString.isEmpty() ) { //remove the image/ in front of the format if ( formatString == "image/jpeg" || formatString == "JPG" || formatString == "jpg" ) { formatString = "JPG"; } else if ( formatString == "image/png" || formatString == "PNG" || formatString == "png" ) { formatString = "PNG"; } else if ( formatString == "image/gif" || formatString == "GIF" || formatString == "gif" ) { formatString = "GIF"; } else { throw QgsMapServiceException( "InvalidFormat", "Invalid format " + formatString + ", only jpg and png are supported" ); } mFormat = formatString; } }
QDomDocument SOAPClient::SendSOAPRequest(const QString &sMethod, QStringMap &list, int &nErrCode, QString &sErrDesc) { QUrl url(m_url); url.setPath(m_sControlPath); nErrCode = UPnPResult_Success; sErrDesc = ""; QDomDocument xmlResult; if (m_sNamespace.isEmpty()) { nErrCode = UPnPResult_MythTV_NoNamespaceGiven; sErrDesc = "No namespace given"; return xmlResult; } // -------------------------------------------------------------- // Add appropriate headers // -------------------------------------------------------------- QHash<QByteArray, QByteArray> headers; headers.insert("Content-Type", "text/xml; charset=\"utf-8\""); QString soapHeader = QString("\"%1#%2\"").arg(m_sNamespace).arg(sMethod); headers.insert("SOAPACTION", soapHeader.toUtf8()); headers.insert("User-Agent", "Mozilla/9.876 (X11; U; Linux 2.2.12-20 i686, en) " "Gecko/25250101 Netscape/5.432b1"); // -------------------------------------------------------------- // Build request payload // -------------------------------------------------------------- QByteArray aBuffer; QTextStream os( &aBuffer ); os.setCodec("UTF-8"); os << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n"; os << "<s:Envelope " " s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"" " xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">\r\n"; os << " <s:Body>\r\n"; os << " <u:" << sMethod << " xmlns:u=\"" << m_sNamespace << "\">\r\n"; // -------------------------------------------------------------- // Add parameters from list // -------------------------------------------------------------- for (QStringMap::iterator it = list.begin(); it != list.end(); ++it) { os << " <" << it.key() << ">"; os << HTTPRequest::Encode( *it ); os << "</" << it.key() << ">\r\n"; } os << " </u:" << sMethod << ">\r\n"; os << " </s:Body>\r\n"; os << "</s:Envelope>\r\n"; os.flush(); // -------------------------------------------------------------- // Perform Request // -------------------------------------------------------------- LOG(VB_UPNP, LOG_DEBUG, QString("SOAPClient(%1) sending:\n %2").arg(url.toString()).arg(aBuffer.constData())); QString sXml; if (!GetMythDownloadManager()->postAuth(url.toString(), &aBuffer, NULL, NULL, &headers)) { LOG(VB_GENERAL, LOG_ERR, QString("SOAPClient::SendSOAPRequest: request failed: %1") .arg(url.toString())); } else sXml = QString(aBuffer); // -------------------------------------------------------------- // Parse response // -------------------------------------------------------------- LOG(VB_UPNP, LOG_DEBUG, "SOAPClient response:\n" + QString("%1\n").arg(sXml)); // TODO handle timeout without response correctly. list.clear(); QDomDocument doc; if (!doc.setContent(sXml, true, &sErrDesc, &nErrCode)) { LOG(VB_UPNP, LOG_ERR, QString("SendSOAPRequest( %1 ) - Invalid response from %2") .arg(sMethod).arg(url.toString()) + QString("%1: %2").arg(nErrCode).arg(sErrDesc)); return xmlResult; } // -------------------------------------------------------------- // Is this a valid response? // -------------------------------------------------------------- QString sResponseName = sMethod + "Response"; QDomNodeList oNodeList = doc.elementsByTagNameNS(m_sNamespace, sResponseName); if (oNodeList.count() == 0) { // -------------------------------------------------------------- // Must be a fault... parse it to return reason // -------------------------------------------------------------- nErrCode = GetNodeValue( doc, "Envelope/Body/Fault/detail/UPnPError/errorCode", 500); sErrDesc = GetNodeValue( doc, "Envelope/Body/Fault/detail/UPnPError/errorDescription", ""); if (sErrDesc.isEmpty()) sErrDesc = QString("Unknown #%1").arg(nErrCode); QDomNode oNode = FindNode( "Envelope/Body/Fault", doc ); oNode = xmlResult.importNode( oNode, true ); xmlResult.appendChild( oNode ); return xmlResult; } QDomNode oMethod = oNodeList.item(0); if (oMethod.isNull()) return xmlResult; QDomNode oNode = oMethod.firstChild(); for (; !oNode.isNull(); oNode = oNode.nextSibling()) { QDomElement e = oNode.toElement(); if (e.isNull()) continue; QString sName = e.tagName(); QString sValue = ""; QDomText oText = oNode.firstChild().toText(); if (!oText.isNull()) sValue = oText.nodeValue(); list.insert(QUrl::fromPercentEncoding(sName.toUtf8()), QUrl::fromPercentEncoding(sValue.toUtf8())); } // Create copy of oMethod that can be used with xmlResult. oMethod = xmlResult.importNode( oMethod.firstChild(), true ); // importNode does not attach the new nodes to the document, // do it here. xmlResult.appendChild( oMethod ); return xmlResult; }
void OwnCloudService::loadTodoItems(QString &data) { QDomDocument doc; doc.setContent(data, true); // fetch all urls that are currently in the calendar QList<QUrl> calendarItemUrlRemoveList = CalendarItem::fetchAllUrlsByCalendar(calendarName); QDomNodeList responseNodes = doc.elementsByTagNameNS(NS_DAV, "response"); int responseNodesCount = responseNodes.length(); int requestCount = 0; // set the preliminary maximum of the progress bar this->todoDialog->todoItemLoadingProgressBarSetMaximum(responseNodesCount); // loop all response blocks for (int i = 0; i < responseNodesCount; ++i) { QDomNode responseNode = responseNodes.at(i); if (responseNode.isElement()) { QDomElement elem = responseNode.toElement(); // check if we have an url QDomNodeList urlPartNodes = elem.elementsByTagNameNS(NS_DAV, "href"); if (urlPartNodes.length()) { QString urlPart = urlPartNodes.at(0).toElement().text(); if (urlPart == "") { continue; } QUrl calendarItemUrl = QUrl(serverUrlWithoutPath + urlPart); // check if we have an etag QDomNodeList etagNodes = elem.elementsByTagNameNS(NS_DAV, "getetag"); if (etagNodes.length()) { QString etag = etagNodes.at(0).toElement().text(); etag.replace("\"", ""); qDebug() << __func__ << " - 'etag': " << etag; // check if we have a last modified date QDomNodeList lastModifiedNodes = elem.elementsByTagNameNS( NS_DAV, "getlastmodified"); if (lastModifiedNodes.length()) { const QString lastModified = lastModifiedNodes.at( 0).toElement().text(); bool fetchItem = false; // try to fetch the calendar item by url CalendarItem calItem = CalendarItem::fetchByUrl( calendarItemUrl); if (calItem.isFetched()) { // check if calendar item was modified if (calItem.getETag() != etag) { // store etag and last modified date calItem.setETag(etag); calItem.setLastModifiedString(lastModified); calItem.store(); // we want to update the item from server fetchItem = true; } } else { // calendar item was not found // create calendar item for fetching CalendarItem::addCalendarItemForRequest( calendarName, calendarItemUrl, etag, lastModified); fetchItem = true; } // remove the url from the list of calendar item urls // to remove if (calendarItemUrlRemoveList.contains( calendarItemUrl)) { calendarItemUrlRemoveList.removeAll( calendarItemUrl); } // fetch the calendar item if (fetchItem) { QNetworkRequest r(calendarItemUrl); addAuthHeader(&r); QNetworkReply *reply = networkManager->get(r); ignoreSslErrorsIfAllowed(reply); requestCount++; } } } } } } // set the real maximum of the progress bar this->todoDialog->todoItemLoadingProgressBarSetMaximum(requestCount); // hide progress bar if there were no updates if (requestCount == 0) { this->todoDialog->todoItemLoadingProgressBarHide(); } // remove all not found items for (int i = 0; i < calendarItemUrlRemoveList.length(); ++i) { QUrl url = calendarItemUrlRemoveList.at(i); CalendarItem calItem = CalendarItem::fetchByUrl(url); if (calItem.isFetched()) { calItem.remove(); } } // reload the existing items this->todoDialog->reloadTodoListItems(); qDebug() << CalendarItem::fetchAllByCalendar(calendarName); }
/** Actually sends the sMethod action to the command URL specified * in the constructor (url+[/]+sControlPath). * * \param sMethod method to be invoked. e.g. "SetChannel", * "GetConnectionInfoResult" * * \param list Parsed as a series of key value pairs for the input params * and then cleared and used for the output params. * * \param nErrCode set to zero on success, non-zero in case of error. * * \param sErrCode returns error description from device, when applicable. * * \param bInQtThread May be set to true if this is run from within * a QThread with a running an event loop. * * \return Returns a QDomDocument containing output parameters on success. */ QDomDocument SOAPClient::SendSOAPRequest(const QString &sMethod, QStringMap &list, int &nErrCode, QString &sErrDesc, bool bInQtThread) { QUrl url(m_url); url.setPath(m_sControlPath); nErrCode = UPnPResult_Success; sErrDesc = ""; QDomDocument xmlResult; if (m_sNamespace.isEmpty()) { nErrCode = UPnPResult_MythTV_NoNamespaceGiven; sErrDesc = "No namespace given"; return xmlResult; } // -------------------------------------------------------------- // Add appropriate headers // -------------------------------------------------------------- QHttpRequestHeader header("POST", sMethod, 1, 0); header.setValue("CONTENT-TYPE", "text/xml; charset=\"utf-8\"" ); header.setValue("SOAPACTION", QString("\"%1#%2\"").arg(m_sNamespace).arg(sMethod)); // -------------------------------------------------------------- // Build request payload // -------------------------------------------------------------- QByteArray aBuffer; QTextStream os( &aBuffer ); os.setCodec("UTF-8"); os << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n"; os << "<s:Envelope " " s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"" " xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">\r\n"; os << " <s:Body>\r\n"; os << " <u:" << sMethod << " xmlns:u=\"" << m_sNamespace << "\">\r\n"; // -------------------------------------------------------------- // Add parameters from list // -------------------------------------------------------------- for (QStringMap::iterator it = list.begin(); it != list.end(); ++it) { os << " <" << it.key() << ">"; os << HTTPRequest::Encode( *it ); os << "</" << it.key() << ">\r\n"; } os << " </u:" << sMethod << ">\r\n"; os << " </s:Body>\r\n"; os << "</s:Envelope>\r\n"; os.flush(); // -------------------------------------------------------------- // Perform Request // -------------------------------------------------------------- QBuffer buff(&aBuffer); LOG(VB_UPNP, LOG_DEBUG, QString("SOAPClient(%1) sending:\n").arg(url.toString()) + header.toString() + QString("\n%1\n").arg(aBuffer.constData())); QString sXml = HttpComms::postHttp(url, &header, &buff, // QIODevice* 10000, // ms -- Technically should be 30ms per spec 3, // retries 0, // redirects false, // allow gzip NULL, // login bInQtThread, QString() // userAgent, UPnP/1.0 very strict on // format if set ); // -------------------------------------------------------------- // Parse response // -------------------------------------------------------------- LOG(VB_UPNP, LOG_DEBUG, "SOAPClient response:\n" + QString("%1\n").arg(sXml)); // TODO handle timeout without response correctly. list.clear(); QDomDocument doc; if (!doc.setContent(sXml, true, &sErrDesc, &nErrCode)) { LOG(VB_UPNP, LOG_ERR, QString("SendSOAPRequest( %1 ) - Invalid response from %2") .arg(sMethod).arg(url.toString()) + QString("%1: %2").arg(nErrCode).arg(sErrDesc)); return xmlResult; } // -------------------------------------------------------------- // Is this a valid response? // -------------------------------------------------------------- QString sResponseName = sMethod + "Response"; QDomNodeList oNodeList = doc.elementsByTagNameNS(m_sNamespace, sResponseName); if (oNodeList.count() == 0) { // -------------------------------------------------------------- // Must be a fault... parse it to return reason // -------------------------------------------------------------- nErrCode = GetNodeValue( doc, "Envelope/Body/Fault/detail/UPnPError/errorCode", 500); sErrDesc = GetNodeValue( doc, "Envelope/Body/Fault/detail/UPnPError/errorDescription", ""); if (sErrDesc.isEmpty()) sErrDesc = QString("Unknown #%1").arg(nErrCode); QDomNode oNode = FindNode( "Envelope/Body/Fault", doc ); oNode = xmlResult.importNode( oNode, true ); xmlResult.appendChild( oNode ); return xmlResult; } QDomNode oMethod = oNodeList.item(0); if (oMethod.isNull()) return xmlResult; QDomNode oNode = oMethod.firstChild(); for (; !oNode.isNull(); oNode = oNode.nextSibling()) { QDomElement e = oNode.toElement(); if (e.isNull()) continue; QString sName = e.tagName(); QString sValue = ""; QDomText oText = oNode.firstChild().toText(); if (!oText.isNull()) sValue = oText.nodeValue(); list.insert(QUrl::fromPercentEncoding(sName.toUtf8()), QUrl::fromPercentEncoding(sValue.toUtf8())); } // Create copy of oMethod that can be used with xmlResult. oMethod = xmlResult.importNode( oMethod.firstChild(), true ); // importNode does not attach the new nodes to the document, // do it here. xmlResult.appendChild( oMethod ); return xmlResult; }
bool SOAPClient::SendSOAPRequest( const QString &sMethod, QStringMap &list, int &nErrCode, QString &sErrDesc, bool bInQtThread ) { QUrl url( m_url ); url.setPath( m_sControlPath ); // -------------------------------------------------------------- // Add appropriate headers // -------------------------------------------------------------- QHttpRequestHeader header; header.setValue("CONTENT-TYPE", "text/xml; charset=\"utf-8\"" ); header.setValue("SOAPACTION" , QString( "\"%1#GetConnectionInfo\"" ) .arg( m_sNamespace )); // -------------------------------------------------------------- // Build request payload // -------------------------------------------------------------- QByteArray aBuffer; QTextStream os( &aBuffer ); os << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n"; os << "<s:Envelope s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">\r\n"; os << " <s:Body>\r\n"; os << " <u:" << sMethod << " xmlns:u=\"" << m_sNamespace << "\">\r\n"; // -------------------------------------------------------------- // Add parameters from list // -------------------------------------------------------------- for ( QStringMap::iterator it = list.begin(); it != list.end(); ++it ) { os << " <" << it.key() << ">"; os << HTTPRequest::Encode( *it ); os << "</" << it.key() << ">\r\n"; } os << " </u:" << sMethod << ">\r\n"; os << " </s:Body>\r\n"; os << "</s:Envelope>\r\n"; os.flush(); // -------------------------------------------------------------- // Perform Request // -------------------------------------------------------------- QBuffer buff( &aBuffer ); QString sXml = HttpComms::postHttp( url, &header, (QIODevice *)&buff, 10000, // ms 3, // retries 0, // redirects false, // allow gzip NULL, // login bInQtThread ); // -------------------------------------------------------------- // Parse response // -------------------------------------------------------------- list.clear(); QDomDocument doc; if ( !doc.setContent( sXml, true, &sErrDesc, &nErrCode )) { VERBOSE( VB_UPNP, QString( "MythXMLClient::SendSOAPRequest( %1 ) - Invalid response from %2" ) .arg( sMethod ) .arg( url.toString() )); return false; } // -------------------------------------------------------------- // Is this a valid response? // -------------------------------------------------------------- QString sResponseName = sMethod + "Response"; QDomNodeList oNodeList = doc.elementsByTagNameNS( m_sNamespace, sResponseName ); if (oNodeList.count() > 0) { QDomNode oMethod = oNodeList.item(0); if (!oMethod.isNull()) { for ( QDomNode oNode = oMethod.firstChild(); !oNode.isNull(); oNode = oNode.nextSibling() ) { QDomElement e = oNode.toElement(); if (!e.isNull()) { QString sName = e.tagName(); QString sValue = ""; QDomText oText = oNode.firstChild().toText(); if (!oText.isNull()) sValue = oText.nodeValue(); list.insert(QUrl::fromPercentEncoding(sName.toUtf8()), QUrl::fromPercentEncoding(sValue.toUtf8())); } } } return true; } // -------------------------------------------------------------- // Must be a fault... parse it to return reason // -------------------------------------------------------------- nErrCode = GetNodeValue( doc, "Envelope/Body/Fault/detail/UPnPResult/errorCode" , 500 ); sErrDesc = GetNodeValue( doc, "Envelope/Body/Fault/detail/UPnPResult/errorDescription", QString( "Unknown" )); return false; }