QGIS API Documentation 3.99.0-Master (2fe06baccd8)
Loading...
Searching...
No Matches
qgsalgorithmhttprequest.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsalgorithmhttprequest.cpp
3 ---------------------
4 begin : September 2024
5 copyright : (C) 2024 by Dave Signer
6 email : david at opengis dot ch
7 ***************************************************************************/
8
9/***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
19
20#include "qgis.h"
23
24#include <QDesktopServices>
25#include <QMimeDatabase>
26#include <QNetworkRequest>
27#include <QUrl>
28#include <QUrlQuery>
29
30#include "moc_qgsalgorithmhttprequest.cpp"
31
33
34QString QgsHttpRequestAlgorithm::name() const
35{
36 return QStringLiteral( "httprequest" );
37}
38
39QString QgsHttpRequestAlgorithm::displayName() const
40{
41 return tr( "HTTP(S) POST/GET request" );
42}
43
44QString QgsHttpRequestAlgorithm::shortDescription() const
45{
46 return tr( "Performs a HTTP(S) POST/GET request and returns the result code, error message and the data." );
47}
48
49QStringList QgsHttpRequestAlgorithm::tags() const
50{
51 return tr( "open,url,internet,url,fetch,get,post,request,https,http,download" ).split( ',' );
52}
53
54QString QgsHttpRequestAlgorithm::group() const
55{
56 return tr( "File tools" );
57}
58
59QString QgsHttpRequestAlgorithm::groupId() const
60{
61 return QStringLiteral( "filetools" );
62}
63
64QString QgsHttpRequestAlgorithm::shortHelpString() const
65{
66 return tr( "This algorithm performs a HTTP(S) POST/GET request and returns the HTTP status code and the reply data.\n"
67 "If an error occurs then the error code and the message will be returned.\n\n"
68 "Optionally, the result can be written to a file on disk.\n\n"
69 "By default the algorithm will warn on errors. Optionally, the algorithm can be set to treat HTTP errors as failures." );
70}
71
72QgsHttpRequestAlgorithm *QgsHttpRequestAlgorithm::createInstance() const
73{
74 return new QgsHttpRequestAlgorithm();
75}
76
77void QgsHttpRequestAlgorithm::initAlgorithm( const QVariantMap & )
78{
79 addParameter( new QgsProcessingParameterString( QStringLiteral( "URL" ), tr( "URL" ), QVariant(), false, false ) );
80
81 auto methodParam = std::make_unique<QgsProcessingParameterEnum>(
82 QStringLiteral( "METHOD" ),
83 QObject::tr( "Method" ),
84 QStringList()
85 << QStringLiteral( "GET" )
86 << QStringLiteral( "POST" ),
87 false,
88 0
89 );
90 methodParam->setHelp( QObject::tr( "The HTTP method to use for the request" ) );
91 addParameter( methodParam.release() );
92
93 auto dataParam = std::make_unique<QgsProcessingParameterString>(
94 QStringLiteral( "DATA" ), tr( "POST data" ), QVariant(), false, true
95 );
96 dataParam->setHelp( QObject::tr( "The data to add in the body if the request is a POST" ) );
97 addParameter( dataParam.release() );
98
99 auto outputFileParam = std::make_unique<QgsProcessingParameterFileDestination>(
100 QStringLiteral( "OUTPUT" ), tr( "File destination" ), QObject::tr( "All files (*.*)" ), QVariant(), true, false
101 );
102 outputFileParam->setHelp( tr( "The result can be written to a file instead of being returned as a string" ) );
103 addParameter( outputFileParam.release() );
104
105 auto authConfigParam = std::make_unique<QgsProcessingParameterAuthConfig>(
106 QStringLiteral( "AUTH_CONFIG" ), tr( "Authentication" ), QVariant(), true
107 );
108 authConfigParam->setHelp( tr( "An authentication configuration to pass" ) );
109 addParameter( authConfigParam.release() );
110
111 auto failureParam = std::make_unique<QgsProcessingParameterBoolean>(
112 QStringLiteral( "FAIL_ON_ERROR" ), tr( "Consider HTTP errors as failures" ), false
113 );
114 failureParam->setHelp( tr( "If set, the algorithm will fail on encountering a HTTP error" ) );
115 addParameter( failureParam.release() );
116
117 addOutput( new QgsProcessingOutputNumber( QStringLiteral( "ERROR_CODE" ), QObject::tr( "Network error code" ) ) );
118 addOutput( new QgsProcessingOutputString( QStringLiteral( "ERROR_MESSAGE" ), QObject::tr( "Network error message" ) ) );
119 addOutput( new QgsProcessingOutputNumber( QStringLiteral( "STATUS_CODE" ), QObject::tr( "HTTP status code" ) ) );
120 addOutput( new QgsProcessingOutputString( QStringLiteral( "RESULT_DATA" ), QObject::tr( "Reply data" ) ) );
121}
122
123QVariantMap QgsHttpRequestAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
124{
125 const QString url = parameterAsString( parameters, QStringLiteral( "URL" ), context );
126 if ( url.isEmpty() )
127 throw QgsProcessingException( tr( "No URL specified" ) );
128 const Qgis::HttpMethod httpMethod = static_cast<Qgis::HttpMethod>( parameterAsEnum( parameters, QStringLiteral( "METHOD" ), context ) );
129 const QString data = parameterAsString( parameters, QStringLiteral( "DATA" ), context );
130 const QString authCfg = parameterAsString( parameters, QStringLiteral( "AUTH_CONFIG" ), context );
131 const QString outputFile = parameterAsFileOutput( parameters, QStringLiteral( "OUTPUT" ), context );
132 const bool failOnError = parameterAsBool( parameters, QStringLiteral( "FAIL_ON_ERROR" ), context );
133 const QUrl qurl = QUrl::fromUserInput( url );
134
135 // Make Request
136 QNetworkRequest request( qurl );
137 QgsBlockingNetworkRequest blockingRequest;
138 blockingRequest.setAuthCfg( authCfg );
140
141 switch ( httpMethod )
142 {
144 {
145 errorCode = blockingRequest.get( request );
146 break;
147 }
149 {
150 errorCode = blockingRequest.post( request, data.toUtf8() );
151 break;
152 }
153
157 throw QgsProcessingException( QObject::tr( "Unsupported HTTP method: %1" ).arg( qgsEnumValueToKey( httpMethod ) ) );
158 }
159
160 // Handle reply
161 const int statusCode = blockingRequest.reply().attribute( QNetworkRequest::HttpStatusCodeAttribute ).toInt();
162 QString errorMessage = QString();
163 QByteArray resultData = QByteArray();
164
165 if ( errorCode == QgsBlockingNetworkRequest::NoError )
166 {
167 feedback->pushInfo( tr( "Request succeeded with code %1" ).arg( statusCode ) );
168 resultData = blockingRequest.reply().content();
169
170 if ( !outputFile.isEmpty() )
171 {
172 QFile tempFile( outputFile );
173 if ( !tempFile.open( QIODevice::WriteOnly ) )
174 {
175 throw QgsProcessingException( QObject::tr( "Could not open %1 for writing" ).arg( outputFile ) );
176 }
177 tempFile.write( resultData );
178 tempFile.close();
179
180 feedback->pushInfo( tr( "Result data written to %1" ).arg( outputFile ) );
181 }
182 }
183 else
184 {
185 feedback->pushInfo( tr( "Request failed with code %1" ).arg( statusCode ) );
186 errorMessage = blockingRequest.reply().errorString();
187 if ( failOnError )
188 {
189 throw QgsProcessingException( errorMessage );
190 }
191 feedback->pushWarning( errorMessage );
192 }
193
194 QVariantMap outputs;
195 outputs.insert( QStringLiteral( "STATUS_CODE" ), statusCode );
196 outputs.insert( QStringLiteral( "ERROR_CODE" ), errorCode );
197 outputs.insert( QStringLiteral( "ERROR_MESSAGE" ), errorMessage );
198 outputs.insert( QStringLiteral( "RESULT_DATA" ), QString( resultData ) );
199 outputs.insert( QStringLiteral( "OUTPUT" ), outputFile );
200 return outputs;
201}
202
HttpMethod
Different methods of HTTP requests.
Definition qgis.h:1037
@ Post
POST method.
Definition qgis.h:1039
@ Head
HEAD method.
Definition qgis.h:1040
@ Get
GET method.
Definition qgis.h:1038
@ Put
PUT method.
Definition qgis.h:1041
@ Delete
DELETE method.
Definition qgis.h:1042
A thread safe class for performing blocking (sync) network requests, with full support for QGIS proxy...
ErrorCode post(QNetworkRequest &request, QIODevice *data, bool forceRefresh=false, QgsFeedback *feedback=nullptr)
Performs a "post" operation on the specified request, using the given data.
void setAuthCfg(const QString &authCfg)
Sets the authentication config id which should be used during the request.
ErrorCode get(QNetworkRequest &request, bool forceRefresh=false, QgsFeedback *feedback=nullptr, RequestFlags requestFlags=QgsBlockingNetworkRequest::RequestFlags())
Performs a "get" operation on the specified request.
@ NoError
No error was encountered.
QgsNetworkReplyContent reply() const
Returns the content of the network reply, after a get(), post(), head() or put() request has been mad...
QVariant attribute(QNetworkRequest::Attribute code) const
Returns the attribute associated with the code.
QString errorString() const
Returns the error text for the reply, or an empty string if no error was encountered.
QByteArray content() const
Returns the reply content.
Contains information about the context in which a processing algorithm is executed.
Custom exception class for processing related exceptions.
Base class for providing feedback from a processing algorithm.
virtual void pushInfo(const QString &info)
Pushes a general informational message from the algorithm.
virtual void pushWarning(const QString &warning)
Pushes a warning informational message from the algorithm.
A numeric output for processing algorithms.
A string output for processing algorithms.
A string parameter for processing algorithms.
QString qgsEnumValueToKey(const T &value, bool *returnOk=nullptr)
Returns the value for the given key of an enum.
Definition qgis.h:6798