File indexing completed on 2025-02-23 04:27:36
0001 /**************************************************************************************** 0002 * Copyright (c) 2006 Ian Monroe <ian@monroe.nu> * 0003 * * 0004 * This program is free software; you can redistribute it and/or modify it under * 0005 * the terms of the GNU General Public License as published by the Free Software * 0006 * Foundation; either version 2 of the License, or (at your option) version 3 or * 0007 * any later version accepted by the membership of KDE e.V. (or its successor approved * 0008 * by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of * 0009 * version 3 of the license. * 0010 * * 0011 * This program is distributed in the hope that it will be useful, but WITHOUT ANY * 0012 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * 0013 * PARTICULAR PURPOSE. See the GNU General Public License for more details. * 0014 * * 0015 * You should have received a copy of the GNU General Public License along with * 0016 * this program. If not, see <http://www.gnu.org/licenses/>. * 0017 ****************************************************************************************/ 0018 0019 #include "contentfetcher.h" 0020 #include "core/support/Debug.h" 0021 #include "hasher.h" 0022 #include "network/NetworkAccessManagerProxy.h" 0023 0024 #include <QBuffer> 0025 #include <QByteArray> 0026 #include <QNetworkReply> 0027 0028 #include <KCodecs> 0029 #include <KCompressionDevice> 0030 0031 using namespace Daap; 0032 int ContentFetcher::s_requestId = 10; 0033 0034 ContentFetcher::ContentFetcher( const QString & hostname, quint16 port, const QString& password, QObject * parent, const char * name ) 0035 : QObject(parent) 0036 , m_reply( nullptr ) 0037 , m_hostname( hostname ) 0038 , m_port( port ) 0039 , m_selfDestruct( false ) 0040 { 0041 setObjectName( name ); 0042 QByteArray pass = password.toUtf8(); 0043 if( !password.isNull() ) 0044 { 0045 m_authorize = "Basic " + KCodecs::base64Encode( "none:" + pass ); 0046 } 0047 } 0048 0049 ContentFetcher::~ContentFetcher() 0050 { } 0051 0052 QByteArray 0053 ContentFetcher::results() 0054 { 0055 return m_lastResult; 0056 } 0057 0058 void 0059 ContentFetcher::getDaap( const QString &command, QIODevice* musicFile /*= 0*/ ) 0060 { 0061 QUrl url( command ); 0062 url.setHost( m_hostname ); 0063 url.setPort( m_port ); 0064 QNetworkRequest request( url ); 0065 char hash[33] = {0}; 0066 const char *cmd = command.toLatin1(); 0067 GenerateHash(3, reinterpret_cast<const unsigned char*>( cmd ), 2, reinterpret_cast<unsigned char*>(hash), 0 /*s_requestId*/); 0068 0069 if( !m_authorize.isEmpty() ) 0070 { 0071 request.setRawHeader( "Authorization", m_authorize ); 0072 } 0073 0074 request.setRawHeader( "Client-DAAP-Request-ID", "0"/*QString::number( s_requestId )*/ ); 0075 request.setRawHeader( "Client-DAAP-Access-Index", "2" ); 0076 request.setRawHeader( "Client-DAAP-Validation", hash ); 0077 request.setRawHeader( "Client-DAAP-Version", "3.0" ); 0078 request.setRawHeader( "User-Agent", "iTunes/4.6 (Windows; N)" ); 0079 request.setRawHeader( "Accept", "*/*" ); 0080 request.setRawHeader( "Accept-Encoding", "gzip" ); 0081 0082 m_reply = The::networkAccessManager()->sendCustomRequest( request, "GET", musicFile ); 0083 0084 if( m_reply->isFinished() ) 0085 onFinished(); 0086 else 0087 connect( m_reply, &QNetworkReply::finished, this, &ContentFetcher::onFinished ); 0088 } 0089 0090 void 0091 ContentFetcher::onFinished() 0092 { 0093 if( !m_reply ) 0094 return; 0095 0096 if( !m_selfDestruct && m_reply->error() ) 0097 { 0098 if( m_reply->error() == QNetworkReply::AuthenticationRequiredError ) 0099 { 0100 Q_EMIT loginRequired(); 0101 return; 0102 } 0103 0104 debug() << "there is an error? " << m_reply->error() << " " << m_reply->errorString(); 0105 m_selfDestruct = true; 0106 Q_EMIT httpError( m_reply->errorString() ); 0107 } 0108 0109 QByteArray read = m_reply->readAll(); 0110 if( m_reply->rawHeader( "Content-Encoding" ) == "gzip" ) 0111 { 0112 QBuffer* bytes = new QBuffer( &read ); 0113 KCompressionDevice *stream = new KCompressionDevice( bytes, true, KCompressionDevice::GZip ); 0114 if ( stream->open( QIODevice::ReadOnly ) ) 0115 m_lastResult = stream->readAll(); 0116 else 0117 m_lastResult = read; 0118 0119 delete stream; 0120 } 0121 else 0122 m_lastResult = read; 0123 0124 Q_EMIT finished(); 0125 m_reply->deleteLater(); 0126 m_reply = nullptr; 0127 } 0128 0129 0130