Libkdav2

davjob.cpp
1/*
2 Copyright (c) 2014 Gregory Oestreicher <greg@kamago.net>
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17*/
18
19#include "davjob.h"
20
21#include "davmanager.h"
22#include "libkdav2_debug.h"
23
24#include <QTextStream>
25
26using namespace KDAV2;
27
28class DavJobPrivate {
29public:
30 QByteArray data;
31 QDomDocument doc;
32 QUrl url;
33
34 QString location;
35 QString etag;
36 QString contentType;
38 int httpStatusCode = 0;
39};
40
41DavJob::DavJob(QNetworkReply *reply, QUrl url, QObject *parent)
42 : KJob(parent),
43 d(new DavJobPrivate)
44{
45 d->url = url;
46 connectToReply(reply);
47}
48
49DavJob::~DavJob()
50{
51}
52
53void DavJob::connectToReply(QNetworkReply *reply)
54{
55 QObject::connect(reply, &QNetworkReply::readyRead, this, [=] () {
56 d->data.append(reply->readAll());
57 });
59 qCWarning(KDAV2_LOG) << "Network error:" << error << "Message:" << reply->errorString() << "HTTP Status code:" << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() << "\nAvailable data:" << reply->readAll();
60 });
62 qCDebug(KDAV2_LOG) << "Metadata changed: " << reply->rawHeaderPairs();
63 d->location = reply->rawHeader("Location");
64 d->etag = reply->rawHeader("ETag");
65 //"text/x-vcard; charset=utf-8" -> "text/x-vcard"
66 d->contentType = reply->rawHeader("Content-Type").split(';').first();
67 });
68 QObject::connect(reply, &QNetworkReply::finished, this, [=] () {
69 //This is a workaround for QNetworkAccessManager::setRedirectPolicy(QNetworkRequest::UserVerifiedRedirectPolicy),
70 //which does not seem to work with multiple redirects.
71 const auto possibleRedirectUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
72 if(!possibleRedirectUrl.isEmpty()) {
73 qCDebug(KDAV2_LOG) << "Redirecting to " << possibleRedirectUrl;
74 auto request = reply->request();
75 request.setUrl(possibleRedirectUrl);
76 reply->disconnect(this);
77
78 //Set in QWebdav
79 const auto requestData = reply->property("requestData").toByteArray();
80 d->data.clear();
81
82 auto redirectReply = [&] {
83 if (reply->property("isPut").toBool()) {
84 return DavManager::networkAccessManager()->put(request, requestData);
85 }
86 return DavManager::networkAccessManager()->sendCustomRequest(request, request.attribute(QNetworkRequest::CustomVerbAttribute).toByteArray(), requestData);
87 }();
88 redirectReply->setProperty("requestData", requestData);
89 connectToReply(redirectReply);
90 return;
91 }
92
93 //Could have changed due to redirects
94 d->url = reply->url();
95
96 d->doc.setContent(d->data, true);
97
98 if (KDAV2_LOG().isDebugEnabled()) {
99 QTextStream stream(stdout, QIODevice::WriteOnly);
100 d->doc.save(stream, 2);
101 }
102
103 d->responseCode = reply->error();
104 d->httpStatusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
105 if (d->responseCode) {
106 setError(KJob::UserDefinedError);
107 setErrorText(reply->errorString());
108 } else if (d->httpStatusCode >= 400) {
109 qWarning() << "No error set even though we clearly have an http error?" << d->responseCode << d->httpStatusCode;
110 Q_ASSERT(false);
111 setError(KJob::UserDefinedError);
112 setErrorText(reply->errorString());
113 }
114 emitResult();
115 });
116
117}
118
119void DavJob::start()
120{
121}
122
123QDomDocument DavJob::response() const
124{
125 return d->doc;
126}
127
128QByteArray DavJob::data() const
129{
130 return d->data;
131}
132
133QUrl DavJob::url() const
134{
135 return d->url;
136}
137
138QString DavJob::getLocationHeader() const
139{
140 return d->location;
141}
142
143QString DavJob::getETagHeader() const
144{
145 return d->etag;
146}
147
148QString DavJob::getContentTypeHeader() const
149{
150 return d->contentType;
151}
152
153QNetworkReply::NetworkError DavJob::responseCode() const
154{
155 return d->responseCode;
156}
157
158int DavJob::httpStatusCode() const
159{
160 return d->httpStatusCode;
161}
static QNetworkAccessManager * networkAccessManager()
Provides access to the internally used network access manager.
void setErrorText(const QString &errorText)
void emitResult()
int error() const
void setError(int errorCode)
QList< QByteArray > split(char sep) const const
QString errorString() const const
QByteArray readAll()
void readyRead()
T & first()
QNetworkReply * put(const QNetworkRequest &request, QHttpMultiPart *multiPart)
QNetworkReply * sendCustomRequest(const QNetworkRequest &request, const QByteArray &verb, QHttpMultiPart *multiPart)
QVariant attribute(QNetworkRequest::Attribute code) const const
NetworkError error() const const
void metaDataChanged()
QByteArray rawHeader(const QByteArray &headerName) const const
const QList< RawHeaderPair > & rawHeaderPairs() const const
QNetworkRequest request() const const
QUrl url() const const
void setUrl(const QUrl &url)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
bool disconnect(const QMetaObject::Connection &connection)
QVariant property(const char *name) const const
bool toBool() const const
QByteArray toByteArray() const const
int toInt(bool *ok) const const
QUrl toUrl() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Mon Nov 18 2024 12:08:18 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.