QBuffer* KDSoapClientInterfacePrivate::prepareRequestBuffer(const QString& method, const KDSoapMessage& message, const KDSoapHeaders& headers) { KDSoapMessageWriter msgWriter; msgWriter.setMessageNamespace(m_messageNamespace); msgWriter.setVersion(m_version); const QByteArray data = msgWriter.messageToXml(message, (m_style == KDSoapClientInterface::RPCStyle) ? method : QString(), headers, m_persistentHeaders, m_version); QBuffer* buffer = new QBuffer; buffer->setData(data); buffer->open(QIODevice::ReadOnly); return buffer; }
void KDSoapServerSocket::sendReply(KDSoapServerObjectInterface* serverObjectInterface, const KDSoapMessage& replyMsg) { const bool isFault = replyMsg.isFault(); QByteArray xmlResponse; if (!replyMsg.isNull()) { KDSoapMessageWriter msgWriter; // Note that the kdsoap client parsing code doesn't care for the name (except if it's fault), even in // Document mode. Other implementations do, though. QString responseName = isFault ? QString::fromLatin1("Fault") : replyMsg.name(); if (responseName.isEmpty()) responseName = m_method; QString responseNamespace = m_messageNamespace; KDSoapHeaders responseHeaders; if (serverObjectInterface) { responseHeaders = serverObjectInterface->responseHeaders(); if (!serverObjectInterface->responseNamespace().isEmpty()) { responseNamespace = serverObjectInterface->responseNamespace(); } } msgWriter.setMessageNamespace(responseNamespace); xmlResponse = msgWriter.messageToXml(replyMsg, responseName, responseHeaders, QMap<QString, KDSoapMessage>()); } const QByteArray response = httpResponseHeaders(isFault, "text/xml", xmlResponse.size()); if (m_doDebug) { qDebug() << "KDSoapServerSocket: writing" << response << xmlResponse; } qint64 written = write(response); Q_ASSERT(written == response.size()); // Please report a bug if you hit this. written = write(xmlResponse); Q_ASSERT(written == xmlResponse.size()); // Please report a bug if you hit this. Q_UNUSED(written); // flush() ? // All done, check if we should log this KDSoapServer* server = m_owner->server(); const KDSoapServer::LogLevel logLevel = server->logLevel(); // we do this here in order to support dynamic settings changes (at the price of a mutex) if (logLevel != KDSoapServer::LogNothing) { if (logLevel == KDSoapServer::LogEveryCall || (logLevel == KDSoapServer::LogFaults && isFault)) { if (isFault) server->log("FAULT " + m_method.toLatin1() + " -- " + replyMsg.faultAsString().toUtf8() + '\n'); else server->log("CALL " + m_method.toLatin1() + '\n'); } } }
//Use mime parts iff the SOAP version is XOP. QHttpMultiPart* KDSoapClientInterfacePrivate::prepareMimeRequestBuffer(const QString& method, const KDSoapMessage& message, const KDSoapHeaders& headers) { QHttpMultiPart *mime = new QHttpMultiPart(QHttpMultiPart::RelatedType); QHttpPart soapPart; soapPart.setRawHeader("Content-Id", "<http://tempuri.org/0>"); soapPart.setRawHeader("Content-Transfer-Encoding", "binary"); if (m_version == SOAP1_1_XOP) { soapPart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant(QString::fromLatin1("application/xop+xml;charset=utf-8;type=\"text/xml\""))); } else if (m_version == SOAP1_2_XOP) { soapPart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant(QString::fromLatin1("application/xop+xml;charset=utf-8;type=\"application/soap+xml\""))); } //TODO: Catch base64 and use xop instead. B4152: WCF optimizes element information items that contain base64-encoded data and exceed 1024 bytes in length. KDSoapMessageWriter msgWriter; msgWriter.setMessageNamespace(m_messageNamespace); const QByteArray data = msgWriter.messageToXml(message, (m_style == KDSoapClientInterface::RPCStyle) ? method : QString(), headers, m_persistentHeaders, m_version); soapPart.setBody(data); mime->append(soapPart); return mime; }