QGIS API Documentation 4.1.0-Master (31622b25bb0)
Loading...
Searching...
No Matches
qgsrequesthandler.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgshttprequesthandler.cpp
3 -------------------------
4 begin : June 29, 2007
5 copyright : (C) 2007 by Marco Hugentobler
6 (C) 2014 by Alessandro Pasotti
7 email : marco dot hugentobler at karto dot baug dot ethz dot ch
8 a dot pasotti at itopen dot it
9 ***************************************************************************/
10
11/***************************************************************************
12 * *
13 * This program is free software; you can redistribute it and/or modify *
14 * it under the terms of the GNU General Public License as published by *
15 * the Free Software Foundation; either version 2 of the License, or *
16 * (at your option) any later version. *
17 * *
18 ***************************************************************************/
19
20#include "qgsrequesthandler.h"
21
22#include "qgis.h"
23#include "qgsmessagelog.h"
24#include "qgsserverrequest.h"
25#include "qgsserverresponse.h"
26
27#include <QByteArray>
28#include <QDomDocument>
29#include <QString>
30#include <QUrl>
31#include <QUrlQuery>
32
33using namespace Qt::StringLiterals;
34
36 : mRequest( request )
37 , mResponse( response )
38{}
39
40QMap<QString, QString> QgsRequestHandler::parameterMap() const
41{
42 return mRequest.parameters();
43}
44
46{
47 return mExceptionRaised;
48}
49
50void QgsRequestHandler::setResponseHeader( const QString &name, const QString &value )
51{
52 mResponse.setHeader( name, value );
53}
54
56{
57 mResponse.clear();
58}
59
60void QgsRequestHandler::removeResponseHeader( const QString &name )
61{
62 mResponse.removeHeader( name );
63}
64
65QString QgsRequestHandler::responseHeader( const QString &name ) const
66{
68 return mResponse.header( name );
70}
71
72QMap<QString, QString> QgsRequestHandler::responseHeaders() const
73{
75 return mResponse.headers();
77}
78
79QList<QString> QgsRequestHandler::fullResponseHeader( const QString &name ) const
80{
81 return mResponse.fullHeader( name );
82}
83
84QMap<QString, QList<QString> > QgsRequestHandler::fullResponseHeaders() const
85{
86 return mResponse.fullHeaders();
87}
88
89void QgsRequestHandler::setRequestHeader( const QString &name, const QString &value )
90{
91 mRequest.setHeader( name, value );
92}
93
94void QgsRequestHandler::removeRequestHeader( const QString &name )
95{
96 mRequest.removeHeader( name );
97}
98
99QString QgsRequestHandler::requestHeader( const QString &name ) const
100{
101 return mRequest.header( name );
102}
103
104
105QMap<QString, QString> QgsRequestHandler::requestHeaders() const
106{
107 return mRequest.headers();
108}
109
110
112{
113 return mResponse.headersSent();
114}
115
116void QgsRequestHandler::appendBody( const QByteArray &body )
117{
118 mResponse.write( body );
119}
120
122{
123 mResponse.truncate();
124}
125
126QByteArray QgsRequestHandler::body() const
127{
128 return mResponse.data();
129}
130
131QByteArray QgsRequestHandler::data() const
132{
133 return mRequest.data();
134}
135
137{
138 return mRequest.url().toString();
139}
140
142{
143 return mRequest.url().path();
144}
145
147{
148 mResponse.setStatusCode( code );
149}
150
152{
153 return mResponse.statusCode();
154}
155
157{
158 // Send data to output
159 mResponse.flush();
160}
161
163{
164 // Safety measure to avoid potential leaks if called repeatedly
165 mExceptionRaised = true;
166 mResponse.write( ex );
167}
168
169void QgsRequestHandler::setupParameters()
170{
171 const QgsServerRequest::Parameters parameters = mRequest.parameters();
172
173 //feature info format?
174 const QString infoFormat = parameters.value( u"INFO_FORMAT"_s );
175 if ( !infoFormat.isEmpty() )
176 {
177 mFormat = infoFormat;
178 }
179 else //capabilities format or GetMap format
180 {
181 mFormatString = parameters.value( u"FORMAT"_s );
182 QString formatString = mFormatString;
183 if ( !formatString.isEmpty() )
184 {
185 //remove the image/ in front of the format
186 if ( formatString.contains( "image/png"_L1, Qt::CaseInsensitive ) || formatString.compare( "png"_L1, Qt::CaseInsensitive ) == 0 )
187 {
188 formatString = u"PNG"_s;
189 }
190 else if ( formatString.contains( "image/jpeg"_L1, Qt::CaseInsensitive ) || formatString.contains( "image/jpg"_L1, Qt::CaseInsensitive ) || formatString.compare( "jpg"_L1, Qt::CaseInsensitive ) == 0 )
191 {
192 formatString = u"JPG"_s;
193 }
194 else if ( formatString.compare( "svg"_L1, Qt::CaseInsensitive ) == 0 )
195 {
196 formatString = u"SVG"_s;
197 }
198 else if ( formatString.contains( "pdf"_L1, Qt::CaseInsensitive ) )
199 {
200 formatString = u"PDF"_s;
201 }
202
203 mFormat = formatString;
204 }
205 }
206}
207
209{
210 if ( mRequest.method() == QgsServerRequest::PostMethod || mRequest.method() == QgsServerRequest::PutMethod || mRequest.method() == QgsServerRequest::PatchMethod )
211 {
212 if ( mRequest.header( u"Content-Type"_s ).contains( u"json"_s ) )
213 {
214 setupParameters();
215 }
216 else
217 {
218 QString inputString( mRequest.data() );
219 QDomDocument doc;
220 QString errorMsg;
221 int line = -1;
222 int column = -1;
223 if ( !doc.setContent( inputString, true, &errorMsg, &line, &column ) )
224 {
225 // Output Warning about POST without XML content
227 logMessage( u"Error parsing post data as XML: at line %1, column %2: %3. Assuming urlencoded query string sent in the post body."_s.arg( line ).arg( column ).arg( errorMsg ), u"Server"_s, Qgis::MessageLevel::Warning );
228
229 // Process input string as a simple query text
230
231 typedef QPair<QString, QString> pair_t;
232 const QUrlQuery query( inputString );
233 const QList<pair_t> items = query.queryItems();
234 for ( const pair_t &pair : items )
235 {
236 mRequest.setParameter( pair.first, pair.second );
237 }
238 setupParameters();
239 }
240 else
241 {
242 // we have an XML document
243
244 setupParameters();
245
246 const QDomElement docElem = doc.documentElement();
247 // the document element tag name is the request
248 mRequest.setParameter( u"REQUEST"_s, docElem.tagName() );
249 // loop through the attributes which are the parameters
250 // excepting the attributes started by xmlns or xsi
251 const QDomNamedNodeMap map = docElem.attributes();
252 for ( int i = 0; i < map.length(); ++i )
253 {
254 if ( map.item( i ).isNull() )
255 continue;
256
257 const QDomNode attrNode = map.item( i );
258 const QDomAttr attr = attrNode.toAttr();
259 if ( attr.isNull() )
260 continue;
261
262 const QString attrName = attr.name();
263 if ( attrName.startsWith( "xmlns" ) || attrName.startsWith( "xsi:" ) )
264 continue;
265
266 mRequest.setParameter( attrName.toUpper(), attr.value() );
267 }
268 mRequest.setParameter( u"REQUEST_BODY"_s, inputString.replace( '+', "%2B"_L1 ) );
269 }
270 }
271 }
272 else
273 {
274 setupParameters();
275 }
276}
277
278void QgsRequestHandler::setParameter( const QString &key, const QString &value )
279{
280 if ( !( key.isEmpty() || value.isEmpty() ) )
281 {
282 // Warn for potential breaking change if plugin set the MAP parameter
283 // expecting changing the config file path, see PR #9773
284 if ( key.compare( "MAP"_L1, Qt::CaseInsensitive ) == 0 )
285 {
286 QgsMessageLog::logMessage( u"Changing the 'MAP' parameter will have no effect on config path: use QgsSerververInterface::setConfigFilePath instead"_s, u"Server"_s, Qgis::MessageLevel::Warning );
287 }
288 mRequest.setParameter( key, value );
289 }
290}
291
292
293QString QgsRequestHandler::parameter( const QString &key ) const
294{
295 return mRequest.parameter( key );
296}
297
298void QgsRequestHandler::removeParameter( const QString &key )
299{
300 mRequest.removeParameter( key );
301}
@ Warning
Warning message.
Definition qgis.h:162
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true, const char *file=__builtin_FILE(), const char *function=__builtin_FUNCTION(), int line=__builtin_LINE(), Qgis::StringFormat format=Qgis::StringFormat::PlainText)
Adds a message to the log instance (and creates it if necessary).
void removeParameter(const QString &key)
Remove a request parameter.
void removeRequestHeader(const QString &name)
Remove an HTTP request header.
QString responseHeader(const QString &name) const
Retrieve response header value.
void clearBody()
Clear response buffer.
QString requestHeader(const QString &name) const
Retrieve request header value.
QMap< QString, QString > parameterMap() const
Returns the parsed parameters as a key-value pair.
QString path() const
Returns the path component of the request URL.
QByteArray data() const
Returns the request POST data (can be null).
bool exceptionRaised() const
Pointer to last raised exception.
bool headersSent() const
Returns true if the HTTP headers were already sent to the client.
void parseInput()
Parses the input and creates a request neutral Parameter/Value map.
void setServiceException(const QgsServerException &ex)
Allow plugins to return a QgsMapServiceException.
void removeResponseHeader(const QString &name)
Remove an HTTP response header.
void sendResponse()
Send out HTTP headers and flush output buffer.
Q_DECL_DEPRECATED QMap< QString, QString > responseHeaders() const
Returns the response headers: note that if multiple values are set for the same header,...
void setRequestHeader(const QString &name, const QString &value)
Sets an HTTP request header.
QMap< QString, QList< QString > > fullResponseHeaders() const
Returns the response headers as a map of header name to list of values (to support multiple values fo...
void appendBody(const QByteArray &body)
Sets the info format string such as "text/xml".
QString parameter(const QString &key) const
Returns a request parameter.
QMap< QString, QString > requestHeaders() const
Returns the Request headers.
QString url() const
Returns the request url.
void setStatusCode(int code)
Sets response http status code.
QgsRequestHandler(QgsServerRequest &request, QgsServerResponse &response)
Constructor.
QByteArray body() const
Returns the response body data.
void clear()
Clears the response body and headers.
void setResponseHeader(const QString &name, const QString &value)
Sets an HTTP response header.
int statusCode() const
Returns the response http status code.
void setParameter(const QString &key, const QString &value)
Sets a request parameter.
QList< QString > fullResponseHeader(const QString &name) const
Returns the list of response headers for a given header name.
Exception base class for server exceptions.
Defines requests passed to QgsService classes.
QgsServerRequest::Parameters parameters() const
Returns a map of query parameters with keys converted to uppercase.
QMap< QString, QString > Parameters
Defines the response interface passed to QgsService.
#define Q_NOWARN_DEPRECATED_POP
Definition qgis.h:7766
#define Q_NOWARN_DEPRECATED_PUSH
Definition qgis.h:7765