L’API PageSpeed v2

Dans cet article je vais revisiter l’article que j’avais écrit en mai 2012 sur l’utilisation de l’API PageSpeed de Google. Cette fois-ci c’est C++Builder XE7 qui sera utilisé avec la version 2 de l’API. Tout comme la première fois, les résultats seront présentés dans un diagramme circulaire à l’aide du contrôle TChart. En plus du code qui sera légèrement différent, un composant TImage sera utilisé pour y afficher une capture d’écran du site web.

La première étape est de créer un nouveau projet FireMonkey. Dans la Form il faut insérer un TRESTClient, un TRESTRequest, un TRESTResponse, un TChart, un TImage et un TLayout dans lequel il y aura un TEdit un TButton. On aligne le contrôle TLayout à Bottom et vous pouvez donner comme texte à votre bouton le mot « Analyser ».

Voici ce à quoi l’interface devrait ressembler:
Analyseur de site web

Dans votre fichier cpp voici la liste de fichier d’en-tête à utiliser ainsi que la macro qui va contenir votre clef d’API. N’essayez pas d’utiliser celle-ci, il s’agit de caractères écrits de façon aléatoire.

#include <System.JSON.hpp>
#include <FMXTee.Series.hpp>
#include <System.NetEncoding.hpp>
#define GOOGLEAPIKEY "dskk1j3sW4WBYdkjds8sSDSD" // Clef d'API

Voici le code à ajouter dans votre constructeur:

    Chart1->Title->Text->Text = "Statistique de la page";
    Chart1->Legend->Title->Text->Text = "Ressource en octets";
    Chart1->Legend->Alignment = TLegendAlignment::laBottom;
    Chart1->BevelOuter = TPanelBevel::bvNone;
    Series::TPieSeries *Series = new Series::TPieSeries(this);
    Series->Marks->Visible = false;
    Chart1->AddSeries(Series);

Étant donné que nous accéderons à un site web qui utilise SSL (https), les fichiers ssleay32.dll et libeay32.dll devront être distribués avec votre application Windows. Une version Win32 et Win64 des fichiers est disponible sur le site web suivant: http://indy.fulgan.com/SSL.

La prochaine étape est d’ajouter le code dans l’événement OnClick du bouton.

    Chart1->Series[0]->Clear(); // Efface le contenu du diagramme

    RESTClient1->BaseURL =
        "https://www.googleapis.com/pagespeedonline/v2/runPagespeed?url=" +
        Edit1->Text + "&key=" GOOGLEAPIKEY + "&screenshot=true";
    RESTRequest1->Execute();

    TJSONObject* Obj = static_cast<TJSONObject*>(RESTResponse1->JSONValue);
    TJSONPair* Pair = Obj->Get("pageStats");
    if(Pair)
    {
        TJSONNumber* Answer;
        TJSONObject* PageStats = static_cast<TJSONObject*>(Pair->JsonValue);
        if((Pair = PageStats->Get("htmlResponseBytes")) != NULL)
        {
            Answer = static_cast<TJSONNumber*>(Pair->JsonValue);
            Chart1->Series[0]->Add(Answer->AsInt, "HTML", TAlphaColor(claGreen));
        }
        if((Pair = PageStats->Get("cssResponseBytes")) != NULL)
        {
            Answer = static_cast<TJSONNumber*>(Pair->JsonValue);
            Chart1->Series[0]->Add(Answer->AsInt, "CSS", TAlphaColor(claOrange));
        }
        if((Pair = PageStats->Get("imageResponseBytes")) != NULL)
        {
            Answer = static_cast<TJSONNumber*>(Pair->JsonValue);
            Chart1->Series[0]->Add(Answer->AsInt, "Image", TAlphaColor(claYellow));
        }
        if((Pair = PageStats->Get("javascriptResponseBytes")) != NULL)
        {
            Answer = static_cast<TJSONNumber*>(Pair->JsonValue);
            Chart1->Series[0]->Add(Answer->AsInt, "JavaScript", TAlphaColor(claRed));
        }
        if((Pair = PageStats->Get("otherResponseBytes")) != NULL)
        {
            Answer = static_cast<TJSONNumber*>(Pair->JsonValue);
            Chart1->Series[0]->Add(Answer->AsInt, "Autre", TAlphaColor(claBlue));
        }
    }
    Pair = Obj->Get("screenshot");
    if(Pair)
    {
        TJSONObject* Screenshot = static_cast<TJSONObject*>(Pair->JsonValue);
        if((Pair = Screenshot->Get("data")) != NULL)
        {
            TJSONString* Answer = static_cast<TJSONString*>(Pair->JsonValue);
            String Value = Answer->Value();
            // On change de base64url à base64
            Value = ReplaceStr(ReplaceStr(Value, "_", "/"), "-", "+");
            // On transforme de base64 vers stream
            TBytes LDAta = TNetEncoding::Base64->DecodeStringToBytes(Value);
            TBytesStream* LStream = new TBytesStream(LDAta);
            try
            {
                Image1->Bitmap->LoadFromStream(LStream);
            }
            __finally
            {
                delete LStream;
            }
        }
    }

Un petit mot sur la ligne 49. La documentation de l’API PageSpeed à propos des données de l’image dit:

Base64-encoded screenshot of the page that was analyzed.

Les données peuvent comporter des caractères moins (-) et souligné (_), donc la documentation est erronée si on se fie à RFC 4648 section 5:

This encoding may be referred to as « base64url ». This encoding should not be regarded as the same as the « base64 » encoding and should not be referred to as only « base64 ». Unless clarified otherwise, « base64 » refers to the base 64 in the previous section.

This encoding is technically identical to the previous one, except for the 62:nd and 63:rd alphabet character, as indicated in Table 2.

Google n’aurait donc pas dû dire qu’il s’agit de base64. Il aurait dû dire que c’est du base64url. C’est pour cette raison que je remplace les deux caractères.

Pourtant, dans d’autres API comme celui de Gmail, Google met la bonne information:

The entire email message in an RFC 2822 formatted and base64url encoded string.

En terminant, je vous rappelle qu’un nouvel outil dans RAD Studio XE7 vous permet de tester les API REST. Il se trouve Tools / Rest Debugger. Voici une capture d’écran du logiciel:
RESTDebugger