mirror of https://github.com/KLayout/klayout.git
Attempt to solve WebDAV redirection issue on Windows.
This commit is contained in:
parent
372a42e84a
commit
fdd5671602
|
|
@ -28,6 +28,8 @@
|
|||
#include "tlStream.h"
|
||||
#include "tlEvents.h"
|
||||
|
||||
class QNetworkReply;
|
||||
|
||||
namespace tl
|
||||
{
|
||||
|
||||
|
|
@ -54,9 +56,11 @@ class TL_PUBLIC HttpErrorException
|
|||
: public tl::Exception
|
||||
{
|
||||
public:
|
||||
HttpErrorException (const std::string &f, int en, const std::string &url)
|
||||
: tl::Exception (tl::to_string (tr ("Error %d: %s, fetching %s")), en, f, url)
|
||||
HttpErrorException (const std::string &f, int ec, QNetworkReply *reply)
|
||||
: tl::Exception (format_error (f, ec, reply))
|
||||
{ }
|
||||
|
||||
static std::string format_error (const std::string &em, int ec, QNetworkReply *reply);
|
||||
};
|
||||
|
||||
class InputHttpStreamPrivateData;
|
||||
|
|
|
|||
|
|
@ -123,6 +123,39 @@ AuthenticationHandler::proxyAuthenticationRequired (const QNetworkProxy &proxy,
|
|||
// ---------------------------------------------------------------
|
||||
// InputHttpStream implementation
|
||||
|
||||
std::string
|
||||
HttpErrorException::format_error (const std::string &em, int ec, QNetworkReply *reply)
|
||||
{
|
||||
std::string msg = tl::sprintf (tl::to_string (tr ("Error %d: %s, fetching %s")), ec, em, tl::to_string (reply->url ().toString ()));
|
||||
|
||||
std::string data = tl::to_string (QString::fromUtf8 (reply->readAll ()));
|
||||
if (data.size () > 1000) {
|
||||
data = data.substr (0, size_t (1000)) + "...";
|
||||
}
|
||||
|
||||
if (! data.empty ()) {
|
||||
|
||||
msg += "\n\n";
|
||||
msg += tl::to_string (tr ("Reply body:"));
|
||||
msg += "\n";
|
||||
msg += data;
|
||||
|
||||
}
|
||||
|
||||
std::string redirected = tl::to_string (reply->attribute (QNetworkRequest::RedirectionTargetAttribute).toString ());
|
||||
if (! redirected.empty ()) {
|
||||
|
||||
msg += "\n\n";
|
||||
msg += tl::to_string (tr ("Redirected to: ")) + redirected;
|
||||
|
||||
}
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// InputHttpStream implementation
|
||||
|
||||
InputHttpStream::InputHttpStream (const std::string &url)
|
||||
{
|
||||
mp_data = new InputHttpStreamPrivateData (url);
|
||||
|
|
@ -237,7 +270,7 @@ static QNetworkAccessManager *s_network_manager (0);
|
|||
static AuthenticationHandler *s_auth_handler (0);
|
||||
|
||||
InputHttpStreamPrivateData::InputHttpStreamPrivateData (const std::string &url)
|
||||
: m_url (url), mp_reply (0), m_request ("GET"), mp_buffer (0)
|
||||
: m_url (url), mp_reply (0), m_request ("GET"), mp_buffer (0), mp_resend_timer (new QTimer (this))
|
||||
{
|
||||
if (! s_network_manager) {
|
||||
|
||||
|
|
@ -252,6 +285,7 @@ InputHttpStreamPrivateData::InputHttpStreamPrivateData (const std::string &url)
|
|||
}
|
||||
|
||||
connect (s_network_manager, SIGNAL (finished (QNetworkReply *)), this, SLOT (finished (QNetworkReply *)));
|
||||
connect (mp_resend_timer, SIGNAL (timeout ()), this, SLOT (resend ()));
|
||||
}
|
||||
|
||||
InputHttpStreamPrivateData::~InputHttpStreamPrivateData ()
|
||||
|
|
@ -293,6 +327,12 @@ InputHttpStreamPrivateData::add_header (const std::string &name, const std::stri
|
|||
m_headers.insert (std::make_pair (name, value));
|
||||
}
|
||||
|
||||
void
|
||||
InputHttpStreamPrivateData::resend ()
|
||||
{
|
||||
issue_request (QUrl (tl::to_qstring (m_url)));
|
||||
}
|
||||
|
||||
void
|
||||
InputHttpStreamPrivateData::finished (QNetworkReply *reply)
|
||||
{
|
||||
|
|
@ -300,16 +340,32 @@ InputHttpStreamPrivateData::finished (QNetworkReply *reply)
|
|||
return;
|
||||
}
|
||||
|
||||
if (tl::verbosity() >= 40) {
|
||||
const QList<QNetworkReply::RawHeaderPair> &raw_headers = reply->rawHeaderPairs ();
|
||||
for (QList<QNetworkReply::RawHeaderPair>::const_iterator h = raw_headers.begin (); h != raw_headers.end (); ++h) {
|
||||
tl::info << "HTTP response header: " << h->first.constData ()<< ": " << h->second.constData ();
|
||||
}
|
||||
}
|
||||
|
||||
QVariant redirect_target = reply->attribute (QNetworkRequest::RedirectionTargetAttribute);
|
||||
if (reply->error () == QNetworkReply::NoError && ! redirect_target.isNull ()) {
|
||||
|
||||
m_url = tl::to_string (redirect_target.toString ());
|
||||
if (tl::verbosity() >= 30) {
|
||||
tl::info << "HTTP redirect to: " << m_url;
|
||||
}
|
||||
issue_request (QUrl (redirect_target.toString ()));
|
||||
|
||||
close ();
|
||||
|
||||
mp_resend_timer->setSingleShot (true);
|
||||
mp_resend_timer->setInterval (0);
|
||||
mp_resend_timer->start ();
|
||||
|
||||
} else {
|
||||
|
||||
mp_reply = reply;
|
||||
m_ready ();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -333,6 +389,14 @@ InputHttpStreamPrivateData::issue_request (const QUrl &url)
|
|||
request.setRawHeader (QByteArray (h->first.c_str ()), QByteArray (h->second.c_str ()));
|
||||
}
|
||||
|
||||
#if QT_VERSION >= 0x50600
|
||||
#if QT_VERSION >= 0x50900
|
||||
request.setAttribute (QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::ManualRedirectPolicy);
|
||||
#else
|
||||
request.setAttribute (QNetworkRequest::FollowRedirectsAttribute, false);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if QT_VERSION < 0x40700
|
||||
if (m_request == "GET" && m_data.isEmpty ()) {
|
||||
mp_active_reply.reset (s_network_manager->get (request));
|
||||
|
|
@ -410,7 +474,7 @@ InputHttpStreamPrivateData::read (char *b, size_t n)
|
|||
ec = int (mp_reply->error ());
|
||||
}
|
||||
|
||||
throw HttpErrorException (em, ec, m_url);
|
||||
throw HttpErrorException (em, ec, mp_reply);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#include <QObject>
|
||||
#include <QBuffer>
|
||||
#include <QByteArray>
|
||||
#include <QTimer>
|
||||
#include <memory>
|
||||
|
||||
class QNetworkAccessManager;
|
||||
|
|
@ -103,6 +104,7 @@ public:
|
|||
|
||||
private slots:
|
||||
void finished (QNetworkReply *);
|
||||
void resend ();
|
||||
|
||||
private:
|
||||
std::string m_url;
|
||||
|
|
@ -113,6 +115,7 @@ private:
|
|||
QBuffer *mp_buffer;
|
||||
std::map<std::string, std::string> m_headers;
|
||||
tl::Event m_ready;
|
||||
QTimer *mp_resend_timer;
|
||||
|
||||
void issue_request (const QUrl &url);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -7,47 +7,47 @@ TARGET = tl_tests
|
|||
include($$PWD/../../lib_ut.pri)
|
||||
|
||||
SOURCES = \
|
||||
tlAlgorithm.cc \
|
||||
tlClassRegistry.cc \
|
||||
tlCommandLineParser.cc \
|
||||
tlAlgorithmTests.cc \
|
||||
tlClassRegistryTests.cc \
|
||||
tlCommandLineParserTests.cc \
|
||||
tlCopyOnWriteTests.cc \
|
||||
tlDataMapping.cc \
|
||||
tlDeflate.cc \
|
||||
tlEvents.cc \
|
||||
tlExpression.cc \
|
||||
tlFileUtils.cc \
|
||||
tlDataMappingTests.cc \
|
||||
tlDeferredExecutionTests.cc \
|
||||
tlDeflateTests.cc \
|
||||
tlEventsTests.cc \
|
||||
tlExpressionTests.cc \
|
||||
tlFileSystemWatcherTests.cc \
|
||||
tlFileUtilsTests.cc \
|
||||
tlHttpStreamTests.cc \
|
||||
tlIncludeTests.cc \
|
||||
tlIntervalMap.cc \
|
||||
tlIntervalSet.cc \
|
||||
tlKDTree.cc \
|
||||
tlMath.cc \
|
||||
tlObject.cc \
|
||||
tlReuseVector.cc \
|
||||
tlStableVector.cc \
|
||||
tlString.cc \
|
||||
tlThreadedWorkers.cc \
|
||||
tlThreads.cc \
|
||||
tlUtils.cc \
|
||||
tlVariant.cc \
|
||||
tlXMLParser.cc \
|
||||
tlInt128SupportTests.cc \
|
||||
tlIntervalMapTests.cc \
|
||||
tlIntervalSetTests.cc \
|
||||
tlKDTreeTests.cc \
|
||||
tlLongIntTests.cc \
|
||||
tlMathTests.cc \
|
||||
tlObjectTests.cc \
|
||||
tlReuseVectorTests.cc \
|
||||
tlStableVectorTests.cc \
|
||||
tlStreamTests.cc \
|
||||
tlWebDAV.cc \
|
||||
tlHttpStream.cc \
|
||||
tlInt128Support.cc \
|
||||
tlLongInt.cc \
|
||||
tlStringTests.cc \
|
||||
tlThreadedWorkersTests.cc \
|
||||
tlThreadsTests.cc \
|
||||
tlUniqueIdTests.cc \
|
||||
tlListTests.cc \
|
||||
tlEquivalenceClustersTests.cc \
|
||||
tlUniqueNameTests.cc \
|
||||
tlGlobPatternTests.cc \
|
||||
tlRecipeTests.cc \
|
||||
tlUriTests.cc
|
||||
tlUriTests.cc \
|
||||
tlUtilsTests.cc \
|
||||
tlVariantTests.cc \
|
||||
tlWebDAVTests.cc \
|
||||
tlXMLParserTests.cc
|
||||
|
||||
!equals(HAVE_QT, "0") {
|
||||
|
||||
SOURCES += \
|
||||
tlDeferredExecution.cc \
|
||||
tlFileSystemWatcher.cc \
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue