QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
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 
32 const QString QgsHttpHeaders::PATH_PREFIX = "http-header/";
33 const QString QgsHttpHeaders::PARAM_PREFIX = "http-header:";
34 const QString QgsHttpHeaders::KEY_REFERER = "referer";
35 
37 
38 QgsHttpHeaders::QgsHttpHeaders( const QMap<QString, QVariant> &headers )
39  : mHeaders( headers )
40 {
41  mHeaders.detach(); // clone like
42 }
43 
44 QgsHttpHeaders::QgsHttpHeaders( const QgsSettings &settings, const QString &key )
45 {
46  setFromSettings( settings, key );
47 }
48 
49 QgsHttpHeaders::QgsHttpHeaders( const QString &key )
50 {
51  setFromSettings( QgsSettings(), key );
52 }
53 
54 QgsHttpHeaders::QgsHttpHeaders( const QDomElement &element )
55 {
56  setFromDomElement( element );
57 }
58 
60 
61 bool 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 
70 bool 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 
79 bool 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 
107 bool 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 
122 bool 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 
140 void 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 
176 void 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 
190 void 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 
209 void 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
248 QString QgsHttpHeaders::sanitizeKey( const QString &key ) const
249 {
250  QString out = QDir::cleanPath( key );
251  return out;
252 }
253 
254 
255 QVariant &QgsHttpHeaders::operator[]( const QString &key )
256 {
257  return mHeaders[sanitizeKey( key )];
258 }
259 
260 const QVariant QgsHttpHeaders::operator[]( const QString &key ) const
261 {
262  return mHeaders[sanitizeKey( key )];
263 }
264 
265 QgsHttpHeaders &QgsHttpHeaders::operator = ( const QMap<QString, QVariant> &headers )
266 {
267  mHeaders = headers;
268  return *this;
269 }
270 
271 QList<QString> QgsHttpHeaders::keys() const
272 {
273  return mHeaders.keys();
274 }
QgsSettings::remove
void remove(const QString &key, QgsSettings::Section section=QgsSettings::NoSection)
Removes the setting key and any sub-settings of key in a section.
Definition: qgssettings.cpp:192
QgsHttpHeaders::~QgsHttpHeaders
virtual ~QgsHttpHeaders()
default detructor
QgsSettings::value
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
Definition: qgssettings.cpp:161
QgsHttpHeaders::setFromSettings
void setFromSettings(const QgsSettings &settings, const QString &key=QString())
Loads headers from the settings.
Definition: qgshttpheaders.cpp:140
QgsHttpHeaders::updateNetworkRequest
bool updateNetworkRequest(QNetworkRequest &request) const
Updates a request by adding all the HTTP headers.
Definition: qgshttpheaders.cpp:61
QgsSettings::allKeys
QStringList allKeys() const
Returns a list of all keys, including subkeys, that can be read using the QSettings object.
Definition: qgssettings.cpp:113
QgsSettings
This class is a composition of two QSettings instances:
Definition: qgssettings.h:61
QgsHttpHeaders::operator=
QgsHttpHeaders & operator=(const QMap< QString, QVariant > &headers)
Definition: qgshttpheaders.cpp:265
QgsHttpHeaders::QgsHttpHeaders
QgsHttpHeaders()
default constructor
QgsHttpHeaders::toSpacedString
QString toSpacedString() const
Returns key/value pairs as strings separated by space.
Definition: qgshttpheaders.cpp:231
QgsHttpHeaders::PATH_PREFIX
static const QString PATH_PREFIX
Used in settings as the group name.
Definition: qgshttpheaders.h:45
qgshttpheaders.h
QgsHttpHeaders::updateMap
bool updateMap(QVariantMap &map) const
Updates a map by adding all the HTTP headers.
Definition: qgshttpheaders.cpp:107
QgsHttpHeaders::operator[]
QVariant & operator[](const QString &key)
Definition: qgshttpheaders.cpp:255
qgsdatasourceuri.h
QgsHttpHeaders::setFromUrlQuery
void setFromUrlQuery(const QUrlQuery &uri)
Loads headers from the uri.
Definition: qgshttpheaders.cpp:176
QgsHttpHeaders::KEY_REFERER
static const QString KEY_REFERER
Used in settings as the referer key.
Definition: qgshttpheaders.h:48
QgsHttpHeaders::updateSettings
bool updateSettings(QgsSettings &settings, const QString &key=QString()) const
Updates the settings by adding all the http headers in the path "key/PATH_PREFIX/".
Definition: qgshttpheaders.cpp:79
QgsSettings::setValue
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
Definition: qgssettings.cpp:279
QgsLogger::debug
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
QgsHttpHeaders::setFromMap
void setFromMap(const QVariantMap &map)
Loads headers from the map.
Definition: qgshttpheaders.cpp:190
QgsHttpHeaders::setFromDomElement
void setFromDomElement(const QDomElement &element)
Loads headers from the element.
Definition: qgshttpheaders.cpp:209
QgsHttpHeaders
This class implements simple http header management.
Definition: qgshttpheaders.h:38
QgsHttpHeaders::keys
QList< QString > keys() const
Definition: qgshttpheaders.cpp:271
QgsHttpHeaders::updateDomElement
bool updateDomElement(QDomElement &el) const
Updates a map by adding all the HTTP headers.
Definition: qgshttpheaders.cpp:122
QgsHttpHeaders::updateUrlQuery
bool updateUrlQuery(QUrlQuery &uri) const
Updates an uri by adding all the HTTP headers.
Definition: qgshttpheaders.cpp:70
QgsSettings::contains
bool contains(const QString &key, QgsSettings::Section section=QgsSettings::NoSection) const
Returns true if there exists a setting called key; returns false otherwise.
Definition: qgssettings.cpp:175
QgsHttpHeaders::sanitizeKey
QString sanitizeKey(const QString &key) const
Returns a cleansed key.
Definition: qgshttpheaders.cpp:248
QgsHttpHeaders::PARAM_PREFIX
static const QString PARAM_PREFIX
Used in uri to pass headers as params.
Definition: qgshttpheaders.h:51