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