File indexing completed on 2024-05-05 04:48:36
0001 /*************************************************************************** 0002 * Copyright (C) 2009, 2010 by Richard J. Moore <rich@kde.org> * 0003 * * 0004 * This program is free software; you can redistribute it and/or modify * 0005 * it under the terms of the GNU General Public License as published by * 0006 * the Free Software Foundation; either version 2 of the License, or * 0007 * (at your option) any later version. * 0008 * * 0009 * This program is distributed in the hope that it will be useful, * 0010 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0012 * GNU General Public License for more details. * 0013 * * 0014 * You should have received a copy of the GNU General Public License * 0015 * along with this program; if not, write to the * 0016 * Free Software Foundation, Inc., * 0017 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * 0018 ***************************************************************************/ 0019 0020 #include "NetworkAccessViewer.h" 0021 0022 #include "core/support/Debug.h" 0023 0024 #include <QNetworkReply> 0025 #include <QNetworkRequest> 0026 #include <QSignalMapper> 0027 0028 NetworkAccessViewer::NetworkAccessViewer( QWidget *parent ) 0029 : QObject( parent ) 0030 { 0031 dialog = new QDialog( parent ); 0032 networkRequestsDialog = new Ui::NetworkRequestsDialog; 0033 networkRequestsDialog->setupUi(dialog); 0034 0035 mapper = new QSignalMapper(this); 0036 connect( mapper, QOverload<QObject*>::of(&QSignalMapper::mapped), 0037 this, &NetworkAccessViewer::requestFinished ); 0038 0039 connect( networkRequestsDialog->requestList, &QTreeWidget::currentItemChanged, this, &NetworkAccessViewer::showItemDetails ); 0040 connect( networkRequestsDialog->clearButton, &QPushButton::clicked, this, &NetworkAccessViewer::clear ); 0041 } 0042 0043 NetworkAccessViewer::~NetworkAccessViewer() 0044 { 0045 delete networkRequestsDialog; 0046 } 0047 0048 void NetworkAccessViewer::addRequest( QNetworkAccessManager::Operation op, const QNetworkRequest&req, QIODevice *outgoingData, QNetworkReply *reply ) 0049 { 0050 Q_UNUSED( outgoingData ) 0051 // Add to list of requests 0052 QStringList cols; 0053 switch( op ) { 0054 case QNetworkAccessManager::HeadOperation: 0055 cols << QString::fromLatin1("HEAD"); 0056 break; 0057 case QNetworkAccessManager::GetOperation: 0058 cols << QString::fromLatin1("GET"); 0059 break; 0060 case QNetworkAccessManager::PutOperation: 0061 cols << QString::fromLatin1("PUT"); 0062 break; 0063 case QNetworkAccessManager::PostOperation: 0064 cols << QString::fromLatin1("POST"); 0065 break; 0066 default: 0067 qWarning() << "Unknown network operation"; 0068 } 0069 cols << req.url().toString(); 0070 cols << tr("Pending"); 0071 0072 QTreeWidgetItem *item = new QTreeWidgetItem( cols ); 0073 networkRequestsDialog->requestList->addTopLevelItem( item ); 0074 networkRequestsDialog->requestList->scrollToItem( item ); 0075 0076 // Add to maps 0077 requestMap.insert( reply, req ); 0078 itemMap.insert( reply, item ); 0079 itemRequestMap.insert( item, req ); 0080 0081 mapper->setMapping( reply, reply ); 0082 connect( reply, &QNetworkReply::finished, 0083 mapper, QOverload<>::of(&QSignalMapper::map) ); 0084 } 0085 0086 void NetworkAccessViewer::show() 0087 { 0088 dialog->show(); 0089 } 0090 0091 void NetworkAccessViewer::hide() 0092 { 0093 dialog->hide(); 0094 } 0095 0096 void NetworkAccessViewer::clear() 0097 { 0098 requestMap.clear(); 0099 itemMap.clear(); 0100 itemReplyMap.clear(); 0101 itemRequestMap.clear(); 0102 networkRequestsDialog->requestList->clear(); 0103 networkRequestsDialog->requestDetails->clear(); 0104 networkRequestsDialog->responseDetails->clear(); 0105 } 0106 0107 void NetworkAccessViewer::requestFinished( QObject *replyObject ) 0108 { 0109 QNetworkReply *reply = qobject_cast<QNetworkReply *>( replyObject ); 0110 if( !reply ) 0111 { 0112 warning() << __PRETTY_FUNCTION__ << "Failed to downcast reply"; 0113 return; 0114 } 0115 QTreeWidgetItem *item = itemMap.value( reply ); 0116 if( !item ) 0117 { 0118 warning() << __PRETTY_FUNCTION__ << "null item"; 0119 return; 0120 } 0121 0122 // Record the reply headers 0123 QList<QByteArray> headerValues; 0124 foreach( const QByteArray &header, reply->rawHeaderList() ) { 0125 headerValues += reply->rawHeader( header ); 0126 } 0127 QPair< QList<QByteArray>, QList<QByteArray> > replyHeaders; 0128 replyHeaders.first = reply->rawHeaderList(); 0129 replyHeaders.second = headerValues; 0130 itemReplyMap[item] = replyHeaders; 0131 0132 // Display the request 0133 int status = reply->attribute( QNetworkRequest::HttpStatusCodeAttribute ).toInt(); 0134 QString reason = reply->attribute( QNetworkRequest::HttpReasonPhraseAttribute ).toString(); 0135 item->setText( 2, tr("%1 %2").arg(status).arg(reason) ); 0136 0137 QString length = reply->header( QNetworkRequest::ContentLengthHeader ).toString(); 0138 item->setText( 3, length ); 0139 0140 QString contentType = reply->header( QNetworkRequest::ContentTypeHeader ).toString(); 0141 item->setText( 4, contentType ); 0142 0143 if ( status == 302 ) { 0144 QUrl target = reply->attribute( QNetworkRequest::RedirectionTargetAttribute ).toUrl(); 0145 item->setText( 5, tr("Redirect: %1").arg( target.toString() ) ); 0146 } 0147 } 0148 0149 void NetworkAccessViewer::showItemDetails( QTreeWidgetItem *item ) 0150 { 0151 // Show request details 0152 QTreeWidget *reqTree = networkRequestsDialog->requestDetails; 0153 reqTree->clear(); 0154 0155 QNetworkRequest req = itemRequestMap[item]; 0156 QByteArray header; 0157 foreach( header, req.rawHeaderList() ) { 0158 QTreeWidgetItem *item = new QTreeWidgetItem(); 0159 item->setText( 0, QString::fromLatin1( header ) ); 0160 item->setText( 1, QString::fromLatin1( req.rawHeader( header ) ) ); 0161 reqTree->addTopLevelItem( item ); 0162 } 0163 0164 // Show reply headers 0165 QTreeWidget *respTree = networkRequestsDialog->responseDetails; 0166 respTree->clear(); 0167 0168 QPair< QList<QByteArray>, QList<QByteArray> > replyHeaders = itemReplyMap[item]; 0169 for ( int i = 0; i < replyHeaders.first.count(); i++ ) { 0170 QTreeWidgetItem *item = new QTreeWidgetItem(); 0171 item->setText( 0, QString::fromLatin1( replyHeaders.first[i] ) ); 0172 item->setText( 1, QString::fromLatin1( replyHeaders.second[i] ) ); 0173 respTree->addTopLevelItem( item ); 0174 } 0175 }