QGIS API Documentation 3.99.0-Master (8e76e220402)
Loading...
Searching...
No Matches
qgshttpheaders.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgshttpheaders.cpp
3 This class implements simple http header management.
4
5 -------------------
6 begin : 2021-09-09
7 copyright : (C) 2021 B. De Mezzo
8 email : benoit dot de dot mezzo at oslandia dot com
9
10***************************************************************************/
11
12/***************************************************************************
13 * *
14 * This program is free software; you can redistribute it and/or modify *
15 * it under the terms of the GNU General Public License as published by *
16 * the Free Software Foundation; either version 2 of the License, or *
17 * (at your option) any later version. *
18 * *
19 ***************************************************************************/
20
21#include "qgshttpheaders.h"
22
23#include "qgssettings.h"
24
25#include <QDir>
26#include <QDomElement>
27#include <QNetworkRequest>
28#include <QString>
29#include <QUrlQuery>
30
31using namespace Qt::StringLiterals;
32
33//
34// QgsHttpHeaders
35//
36
37const QString QgsHttpHeaders::PATH_PREFIX = "http-header/";
38const QString QgsHttpHeaders::PARAM_PREFIX = "http-header:";
39const QString QgsHttpHeaders::KEY_REFERER = "referer";
40
42
44 : mHeaders( headers )
45{
46 mHeaders.detach(); // clone like
47}
48
49QgsHttpHeaders::QgsHttpHeaders( const QgsSettings &settings, const QString &key )
50{
51 setFromSettings( settings, key );
52}
53
54QgsHttpHeaders::QgsHttpHeaders( const QString &key )
55{
57}
58
59QgsHttpHeaders::QgsHttpHeaders( const QDomElement &element )
60{
61 setFromDomElement( element );
62}
63
65
66bool QgsHttpHeaders::updateNetworkRequest( QNetworkRequest &request ) const
67{
68 for ( auto ite = mHeaders.constBegin(); ite != mHeaders.constEnd(); ++ite )
69 {
70 request.setRawHeader( ite.key().toUtf8(), ite.value().toString().toUtf8() );
71 }
72 return true;
73}
74
75bool QgsHttpHeaders::updateUrlQuery( QUrlQuery &uri ) const
76{
77 for ( auto ite = mHeaders.constBegin(); ite != mHeaders.constEnd(); ++ite )
78 {
79 uri.addQueryItem( QgsHttpHeaders::PARAM_PREFIX + ite.key().toUtf8(), QUrl::toPercentEncoding( ite.value().toString() ) );
80 }
81 return true;
82}
83
84bool QgsHttpHeaders::updateSettings( QgsSettings &settings, const QString &key ) const
85{
86 QString keyFixed = sanitizeKey( key );
87 if ( !keyFixed.isEmpty() )
88 keyFixed = keyFixed + "/";
89
90 QString keyHH = keyFixed + QgsHttpHeaders::PATH_PREFIX;
91 settings.remove( keyHH ); // cleanup
92 for ( auto ite = mHeaders.constBegin(); ite != mHeaders.constEnd(); ++ite )
93 {
94 settings.setValue( keyHH + ite.key(), ite.value() );
95 }
96
97 if ( !mHeaders[QgsHttpHeaders::KEY_REFERER].toString().isEmpty() && settings.contains( keyFixed + QgsHttpHeaders::KEY_REFERER ) ) // backward comptibility
98 {
99 settings.setValue( keyFixed + QgsHttpHeaders::KEY_REFERER, mHeaders[QgsHttpHeaders::KEY_REFERER].toString() );
100 }
101
102// TODO REMOVE!
103#if 0
104 QgsLogger::debug( QString( "updateSettings key: %1" ).arg( keyFixed ) );
105 for ( auto k : settings.allKeys() )
106 if ( k.startsWith( keyFixed ) )
107 QgsLogger::debug( QString( "updateSettings in settings: %1=%2" ).arg( k, settings.value( k ).toString() ) );
108#endif
109 return true;
110}
111
112bool QgsHttpHeaders::updateMap( QVariantMap &map ) const
113{
114 for ( auto ite = mHeaders.constBegin(); ite != mHeaders.constEnd(); ++ite )
115 {
116 map.insert( QgsHttpHeaders::PARAM_PREFIX + ite.key().toUtf8(), ite.value().toString() );
117 }
118
119 if ( mHeaders.contains( QgsHttpHeaders::KEY_REFERER ) )
120 {
121 map.insert( QgsHttpHeaders::KEY_REFERER, mHeaders[QgsHttpHeaders::KEY_REFERER].toString() );
122 }
123
124 return true;
125}
126
127bool QgsHttpHeaders::updateDomElement( QDomElement &el ) const
128{
129 QMap<QString, QString> namespaceDeclarations;
130 return updateDomElement( el, namespaceDeclarations );
131}
132
133bool QgsHttpHeaders::updateDomElement( QDomElement &el, QMap<QString, QString> &namespaceDeclarations ) const
134{
135 QString httpHeaderURIPrefix( QgsHttpHeaders::PARAM_PREFIX );
136 httpHeaderURIPrefix.chop( 1 );
137
138 for ( auto ite = mHeaders.constBegin(); ite != mHeaders.constEnd(); ++ite )
139 {
140 namespaceDeclarations.insert( httpHeaderURIPrefix, u"https://qgis.org/"_s + httpHeaderURIPrefix );
141 el.setAttribute( QgsHttpHeaders::PARAM_PREFIX + ite.key().toUtf8(), ite.value().toString() );
142 }
143
144 if ( mHeaders.contains( QgsHttpHeaders::KEY_REFERER ) )
145 {
146 el.setAttribute( QgsHttpHeaders::KEY_REFERER, mHeaders[QgsHttpHeaders::KEY_REFERER].toString() );
147 }
148
149 return true;
150}
151
152
153void QgsHttpHeaders::setFromSettings( const QgsSettings &settings, const QString &key )
154{
155 QString keyFixed = sanitizeKey( key );
156 if ( !keyFixed.isEmpty() )
157 keyFixed = keyFixed + "/";
158 QString keyHH = keyFixed + QgsHttpHeaders::PATH_PREFIX;
159
160#if 0
161 QgsLogger::debug( QString( "setFromSettings key: %1" ).arg( keyFixed ) );
162 for ( auto k : settings.allKeys() )
163 if ( k.startsWith( keyFixed ) )
164 QgsLogger::debug( QString( "setFromSettings called: %1=%2" ).arg( k, settings.value( k ).toString() ) );
165 QgsLogger::debug( QString( "setFromSettings keyHH: %1" ).arg( keyHH ) );
166#endif
167
168 QStringList keys = settings.allKeys();
169 for ( auto ite = keys.cbegin(); ite != keys.cend(); ++ite )
170 {
171 if ( ite->startsWith( keyHH ) )
172 {
173 QString name = ite->right( ite->size() - keyHH.size() );
174 mHeaders.insert( name, settings.value( *ite ).toString() );
175 }
176 }
177
178 if ( settings.contains( keyFixed + QgsHttpHeaders::KEY_REFERER ) ) // backward comptibility
179 {
180 mHeaders[QgsHttpHeaders::KEY_REFERER] = settings.value( keyFixed + QgsHttpHeaders::KEY_REFERER ).toString(); // retrieve value from old location
181 }
182
183#if 0
184 for ( auto k : mHeaders.keys() )
185 QgsLogger::debug( QString( "setFromSettings mHeaders[%1]=%2" ).arg( k, mHeaders[k].toString() ) );
186#endif
187}
188
189void QgsHttpHeaders::setFromUrlQuery( const QUrlQuery &uri )
190{
191 const auto constQueryItems = uri.queryItems( QUrl::ComponentFormattingOption::FullyDecoded );
192 for ( const QPair<QString, QString> &item : constQueryItems )
193 {
194 const QString &key = item.first;
195 if ( key.startsWith( QgsHttpHeaders::PARAM_PREFIX ) )
196 {
197 QString name = key.right( key.size() - QgsHttpHeaders::PARAM_PREFIX.size() );
198 mHeaders[sanitizeKey( name )] = item.second;
199 }
200 else if ( key == QgsHttpHeaders::KEY_REFERER ) // backward comptibility
201 {
202 mHeaders[QgsHttpHeaders::KEY_REFERER] = item.second;
203 }
204 }
205}
206
207void QgsHttpHeaders::setFromMap( const QVariantMap &map )
208{
209 for ( auto ite = map.keyBegin(); ite != map.keyEnd(); ++ite )
210 {
211 QString key = *ite;
212 if ( key.startsWith( QgsHttpHeaders::PARAM_PREFIX ) )
213 {
214 QString name = key.right( key.size() - QgsHttpHeaders::PARAM_PREFIX.size() );
215 mHeaders[sanitizeKey( name )] = map [key].toString();
216 }
217 }
218
219 if ( map.contains( QgsHttpHeaders::KEY_REFERER ) ) // backward comptibility
220 {
221 mHeaders[QgsHttpHeaders::KEY_REFERER] = map [QgsHttpHeaders::KEY_REFERER].toString();
222 }
223}
224
225
226void QgsHttpHeaders::setFromDomElement( const QDomElement &el )
227{
228 QDomNamedNodeMap attribs = el.attributes();
229
230 for ( int i = 0; i < attribs.length(); i++ )
231 {
232 QDomNode item = attribs.item( i );
233 QString key = item.nodeName();
234 if ( key.startsWith( QgsHttpHeaders::PARAM_PREFIX ) )
235 {
236 QString name = key.right( key.size() - QgsHttpHeaders::PARAM_PREFIX.size() );
237 mHeaders[sanitizeKey( name )] = item.nodeValue();
238 }
239 }
240
241 if ( attribs.contains( QgsHttpHeaders::KEY_REFERER ) ) // backward comptibility
242 {
243 mHeaders[QgsHttpHeaders::KEY_REFERER] = attribs.namedItem( QgsHttpHeaders::KEY_REFERER ).nodeValue();
244 }
245
246}
247
249{
250 QString out;
251 for ( auto ite = mHeaders.constBegin(); ite != mHeaders.constEnd(); ++ite )
252 {
253 out += u" %1%2='%3'"_s.arg( QgsHttpHeaders::PARAM_PREFIX, ite.key(), ite.value().toString() );
254 }
255
256 if ( !mHeaders [ QgsHttpHeaders::KEY_REFERER ].toString().isEmpty() )
257 out += u" %1='%2'"_s.arg( QgsHttpHeaders::KEY_REFERER, mHeaders [QgsHttpHeaders::KEY_REFERER].toString() );
258
259 return out;
260}
261
262
263
264// To clean the path
265QString QgsHttpHeaders::sanitizeKey( const QString &key ) const
266{
267 QString out = QDir::cleanPath( key );
268 return out;
269}
270
271
272QVariant &QgsHttpHeaders::operator[]( const QString &key )
273{
274 return mHeaders[sanitizeKey( key )];
275}
276
277const QVariant QgsHttpHeaders::operator[]( const QString &key ) const
278{
279 return mHeaders[sanitizeKey( key )];
280}
281
282QgsHttpHeaders &QgsHttpHeaders::operator = ( const QMap<QString, QVariant> &headers )
283{
284 mHeaders = headers;
285 return *this;
286}
287
288QList<QString> QgsHttpHeaders::keys() const
289{
290 return mHeaders.keys();
291}
292
293
294void QgsHttpHeaders::insert( const QString &key, const QVariant &val )
295{
296 QString k2 = key;
297
298 if ( k2.startsWith( QgsHttpHeaders::PARAM_PREFIX ) )
299 {
300 k2 = k2.right( k2.length() - QgsHttpHeaders::PARAM_PREFIX.length() );
301 }
302 mHeaders.insert( k2, val );
303}
304
306{
307 return mHeaders == other.mHeaders;
308}
309
311{
312 return !( *this == other );
313}
Q_DECL_DEPRECATED bool updateDomElement(QDomElement &el) const
Updates a DOM element by adding all the HTTP headers.
QString toSpacedString() const
Returns key/value pairs as strings separated by space.
QString sanitizeKey(const QString &key) const
Returns a cleansed key.
Q_DECL_DEPRECATED bool updateSettings(QgsSettings &settings, const QString &key=QString()) const
Updates the settings by adding all the http headers in the path "key/PATH_PREFIX/".
QList< QString > keys() const
Returns the list of all HTTP header keys.
static const QString PARAM_PREFIX
Used in uri to pass headers as params.
QgsHttpHeaders & operator=(const QMap< QString, QVariant > &headers)
static const QString KEY_REFERER
Used in settings as the referer key.
bool updateMap(QVariantMap &map) const
Updates a map by adding all the HTTP headers.
QVariantMap headers() const
Returns the headers as a variant map.
bool updateUrlQuery(QUrlQuery &uri) const
Updates an uri by adding all the HTTP headers.
bool updateNetworkRequest(QNetworkRequest &request) const
Updates a request by adding all the HTTP headers.
void setFromSettings(const QgsSettings &settings, const QString &key=QString())
Loads headers from the settings.
QgsHttpHeaders(const QVariantMap &headers)
Constructor from map.
void setFromMap(const QVariantMap &map)
Loads headers from the map.
void setFromUrlQuery(const QUrlQuery &uri)
Loads headers from the uri.
QVariant & operator[](const QString &key)
static const QString PATH_PREFIX
Used in settings as the group name.
void setFromDomElement(const QDomElement &element)
Loads headers from the element.
virtual ~QgsHttpHeaders()
default detructor
bool operator==(const QgsHttpHeaders &other) const
void insert(const QString &key, const QVariant &value)
insert a key with the specific value
bool operator!=(const QgsHttpHeaders &other) const
static void debug(const QString &msg, int debuglevel=1, const char *file=nullptr, const char *function=nullptr, int line=-1)
Goes to qDebug.
Definition qgslogger.cpp:62
Stores settings for use within QGIS.
Definition qgssettings.h:68
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
bool contains(const QString &key, QgsSettings::Section section=QgsSettings::NoSection) const
Returns true if there exists a setting called key; returns false otherwise.
void remove(const QString &key, QgsSettings::Section section=QgsSettings::NoSection)
Removes the setting key and any sub-settings of key in a section.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
QStringList allKeys() const
Returns a list of all keys, including subkeys, that can be read using the QSettings object.