QGIS API Documentation 3.99.0-Master (357b655ed83)
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 <QString>
28#include <QUrl>
29#include <QUrlQuery>
30
31#include "moc_qgsalgorithmhttprequest.cpp"
32
33using namespace Qt::StringLiterals;
34
36
37QString QgsHttpRequestAlgorithm::name() const
38{
39 return u"httprequest"_s;
40}
41
42QString QgsHttpRequestAlgorithm::displayName() const
43{
44 return tr( "HTTP(S) POST/GET request" );
45}
46
47QString QgsHttpRequestAlgorithm::shortDescription() const
48{
49 return tr( "Performs a HTTP(S) POST/GET request and returns the result code, error message and the data." );
50}
51
52QStringList QgsHttpRequestAlgorithm::tags() const
53{
54 return tr( "open,url,internet,url,fetch,get,post,request,https,http,download" ).split( ',' );
55}
56
57QString QgsHttpRequestAlgorithm::group() const
58{
59 return tr( "File tools" );
60}
61
62QString QgsHttpRequestAlgorithm::groupId() const
63{
64 return u"filetools"_s;
65}
66
67QString QgsHttpRequestAlgorithm::shortHelpString() const
68{
69 return tr( "This algorithm performs a HTTP(S) POST/GET request and returns the HTTP status code and the reply data.\n"
70 "If an error occurs then the error code and the message will be returned.\n\n"
71 "Optionally, the result can be written to a file on disk.\n\n"
72 "By default the algorithm will warn on errors. Optionally, the algorithm can be set to treat HTTP errors as failures." );
73}
74
75QgsHttpRequestAlgorithm *QgsHttpRequestAlgorithm::createInstance() const
76{
77 return new QgsHttpRequestAlgorithm();
78}
79
80void QgsHttpRequestAlgorithm::initAlgorithm( const QVariantMap & )
81{
82 addParameter( new QgsProcessingParameterString( u"URL"_s, tr( "URL" ), QVariant(), false, false ) );
83
84 auto methodParam = std::make_unique<QgsProcessingParameterEnum>(
85 u"METHOD"_s,
86 QObject::tr( "Method" ),
87 QStringList()
88 << u"GET"_s
89 << u"POST"_s,
90 false,
91 0
92 );
93 methodParam->setHelp( QObject::tr( "The HTTP method to use for the request" ) );
94 addParameter( methodParam.release() );
95
96 auto dataParam = std::make_unique<QgsProcessingParameterString>(
97 u"DATA"_s, tr( "POST data" ), QVariant(), false, true
98 );
99 dataParam->setHelp( QObject::tr( "The data to add in the body if the request is a POST" ) );
100 addParameter( dataParam.release() );
101
102 auto outputFileParam = std::make_unique<QgsProcessingParameterFileDestination>(
103 u"OUTPUT"_s, tr( "File destination" ), QObject::tr( "All files (*.*)" ), QVariant(), true, false
104 );
105 outputFileParam->setHelp( tr( "The result can be written to a file instead of being returned as a string" ) );
106 addParameter( outputFileParam.release() );
107
108 auto authConfigParam = std::make_unique<QgsProcessingParameterAuthConfig>(
109 u"AUTH_CONFIG"_s, tr( "Authentication" ), QVariant(), true
110 );
111 authConfigParam->setHelp( tr( "An authentication configuration to pass" ) );
112 addParameter( authConfigParam.release() );
113
114 auto failureParam = std::make_unique<QgsProcessingParameterBoolean>(
115 u"FAIL_ON_ERROR"_s, tr( "Consider HTTP errors as failures" ), false
116 );
117 failureParam->setHelp( tr( "If set, the algorithm will fail on encountering a HTTP error" ) );
118 addParameter( failureParam.release() );
119
120 addOutput( new QgsProcessingOutputNumber( u"ERROR_CODE"_s, QObject::tr( "Network error code" ) ) );
121 addOutput( new QgsProcessingOutputString( u"ERROR_MESSAGE"_s, QObject::tr( "Network error message" ) ) );
122 addOutput( new QgsProcessingOutputNumber( u"STATUS_CODE"_s, QObject::tr( "HTTP status code" ) ) );
123 addOutput( new QgsProcessingOutputString( u"RESULT_DATA"_s, QObject::tr( "Reply data" ) ) );
124}
125
126QVariantMap QgsHttpRequestAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
127{
128 const QString url = parameterAsString( parameters, u"URL"_s, context );
129 if ( url.isEmpty() )
130 throw QgsProcessingException( tr( "No URL specified" ) );
131 const Qgis::HttpMethod httpMethod = static_cast<Qgis::HttpMethod>( parameterAsEnum( parameters, u"METHOD"_s, context ) );
132 const QString data = parameterAsString( parameters, u"DATA"_s, context );
133 const QString authCfg = parameterAsString( parameters, u"AUTH_CONFIG"_s, context );
134 const QString outputFile = parameterAsFileOutput( parameters, u"OUTPUT"_s, context );
135 const bool failOnError = parameterAsBool( parameters, u"FAIL_ON_ERROR"_s, context );
136 const QUrl qurl = QUrl::fromUserInput( url );
137
138 // Make Request
139 QNetworkRequest request( qurl );
140 QgsBlockingNetworkRequest blockingRequest;
141 blockingRequest.setAuthCfg( authCfg );
143
144 switch ( httpMethod )
145 {
147 {
148 errorCode = blockingRequest.get( request );
149 break;
150 }
152 {
153 errorCode = blockingRequest.post( request, data.toUtf8() );
154 break;
155 }
156
160 throw QgsProcessingException( QObject::tr( "Unsupported HTTP method: %1" ).arg( qgsEnumValueToKey( httpMethod ) ) );
161 }
162
163 // Handle reply
164 const int statusCode = blockingRequest.reply().attribute( QNetworkRequest::HttpStatusCodeAttribute ).toInt();
165 QString errorMessage = QString();
166 QByteArray resultData = QByteArray();
167
168 if ( errorCode == QgsBlockingNetworkRequest::NoError )
169 {
170 feedback->pushInfo( tr( "Request succeeded with code %1" ).arg( statusCode ) );
171 resultData = blockingRequest.reply().content();
172
173 if ( !outputFile.isEmpty() )
174 {
175 QFile tempFile( outputFile );
176 if ( !tempFile.open( QIODevice::WriteOnly ) )
177 {
178 throw QgsProcessingException( QObject::tr( "Could not open %1 for writing" ).arg( outputFile ) );
179 }
180 tempFile.write( resultData );
181 tempFile.close();
182
183 feedback->pushInfo( tr( "Result data written to %1" ).arg( outputFile ) );
184 }
185 }
186 else
187 {
188 feedback->pushInfo( tr( "Request failed with code %1" ).arg( statusCode ) );
189 errorMessage = blockingRequest.reply().errorString();
190 if ( failOnError )
191 {
192 throw QgsProcessingException( errorMessage );
193 }
194 feedback->pushWarning( errorMessage );
195 }
196
197 QVariantMap outputs;
198 outputs.insert( u"STATUS_CODE"_s, statusCode );
199 outputs.insert( u"ERROR_CODE"_s, errorCode );
200 outputs.insert( u"ERROR_MESSAGE"_s, errorMessage );
201 outputs.insert( u"RESULT_DATA"_s, QString( resultData ) );
202 outputs.insert( u"OUTPUT"_s, outputFile );
203 return outputs;
204}
205
HttpMethod
Different methods of HTTP requests.
Definition qgis.h:1056
@ Post
POST method.
Definition qgis.h:1058
@ Head
HEAD method.
Definition qgis.h:1059
@ Get
GET method.
Definition qgis.h:1057
@ Put
PUT method.
Definition qgis.h:1060
@ Delete
DELETE method.
Definition qgis.h:1061
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:7126