Bonjour,

Nous observons une différence entre Delphi 11.1 et 11.3 sur les réponses REST, différence qui créé un dysfonctionnement sur un process de notre application en communication avec Microsoft Azure/Graph.

Requête : "https://graph.microsoft.com/v1.0/me"

Dans le RestDebogueur
- Delphi 11.1 = le corps contient bien résultat attendu (Json)
- Delphi 11.2 et 3 = le corps reste vide

Avec PostMan le corps contient bien résultat attendu (Json), (idem Delphi 11.1).

Après recherche dans le code entre les deux versions de Delphi, il apparaît que le code a évolué dans la procedure "TCustomRESTRequest.Execute" de l'unité REST.Client, lors du traitement du Charset et ContentType

11.1 : REST.Client ligne 3253 à 3285
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
        
        LContentIsString := False;
        LEncoding := nil;
        try
          LLowerContentType := LowerCase(Client.HTTPClient.Response.ContentType);
          LCharSet := Client.HTTPClient.Response.CharSet;
          if LCharSet <> '' then
            LContentIsString := True
          else
          begin
            TMimeTypes.Default.GetTypeInfo(LLowerContentType, LExt, LMimeKind);
            // Skip if blank or 'raw'
            if (FClient.FallbackCharsetEncoding <> '') and
               not SameText(REST_NO_FALLBACK_CHARSET, FClient.FallbackCharsetEncoding) then
            begin
              // Skip some obvious binary types
              if LMimeKind <> TMimeTypes.TKind.Binary then
              begin
                LEncoding := TEncoding.GetEncoding(FClient.FallbackCharsetEncoding);
                LContentIsString := True;
              end;
            end
            else
            begin
              // Even if no fallback, handle some obvious string types
              if LMimeKind = TMimeTypes.TKind.Text then
                LContentIsString := True;
            end;
          end;
          if LContentIsString then
            LContent := FClient.HTTPClient.Response.ContentAsString(LEncoding);
        finally
          LEncoding.Free;
        end;

11.3 : REST.Client ligne 3269 à 3317
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
        LContentIsString := False;
        LEncoding := nil;
        LTryFallback := True;
        try
          LLowerContentType := LowerCase(Client.HTTPClient.Response.ContentType);
          if LLowerContentType <> '' then
            TMimeTypes.Default.GetTypeInfo(LLowerContentType, LExt, LMimeKind)
          else
            LMimeKind := TMimeTypes.TKind.Text;
          // Try "charset", skip if blank
          if Client.HTTPClient.Response.CharSet <> '' then
          begin
            LTryFallback := False;
            // Handle some obvious text types
            if LMimeKind = TMimeTypes.TKind.Text then
            begin
              try
                LEncoding := TEncoding.GetEncoding(Client.HTTPClient.Response.CharSet);
                LContentIsString := True;
              except
                LTryFallback := True;
              end;
            end;
          end;
          if LTryFallback then
          begin
            // Try fallback charset, skip if blank or 'raw'
            if (FClient.FallbackCharsetEncoding <> '') and
               not SameText(REST_NO_FALLBACK_CHARSET, FClient.FallbackCharsetEncoding) then
            begin
              // Handle some obvious text types
              if LMimeKind = TMimeTypes.TKind.Text then
              begin
                LEncoding := TEncoding.GetEncoding(FClient.FallbackCharsetEncoding);
                LContentIsString := True;
              end;
            end
            else
            // Even if no fallback, handle some obvious text types
            begin
              if LMimeKind = TMimeTypes.TKind.Text then
                LContentIsString := True;
            end;
          end;
          if LContentIsString then
            LContent := FClient.HTTPClient.Response.ContentAsString(LEncoding);
        finally
          LEncoding.Free;
        end;
Dans le 1° cas, le test du CharSet nous envoie directement sur la récupération du Content
Ce que nous attendons

Dans le 2° cas, le ContentType est analysé avant le test du CharSet (dans notre cas "application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false")
lorsque le ContentType est
- rigoureusement égal à 'application/json', "LMimeKind" est positionné sur "Text"
- n'est pas rigoureusement égal, "LMimeKind" est positionné sur "Undifined" et le Content n'est pas récupéré et reste vide

Autrement dit il manque un split du Content-type avant analyse, en l'état le retour du Content-type par Graph pose problème, nous avons essayé de voir comment le rendre plus concis ("accept=application/json") sans succès.

En espérant partager notre expérience et en remerciant ceux qui se pencheront éventuellement dessus.