Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #38560 from elpaso/server-standalone-post-data
Fix unreported server standalone POST data handling
  • Loading branch information
elpaso committed Sep 7, 2020
2 parents 47fb11a + 9053ac8 commit 5c241c8
Showing 1 changed file with 29 additions and 10 deletions.
39 changes: 29 additions & 10 deletions src/server/qgis_mapserver.cpp
Expand Up @@ -239,13 +239,16 @@ int main( int argc, char *argv[] )
std::cout << QObject::tr( "CTRL+C to exit" ).toStdString() << std::endl;
#endif


// Starts HTTP loop with a poor man's HTTP parser
tcpServer.connect( &tcpServer, &QTcpServer::newConnection, [ & ]
{
QTcpSocket *clientConnection = tcpServer.nextPendingConnection();

connCounter++;

QString *incomingData = new QString();

//qDebug() << "Active connections: " << connCounter;

// Lambda disconnect context
Expand All @@ -256,6 +259,7 @@ int main( int argc, char *argv[] )
{
clientConnection->deleteLater();
connCounter--;
delete incomingData;
};

// This will delete the connection when disconnected before ready read is called
Expand All @@ -264,26 +268,22 @@ int main( int argc, char *argv[] )
// Incoming connection parser
clientConnection->connect( clientConnection, &QIODevice::readyRead, context, [ =, &server, &connCounter ] {

// Disconnect the lambdas
delete context;

// Read all incoming data
QString incomingData;
while ( clientConnection->bytesAvailable() > 0 )
{
incomingData += clientConnection->readAll();
incomingData->append( clientConnection->readAll() );
}

try
{
// Parse protocol and URL GET /path HTTP/1.1
int firstLinePos { incomingData.indexOf( "\r\n" ) };
int firstLinePos { incomingData->indexOf( "\r\n" ) };
if ( firstLinePos == -1 )
{
throw HttpException( QStringLiteral( "HTTP error finding protocol header" ) );
}

const QString firstLine { incomingData.left( firstLinePos ) };
const QString firstLine { incomingData->left( firstLinePos ) };
const QStringList firstLinePieces { firstLine.split( ' ' ) };
if ( firstLinePieces.size() != 3 )
{
Expand Down Expand Up @@ -330,14 +330,14 @@ int main( int argc, char *argv[] )

// Headers
QgsBufferServerRequest::Headers headers;
int endHeadersPos { incomingData.indexOf( "\r\n\r\n" ) };
int endHeadersPos { incomingData->indexOf( "\r\n\r\n" ) };

if ( endHeadersPos == -1 )
{
throw HttpException( QStringLiteral( "HTTP error finding headers" ) );
}

const QStringList httpHeaders { incomingData.mid( firstLinePos + 2, endHeadersPos - firstLinePos ).split( "\r\n" ) };
const QStringList httpHeaders { incomingData->mid( firstLinePos + 2, endHeadersPos - firstLinePos ).split( "\r\n" ) };

for ( const auto &headerLine : httpHeaders )
{
Expand All @@ -348,6 +348,23 @@ int main( int argc, char *argv[] )
}
}

const int headersSize { endHeadersPos + 4 };

// Check for content length and if we have got all data
if ( headers.contains( QStringLiteral( "Content-Length" ) ) )
{
bool ok;
const int contentLength { headers.value( QStringLiteral( "Content-Length" ) ).toInt( &ok ) };
if ( ok && contentLength > incomingData->length() - headersSize )
{
return;
}
}

// At this point we should have read all data:
// disconnect the lambdas
delete context;

// Build URL from env ...
QString url { qgetenv( "REQUEST_URI" ) };
// ... or from server ip/port and request path
Expand All @@ -366,7 +383,7 @@ int main( int argc, char *argv[] )
}

// Inefficient copy :(
QByteArray data { incomingData.mid( endHeadersPos + 4 ).toUtf8() };
QByteArray data { incomingData->mid( headersSize ).toUtf8() };

auto start = std::chrono::steady_clock::now();

Expand All @@ -386,6 +403,7 @@ int main( int argc, char *argv[] )
{
connCounter --;
clientConnection->deleteLater();
delete incomingData;
return;
}

Expand Down Expand Up @@ -433,6 +451,7 @@ int main( int argc, char *argv[] )
{
connCounter --;
clientConnection->deleteLater();
delete incomingData;
return;
}

Expand Down

0 comments on commit 5c241c8

Please sign in to comment.