KD SOAP API Documentation: KDSoapPendingCall.cpp Source File

| KD SOAP API Documentation 2.2

Loading...
Searching...
No Matches
KDSoapPendingCall.cpp
Go to the documentation of this file.
1/****************************************************************************
2**
3** This file is part of the KD Soap project.
4**
5** SPDX-FileCopyrightText: 2010 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
6**
7** SPDX-License-Identifier: MIT
8**
9****************************************************************************/
10#include "KDSoapPendingCall.h"
11#include "KDSoapMessageReader_p.h"
12#include "KDSoapNamespaceManager.h"
13#include "KDSoapPendingCall_p.h"
14#include <QDebug>
15#include <QNetworkReply>
16
17 static void debugHelper(const QByteArray &data, const QList<QNetworkReply::RawHeaderPair> &headerList)
18{
19 const QByteArray doDebug = qgetenv("KDSOAP_DEBUG");
20 const QList<QByteArray> options = doDebug.toLower().split(',');
21 const bool optEscape = options.contains("escape");
22 const bool optHttp = options.contains("http") || options.contains("https");
23 const bool optReformat = options.contains("reformat");
24 quint8 indentation = 4;
25 for (const QByteArray &opt : qAsConst(options)) {
26 if (opt.startsWith("indent=")) { // krazy:exclude=strings
27 indentation = opt.mid(7).toUShort();
28 }
29 }
30
31 QByteArray toOutput;
32 if (optHttp) {
33 for (const QNetworkReply::RawHeaderPair &header : qAsConst(headerList)) {
34 if (!header.first.isEmpty()) {
35 toOutput += header.first + ": ";
36 }
37 toOutput += header.second + "\n";
38 }
39 toOutput += "\n";
40 }
41
42 if (optReformat) {
43 QByteArray reformatted;
44 QXmlStreamReader reader(data);
45 QXmlStreamWriter writer(&reformatted);
46 writer.setAutoFormatting(true);
47 writer.setAutoFormattingIndent(indentation);
48
49 while (!reader.atEnd()) {
50 reader.readNext();
51 if (!reader.hasError() && !reader.isWhitespace()) {
52 writer.writeCurrentToken(reader);
53 }
54 }
55
56 toOutput += reader.hasError() ? data : reformatted;
57 } else {
58 toOutput += data;
59 }
60
61 if (optEscape) {
62 qDebug() << toOutput;
63 } else {
64 qDebug().noquote() << toOutput;
65 }
66}
67
68// Log the HTTP and XML of a response from the server.
69 static void maybeDebugResponse(const QByteArray &data, QNetworkReply *reply)
70{
71 const QByteArray doDebug = qgetenv("KDSOAP_DEBUG");
72 if (doDebug.trimmed().isEmpty() || doDebug == "0") {
73 return;
74 }
75
76 debugHelper(data, reply->rawHeaderPairs());
77}
78
79// Log the HTTP and XML of a request.
80// (not static, because this is used in KDSoapClientInterface)
81 void maybeDebugRequest(const QByteArray &data, const QNetworkRequest &request, QNetworkReply *reply)
82{
83 const QByteArray doDebug = qgetenv("KDSOAP_DEBUG");
84 if (doDebug.trimmed().isEmpty() || doDebug == "0") {
85 return;
86 }
87
88 QList<QNetworkReply::RawHeaderPair> headerList;
89 if (reply) {
90 QByteArray method;
91 switch (reply->operation()) {
92 default:
93 break; // don't try to mimic the basic HTTP command
94 case QNetworkAccessManager::GetOperation:
95 method = "GET";
96 break;
97 case QNetworkAccessManager::HeadOperation:
98 method = "HEAD";
99 break;
100 case QNetworkAccessManager::PutOperation:
101 method = "PUT";
102 break;
103 case QNetworkAccessManager::PostOperation:
104 method = "POST";
105 break;
106 case QNetworkAccessManager::DeleteOperation:
107 method = "DELETE";
108 break;
109 }
110 if (!method.isEmpty()) {
111 QByteArray output = method + " " + reply->url().toString().toUtf8();
112 headerList << QNetworkReply::RawHeaderPair {{}, std::move(output)};
113 }
114 }
115 const auto rawHeaders = request.rawHeaderList();
116 for (const QByteArray &h : rawHeaders) {
117 headerList << QNetworkReply::RawHeaderPair {h, request.rawHeader(h)};
118 }
119 debugHelper(data, headerList);
120}
121
122KDSoapPendingCall::Private::~Private()
123{
124 if (reply) {
125 // Ensure the connection is closed, which QNetworkReply doesn't do in its destructor. This needs abort().
126 QObject::disconnect(reply.data(), &QNetworkReply::finished, nullptr, nullptr);
127 reply->abort();
128 }
129 delete reply.data();
130 delete buffer;
131}
132
133 KDSoapPendingCall::KDSoapPendingCall(QNetworkReply *reply, QBuffer *buffer)
134 : d(new Private(reply, buffer))
135{
136}
137
138KDSoapPendingCall::KDSoapPendingCall(const KDSoapPendingCall &other)
139 : d(other.d)
140{
141}
142
143KDSoapPendingCall::~KDSoapPendingCall()
144{
145}
146
147 KDSoapPendingCall &KDSoapPendingCall::operator=(const KDSoapPendingCall &other)
148{
149 d = other.d;
150 return *this;
151}
152
153 bool KDSoapPendingCall::isFinished() const
154{
155 return d->reply.data()->isFinished();
156}
157
158 KDSoapMessage KDSoapPendingCall::returnMessage() const
159{
160 d->parseReply();
161 return d->replyMessage;
162}
163
164 KDSoapHeaders KDSoapPendingCall::returnHeaders() const
165{
166 d->parseReply();
167 return d->replyHeaders;
168}
169
170 QVariant KDSoapPendingCall::returnValue() const
171{
172 d->parseReply();
173 if (!d->replyMessage.childValues().isEmpty()) {
174 return d->replyMessage.childValues().first().value();
175 }
176 return QVariant();
177}
178
179 void KDSoapPendingCall::Private::parseReply()
180{
181 if (parsed) {
182 return;
183 }
184 QNetworkReply *reply = this->reply.data();
185 if (!reply->isFinished()) {
186 qWarning("KDSoap: Parsing reply before it finished!");
187 return;
188 }
189 parsed = true;
190
191 // Don't try to read from an aborted (closed) reply
192 const QByteArray data = reply->isOpen() ? reply->readAll() : QByteArray();
193 maybeDebugResponse(data, reply);
194
195 if (!data.isEmpty()) {
196 KDSoapMessageReader reader;
197 reader.xmlToMessage(data, &replyMessage, nullptr, &replyHeaders, this->soapVersion);
198 }
199
200 if (reply->error()) {
201 if (!replyMessage.isFault()) {
202 replyHeaders.clear();
203 if (reply->error() == QNetworkReply::OperationCanceledError
204 && reply->property("kdsoap_reply_timed_out").toBool()) { // see KDSoapClientInterface.cpp
205 replyMessage.createFaultMessage(QString::number(QNetworkReply::TimeoutError), QLatin1String("Operation timed out"), soapVersion);
206 } else {
207 replyMessage.createFaultMessage(QString::number(reply->error()), reply->errorString(), soapVersion);
208 }
209 }
210 }
211}
KDSoapMessageReader_p.h
KDSoapNamespaceManager.h
debugHelper
static void debugHelper(const QByteArray &data, const QList< QNetworkReply::RawHeaderPair > &headerList)
Definition KDSoapPendingCall.cpp:17
maybeDebugRequest
void maybeDebugRequest(const QByteArray &data, const QNetworkRequest &request, QNetworkReply *reply)
Definition KDSoapPendingCall.cpp:81
maybeDebugResponse
static void maybeDebugResponse(const QByteArray &data, QNetworkReply *reply)
Definition KDSoapPendingCall.cpp:69
KDSoapPendingCall.h
KDSoapPendingCall_p.h
KDSoapHeaders
Definition KDSoapMessage.h:185
KDSoapMessageReader
Definition KDSoapMessageReader_p.h:18
KDSoapMessageReader::xmlToMessage
XmlError xmlToMessage(const QByteArray &data, KDSoapMessage *pParsedMessage, QString *pMessageNamespace, KDSoapHeaders *pRequestHeaders, KDSoap::SoapVersion soapVersion) const
Definition KDSoapMessageReader.cpp:188
KDSoapMessage
Definition KDSoapMessage.h:29
KDSoapMessage::createFaultMessage
void createFaultMessage(const QString &faultCode, const QString &faultText, KDSoap::SoapVersion soapVersion)
Definition KDSoapMessage.cpp:154
KDSoapMessage::isFault
bool isFault() const
Definition KDSoapMessage.cpp:110
KDSoapPendingCall::Private
Definition KDSoapPendingCall_p.h:26
KDSoapPendingCall::Private::reply
QPointer< QNetworkReply > reply
Definition KDSoapPendingCall_p.h:42
KDSoapPendingCall::Private::replyHeaders
KDSoapHeaders replyHeaders
Definition KDSoapPendingCall_p.h:45
KDSoapPendingCall::Private::parsed
bool parsed
Definition KDSoapPendingCall_p.h:47
KDSoapPendingCall::Private::~Private
~Private()
Definition KDSoapPendingCall.cpp:122
KDSoapPendingCall::Private::replyMessage
KDSoapMessage replyMessage
Definition KDSoapPendingCall_p.h:44
KDSoapPendingCall::Private::buffer
QBuffer * buffer
Definition KDSoapPendingCall_p.h:43
KDSoapPendingCall::Private::parseReply
void parseReply()
Definition KDSoapPendingCall.cpp:179
KDSoapPendingCall::Private::soapVersion
KDSoap::SoapVersion soapVersion
Definition KDSoapPendingCall_p.h:46
KDSoapPendingCall
Definition KDSoapPendingCall.h:39
KDSoapPendingCall::KDSoapPendingCall
KDSoapPendingCall(const KDSoapPendingCall &other)
Definition KDSoapPendingCall.cpp:138
KDSoapPendingCall::returnHeaders
KDSoapHeaders returnHeaders() const
Definition KDSoapPendingCall.cpp:164
KDSoapPendingCall::returnValue
QVariant returnValue() const
Definition KDSoapPendingCall.cpp:170
KDSoapPendingCall::operator=
KDSoapPendingCall & operator=(const KDSoapPendingCall &other)
Definition KDSoapPendingCall.cpp:147
KDSoapPendingCall::isFinished
bool isFinished() const
Definition KDSoapPendingCall.cpp:153
KDSoapPendingCall::~KDSoapPendingCall
~KDSoapPendingCall()
Definition KDSoapPendingCall.cpp:143
KDSoapPendingCall::returnMessage
KDSoapMessage returnMessage() const
Definition KDSoapPendingCall.cpp:158
QBuffer
QByteArray
QByteArray::isEmpty
bool isEmpty() const const
QByteArray::split
QList< QByteArray > split(char sep) const const
QByteArray::toLower
QByteArray toLower() const const
QByteArray::trimmed
QByteArray trimmed() const const
QLatin1String
QList
QList::clear
void clear()
QList::contains
bool contains(const T &value) const const
QNetworkAccessManager::GetOperation
GetOperation
QNetworkReply
QNetworkReply::OperationCanceledError
OperationCanceledError
QNetworkReply::RawHeaderPair
typedef RawHeaderPair
QNetworkReply::error
QNetworkReply::NetworkError error() const const
QNetworkReply::finished
void finished()
QNetworkReply::operation
QNetworkAccessManager::Operation operation() const const
QNetworkReply::rawHeaderPairs
const QList< QNetworkReply::RawHeaderPair > & rawHeaderPairs() const const
QNetworkReply::url
QUrl url() const const
QNetworkRequest
QNetworkRequest::rawHeader
QByteArray rawHeader(const QByteArray &headerName) const const
QNetworkRequest::rawHeaderList
QList< QByteArray > rawHeaderList() const const
QObject::disconnect
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
QPointer::data
T * data() const const
QString::number
QString number(int n, int base)
QString::toUtf8
QByteArray toUtf8() const const
QUrl::toString
QString toString(QUrl::FormattingOptions options) const const
QVariant
QXmlStreamReader
QXmlStreamReader::atEnd
bool atEnd() const const
QXmlStreamReader::hasError
bool hasError() const const
QXmlStreamReader::isWhitespace
bool isWhitespace() const const
QXmlStreamReader::readNext
QXmlStreamReader::TokenType readNext()
QXmlStreamWriter
QXmlStreamWriter::setAutoFormattingIndent
void setAutoFormattingIndent(int spacesOrTabs)
QXmlStreamWriter::setAutoFormatting
void setAutoFormatting(bool enable)
QXmlStreamWriter::writeCurrentToken
void writeCurrentToken(const QXmlStreamReader &reader)

© 2010-2024 Klarälvdalens Datakonsult AB (KDAB)
"The Qt, C++ and OpenGL Experts"
https://www.kdab.com/
https://www.kdab.com/development-resources/qt-tools/kd-soap/
Generated on Sun Jan 7 2024 11:47:36 for KD SOAP API Documentation by doxygen 1.9.8