22 #include <QNetworkReply> 
   24 #include <QRegularExpression> 
   26 #include <QStringList> 
   32   if ( !mReply ) 
return;
 
   40     QMap<QByteArray, QByteArray> 
headers;
 
   41     const auto constRawHeaderList = mReply->rawHeaderList();
 
   42     for ( 
const QByteArray &h : constRawHeaderList )
 
   44       headers.insert( h, mReply->rawHeader( h ) );
 
   47     mBodies.append( mReply->readAll() );
 
   51     const QString contentType = mReply->header( QNetworkRequest::ContentTypeHeader ).toString();
 
   54     const QRegularExpression re( 
".*boundary=\"?([^\"]+)\"?\\s?", QRegularExpression::CaseInsensitiveOption );
 
   55     const QRegularExpressionMatch match = re.match( contentType );
 
   56     if ( !( match.capturedStart( 0 ) == 0 ) )
 
   58       mError = tr( 
"Cannot find boundary in multipart content type" );
 
   62     QString boundary = match.captured( 1 );
 
   63     QgsDebugMsg( QStringLiteral( 
"boundary = %1 size = %2" ).arg( boundary ).arg( boundary.size() ) );
 
   64     boundary = 
"--" + boundary;
 
   67     const QByteArray data = mReply->readAll();
 
   69     from = data.indexOf( boundary.toLatin1(), 0 ) + boundary.length() + 1;
 
   75       to = data.indexOf( boundary.toLatin1(), from );
 
   78         QgsDebugMsg( QStringLiteral( 
"No more boundaries, rest size = %1" ).arg( data.size() - from - 1 ) );
 
   80         if ( data.size() - from - 1 == 2 && QString( data.mid( from, 2 ) ) == QLatin1String( 
"--" ) ) 
 
   87         if ( data.size() - from > 1 )
 
   96       QgsDebugMsg( QStringLiteral( 
"part %1 - %2" ).arg( from ).arg( to ) );
 
   97       QByteArray part = data.mid( from, to - from );
 
   99       while ( !part.isEmpty() && ( part.at( 0 ) == 
'\r' || part.at( 0 ) == 
'\n' ) )
 
  106       while ( pos < part.size() - 1 )
 
  108         if ( part.at( pos ) == 
'\n' && ( part.at( pos + 1 ) == 
'\n' || part.at( pos + 1 ) == 
'\r' ) )
 
  110           if ( part.at( pos + 1 ) == 
'\r' ) pos++;
 
  118       const QByteArray 
headers = part.left( pos );
 
  121       const QStringList headerRows = QString( 
headers ).split( QRegularExpression( 
"[\n\r]+" ) );
 
  122       const auto constHeaderRows = headerRows;
 
  123       for ( 
const QString &row : constHeaderRows )
 
  126         const QStringList kv = row.split( QStringLiteral( 
": " ) );
 
  127         headersMap.insert( kv.value( 0 ).toLatin1(), kv.value( 1 ).toLatin1() );
 
  129       mHeaders.append( headersMap );
 
  131       mBodies.append( part.mid( pos ) );
 
  133       from = to + boundary.length();
 
  141   if ( !reply ) 
return false;
 
  143   const QString contentType = reply->header( QNetworkRequest::ContentTypeHeader ).toString();
 
  149   return contentType.startsWith( QLatin1String( 
"multipart/" ), Qt::CaseInsensitive );
 
QMap< QByteArray, QByteArray > RawHeaderMap
QgsNetworkReplyParser(QNetworkReply *reply)
Constructor.
static bool isMultipart(QNetworkReply *reply)
Test if reply is multipart.
QList< RawHeaderMap > headers() const
Gets headers.