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"
13#include "KDSoapPendingCall_p.h"
14#include <QDebug>
15#include <QNetworkReply>
16
17static 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.
69static 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)
81void 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
89 if (reply) {
90 QByteArray method;
91 switch (reply->operation()) {
92 default:
93 break; // don't try to mimic the basic HTTP command
95 method = "GET";
96 break;
98 method = "HEAD";
99 break;
101 method = "PUT";
102 break;
104 method = "POST";
105 break;
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
123{
124 if (reply) {
125 // Ensure the connection is closed, which QNetworkReply doesn't do in its destructor. This needs abort().
127 reply->abort();
128 }
129 delete reply.data();
130 delete buffer;
131}
132
134 : d(new Private(reply, buffer))
135{
136}
137
139 : d(other.d)
140{
141}
142
146
148{
149 d = other.d;
150 return *this;
151}
152
154{
155 return d->reply.data()->isFinished();
156}
157
159{
160 d->parseReply();
161 return d->replyMessage;
162}
163
165{
166 d->parseReply();
167 return d->replyHeaders;
168}
169
171{
172 d->parseReply();
173 if (!d->replyMessage.childValues().isEmpty()) {
174 return d->replyMessage.childValues().first().value();
175 }
176 return QVariant();
177}
178
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();
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()) {
204 && reply->property("kdsoap_reply_timed_out").toBool()) { // see KDSoapClientInterface.cpp
206 } else {
208 }
209 }
210 }
211}
static void debugHelper(const QByteArray &data, const QList< QNetworkReply::RawHeaderPair > &headerList)
void maybeDebugRequest(const QByteArray &data, const QNetworkRequest &request, QNetworkReply *reply)
static void maybeDebugResponse(const QByteArray &data, QNetworkReply *reply)
XmlError xmlToMessage(const QByteArray &data, KDSoapMessage *pParsedMessage, QString *pMessageNamespace, KDSoapHeaders *pRequestHeaders, KDSoap::SoapVersion soapVersion) const
void createFaultMessage(const QString &faultCode, const QString &faultText, KDSoap::SoapVersion soapVersion)
bool isFault() const
QPointer< QNetworkReply > reply
KDSoap::SoapVersion soapVersion
KDSoapPendingCall(const KDSoapPendingCall &other)
KDSoapHeaders returnHeaders() const
QVariant returnValue() const
KDSoapPendingCall & operator=(const KDSoapPendingCall &other)
KDSoapMessage returnMessage() const
bool isEmpty() const const
QList< QByteArray > split(char sep) const const
QByteArray toLower() const const
QByteArray trimmed() const const
void clear()
bool contains(const T &value) const const
typedef RawHeaderPair
QNetworkReply::NetworkError error() const const
QNetworkAccessManager::Operation operation() const const
const QList< QNetworkReply::RawHeaderPair > & rawHeaderPairs() const const
QUrl url() const const
QByteArray rawHeader(const QByteArray &headerName) const const
QList< QByteArray > rawHeaderList() const const
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
T * data() const const
QString number(int n, int base)
QByteArray toUtf8() const const
QString toString(QUrl::FormattingOptions options) const const
bool atEnd() const const
bool hasError() const const
bool isWhitespace() const const
QXmlStreamReader::TokenType readNext()
void setAutoFormattingIndent(int spacesOrTabs)
void setAutoFormatting(bool enable)
void writeCurrentToken(const QXmlStreamReader &reader)

© 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 Sat Apr 20 2024 00:04:25 for KD SOAP API Documentation by doxygen 1.9.8