mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-01-18 23:17:59 +01:00
Do a native (Qt) request if the 'Referer' header was supplied
This commit is contained in:
parent
4e9a088af4
commit
655e63f261
@ -277,6 +277,35 @@ Tomahawk.syncRequest = function (url, extraHeaders, options) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal counter used to identify asyncRequest callback from native code.
|
||||||
|
*/
|
||||||
|
Tomahawk.asyncRequestIdCounter = 0;
|
||||||
|
/**
|
||||||
|
* Internal map used to map asyncRequestIds to the respective javascript
|
||||||
|
* callback functions.
|
||||||
|
*/
|
||||||
|
Tomahawk.asyncRequestCallbacks = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pass the natively retrived reply back to the javascript callback
|
||||||
|
* and augment the fake XMLHttpRequest object.
|
||||||
|
*
|
||||||
|
* Internal use only!
|
||||||
|
*/
|
||||||
|
Tomahawk.nativeAsyncRequestDone = function (reqId, xhr) {
|
||||||
|
// Check we have a matching callback stored.
|
||||||
|
if (!Tomahawk.asyncRequestCallbacks.hasOwnProperty(reqId)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call the real callback
|
||||||
|
Tomahawk.asyncRequestCallbacks[reqId](xhr);
|
||||||
|
|
||||||
|
// Callback are only used once.
|
||||||
|
delete Tomahawk.asyncRequestCallbacks[reqId];
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Possible options:
|
* Possible options:
|
||||||
* - method: The HTTP request method (default: GET)
|
* - method: The HTTP request method (default: GET)
|
||||||
@ -289,7 +318,20 @@ Tomahawk.asyncRequest = function (url, callback, extraHeaders, options) {
|
|||||||
// unpack options
|
// unpack options
|
||||||
var opt = options || {};
|
var opt = options || {};
|
||||||
var method = opt.method || 'GET';
|
var method = opt.method || 'GET';
|
||||||
|
var doNativeRequest = false;
|
||||||
|
|
||||||
|
if (extraHeaders && (extraHeaders.hasOwnProperty("Referer") || extraHeaders.hasOwnProperty("referer"))) {
|
||||||
|
doNativeRequest = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (doNativeRequest) {
|
||||||
|
// Assign a request Id to the callback so we can use it when we are
|
||||||
|
// returning from the native call.
|
||||||
|
var reqId = Tomahawk.asyncRequestIdCounter;
|
||||||
|
Tomahawk.asyncRequestIdCounter++;
|
||||||
|
Tomahawk.asyncRequestCallbacks[reqId] = callback;
|
||||||
|
Tomahawk.nativeAsyncRequest(reqId, url, extraHeaders, options);
|
||||||
|
} else {
|
||||||
var xmlHttpRequest = new XMLHttpRequest();
|
var xmlHttpRequest = new XMLHttpRequest();
|
||||||
xmlHttpRequest.open(method, url, true, opt.username, opt.password);
|
xmlHttpRequest.open(method, url, true, opt.username, opt.password);
|
||||||
if (extraHeaders) {
|
if (extraHeaders) {
|
||||||
@ -309,6 +351,7 @@ Tomahawk.asyncRequest = function (url, callback, extraHeaders, options) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
xmlHttpRequest.send(opt.data || null);
|
xmlHttpRequest.send(opt.data || null);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Tomahawk.sha256 = Tomahawk.sha256 || CryptoJS.SHA256;
|
Tomahawk.sha256 = Tomahawk.sha256 || CryptoJS.SHA256;
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include "resolvers/ScriptEngine.h"
|
#include "resolvers/ScriptEngine.h"
|
||||||
#include "network/Servent.h"
|
#include "network/Servent.h"
|
||||||
#include "utils/Closure.h"
|
#include "utils/Closure.h"
|
||||||
|
#include "utils/Json.h"
|
||||||
#include "utils/NetworkAccessManager.h"
|
#include "utils/NetworkAccessManager.h"
|
||||||
#include "utils/NetworkReply.h"
|
#include "utils/NetworkReply.h"
|
||||||
#include "utils/Logger.h"
|
#include "utils/Logger.h"
|
||||||
@ -487,6 +488,69 @@ JSResolverHelper::reportStreamUrl( const QString& qid,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
JSResolverHelper::nativeAsyncRequest( const int requestId, const QString& url,
|
||||||
|
const QVariantMap& headers,
|
||||||
|
const QVariantMap& options )
|
||||||
|
{
|
||||||
|
QNetworkRequest req( url );
|
||||||
|
foreach ( const QString& key , headers.keys() ) {
|
||||||
|
req.setRawHeader( key.toLatin1(), headers[key].toString().toLatin1() );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( options.contains( "username" ) && options.contains( "password" ) )
|
||||||
|
{
|
||||||
|
// If we have sufficient authentication data, we will send
|
||||||
|
// username+password as HTTP Basic Auth
|
||||||
|
QString credentials = QString( "Basic %1" )
|
||||||
|
.arg( QString( QString("%1:%2")
|
||||||
|
.arg( options["username"].toString() )
|
||||||
|
.arg( options["password"].toString() )
|
||||||
|
.toLatin1().toBase64() )
|
||||||
|
);
|
||||||
|
req.setRawHeader( "Authorization", credentials.toLatin1() );
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkReply* reply = NULL;
|
||||||
|
if ( options.contains( "method") && options["method"].toString().toUpper() == "POST" ) {
|
||||||
|
QByteArray data;
|
||||||
|
if ( options.contains( "data" ) ) {
|
||||||
|
data = options["data"].toString().toLatin1();
|
||||||
|
}
|
||||||
|
reply = new NetworkReply( Tomahawk::Utils::nam()->post( req, data ) );
|
||||||
|
} else if ( options.contains( "method") && options["method"].toString().toUpper() == "HEAD" ) {
|
||||||
|
reply = new NetworkReply( Tomahawk::Utils::nam()->head( req ) );
|
||||||
|
} else {
|
||||||
|
reply = new NetworkReply( Tomahawk::Utils::nam()->get( req ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
NewClosure( reply , SIGNAL( finished() ), this, SLOT( nativeAsyncRequestDone( int, NetworkReply* ) ), requestId, reply );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
JSResolverHelper::nativeAsyncRequestDone( int requestId, NetworkReply* reply )
|
||||||
|
{
|
||||||
|
QVariantMap map;
|
||||||
|
map["response"] = QString::fromUtf8( reply->reply()->readAll() );
|
||||||
|
map["responseText"] = map["response"];
|
||||||
|
map["responseType"] = QString(); // Default, indicates a string in map["response"]
|
||||||
|
map["readyState"] = 4;
|
||||||
|
map["status"] = reply->reply()->attribute( QNetworkRequest::HttpStatusCodeAttribute ).toInt();
|
||||||
|
map["statusText"] = QString("%1 %2").arg( map["status"].toString() )
|
||||||
|
.arg( reply->reply()->attribute( QNetworkRequest::HttpReasonPhraseAttribute ).toString() );
|
||||||
|
|
||||||
|
bool ok = false;
|
||||||
|
QString json = QString::fromUtf8( TomahawkUtils::toJson( map, &ok ) );
|
||||||
|
Q_ASSERT( ok );
|
||||||
|
|
||||||
|
QString javascript = QString( "Tomahawk.nativeAsyncRequestDone( %1, %2 );" )
|
||||||
|
.arg( QString::number( requestId ) )
|
||||||
|
.arg( json );
|
||||||
|
m_resolver->d_func()->engine->mainFrame()->evaluateJavaScript( javascript );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
JSResolverHelper::hasFuzzyIndex()
|
JSResolverHelper::hasFuzzyIndex()
|
||||||
{
|
{
|
||||||
|
@ -49,6 +49,19 @@ public:
|
|||||||
Q_INVOKABLE void reportStreamUrl( const QString& qid, const QString& streamUrl );
|
Q_INVOKABLE void reportStreamUrl( const QString& qid, const QString& streamUrl );
|
||||||
Q_INVOKABLE void reportStreamUrl( const QString& qid, const QString& streamUrl, const QVariantMap& headers );
|
Q_INVOKABLE void reportStreamUrl( const QString& qid, const QString& streamUrl, const QVariantMap& headers );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Native handler for asynchronous HTTP requests.
|
||||||
|
*
|
||||||
|
* This handler shall only be used if we cannot achieve the request with
|
||||||
|
* XMLHttpRequest as that would be more efficient.
|
||||||
|
* Use cases are:
|
||||||
|
* * Referer header: Stripped on MacOS and the specification says it
|
||||||
|
* should be stripped
|
||||||
|
*/
|
||||||
|
Q_INVOKABLE void nativeAsyncRequest( int requestId, const QString& url,
|
||||||
|
const QVariantMap& headers,
|
||||||
|
const QVariantMap& options );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clucene indices for JS resolvers
|
* Clucene indices for JS resolvers
|
||||||
**/
|
**/
|
||||||
@ -89,6 +102,7 @@ private slots:
|
|||||||
void gotStreamUrl( IODeviceCallback callback, NetworkReply* reply );
|
void gotStreamUrl( IODeviceCallback callback, NetworkReply* reply );
|
||||||
void tracksAdded( const QList<Tomahawk::query_ptr>& tracks, const Tomahawk::ModelMode, const Tomahawk::collection_ptr& collection );
|
void tracksAdded( const QList<Tomahawk::query_ptr>& tracks, const Tomahawk::ModelMode, const Tomahawk::collection_ptr& collection );
|
||||||
void pltemplateTracksLoadedForUrl( const QString& url, const Tomahawk::playlisttemplate_ptr& pltemplate );
|
void pltemplateTracksLoadedForUrl( const QString& url, const Tomahawk::playlisttemplate_ptr& pltemplate );
|
||||||
|
void nativeAsyncRequestDone( int requestId, NetworkReply* reply );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Tomahawk::query_ptr parseTrack( const QVariantMap& track );
|
Tomahawk::query_ptr parseTrack( const QVariantMap& track );
|
||||||
|
Loading…
x
Reference in New Issue
Block a user