30#include <fcgi_stdio.h>
32using namespace Qt::StringLiterals;
37 QString uri = getenv(
"REQUEST_URI" );
41 uri = getenv(
"SCRIPT_NAME" );
50 const QString qs = getenv(
"QUERY_STRING" );
51 const QString questionMark = qs.isEmpty() ? QString() : QChar(
'?' );
52 const QString extraPath = u
"%1%2%3"_s.arg( getenv(
"PATH_INFO" ) ).arg( questionMark ).arg( qs );
55 if ( uri.endsWith( extraPath ) )
57 baseUrl.setUrl( uri.left( uri.length() - extraPath.length() ) );
75 qDebug() <<
"fcgi query string: " <<
url.query();
81 const char *me = getenv(
"REQUEST_METHOD" );
85 if ( strcmp( me,
"POST" ) == 0 )
89 else if ( strcmp( me,
"PUT" ) == 0 )
93 else if ( strcmp( me,
"DELETE" ) == 0 )
97 else if ( strcmp( me,
"HEAD" ) == 0 )
101 else if ( strcmp( me,
"PATCH" ) == 0 )
122 .replace(
' '_L1,
'-'_L1 );
123 const char *result = getenv( u
"HTTP_%1"_s.arg( headerKey ).toStdString().c_str() );
124 if ( result && strlen( result ) > 0 )
134 printRequestInfos(
url );
138void QgsFcgiServerRequest::fillUrl( QUrl &url )
const
141 if (
url.host().isEmpty() )
143 url.setHost( getenv(
"SERVER_NAME" ) );
147 if (
url.port( -1 ) == -1 )
149 const QString portString = getenv(
"SERVER_PORT" );
150 if ( !portString.isEmpty() )
153 const int portNumber = portString.toInt( &portOk );
154 if ( portOk && portNumber != 80 )
156 url.setPort( portNumber );
162 if (
url.scheme().isEmpty() )
164 QString( getenv(
"HTTPS" ) ).compare(
"on"_L1, Qt::CaseInsensitive ) == 0
165 ?
url.setScheme( u
"https"_s )
166 :
url.setScheme( u
"http"_s );
176void QgsFcgiServerRequest::readData()
179 const char *lengthstr = getenv(
"CONTENT_LENGTH" );
182 bool success =
false;
183 const int length = QString( lengthstr ).toInt( &success );
184 if ( !success || length < 0 )
195 const char *requestBody = getenv(
"REQUEST_BODY" );
198 qDebug() <<
"fcgi: reading " << lengthstr <<
" bytes from " << ( requestBody ?
"REQUEST_BODY" :
"stdin" );
203 const size_t requestBodyLength = strlen( requestBody );
204 const int actualLength =
static_cast<int>( std::min<size_t>( length, requestBodyLength ) );
205 if (
static_cast<size_t>( actualLength ) < requestBodyLength )
210 mData = QByteArray::fromRawData( requestBody, actualLength );
214 mData.resize( length );
215 const int actualLength =
static_cast<int>( fread( mData.data(), 1, length, stdin ) );
216 if ( actualLength < length )
218 mData.resize( actualLength );
231void QgsFcgiServerRequest::printRequestInfos(
const QUrl &url )
const
235 const QStringList envVars {
252 u
"QGIS_PROJECT_FILE"_s,
253 u
"QGIS_SERVER_IGNORE_BAD_LAYERS"_s,
254 u
"QGIS_SERVER_SERVICE_URL"_s,
255 u
"QGIS_SERVER_WMS_SERVICE_URL"_s,
256 u
"QGIS_SERVER_WFS_SERVICE_URL"_s,
257 u
"QGIS_SERVER_WMTS_SERVICE_URL"_s,
258 u
"QGIS_SERVER_WCS_SERVICE_URL"_s,
266 for (
const auto &envVar : envVars )
268 if ( getenv( envVar.toStdString().c_str() ) )
274 qDebug() <<
"Headers:";
275 qDebug() <<
"------------------------------------------------";
276 const QMap<QString, QString> &hdrs =
headers();
277 for (
auto it = hdrs.constBegin(); it != hdrs.constEnd(); it++ )
279 qDebug() << it.key() <<
": " << it.value();
290 if ( result.isEmpty() )
292 result = qgetenv( u
"HTTP_%1"_s.arg( name.toUpper().replace(
'-'_L1,
'_'_L1 ) ).toStdString().c_str() );
MessageLevel
Level for messages This will be used both for message log and message bar in application.
@ Critical
Critical/error message.
@ Info
Information message.
@ TitleCase
Simple title case conversion - does not fully grammatically parse the text and uses simple rules only...
QString header(const QString &name) const override
Returns the header value.
QByteArray data() const override
Returns post/put data Check for QByteArray::isNull() to check if data is available.
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())
Adds a message to the log instance (and creates it if necessary).
static QgsServerLogger * instance()
Gets the singleton instance.
Qgis::MessageLevel logLevel() const
Gets the current log level.
void setOriginalUrl(const QUrl &url)
Set the request original url (the request url as seen by the web server).
Method
HTTP Method (or equivalent) used for the request.
virtual QString header(const QString &name) const
Returns the header value.
virtual void setUrl(const QUrl &url)
Set the request url.
QUrl url() const
Returns the request URL as seen by QGIS server.
QMap< QString, QString > headers() const
Returns the header map.
QUrl baseUrl() const
Returns the base URL of QGIS server.
QgsServerRequest::Method method() const
Returns the request method.
void setMethod(QgsServerRequest::Method method)
Set the request method.
void setBaseUrl(const QUrl &url)
Set the base URL of QGIS server.
void setHeader(const QString &name, const QString &value)
Set an header.
static QString capitalize(const QString &string, Qgis::Capitalization capitalization)
Converts a string by applying capitalization rules to the string.
const QMap< T, QString > qgsEnumMap()
Returns a map of all enum entries.