Skip to content

Commit

Permalink
[server] Fix URL rewrite from fcgi servers
Browse files Browse the repository at this point in the history
The URL exposed in the XML documents generated
by the server was wrong because instead of
using the original URL (from REQUEST_URI)
the rewritten query string (from QUERY_STRING)
was applied to the internal mUrl variable.

This patch also adds some tests for the
FCGI request, that handle most common
scenarios with bot rewritten and not
rewritten URLs.

QgsFcgiServerRequest is now exposed to
Python mainly for testability purposes.
  • Loading branch information
elpaso committed Jan 9, 2019
1 parent 2c8acf1 commit bb9ec39
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 54 deletions.
55 changes: 55 additions & 0 deletions python/server/auto_generated/qgsfcgiserverrequest.sip.in
@@ -0,0 +1,55 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/server/qgsfcgiserverrequest.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/





class QgsFcgiServerRequest: QgsServerRequest
{
%Docstring
Class defining fcgi request

.. versionadded:: 3.0
%End

%TypeHeaderCode
#include "qgsfcgiserverrequest.h"
%End
public:
QgsFcgiServerRequest();

virtual QByteArray data() const;


bool hasError() const;
%Docstring
Returns true if an error occurred during initialization
%End

virtual QUrl url() const;

%Docstring

:return: the request url

Subclasses may override in case the original URL needs to be
returned instead of the rewritten one (i.e. from a web server
rewrite module).
%End


};

/************************************************************************
* This file has been generated automatically from *
* *
* src/server/qgsfcgiserverrequest.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
6 changes: 5 additions & 1 deletion python/server/auto_generated/qgsserverrequest.sip.in
Expand Up @@ -56,10 +56,14 @@ Constructor

virtual ~QgsServerRequest();

QUrl url() const;
virtual QUrl url() const;
%Docstring

:return: the request url

Subclasses may override in case the original URL needs to be
returned instead of the rewritten one (i.e. from a web server
rewrite module).
%End

QgsServerRequest::Method method() const;
Expand Down
1 change: 1 addition & 0 deletions python/server/server_auto.sip
Expand Up @@ -8,6 +8,7 @@
%Include auto_generated/qgsserverparameters.sip
%Include auto_generated/qgsbufferserverrequest.sip
%Include auto_generated/qgsbufferserverresponse.sip
%Include auto_generated/qgsfcgiserverrequest.sip
%Include auto_generated/qgsrequesthandler.sip
%Include auto_generated/qgsserver.sip
%Include auto_generated/qgsserverexception.sip
Expand Down
84 changes: 35 additions & 49 deletions src/server/qgsfcgiserverrequest.cpp
Expand Up @@ -29,13 +29,11 @@

QgsFcgiServerRequest::QgsFcgiServerRequest()
{
mHasError = false;

// Rebuild the full URL

// Get the REQUEST_URI from the environment
QUrl url;
QString uri = getenv( "REQUEST_URI" );

if ( uri.isEmpty() )
{
uri = getenv( "SCRIPT_NAME" );
Expand Down Expand Up @@ -72,9 +70,12 @@ QgsFcgiServerRequest::QgsFcgiServerRequest()
: url.setScheme( QStringLiteral( "http" ) );
}

// XXX OGC paremetrs are passed with the query string
// we override the query string url in case it is
// defined independently of REQUEST_URI
// Store the URL before the server rewrite that could have been set in QUERY_STRING
mOriginalUrl = url;

// OGC parametrs are passed with the query string, which is normally part of
// the REQUEST_URI, we override the query string url in case it is defined
// independently of REQUEST_URI
const char *qs = getenv( "QUERY_STRING" );
if ( qs )
{
Expand Down Expand Up @@ -132,6 +133,11 @@ QByteArray QgsFcgiServerRequest::data() const
return mData;
}

QUrl QgsFcgiServerRequest::url() const
{
return mOriginalUrl;
}

// Read post put data
void QgsFcgiServerRequest::readData()
{
Expand Down Expand Up @@ -168,48 +174,28 @@ void QgsFcgiServerRequest::readData()
void QgsFcgiServerRequest::printRequestInfos()
{
QgsMessageLog::logMessage( QStringLiteral( "******************** New request ***************" ), QStringLiteral( "Server" ), Qgis::Info );
if ( getenv( "REMOTE_ADDR" ) )
{
QgsMessageLog::logMessage( "REMOTE_ADDR: " + QString( getenv( "REMOTE_ADDR" ) ), QStringLiteral( "Server" ), Qgis::Info );
}
if ( getenv( "REMOTE_HOST" ) )
{
QgsMessageLog::logMessage( "REMOTE_HOST: " + QString( getenv( "REMOTE_HOST" ) ), QStringLiteral( "Server" ), Qgis::Info );
}
if ( getenv( "REMOTE_USER" ) )
{
QgsMessageLog::logMessage( "REMOTE_USER: " + QString( getenv( "REMOTE_USER" ) ), QStringLiteral( "Server" ), Qgis::Info );
}
if ( getenv( "REMOTE_IDENT" ) )
{
QgsMessageLog::logMessage( "REMOTE_IDENT: " + QString( getenv( "REMOTE_IDENT" ) ), QStringLiteral( "Server" ), Qgis::Info );
}
if ( getenv( "CONTENT_TYPE" ) )
{
QgsMessageLog::logMessage( "CONTENT_TYPE: " + QString( getenv( "CONTENT_TYPE" ) ), QStringLiteral( "Server" ), Qgis::Info );
}
if ( getenv( "AUTH_TYPE" ) )
{
QgsMessageLog::logMessage( "AUTH_TYPE: " + QString( getenv( "AUTH_TYPE" ) ), QStringLiteral( "Server" ), Qgis::Info );
}
if ( getenv( "HTTP_USER_AGENT" ) )
{
QgsMessageLog::logMessage( "HTTP_USER_AGENT: " + QString( getenv( "HTTP_USER_AGENT" ) ), QStringLiteral( "Server" ), Qgis::Info );
}
if ( getenv( "HTTP_PROXY" ) )
{
QgsMessageLog::logMessage( "HTTP_PROXY: " + QString( getenv( "HTTP_PROXY" ) ), QStringLiteral( "Server" ), Qgis::Info );
}
if ( getenv( "HTTPS_PROXY" ) )
{
QgsMessageLog::logMessage( "HTTPS_PROXY: " + QString( getenv( "HTTPS_PROXY" ) ), QStringLiteral( "Server" ), Qgis::Info );
}
if ( getenv( "NO_PROXY" ) )
{
QgsMessageLog::logMessage( "NO_PROXY: " + QString( getenv( "NO_PROXY" ) ), QStringLiteral( "Server" ), Qgis::Info );
}
if ( getenv( "HTTP_AUTHORIZATION" ) )
{
QgsMessageLog::logMessage( "HTTP_AUTHORIZATION: " + QString( getenv( "HTTP_AUTHORIZATION" ) ), QStringLiteral( "Server" ), Qgis::Info );

const QStringList envVars
{
QStringLiteral( "SERVER_NAME" ),
QStringLiteral( "REQUEST_URI" ),
QStringLiteral( "REMOTE_ADDR" ),
QStringLiteral( "REMOTE_HOST" ),
QStringLiteral( "REMOTE_USER" ),
QStringLiteral( "REMOTE_IDENT" ),
QStringLiteral( "CONTENT_TYPE" ),
QStringLiteral( "AUTH_TYPE" ),
QStringLiteral( "HTTP_USER_AGENT" ),
QStringLiteral( "HTTP_PROXY" ),
QStringLiteral( "NO_PROXY" ),
QStringLiteral( "HTTP_AUTHORIZATION" )
};

for ( const auto &envVar : envVars )
{
if ( getenv( envVar.toStdString().c_str() ) )
{
QgsMessageLog::logMessage( envVar + QString( getenv( envVar.toStdString().c_str() ) ), QStringLiteral( "Server" ), Qgis::Info );
}
}
}
16 changes: 13 additions & 3 deletions src/server/qgsfcgiserverrequest.h
Expand Up @@ -19,8 +19,6 @@
#ifndef QGSFCGISERVERREQUEST_H
#define QGSFCGISERVERREQUEST_H

#define SIP_NO_FILE


#include "qgsserverrequest.h"

Expand All @@ -44,6 +42,16 @@ class SERVER_EXPORT QgsFcgiServerRequest: public QgsServerRequest
*/
bool hasError() const { return mHasError; }

/**
* \returns the request url
*
* Subclasses may override in case the original URL needs to be
* returned instead of the rewritten one (i.e. from a web server
* rewrite module).
*/
QUrl url() const override;


private:
void readData();

Expand All @@ -53,7 +61,9 @@ class SERVER_EXPORT QgsFcgiServerRequest: public QgsServerRequest


QByteArray mData;
bool mHasError;
bool mHasError = false;
//! Url before the server rewrite
QUrl mOriginalUrl;
};

#endif
6 changes: 5 additions & 1 deletion src/server/qgsserverrequest.h
Expand Up @@ -83,8 +83,12 @@ class SERVER_EXPORT QgsServerRequest

/**
* \returns the request url
*
* Subclasses may override in case the original URL needs to be
* returned instead of the rewritten one (i.e. from a web server
* rewrite module).
*/
QUrl url() const;
virtual QUrl url() const;

/**
* \returns the request method
Expand Down

0 comments on commit bb9ec39

Please sign in to comment.