Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Allow access to content of POST requests in QgsNetworkReplyContent
  • Loading branch information
nyalldawson committed Jan 25, 2019
1 parent 8120e4a commit 009ee57
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 4 deletions.
9 changes: 8 additions & 1 deletion python/core/auto_generated/qgsnetworkaccessmanager.sip.in
Expand Up @@ -30,7 +30,8 @@ Default constructor.

QgsNetworkRequestParameters( QNetworkAccessManager::Operation operation,
const QNetworkRequest &request,
int requestId );
int requestId,
const QByteArray &content = QByteArray() );
%Docstring
Constructor for QgsNetworkRequestParameters, with the specified network
``operation`` and original ``request``.
Expand All @@ -57,6 +58,12 @@ Returns a string identifying the thread which the request originated from.
int requestId() const;
%Docstring
Returns a unique ID identifying the request.
%End

QByteArray content() const;
%Docstring
Returns the request's content. This is only used for POST or PUT operation
requests.
%End

};
Expand Down
11 changes: 9 additions & 2 deletions src/core/qgsnetworkaccessmanager.cpp
Expand Up @@ -32,6 +32,7 @@

#include <QUrl>
#include <QTimer>
#include <QBuffer>
#include <QNetworkReply>
#include <QThreadStorage>
#include <QAuthenticator>
Expand Down Expand Up @@ -206,8 +207,13 @@ QNetworkReply *QgsNetworkAccessManager::createRequest( QNetworkAccessManager::Op

static QAtomicInt sRequestId = 0;
const int requestId = ++sRequestId;
QByteArray content;
if ( QBuffer *buffer = qobject_cast<QBuffer *>( outgoingData ) )
{
content = buffer->buffer();
}

emit requestAboutToBeCreated( QgsNetworkRequestParameters( op, req, requestId ) );
emit requestAboutToBeCreated( QgsNetworkRequestParameters( op, req, requestId, content ) );
Q_NOWARN_DEPRECATED_PUSH
emit requestAboutToBeCreated( op, req, outgoingData );
Q_NOWARN_DEPRECATED_POP
Expand Down Expand Up @@ -423,10 +429,11 @@ void QgsNetworkAccessManager::setupDefaultProxyAndCache( Qt::ConnectionType conn
// QgsNetworkRequestParameters
//

QgsNetworkRequestParameters::QgsNetworkRequestParameters( QNetworkAccessManager::Operation operation, const QNetworkRequest &request, int requestId )
QgsNetworkRequestParameters::QgsNetworkRequestParameters( QNetworkAccessManager::Operation operation, const QNetworkRequest &request, int requestId, const QByteArray &content )
: mOperation( operation )
, mRequest( request )
, mOriginatingThreadId( QStringLiteral( "0x%2" ).arg( reinterpret_cast<quintptr>( QThread::currentThread() ), 2 * QT_POINTER_SIZE, 16, QLatin1Char( '0' ) ) )
, mRequestId( requestId )
, mContent( content )
{
}
10 changes: 9 additions & 1 deletion src/core/qgsnetworkaccessmanager.h
Expand Up @@ -50,7 +50,8 @@ class CORE_EXPORT QgsNetworkRequestParameters
*/
QgsNetworkRequestParameters( QNetworkAccessManager::Operation operation,
const QNetworkRequest &request,
int requestId );
int requestId,
const QByteArray &content = QByteArray() );

/**
* Returns the request operation, e.g. GET or POST.
Expand All @@ -75,12 +76,19 @@ class CORE_EXPORT QgsNetworkRequestParameters
*/
int requestId() const { return mRequestId; }

/**
* Returns the request's content. This is only used for POST or PUT operation
* requests.
*/
QByteArray content() const { return mContent; }

private:

QNetworkAccessManager::Operation mOperation;
QNetworkRequest mRequest;
QString mOriginatingThreadId;
int mRequestId = 0;
QByteArray mContent;
};

/**
Expand Down
39 changes: 39 additions & 0 deletions tests/src/core/testqgsnetworkaccessmanager.cpp
Expand Up @@ -59,6 +59,7 @@ class TestQgsNetworkAccessManager : public QObject
void fetchEmptyUrl(); //test fetching blank url
void fetchBadUrl(); //test fetching bad url
void fetchEncodedContent(); //test fetching url content encoded as utf-8
void fetchPost();
void fetchBadSsl();
void fetchTimeout();

Expand Down Expand Up @@ -235,6 +236,44 @@ void TestQgsNetworkAccessManager::fetchEncodedContent()
thread->deleteLater();
}

void TestQgsNetworkAccessManager::fetchPost()
{
if ( QgsTest::isTravis() )
QSKIP( "This test is disabled on Travis CI environment" );

QObject context;
//test fetching from a blank url
bool loaded = false;
bool gotRequestAboutToBeCreatedSignal = false;
int requestId = -1;
QUrl u = QUrl::fromLocalFile( QStringLiteral( TEST_DATA_DIR ) + '/' + "encoded_html.html" );
connect( QgsNetworkAccessManager::instance(), qgis::overload< QgsNetworkRequestParameters >::of( &QgsNetworkAccessManager::requestAboutToBeCreated ), &context, [&]( const QgsNetworkRequestParameters & params )
{
gotRequestAboutToBeCreatedSignal = true;
requestId = params.requestId();
QVERIFY( requestId > 0 );
QCOMPARE( params.operation(), QNetworkAccessManager::GetOperation );
QCOMPARE( params.request().url(), u );
QCOMPARE( params.content(), QByteArray( "a=b&c=d" ) );
} );
connect( QgsNetworkAccessManager::instance(), qgis::overload< QgsNetworkReplyContent >::of( &QgsNetworkAccessManager::finished ), &context, [&]( const QgsNetworkReplyContent & reply )
{
QCOMPARE( reply.error(), QNetworkReply::NoError );
QCOMPARE( reply.requestId(), requestId );
QVERIFY( reply.rawHeaderList().contains( "Content-Length" ) );
QCOMPARE( reply.request().url(), u );
loaded = true;
} );
QgsNetworkAccessManager::instance()->post( QNetworkRequest( u ), QByteArray( "a=b&c=d" ) );

while ( !loaded )
{
qApp->processEvents();
}

QVERIFY( gotRequestAboutToBeCreatedSignal );
}

void TestQgsNetworkAccessManager::fetchBadSsl()
{
if ( QgsTest::isTravis() )
Expand Down

0 comments on commit 009ee57

Please sign in to comment.