QGIS API Documentation 3.28.0-Firenze (ed3ad0430f)
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#include "qgsdatasourceuri.h"
23#include <QDir>
24#include <QNetworkRequest>
25#include <QUrlQuery>
26#include <QDomElement>
27
28//
29// QgsHttpHeaders
30//
31
32const QString QgsHttpHeaders::PATH_PREFIX = "http-header/";
33const QString QgsHttpHeaders::PARAM_PREFIX = "http-header:";
34const QString QgsHttpHeaders::KEY_REFERER = "referer";
35
37
38QgsHttpHeaders::QgsHttpHeaders( const QMap<QString, QVariant> &headers )
39 : mHeaders( headers )
40{
41 mHeaders.detach(); // clone like
42}
43
44QgsHttpHeaders::QgsHttpHeaders( const QgsSettings &settings, const QString &key )
45{
46 setFromSettings( settings, key );
47}
48
49QgsHttpHeaders::QgsHttpHeaders( const QString &key )
50{
52}
53
54QgsHttpHeaders::QgsHttpHeaders( const QDomElement &element )
55{
56 setFromDomElement( element );
57}
58
60
61bool QgsHttpHeaders::updateNetworkRequest( QNetworkRequest &request ) const
62{
63 for ( auto ite = mHeaders.constBegin(); ite != mHeaders.constEnd(); ++ite )
64 {
65 request.setRawHeader( ite.key().toUtf8(), ite.value().toString().toUtf8() );
66 }
67 return true;
68}
69
70bool QgsHttpHeaders::updateUrlQuery( QUrlQuery &uri ) const
71{
72 for ( auto ite = mHeaders.constBegin(); ite != mHeaders.constEnd(); ++ite )
73 {
74 uri.addQueryItem( QgsHttpHeaders::PARAM_PREFIX + ite.key().toUtf8(), ite.value().toString().toUtf8() );
75 }
76 return true;
77}
78
79bool QgsHttpHeaders::updateSettings( QgsSettings &settings, const QString &key ) const
80{
81 QString keyFixed = sanitizeKey( key );
82 if ( !keyFixed.isEmpty() )
83 keyFixed = keyFixed + "/";
84
85 QString keyHH = keyFixed + QgsHttpHeaders::PATH_PREFIX;
86 settings.remove( keyHH ); // cleanup
87 for ( auto ite = mHeaders.constBegin(); ite != mHeaders.constEnd(); ++ite )
88 {
89 settings.setValue( keyHH + ite.key(), ite.value() );
90 }
91
92 if ( !mHeaders[QgsHttpHeaders::KEY_REFERER].toString().isEmpty() && settings.contains( keyFixed + QgsHttpHeaders::KEY_REFERER ) ) // backward comptibility
93 {
94 settings.setValue( keyFixed + QgsHttpHeaders::KEY_REFERER, mHeaders[QgsHttpHeaders::KEY_REFERER].toString() );
95 }
96
97// TODO REMOVE!
98#if 0
99 QgsLogger::debug( QString( "updateSettings key: %1" ).arg( keyFixed ) );
100 for ( auto k : settings.allKeys() )
101 if ( k.startsWith( keyFixed ) )
102 QgsLogger::debug( QString( "updateSettings in settings: %1=%2" ).arg( k, settings.value( k ).toString() ) );
103#endif
104 return true;
105}
106
107bool QgsHttpHeaders::updateMap( QVariantMap &map ) const
108{
109 for ( auto ite = mHeaders.constBegin(); ite != mHeaders.constEnd(); ++ite )
110 {
111 map.insert( QgsHttpHeaders::PARAM_PREFIX + ite.key().toUtf8(), ite.value().toString() );
112 }
113
114 if ( mHeaders.contains( QgsHttpHeaders::KEY_REFERER ) )
115 {
116 map.insert( QgsHttpHeaders::KEY_REFERER, mHeaders[QgsHttpHeaders::KEY_REFERER].toString() );
117 }
118
119 return true;
120}
121
122bool QgsHttpHeaders::updateDomElement( QDomElement &el ) const
123{
124 for ( auto ite = mHeaders.constBegin(); ite != mHeaders.constEnd(); ++ite )
125 {
126 el.setAttribute( QgsHttpHeaders::PARAM_PREFIX + ite.key().toUtf8(), ite.value().toString() );
127 }
128
129 if ( mHeaders.contains( QgsHttpHeaders::KEY_REFERER ) )
130 {
131 el.setAttribute( QgsHttpHeaders::KEY_REFERER, mHeaders[QgsHttpHeaders::KEY_REFERER].toString() );
132 }
133
134 return true;
135}
136
137
138
139
140void QgsHttpHeaders::setFromSettings( const QgsSettings &settings, const QString &key )
141{
142 QString keyFixed = sanitizeKey( key );
143 if ( !keyFixed.isEmpty() )
144 keyFixed = keyFixed + "/";
145 QString keyHH = keyFixed + QgsHttpHeaders::PATH_PREFIX;
146
147#if 0
148 QgsLogger::debug( QString( "setFromSettings key: %1" ).arg( keyFixed ) );
149 for ( auto k : settings.allKeys() )
150 if ( k.startsWith( keyFixed ) )
151 QgsLogger::debug( QString( "setFromSettings called: %1=%2" ).arg( k, settings.value( k ).toString() ) );
152 QgsLogger::debug( QString( "setFromSettings keyHH: %1" ).arg( keyHH ) );
153#endif
154
155 QStringList keys = settings.allKeys();
156 for ( auto ite = keys.cbegin(); ite != keys.cend(); ++ite )
157 {
158 if ( ite->startsWith( keyHH ) )
159 {
160 QString name = ite->right( ite->size() - keyHH.size() );
161 mHeaders.insert( name, settings.value( *ite ).toString() );
162 }
163 }
164
165 if ( settings.contains( keyFixed + QgsHttpHeaders::KEY_REFERER ) ) // backward comptibility
166 {
167 mHeaders[QgsHttpHeaders::KEY_REFERER] = settings.value( keyFixed + QgsHttpHeaders::KEY_REFERER ).toString(); // retrieve value from old location
168 }
169
170#if 0
171 for ( auto k : mHeaders.keys() )
172 QgsLogger::debug( QString( "setFromSettings mHeaders[%1]=%2" ).arg( k, mHeaders[k].toString() ) );
173#endif
174}
175
176void QgsHttpHeaders::setFromUrlQuery( const QUrlQuery &uri )
177{
178 const auto constQueryItems = uri.queryItems( QUrl::ComponentFormattingOption::FullyDecoded );
179 for ( const QPair<QString, QString> &item : constQueryItems )
180 {
181 const QString &key = item.first;
182 if ( key.startsWith( QgsHttpHeaders::PARAM_PREFIX ) )
183 {
184 QString name = key.right( key.size() - QgsHttpHeaders::PARAM_PREFIX.size() );
185 mHeaders[sanitizeKey( name )] = item.second;
186 }
187 }
188}
189
190void QgsHttpHeaders::setFromMap( const QVariantMap &map )
191{
192 for ( auto ite = map.keyBegin(); ite != map.keyEnd(); ++ite )
193 {
194 QString key = *ite;
195 if ( key.startsWith( QgsHttpHeaders::PARAM_PREFIX ) )
196 {
197 QString name = key.right( key.size() - QgsHttpHeaders::PARAM_PREFIX.size() );
198 mHeaders[sanitizeKey( name )] = map [key].toString();
199 }
200 }
201
202 if ( map.contains( QgsHttpHeaders::KEY_REFERER ) ) // backward comptibility
203 {
204 mHeaders[QgsHttpHeaders::KEY_REFERER] = map [QgsHttpHeaders::KEY_REFERER].toString();
205 }
206}
207
208
209void QgsHttpHeaders::setFromDomElement( const QDomElement &el )
210{
211 QDomNamedNodeMap attribs = el.attributes();
212
213 for ( int i = 0; i < attribs.length(); i++ )
214 {
215 QDomNode item = attribs.item( i );
216 QString key = item.nodeName();
217 if ( key.startsWith( QgsHttpHeaders::PARAM_PREFIX ) )
218 {
219 QString name = key.right( key.size() - QgsHttpHeaders::PARAM_PREFIX.size() );
220 mHeaders[sanitizeKey( name )] = item.nodeValue();
221 }
222 }
223
224 if ( attribs.contains( QgsHttpHeaders::KEY_REFERER ) ) // backward comptibility
225 {
226 mHeaders[QgsHttpHeaders::KEY_REFERER] = attribs.namedItem( QgsHttpHeaders::KEY_REFERER ).nodeValue();
227 }
228
229}
230
232{
233 QString out;
234 for ( auto ite = mHeaders.constBegin(); ite != mHeaders.constEnd(); ++ite )
235 {
236 out += QStringLiteral( " %1%2='%3'" ).arg( QgsHttpHeaders::PARAM_PREFIX, ite.key(), ite.value().toString() );
237 }
238
239 if ( !mHeaders [ QgsHttpHeaders::KEY_REFERER ].toString().isEmpty() )
240 out += QStringLiteral( " %1='%2'" ).arg( QgsHttpHeaders::KEY_REFERER, mHeaders [QgsHttpHeaders::KEY_REFERER].toString() );
241
242 return out;
243}
244
245
246
247// To clean the path
248QString QgsHttpHeaders::sanitizeKey( const QString &key ) const
249{
250 QString out = QDir::cleanPath( key );
251 return out;
252}
253
254
255QVariant &QgsHttpHeaders::operator[]( const QString &key )
256{
257 return mHeaders[sanitizeKey( key )];
258}
259
260const QVariant QgsHttpHeaders::operator[]( const QString &key ) const
261{
262 return mHeaders[sanitizeKey( key )];
263}
264
265QgsHttpHeaders &QgsHttpHeaders::operator = ( const QMap<QString, QVariant> &headers )
266{
267 mHeaders = headers;
268 return *this;
269}
270
271QList<QString> QgsHttpHeaders::keys() const
272{
273 return mHeaders.keys();
274}
This class implements simple http header management.
bool updateDomElement(QDomElement &el) const
Updates a map 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.
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
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.
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.
void setFromMap(const QVariantMap &map)
Loads headers from the map.
QgsHttpHeaders()
default constructor
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
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:58
This class is a composition of two QSettings instances:
Definition: qgssettings.h:62
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.