Il y a quelques jours, avec un collègue de travail, on vient à parler des raccourcisseurs d'URL. Un raccourcisseur d'URL est un système qui permet de réduire la longueur d'une URL.

Pour rappel, une URL est de la forme : protocole://sous-domaine.domaine.tld

C'est la représentation textuelle d'une adresse IP.

Pour rappel, une adresse IP est de la forme : 192.168.1.0

C'est une sorte de numéro de téléphone qui peut être global ou local (accessible depuis l’extérieur ou simplement à l'intérieur de votre entreprise).

Prenons l'exemple de cette URL :

https://www.google.fr

Elle n'est pas trop longue et peut facilement être intégrée dans tous types de messages.

Là où le raccourcisseur entre en jeu, c'est lorsque l'URL ressemble à ceci :

http://www.probikeshop.fr/vtt/velos-complets-vtt-complets-c10096.html#t=255&typeSearch=1&minPrice=8509&maxPrice=10000&page=1&search=10096

Dans certains cas, nous sommes limités dans le nombre de caractères (sms, post Facebook, etc...). Même si la tendance générale vise à supprimer toutes formes de limitations, il est plus confortable d'afficher des URL courtes pour ne pas empiéter sur le contenu de notre message.

Revenons à la discussion avec mon collègue :-)

Il me dit qu'il ne comprends pas comment cela fonctionne. Je lui réponds basiquement, "C'est simple, c'est un système qui stocke une paire clé / valeur pour que, lorsque tu lui donne une clé, il te retourne une valeur.".

Quelques jours passent, et je repense à cette conversation. Je commence à imaginer comment on pourrait vraiment construire un tel système.

Et rapidement, je me heurte à certaines complications. Ma réponse de l'autre jour était vraiment simpliste :-p

via GIPHY

C'est là que j'ai décidé de le créer pour de vrai histoire d'en comprendre les mécanismes.

Je préviens tout de suite, c'est une application très simple, je n'ai pas la prétention d'avoir inventé l’algorithme du siècle :-p Mais ça fonctionne ;-)

Comme pour tout projet, chez moi, ça se passe en trois grandes phases.

  • La conception sur papier
  • La réalisation du code
  • La personnalisation graphique

1. La conception sur papier

Durant la première phase j'ai commencé à penser aux objectifs principaux d'un raccourcisseur d'URL.

Il faut que l'URL soit la plus courte possible et il faut que l'URL raccourcie ne soit lié qu'à une seule URL soumise par un ou plusieurs utilisateurs.

Il va donc falloir trouver un moyen de générer une clé unique que nous allons stocker dans une base de données et qui va identifier une URL soumise par un utilisateur.

Je pars sur un schéma de base simple :

id | shortened_url | original_url | hits  

Où :

  • id est l'identifiant de l'enregistrement dans la base de données
  • shortened_url est notre clé unique
  • original_url est l'URL soumise par l'utilisateur
  • hits le nombre de fois que cette URL raccourcie est appelée

Voici le scénario complet (cas où tout se passe bien) :

  • Alice veut envoyer à Bob une URL longue
  • Elle copie l'URL longue et la colle dans un champ vide
  • Elle clique sur un bouton pour obtenir une URL raccourcie
  • Si l'URL longue existe déjà dans la base de données, on lui retourne cette dernière
  • Sinon, on génère une valeur pour shortened_url, on enregistre une nouvelle ligne dans notre base de données et on retourne l'URL raccourcie

Comme cité précédemment, il faut que l'URL raccourcie soit courte. Cela passe également par un nom de domaine court. Je me lance donc à la recherche d'un nom de domaine court et disponible à l'achat.

Moi choix s'arrête sur le domaine : t3d.in

On a quand même six caractères mais je n'ai pas trouvé mieux et puis, je ne voulais pas passer une heure à chercher :-p

Maintenant je me concentre sur la génération du shortened_url...

Deux approches me viennent à l'idée :

  • Générer aléatoirement une suite de symboles (lettres et chiffres)
  • Attribuer au fur et à mesure des demandes une suite de symboles (lettres et chiffres)

La première option est tentante mais il va falloir gérer les collisions. Il ne faudrait pas que pour une même URL longue on donne deux URL raccourcies identiques.

Il faudrait, par exemple, à chaque attribution vérifier que l'URL raccourcie n'a pas déjà était attribuée. Ce n'est pas vraiment un problème lorsque l'on doit vérifier 10 enregistrements mais au bout du millionième...? Je n'ai pas vraiment de l'idée du coût (le coût en informatique fait référence au travail que doit effectuer un système pour réaliser une tâche. Il peut s'exprimer en temps, en occupation de ressources systèmes, etc...) mais ce n'est surement pas neutre à grand volume.

Je pars donc sur la deuxième approche.

Pour générer la suite de symboles, je suis parti de notre alphabet en minuscule et majuscule plus l'ensemble des chiffres de 0 à 9.

On va donc créer un tableau comme celui-ci :

[0,1,2...7,8,9,a,b,c...x,y,z,A,B,C...X,Y,Z]

On va par conséquent attribuer les symboles de gauche à droite. Une fois que nous atteignons Z, on recommence à zéro et ainsi de suite.

La première URL raccourcie sera donc http://t3d.in/0

Comme vous l'avez compris, les URL raccourcies par cette application sont publiques et facilement consultables, il suffit d'itérer en utilisant le même tableau que celui précédemment cité.

Pour "bloquer" un peu cela, j'ai pensé à limiter le nombres de requêtes possibles par minute à 10. Du coup, à défaut de vous bloquer, ça va au moins vous ralentir :-p Sans gêner une utilisation normale de l'application pour un utilisateur lambda.

2. La réalisation du code

Pour réaliser le projet j'ai décidé de prendre une instance Digital Ocean avec une installation "one-click" de Django. Django est un framework Python très complet.

La mauvaise surprise avec cette installation "one-click" c'est que Digital Ocean à utilisé la version 1.6 de Django (on utilise actuellement la 1.10) et que la distribution utilisée est une Ubuntu 14.04 (on est actuellement à la version 16.04).

Ceci étant dit, il on pré-configuré gunicorn comme serveur de production et ngixn comme reverse-proxy pour mapper le port gunicorn au port public de votre serveur. Si on ne l'a jamais fait, ça donne pas mal d'aide pour configurer le tout. Même si c'est vraiment simple.

Je ne m'étale pas trop sur le code. Il est disponible dans mon Github (https://github.com/TeddyBear06/mus).

Si vous ne connaissez pas Django je vous invite à consulter leur très beau tutoriel (https://docs.djangoproject.com/fr/1.10/intro/tutorial01/), si vous suivez toutes les étapes vous aurez une belle vue d'ensemble de son fonctionnement.

3. La personnalisation graphique

C'est un petit projet, je n'avais pas trop envie de faire un truc super "fancy". J'ai préféré une approche vraiment minimaliste. L'objectif c'était d'avoir un outil utilisable autant sur mobile que sur desktop.

Ce que je voulais, c'était ajouter une fonctionnalité qui permettait sur mobile de copier le lien généré directement dans son presse-papier pour éviter le possible laborieux copier/coller.

Du coup, ça donne ça au final :

Mus screenshot

And voilà !

Bon je peux rajouter une tonne de fonctionnalités, mais ce que je voulais, c'était produire un outil dont je vais moi même me servir au quotidien.

Si jamais il peut vous être utile... Tant mieux !

Une petite note pour vous rappelez que les URL partagées sont publiques et que je ne pourrais en aucun cas être tenu responsable du non-fonctionnement de la plateforme de raccourcissement d'URL.

Sur ce, @ bientôt les amis :-) !

Crédit photo :