Dans un article précédent je vous avais présenté Aria2, un client de téléchargement très léger. Nous avions également vu comment mettre en place une interface web grâce au projet de ziahamza : https://github.com/ziahamza/webui-aria2 .
Voici un schéma du mode de fonctionnement de notre plateforme :
Lorsque l’on se connecte à l’interface web, on récupère la page via le port 80 de notre serveur. Dans la page est contenue du code JavaScript qui va permettre de communiquer avec le RPC d’Aria en envoyant des appels AJAX sur le port 6800 par défaut.
Mais que se passerait-il si l’on passait notre site en HTTPS ?
Ça ne marcherait simplement pas. En effet, comme le site est en HTTPS, il requiert d’avoir tout son trafic transitant sur le même port.. et c’est là que commence la bidouille !
On va créer un script PHP sur notre serveur qui va être chargé de communiquer avec le RPC d’Aria (qui va donc envoyer des requêtes à localhost:6800) et c’est vers ce script PHP que nous enverrons nos requêtes AJAX, cette fois sur le port 443 !
Tout d’abord, on va créer une classe Aria2 :
<?php class Aria2 { protected $ch; public function __construct() { $this->ch = curl_init(); curl_setopt_array($this->ch, [ CURLOPT_RETURNTRANSFER=>true, CURLOPT_HEADER=>false ]); } public function __destruct() { curl_close($this->ch); } // Construction de l'URL à requêter à partir du tableau de paramètres protected function req($data) { $url = 'http://127.0.0.1:6800/jsonrpc?'; foreach ($data as $c => $d) { $url .= $c . '=' . $d . '&'; } $url = substr($url, 0, -1); curl_setopt($this->ch, CURLOPT_URL, $url); return curl_exec($this->ch); } // On parcourt les POST et on construit un appel vers le RPC public function multicall() { $data = array(); foreach($_POST as $c => $g) { $data[$c] = $g; } $response = $this->req($data); if($response===false) { trigger_error(curl_error($this->ch)); } return $response; } } ?>
Et un fichier jsonrpc.php :
<?php require('Aria2.php'); $aria = new Aria2(); echo $aria->multicall(); ?>
Il ne nous reste plus qu’à modifier le fichier jsoncall.js présent dans le dossier /var/www/aria2webui/js/service/rpc/ comme suit :
angular .module('webui.services.rpc.jsoncall', [ 'webui.services.deps', 'webui.services.base64']) .factory('$jsoncall', ['$', '$json', '$base64', function($, JSON, base64) { return { init: function(conf) { this.avgTimeout = 2000; this.serverConf = conf; }, encode: function(obj) { return base64.btoa( JSON.stringify(obj) ); }, ariaRequest: function(url, funcName, params, success, error) { var startTime = new Date(); var conn = this; $.ajax({ url: url, timeout: this.avgTimeout, method:'POST', // Les requêtes sont maitenant envoyées en POST data: { jsonrpc: 2.0, id: 'webui', method: funcName, params: params && params.length ? this.encode(params) : undefined }, success: function(data) { conn.avgTimeout = 2000 + 3 * (new Date() - startTime); return success(data); }, error: error, dataType: 'JSON' // Et on n'a plus besoin de passer par JSONp (même domaine) }); }, invoke: function(opts) { var rpc = this; var scheme = rpc.serverConf.encrypt ? 'https' : 'http'; rpc.ariaRequest( 'jsonrpc.php', opts.name, opts.params, opts.success, function() { // check if authentication details are given, if yes then use a // hack to support http authentication otherwise emit error if (!rpc.serverConf.auth || !rpc.serverConf.auth.user) { console.log("jsonrpc disconnect!!!"); return opts.error(); } var authUrl = 'jsonrpc.php'; // hack is to basically inject an image with same uri as the aria2 rpc url, // most browsers will then cache the authentication details and we dont have // to give them next time we make a request // var img = $('img').attr("src", authUrl); // $('body').append(img); // img.remove(); // -> Plus besoin de hack, l'authentification peut être gérée // au niveau de jsonrpc.php (par exemple avec la $_SESSION) // timeout to let the image load and then make a request, setTimeout(function() { rpc.ariaRequest( authUrl, opts.name, opts.params, opts.success, function() { console.log("jsonrpc disconnect!!!"); return opts.error(); } ); }, rpc.avgTimeout); } ); } }; }]);
Petite vérification avec Firebug :
Victoire !