mirror of
https://github.com/qgis/QGIS.git
synced 2025-02-25 00:58:06 -05:00
Support requests with http post. Up to now, only SOAP requests over HTTP POST have been supported
This commit is contained in:
parent
d750abfa2b
commit
783b30e87d
@ -24,6 +24,7 @@ SET ( qgis_mapserv_SRCS
|
||||
qgsprojectparser.cpp
|
||||
qgshttprequesthandler.cpp
|
||||
qgsgetrequesthandler.cpp
|
||||
qgspostrequesthandler.cpp
|
||||
qgssoaprequesthandler.cpp
|
||||
qgssldparser.cpp
|
||||
qgssldrenderer.cpp
|
||||
|
@ -21,6 +21,7 @@ map service syntax for SOAP/HTTP POST
|
||||
#include "qgscapabilitiescache.h"
|
||||
#include "qgsconfigcache.h"
|
||||
#include "qgsgetrequesthandler.h"
|
||||
#include "qgspostrequesthandler.h"
|
||||
#include "qgssoaprequesthandler.h"
|
||||
#include "qgsproviderregistry.h"
|
||||
#include "qgslogger.h"
|
||||
@ -206,8 +207,9 @@ int main( int argc, char * argv[] )
|
||||
{
|
||||
if ( strcmp( requestMethod, "POST" ) == 0 )
|
||||
{
|
||||
QgsDebugMsg( "Creating QgsSOAPRequestHandler" );
|
||||
theRequestHandler = new QgsSOAPRequestHandler();
|
||||
//QgsDebugMsg( "Creating QgsSOAPRequestHandler" );
|
||||
//theRequestHandler = new QgsSOAPRequestHandler();
|
||||
theRequestHandler = new QgsPostRequestHandler();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1,16 +1,9 @@
|
||||
#include "qgsgetrequesthandler.h"
|
||||
#include "qgsftptransaction.h"
|
||||
#include "qgslogger.h"
|
||||
#include "qgsmapserviceexception.h"
|
||||
#include "qgsremotedatasourcebuilder.h"
|
||||
#include "qgshttptransaction.h"
|
||||
#include <QBuffer>
|
||||
#include <QDomDocument>
|
||||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
#include <QImage>
|
||||
#include <QStringList>
|
||||
#include <QUrl>
|
||||
#include <stdlib.h>
|
||||
|
||||
QgsGetRequestHandler::QgsGetRequestHandler(): QgsHttpRequestHandler()
|
||||
{
|
||||
@ -18,8 +11,9 @@ QgsGetRequestHandler::QgsGetRequestHandler(): QgsHttpRequestHandler()
|
||||
|
||||
std::map<QString, QString> QgsGetRequestHandler::parseInput()
|
||||
{
|
||||
std::map<QString, QString> parameters;
|
||||
QString queryString;
|
||||
std::map<QString, QString> parameters;
|
||||
|
||||
const char* qs = getenv( "QUERY_STRING" );
|
||||
if ( qs )
|
||||
{
|
||||
@ -32,282 +26,6 @@ std::map<QString, QString> QgsGetRequestHandler::parseInput()
|
||||
return parameters; //no query string? something must be wrong...
|
||||
}
|
||||
|
||||
//parameters are separated by &
|
||||
QStringList elements = queryString.split( "&" );
|
||||
|
||||
QString element, key, value;
|
||||
|
||||
//insert key and value into the map
|
||||
for ( QStringList::const_iterator it = elements.begin(); it != elements.end(); ++it )
|
||||
{
|
||||
element = *it;
|
||||
int sepidx = element.indexOf( "=", 0, Qt::CaseSensitive );
|
||||
if ( sepidx == -1 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
key = element.left( sepidx );
|
||||
value = element.mid( sepidx + 1 );
|
||||
value = QUrl::fromPercentEncoding( value.toLocal8Bit() ); //replace encoded special caracters and utf-8 encodings
|
||||
|
||||
|
||||
if ( key.compare( "SLD_BODY", Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
key = "SLD";
|
||||
}
|
||||
else if ( key.compare( "SLD", Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
QByteArray fileContents;
|
||||
if ( value.startsWith( "http", Qt::CaseInsensitive ) )
|
||||
{
|
||||
QgsHttpTransaction http( value );
|
||||
if ( !http.getSynchronously( fileContents ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if ( value.startsWith( "ftp", Qt::CaseInsensitive ) )
|
||||
{
|
||||
QgsFtpTransaction ftp;
|
||||
if ( !ftp.get( value, fileContents ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
value = QUrl::fromPercentEncoding( fileContents );
|
||||
}
|
||||
else
|
||||
{
|
||||
continue; //only http and ftp supported at the moment
|
||||
}
|
||||
value = QUrl::fromPercentEncoding( fileContents );
|
||||
|
||||
}
|
||||
parameters.insert( std::make_pair( key.toUpper(), value ) );
|
||||
QgsDebugMsg( "inserting pair " + key.toUpper() + " // " + value + " into the parameter map" );
|
||||
}
|
||||
|
||||
//feature info format?
|
||||
std::map<QString, QString>::const_iterator info_format_it = parameters.find( "INFO_FORMAT" );
|
||||
if ( info_format_it != parameters.end() )
|
||||
{
|
||||
mFormat = info_format_it->second;
|
||||
}
|
||||
else //capabilities format or GetMap format
|
||||
{
|
||||
std::map<QString, QString>::const_iterator formatIt = parameters.find( "FORMAT" );
|
||||
if ( formatIt != parameters.end() )
|
||||
{
|
||||
QString formatString = formatIt->second;
|
||||
|
||||
QgsDebugMsg( QString( "formatString is: %1" ).arg( formatString ) );
|
||||
|
||||
//remove the image/ in front of the format
|
||||
if ( formatString.compare( "image/png", Qt::CaseInsensitive ) == 0 || formatString.compare( "png", Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
formatString = "PNG";
|
||||
}
|
||||
else if ( formatString.compare( "image/jpeg", Qt::CaseInsensitive ) == 0 || formatString.compare( "image/jpg", Qt::CaseInsensitive ) == 0 \
|
||||
|| formatString.compare( "jpg", Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
formatString = "JPG";
|
||||
}
|
||||
else if ( formatString.compare( "svg", Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
formatString = "SVG";
|
||||
}
|
||||
else if ( formatString.compare( "pdf", Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
formatString = "PDF";
|
||||
}
|
||||
|
||||
mFormat = formatString;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
requestStringToParameterMap( queryString, parameters );
|
||||
return parameters;
|
||||
}
|
||||
|
||||
void QgsGetRequestHandler::sendGetMapResponse( const QString& service, QImage* img ) const
|
||||
{
|
||||
Q_UNUSED( service );
|
||||
if ( img )
|
||||
{
|
||||
if ( mFormat != "PNG" && mFormat != "JPG" )
|
||||
{
|
||||
sendServiceException( QgsMapServiceException( "InvalidFormat", "Output format '" + mFormat + "' is not supported in the GetMap request" ) );
|
||||
return;
|
||||
}
|
||||
|
||||
//store the image in a QByteArray and send it directly
|
||||
QByteArray ba;
|
||||
QBuffer buffer( &ba );
|
||||
buffer.open( QIODevice::WriteOnly );
|
||||
img->save( &buffer, mFormat.toLocal8Bit().data(), -1 );
|
||||
|
||||
sendHttpResponse( &ba, formatToMimeType( mFormat ) );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsGetRequestHandler::sendGetCapabilitiesResponse( const QDomDocument& doc ) const
|
||||
{
|
||||
QByteArray ba = doc.toByteArray();
|
||||
sendHttpResponse( &ba, "text/xml" );
|
||||
}
|
||||
|
||||
void QgsGetRequestHandler::sendGetStyleResponse( const QDomDocument& doc ) const
|
||||
{
|
||||
QByteArray ba = doc.toByteArray();
|
||||
sendHttpResponse( &ba, "text/xml" );
|
||||
}
|
||||
|
||||
void QgsGetRequestHandler::sendGetFeatureInfoResponse( const QDomDocument& infoDoc, const QString& infoFormat ) const
|
||||
{
|
||||
QByteArray ba;
|
||||
QgsDebugMsg( "Info format is:" + infoFormat );
|
||||
|
||||
if ( infoFormat == "text/xml" )
|
||||
{
|
||||
ba = infoDoc.toByteArray();
|
||||
}
|
||||
else if ( infoFormat == "text/plain" || infoFormat == "text/html" )
|
||||
{
|
||||
//create string
|
||||
QString featureInfoString;
|
||||
|
||||
if ( infoFormat == "text/plain" )
|
||||
{
|
||||
featureInfoString.append( "GetFeatureInfo results\n" );
|
||||
featureInfoString.append( "\n" );
|
||||
}
|
||||
else if ( infoFormat == "text/html" )
|
||||
{
|
||||
featureInfoString.append( "<HEAD>\n" );
|
||||
featureInfoString.append( "<TITLE> GetFeatureInfo results </TITLE>\n" );
|
||||
featureInfoString.append( "<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\">\n" );
|
||||
featureInfoString.append( "</HEAD>\n" );
|
||||
featureInfoString.append( "<BODY>\n" );
|
||||
}
|
||||
|
||||
QDomNodeList layerList = infoDoc.elementsByTagName( "Layer" );
|
||||
|
||||
//layer loop
|
||||
for ( int i = 0; i < layerList.size(); ++i )
|
||||
{
|
||||
QDomElement layerElem = layerList.at( i ).toElement();
|
||||
if ( infoFormat == "text/plain" )
|
||||
{
|
||||
featureInfoString.append( "Layer '" + layerElem.attribute( "name" ) + "'\n" );
|
||||
}
|
||||
else if ( infoFormat == "text/html" )
|
||||
{
|
||||
featureInfoString.append( "<TABLE border=1 width=100%>\n" );
|
||||
featureInfoString.append( "<TR><TH width=25%>Layer</TH><TD>" + layerElem.attribute( "name" ) + "</TD></TR>\n" );
|
||||
featureInfoString.append( "</BR>" );
|
||||
}
|
||||
|
||||
//feature loop (for vector layers)
|
||||
QDomNodeList featureNodeList = layerElem.elementsByTagName( "Feature" );
|
||||
QDomElement currentFeatureElement;
|
||||
|
||||
if ( featureNodeList.size() < 1 ) //raster layer?
|
||||
{
|
||||
QDomNodeList attributeNodeList = layerElem.elementsByTagName( "Attribute" );
|
||||
for ( int j = 0; j < attributeNodeList.size(); ++j )
|
||||
{
|
||||
QDomElement attributeElement = attributeNodeList.at( j ).toElement();
|
||||
if ( infoFormat == "text/plain" )
|
||||
{
|
||||
featureInfoString.append( attributeElement.attribute( "name" ) + " = '" +
|
||||
attributeElement.attribute( "value" ) + "'\n" );
|
||||
}
|
||||
else if ( infoFormat == "text/html" )
|
||||
{
|
||||
featureInfoString.append( "<TR><TH>" + attributeElement.attribute( "name" ) + "</TH><TD>" +
|
||||
attributeElement.attribute( "value" ) + "</TD></TR>\n" );
|
||||
}
|
||||
}
|
||||
}
|
||||
else //vector layer
|
||||
{
|
||||
for ( int j = 0; j < featureNodeList.size(); ++j )
|
||||
{
|
||||
QDomElement featureElement = featureNodeList.at( j ).toElement();
|
||||
if ( infoFormat == "text/plain" )
|
||||
{
|
||||
featureInfoString.append( "Feature " + featureElement.attribute( "id" ) + "\n" );
|
||||
}
|
||||
else if ( infoFormat == "text/html" )
|
||||
{
|
||||
featureInfoString.append( "<TABLE border=1 width=100%>\n" );
|
||||
featureInfoString.append( "<TR><TH>Feature</TH><TD>" + featureElement.attribute( "id" ) + "</TD></TR>\n" );
|
||||
}
|
||||
//attribute loop
|
||||
QDomNodeList attributeNodeList = featureElement.elementsByTagName( "Attribute" );
|
||||
for ( int k = 0; k < attributeNodeList.size(); ++k )
|
||||
{
|
||||
QDomElement attributeElement = attributeNodeList.at( k ).toElement();
|
||||
if ( infoFormat == "text/plain" )
|
||||
{
|
||||
featureInfoString.append( attributeElement.attribute( "name" ) + " = '" +
|
||||
attributeElement.attribute( "value" ) + "'\n" );
|
||||
}
|
||||
else if ( infoFormat == "text/html" )
|
||||
{
|
||||
featureInfoString.append( "<TR><TH>" + attributeElement.attribute( "name" ) + "</TH><TD>" + attributeElement.attribute( "value" ) + "</TD></TR>\n" );
|
||||
}
|
||||
}
|
||||
|
||||
if ( infoFormat == "text/html" )
|
||||
{
|
||||
featureInfoString.append( "</TABLE>\n</BR>\n" );
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( infoFormat == "text/plain" )
|
||||
{
|
||||
featureInfoString.append( "\n" );
|
||||
}
|
||||
else if ( infoFormat == "text/html" )
|
||||
{
|
||||
featureInfoString.append( "</TABLE>\n<BR></BR>\n" );
|
||||
|
||||
}
|
||||
}
|
||||
if ( infoFormat == "text/html" )
|
||||
{
|
||||
featureInfoString.append( "</BODY>\n" );
|
||||
}
|
||||
ba = featureInfoString.toUtf8();
|
||||
}
|
||||
else //unsupported format, send exception
|
||||
{
|
||||
//todo: send service exception
|
||||
}
|
||||
|
||||
sendHttpResponse( &ba, infoFormat );
|
||||
}
|
||||
|
||||
void QgsGetRequestHandler::sendServiceException( const QgsMapServiceException& ex ) const
|
||||
{
|
||||
//create Exception DOM document
|
||||
QDomDocument exceptionDoc;
|
||||
QDomElement serviceExceptionReportElem = exceptionDoc.createElement( "ServiceExceptionReport" );
|
||||
serviceExceptionReportElem.setAttribute( "version", "1.3.0" );
|
||||
serviceExceptionReportElem.setAttribute( "xmlns", "http://www.opengis.net/ogc" );
|
||||
exceptionDoc.appendChild( serviceExceptionReportElem );
|
||||
QDomElement serviceExceptionElem = exceptionDoc.createElement( "ServiceException" );
|
||||
serviceExceptionElem.setAttribute( "code", ex.code() );
|
||||
QDomText messageText = exceptionDoc.createTextNode( ex.message() );
|
||||
serviceExceptionElem.appendChild( messageText );
|
||||
serviceExceptionReportElem.appendChild( serviceExceptionElem );
|
||||
|
||||
QByteArray ba = exceptionDoc.toByteArray();
|
||||
sendHttpResponse( &ba, "text/xml" );
|
||||
}
|
||||
|
||||
void QgsGetRequestHandler::sendGetPrintResponse( QByteArray* ba ) const
|
||||
{
|
||||
sendHttpResponse( ba, formatToMimeType( mFormat ) );
|
||||
}
|
||||
|
@ -23,11 +23,4 @@ class QgsGetRequestHandler: public QgsHttpRequestHandler
|
||||
public:
|
||||
QgsGetRequestHandler();
|
||||
std::map<QString, QString> parseInput();
|
||||
/**Sends the image back (but does not delete it)*/
|
||||
void sendGetMapResponse( const QString& service, QImage* img ) const;
|
||||
void sendGetCapabilitiesResponse( const QDomDocument& doc ) const;
|
||||
void sendGetFeatureInfoResponse( const QDomDocument& infoDoc, const QString& infoFormat ) const;
|
||||
void sendServiceException( const QgsMapServiceException& ex ) const;
|
||||
void sendGetStyleResponse( const QDomDocument& doc ) const;
|
||||
void sendGetPrintResponse( QByteArray* ba ) const;
|
||||
};
|
||||
|
@ -16,7 +16,18 @@
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgshttprequesthandler.h"
|
||||
#include "qgsftptransaction.h"
|
||||
#include "qgshttptransaction.h"
|
||||
#include "qgslogger.h"
|
||||
#include "qgsmapserviceexception.h"
|
||||
#include <QBuffer>
|
||||
#include <QByteArray>
|
||||
#include <QDomDocument>
|
||||
#include <QFile>
|
||||
#include <QImage>
|
||||
#include <QTextStream>
|
||||
#include <QStringList>
|
||||
#include <QUrl>
|
||||
#include <fcgi_stdio.h>
|
||||
|
||||
QgsHttpRequestHandler::QgsHttpRequestHandler(): QgsRequestHandler()
|
||||
@ -69,3 +80,333 @@ QString QgsHttpRequestHandler::formatToMimeType( const QString& format ) const
|
||||
}
|
||||
return format;
|
||||
}
|
||||
|
||||
void QgsHttpRequestHandler::sendGetMapResponse( const QString& service, QImage* img ) const
|
||||
{
|
||||
Q_UNUSED( service );
|
||||
if ( img )
|
||||
{
|
||||
if ( mFormat != "PNG" && mFormat != "JPG" )
|
||||
{
|
||||
sendServiceException( QgsMapServiceException( "InvalidFormat", "Output format '" + mFormat + "' is not supported in the GetMap request" ) );
|
||||
return;
|
||||
}
|
||||
|
||||
//store the image in a QByteArray and send it directly
|
||||
QByteArray ba;
|
||||
QBuffer buffer( &ba );
|
||||
buffer.open( QIODevice::WriteOnly );
|
||||
img->save( &buffer, mFormat.toLocal8Bit().data(), -1 );
|
||||
|
||||
sendHttpResponse( &ba, formatToMimeType( mFormat ) );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsHttpRequestHandler::sendGetCapabilitiesResponse( const QDomDocument& doc ) const
|
||||
{
|
||||
QByteArray ba = doc.toByteArray();
|
||||
sendHttpResponse( &ba, "text/xml" );
|
||||
}
|
||||
|
||||
void QgsHttpRequestHandler::sendGetStyleResponse( const QDomDocument& doc ) const
|
||||
{
|
||||
QByteArray ba = doc.toByteArray();
|
||||
sendHttpResponse( &ba, "text/xml" );
|
||||
}
|
||||
|
||||
void QgsHttpRequestHandler::sendGetFeatureInfoResponse( const QDomDocument& infoDoc, const QString& infoFormat ) const
|
||||
{
|
||||
QByteArray ba;
|
||||
QgsDebugMsg( "Info format is:" + infoFormat );
|
||||
|
||||
if ( infoFormat == "text/xml" )
|
||||
{
|
||||
ba = infoDoc.toByteArray();
|
||||
}
|
||||
else if ( infoFormat == "text/plain" || infoFormat == "text/html" )
|
||||
{
|
||||
//create string
|
||||
QString featureInfoString;
|
||||
|
||||
if ( infoFormat == "text/plain" )
|
||||
{
|
||||
featureInfoString.append( "GetFeatureInfo results\n" );
|
||||
featureInfoString.append( "\n" );
|
||||
}
|
||||
else if ( infoFormat == "text/html" )
|
||||
{
|
||||
featureInfoString.append( "<HEAD>\n" );
|
||||
featureInfoString.append( "<TITLE> GetFeatureInfo results </TITLE>\n" );
|
||||
featureInfoString.append( "<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\">\n" );
|
||||
featureInfoString.append( "</HEAD>\n" );
|
||||
featureInfoString.append( "<BODY>\n" );
|
||||
}
|
||||
|
||||
QDomNodeList layerList = infoDoc.elementsByTagName( "Layer" );
|
||||
|
||||
//layer loop
|
||||
for ( int i = 0; i < layerList.size(); ++i )
|
||||
{
|
||||
QDomElement layerElem = layerList.at( i ).toElement();
|
||||
if ( infoFormat == "text/plain" )
|
||||
{
|
||||
featureInfoString.append( "Layer '" + layerElem.attribute( "name" ) + "'\n" );
|
||||
}
|
||||
else if ( infoFormat == "text/html" )
|
||||
{
|
||||
featureInfoString.append( "<TABLE border=1 width=100%>\n" );
|
||||
featureInfoString.append( "<TR><TH width=25%>Layer</TH><TD>" + layerElem.attribute( "name" ) + "</TD></TR>\n" );
|
||||
featureInfoString.append( "</BR>" );
|
||||
}
|
||||
|
||||
//feature loop (for vector layers)
|
||||
QDomNodeList featureNodeList = layerElem.elementsByTagName( "Feature" );
|
||||
QDomElement currentFeatureElement;
|
||||
|
||||
if ( featureNodeList.size() < 1 ) //raster layer?
|
||||
{
|
||||
QDomNodeList attributeNodeList = layerElem.elementsByTagName( "Attribute" );
|
||||
for ( int j = 0; j < attributeNodeList.size(); ++j )
|
||||
{
|
||||
QDomElement attributeElement = attributeNodeList.at( j ).toElement();
|
||||
if ( infoFormat == "text/plain" )
|
||||
{
|
||||
featureInfoString.append( attributeElement.attribute( "name" ) + " = '" +
|
||||
attributeElement.attribute( "value" ) + "'\n" );
|
||||
}
|
||||
else if ( infoFormat == "text/html" )
|
||||
{
|
||||
featureInfoString.append( "<TR><TH>" + attributeElement.attribute( "name" ) + "</TH><TD>" +
|
||||
attributeElement.attribute( "value" ) + "</TD></TR>\n" );
|
||||
}
|
||||
}
|
||||
}
|
||||
else //vector layer
|
||||
{
|
||||
for ( int j = 0; j < featureNodeList.size(); ++j )
|
||||
{
|
||||
QDomElement featureElement = featureNodeList.at( j ).toElement();
|
||||
if ( infoFormat == "text/plain" )
|
||||
{
|
||||
featureInfoString.append( "Feature " + featureElement.attribute( "id" ) + "\n" );
|
||||
}
|
||||
else if ( infoFormat == "text/html" )
|
||||
{
|
||||
featureInfoString.append( "<TABLE border=1 width=100%>\n" );
|
||||
featureInfoString.append( "<TR><TH>Feature</TH><TD>" + featureElement.attribute( "id" ) + "</TD></TR>\n" );
|
||||
}
|
||||
//attribute loop
|
||||
QDomNodeList attributeNodeList = featureElement.elementsByTagName( "Attribute" );
|
||||
for ( int k = 0; k < attributeNodeList.size(); ++k )
|
||||
{
|
||||
QDomElement attributeElement = attributeNodeList.at( k ).toElement();
|
||||
if ( infoFormat == "text/plain" )
|
||||
{
|
||||
featureInfoString.append( attributeElement.attribute( "name" ) + " = '" +
|
||||
attributeElement.attribute( "value" ) + "'\n" );
|
||||
}
|
||||
else if ( infoFormat == "text/html" )
|
||||
{
|
||||
featureInfoString.append( "<TR><TH>" + attributeElement.attribute( "name" ) + "</TH><TD>" + attributeElement.attribute( "value" ) + "</TD></TR>\n" );
|
||||
}
|
||||
}
|
||||
|
||||
if ( infoFormat == "text/html" )
|
||||
{
|
||||
featureInfoString.append( "</TABLE>\n</BR>\n" );
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( infoFormat == "text/plain" )
|
||||
{
|
||||
featureInfoString.append( "\n" );
|
||||
}
|
||||
else if ( infoFormat == "text/html" )
|
||||
{
|
||||
featureInfoString.append( "</TABLE>\n<BR></BR>\n" );
|
||||
|
||||
}
|
||||
}
|
||||
if ( infoFormat == "text/html" )
|
||||
{
|
||||
featureInfoString.append( "</BODY>\n" );
|
||||
}
|
||||
ba = featureInfoString.toUtf8();
|
||||
}
|
||||
else //unsupported format, send exception
|
||||
{
|
||||
//todo: send service exception
|
||||
}
|
||||
|
||||
sendHttpResponse( &ba, infoFormat );
|
||||
}
|
||||
|
||||
void QgsHttpRequestHandler::sendServiceException( const QgsMapServiceException& ex ) const
|
||||
{
|
||||
//create Exception DOM document
|
||||
QDomDocument exceptionDoc;
|
||||
QDomElement serviceExceptionReportElem = exceptionDoc.createElement( "ServiceExceptionReport" );
|
||||
serviceExceptionReportElem.setAttribute( "version", "1.3.0" );
|
||||
serviceExceptionReportElem.setAttribute( "xmlns", "http://www.opengis.net/ogc" );
|
||||
exceptionDoc.appendChild( serviceExceptionReportElem );
|
||||
QDomElement serviceExceptionElem = exceptionDoc.createElement( "ServiceException" );
|
||||
serviceExceptionElem.setAttribute( "code", ex.code() );
|
||||
QDomText messageText = exceptionDoc.createTextNode( ex.message() );
|
||||
serviceExceptionElem.appendChild( messageText );
|
||||
serviceExceptionReportElem.appendChild( serviceExceptionElem );
|
||||
|
||||
QByteArray ba = exceptionDoc.toByteArray();
|
||||
sendHttpResponse( &ba, "text/xml" );
|
||||
}
|
||||
|
||||
void QgsHttpRequestHandler::sendGetPrintResponse( QByteArray* ba ) const
|
||||
{
|
||||
sendHttpResponse( ba, formatToMimeType( mFormat ) );
|
||||
}
|
||||
|
||||
void QgsHttpRequestHandler::requestStringToParameterMap( const QString& request, std::map<QString, QString>& parameters )
|
||||
{
|
||||
parameters.clear();
|
||||
|
||||
//parameters are separated by &
|
||||
QStringList elements = request.split( "&" );
|
||||
|
||||
QString element, key, value;
|
||||
|
||||
//insert key and value into the map
|
||||
for ( QStringList::const_iterator it = elements.begin(); it != elements.end(); ++it )
|
||||
{
|
||||
element = *it;
|
||||
int sepidx = element.indexOf( "=", 0, Qt::CaseSensitive );
|
||||
if ( sepidx == -1 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
key = element.left( sepidx );
|
||||
value = element.mid( sepidx + 1 );
|
||||
value = QUrl::fromPercentEncoding( value.toLocal8Bit() ); //replace encoded special caracters and utf-8 encodings
|
||||
|
||||
|
||||
if ( key.compare( "SLD_BODY", Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
key = "SLD";
|
||||
}
|
||||
else if ( key.compare( "SLD", Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
QByteArray fileContents;
|
||||
if ( value.startsWith( "http", Qt::CaseInsensitive ) )
|
||||
{
|
||||
QgsHttpTransaction http( value );
|
||||
if ( !http.getSynchronously( fileContents ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if ( value.startsWith( "ftp", Qt::CaseInsensitive ) )
|
||||
{
|
||||
QgsFtpTransaction ftp;
|
||||
if ( !ftp.get( value, fileContents ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
value = QUrl::fromPercentEncoding( fileContents );
|
||||
}
|
||||
else
|
||||
{
|
||||
continue; //only http and ftp supported at the moment
|
||||
}
|
||||
value = QUrl::fromPercentEncoding( fileContents );
|
||||
|
||||
}
|
||||
parameters.insert( std::make_pair( key.toUpper(), value ) );
|
||||
QgsDebugMsg( "inserting pair " + key.toUpper() + " // " + value + " into the parameter map" );
|
||||
}
|
||||
|
||||
//feature info format?
|
||||
std::map<QString, QString>::const_iterator info_format_it = parameters.find( "INFO_FORMAT" );
|
||||
if ( info_format_it != parameters.end() )
|
||||
{
|
||||
mFormat = info_format_it->second;
|
||||
}
|
||||
else //capabilities format or GetMap format
|
||||
{
|
||||
std::map<QString, QString>::const_iterator formatIt = parameters.find( "FORMAT" );
|
||||
if ( formatIt != parameters.end() )
|
||||
{
|
||||
QString formatString = formatIt->second;
|
||||
|
||||
QgsDebugMsg( QString( "formatString is: %1" ).arg( formatString ) );
|
||||
|
||||
//remove the image/ in front of the format
|
||||
if ( formatString.compare( "image/png", Qt::CaseInsensitive ) == 0 || formatString.compare( "png", Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
formatString = "PNG";
|
||||
}
|
||||
else if ( formatString.compare( "image/jpeg", Qt::CaseInsensitive ) == 0 || formatString.compare( "image/jpg", Qt::CaseInsensitive ) == 0 \
|
||||
|| formatString.compare( "jpg", Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
formatString = "JPG";
|
||||
}
|
||||
else if ( formatString.compare( "svg", Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
formatString = "SVG";
|
||||
}
|
||||
else if ( formatString.compare( "pdf", Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
formatString = "PDF";
|
||||
}
|
||||
|
||||
mFormat = formatString;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QString QgsHttpRequestHandler::readPostBody() const
|
||||
{
|
||||
char* lengthString = NULL;
|
||||
int length = 0;
|
||||
char* input = NULL;
|
||||
QString inputString;
|
||||
QString lengthQString;
|
||||
|
||||
lengthString = getenv( "CONTENT_LENGTH" );
|
||||
if ( lengthString != NULL )
|
||||
{
|
||||
bool conversionSuccess = false;
|
||||
lengthQString = QString( lengthString );
|
||||
length = lengthQString.toInt( &conversionSuccess );
|
||||
QgsDebugMsg( "length is: " + lengthQString );
|
||||
if ( conversionSuccess )
|
||||
{
|
||||
input = ( char* )malloc( length + 1 );
|
||||
memset( input, 0, length + 1 );
|
||||
for ( int i = 0; i < length; ++i )
|
||||
{
|
||||
input[i] = getchar();
|
||||
}
|
||||
//fgets(input, length+1, stdin);
|
||||
if ( input != NULL )
|
||||
{
|
||||
inputString = QString::fromLocal8Bit( input );
|
||||
#ifdef WIN32 //cut off any strange charactes at the end of the file
|
||||
int lastClosedBracketPos = inputString.lastIndexOf( ">" );
|
||||
if ( lastClosedBracketPos != -1 )
|
||||
{
|
||||
inputString.truncate( lastClosedBracketPos + 1 );
|
||||
}
|
||||
#endif //WIN32
|
||||
}
|
||||
else
|
||||
{
|
||||
QgsDebugMsg( "input is NULL " );
|
||||
}
|
||||
free( input );
|
||||
}
|
||||
else
|
||||
{
|
||||
QgsDebugMsg( "could not convert CONTENT_LENGTH to int" );
|
||||
}
|
||||
}
|
||||
return inputString;
|
||||
}
|
||||
|
@ -28,11 +28,22 @@ class QgsHttpRequestHandler: public QgsRequestHandler
|
||||
QgsHttpRequestHandler();
|
||||
~QgsHttpRequestHandler();
|
||||
|
||||
virtual void sendGetMapResponse( const QString& service, QImage* img ) const;
|
||||
virtual void sendGetCapabilitiesResponse( const QDomDocument& doc ) const;
|
||||
virtual void sendGetFeatureInfoResponse( const QDomDocument& infoDoc, const QString& infoFormat ) const;
|
||||
virtual void sendServiceException( const QgsMapServiceException& ex ) const;
|
||||
virtual void sendGetStyleResponse( const QDomDocument& doc ) const;
|
||||
virtual void sendGetPrintResponse( QByteArray* ba ) const;
|
||||
|
||||
protected:
|
||||
void sendHttpResponse( QByteArray* ba, const QString& format ) const;
|
||||
/**Converts format to official mimetype (e.g. 'jpg' to 'image/jpeg')
|
||||
@return mime string (or the entered string if not found)*/
|
||||
QString formatToMimeType( const QString& format ) const;
|
||||
|
||||
void requestStringToParameterMap( const QString& request, std::map<QString, QString>& parameters );
|
||||
/**Read CONTENT_LENGTH characters from stdin*/
|
||||
QString readPostBody() const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -40,51 +40,7 @@ QgsSOAPRequestHandler::~QgsSOAPRequestHandler()
|
||||
std::map<QString, QString> QgsSOAPRequestHandler::parseInput()
|
||||
{
|
||||
std::map<QString, QString> result;
|
||||
|
||||
char* lengthString = NULL;
|
||||
int length = 0;
|
||||
char* input = NULL;
|
||||
QString inputString;
|
||||
QString lengthQString;
|
||||
|
||||
lengthString = getenv( "CONTENT_LENGTH" );
|
||||
if ( lengthString != NULL )
|
||||
{
|
||||
bool conversionSuccess = false;
|
||||
lengthQString = QString( lengthString );
|
||||
length = lengthQString.toInt( &conversionSuccess );
|
||||
QgsDebugMsg( "length is: " + lengthQString );
|
||||
if ( conversionSuccess )
|
||||
{
|
||||
input = ( char* )malloc( length + 1 );
|
||||
memset( input, 0, length + 1 );
|
||||
for ( int i = 0; i < length; ++i )
|
||||
{
|
||||
input[i] = getchar();
|
||||
}
|
||||
//fgets(input, length+1, stdin);
|
||||
if ( input != NULL )
|
||||
{
|
||||
inputString = QString::fromLocal8Bit( input );
|
||||
#ifdef WIN32 //cut off any strange charactes at the end of the file
|
||||
int lastClosedBracketPos = inputString.lastIndexOf( ">" );
|
||||
if ( lastClosedBracketPos != -1 )
|
||||
{
|
||||
inputString.truncate( lastClosedBracketPos + 1 );
|
||||
}
|
||||
#endif //WIN32
|
||||
}
|
||||
else
|
||||
{
|
||||
QgsDebugMsg( "input is NULL " );
|
||||
}
|
||||
free( input );
|
||||
}
|
||||
else
|
||||
{
|
||||
QgsDebugMsg( "could not convert CONTENT_LENGTH to int" );
|
||||
}
|
||||
}
|
||||
QString inputString = readPostBody();
|
||||
|
||||
//QgsDebugMsg("input string is: " + inputString)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user