22#include "moc_qgsfcgiserverresponse.cpp" 
   24#include <fcgi_stdio.h> 
   30#if defined( Q_OS_UNIX ) && !defined( Q_OS_ANDROID ) 
   33#include <sys/socket.h> 
   39typedef struct QgsFCGXStreamData
 
   44    unsigned char *buffStop;  
 
   54    int isAnythingWritten;    
 
   56    FCGX_Request *reqDataPtr; 
 
   61using namespace std::chrono_literals;
 
   66  : mFeedback( std::move( feedback ) )
 
   69  Q_ASSERT( mFeedback );
 
   71  mShouldStop.store( 
false );
 
   73#if defined( Q_OS_UNIX ) && !defined( Q_OS_ANDROID ) 
   74  if ( FCGI_stdout && FCGI_stdout->fcgx_stream && FCGI_stdout->fcgx_stream->data )
 
   76    QgsFCGXStreamData *stream = 
static_cast<QgsFCGXStreamData *
>( FCGI_stdout->fcgx_stream->data );
 
   77    if ( stream && stream->reqDataPtr )
 
   79      mIpcFd = stream->reqDataPtr->ipcFd;
 
   84                                 QStringLiteral( 
"FCGIServer" ),                                                   
 
   91                               QStringLiteral( 
"FCGIServer" ),                                       
 
 
  100  mShouldStop.store( 
true );
 
 
  117#if defined( Q_OS_UNIX ) && !defined( Q_OS_ANDROID ) 
  118  quint64 threadId = 
reinterpret_cast<quint64
>( QThread::currentThreadId() );
 
  123  FD_ZERO( &setOptions );        
 
  124  FD_SET( mIpcFd, &setOptions ); 
 
  126  struct timeval timeout;
 
  128  timeout.tv_usec = 10000; 
 
  130  while ( !mShouldStop.load() )
 
  134    int rv = select( mIpcFd + 1, &setOptions, NULL, NULL, &timeout );
 
  149      const ssize_t x = recv( mIpcFd, &
c, 1, MSG_PEEK | MSG_DONTWAIT );
 
  153        QgsDebugMsgLevel( QStringLiteral( 
"FCGIServer %1: remote socket still connected. errno: %2, x: %3" ) 
 
  174    if ( mMutex.try_lock_for( 333ms ) )
 
  178  if ( mShouldStop.load() )
 
 
  199  mBuffer.open( QIODevice::ReadWrite );
 
  202  mSocketMonitoringThread = std::make_unique<QgsSocketMonitoringThread>( mFeedback );
 
 
  213  mSocketMonitoringThread->stop();
 
 
  221  mHeaders.remove( key );
 
 
  226  mHeaders.insert( key, value );
 
 
  231  return mHeaders.value( key );
 
 
  242  mHeaders.insert( QStringLiteral( 
"Status" ), QStringLiteral( 
" %1" ).arg( code ) );
 
 
  257  setHeader( QStringLiteral( 
"Content-Type" ), QStringLiteral( 
"text/html;charset=utf-8" ) );
 
  258  write( QStringLiteral( 
"<html><body>%1</body></html>" ).arg( message ) );
 
 
  275  if ( mFeedback->isCanceled() )
 
  278    FCGI_stdout->fcgx_stream->wasFCloseCalled = 
true; 
 
  285    if ( !mHeaders.contains( 
"Content-Length" ) )
 
  287      mHeaders.insert( QStringLiteral( 
"Content-Length" ), QString::number( mBuffer.pos() ) );
 
 
  299    QMap<QString, QString>::const_iterator it;
 
  300    for ( it = mHeaders.constBegin(); it != mHeaders.constEnd(); ++it )
 
  302      fputs( it.key().toUtf8(), FCGI_stdout );
 
  303      fputs( 
": ", FCGI_stdout );
 
  304      fputs( it.value().toUtf8(), FCGI_stdout );
 
  305      fputs( 
"\n", FCGI_stdout );
 
  307    fputs( 
"\n", FCGI_stdout );
 
  316    mBuffer.buffer().clear();
 
  318  else if ( mBuffer.bytesAvailable() > 0 )
 
  320    QByteArray &ba = mBuffer.buffer();
 
  321    const size_t count = fwrite( ( 
void * ) ba.data(), ba.size(), 1, FCGI_stdout );
 
  323    qDebug() << QStringLiteral( 
"Sent %1 blocks of %2 bytes" ).arg( count ).arg( ba.size() );
 
 
  337  mBuffer.buffer().clear();
 
 
  346  return mBuffer.data();
 
 
  353  mBuffer.buffer().clear();
 
 
  359  mHeaders.insert( QStringLiteral( 
"Server" ), QStringLiteral( 
" QGIS FCGI server - QGIS version %1" ).arg( 
Qgis::version() ) );
 
 
static QString version()
Version string.
 
@ Warning
Warning message.
 
@ Info
Information message.
 
void setDefaultHeaders()
Set the default headers.
 
void clear() override
Reset all headers and content for this response.
 
void setHeader(const QString &key, const QString &value) override
Set Header entry Add Header entry to the response Note that it is usually an error to set Header afte...
 
void flush() override
Flushes the current output buffer to the network.
 
virtual ~QgsFcgiServerResponse() override
 
void removeHeader(const QString &key) override
Clear header Undo a previous 'setHeader' call.
 
QByteArray data() const override
Gets the data written so far.
 
QIODevice * io() override
Returns the underlying QIODevice.
 
bool headersSent() const override
Returns true if the headers have already been sent.
 
void setStatusCode(int code) override
Set the http status code.
 
QgsFcgiServerResponse(QgsServerRequest::Method method=QgsServerRequest::GetMethod)
Constructor for QgsFcgiServerResponse.
 
void sendError(int code, const QString &message) override
Send error This method delegates error handling at the server level.
 
void truncate() override
Truncate data.
 
void finish() override
Finish the response, ending the transaction.
 
QString header(const QString &key) const override
Returns the header value.
 
Base class for feedback objects to be used for cancellation of something running in a worker thread.
 
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).
 
Method
HTTP Method (or equivalent) used for the request.
 
virtual void write(const QString &data)
Write string This is a convenient method that will write directly to the underlying I/O device.
 
void run()
main thread function
 
void stop()
Stop the thread.
 
QgsSocketMonitoringThread(std::shared_ptr< QgsFeedback > feedback)
Constructor for QgsSocketMonitoringThread.
 
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
 
#define QgsDebugMsgLevel(str, level)