Comment afficher simplement les requêtes HTTPS émises par une application java Link to heading

Si on veut connaître les requêtes https (et leur contenu) émises par une application java, on peut ajouter cette option au démarrage de la VM : -Djavax.net.debug=ssl:record:plaintext. On trouvera dans la sortie standard du processus java les requêtes https émises en clair, ainsi que plusieurs autres informations produites par JSSE (Java secure socket extension) comme les certificats des hôtes contactés.

Cela peut s’avérer utile pour mieux en comprendre le fonctionnement d’un composant qu’on connait mal et qui produit peu de logs, vérifier les en-têtes http produites, les paramètre utilisés ou encore les redirections.

Attention des données confidentielles comme des tokens peuvent apparaître dans la sortie standard

Exemple Link to heading

On va observer le comportement la méthode URLConnection#connect qui par défaut suit les redirections HTTP avec le code suivant :

package poc.java;

import java.io.IOException;
import java.net.URI;
import java.net.URLConnection;

public class LogHttps {
    public static void main(String[] args) throws IOException {
        URLConnection connection = URI.create("https://packages.debian.org/").toURL().openConnection();
        connection.connect();
        System.out.println(connection.getContentLength());
    }
}

Si on lance la jvm de la sorte : java -Djavax.net.debug=ssl:record:plaintext -classpath . poc.java.LogHttps

On obtient des sorties de la sorte dans la console qui concernent :

  • les algorithmes de chiffrement utilisés et leur configuration
  • la version de TLS utilisée
  • l’affichage de tous les paquets chiffrés et déchiffrés pour la couche de chiffrement de la JVM : cela comprend les requêtes http et les réponses ainsi que les certificats envoyés par les serveurs

Si on se limite aux sorties concernant les requêtes https et les réponses, on a les informations suivantes :

javax.net.ssl|DEBUG|30|main|2025-04-07 08:20:16.436 CEST|SSLCipher.java:2030|Plaintext before ENCRYPTION (
  0000: 47 45 54 20 2F 20 48 54   54 50 2F 31 2E 31 0D 0A  GET / HTTP/1.1..
  0010: 55 73 65 72 2D 41 67 65   6E 74 3A 20 4A 61 76 61  User-Agent: Java
  0020: 2F 32 34 0D 0A 48 6F 73   74 3A 20 70 61 63 6B 61  /24..Host: packa
  0030: 67 65 73 2E 64 65 62 69   61 6E 2E 6F 72 67 0D 0A  ges.debian.org..
  0040: 41 63 63 65 70 74 3A 20   2A 2F 2A 0D 0A 43 6F 6E  Accept: */*..Con
  0050: 6E 65 63 74 69 6F 6E 3A   20 6B 65 65 70 2D 61 6C  nection: keep-al
  0060: 69 76 65 0D 0A 0D 0A 17   00 00 00 00 00 00 00 00  ive.............
  0070: 00 00 00 00 00 00 00 00                            ........
)

...

javax.net.ssl|DEBUG|30|main|2025-04-07 08:20:16.584 CEST|SSLCipher.java:1936|Plaintext after DECRYPTION (
  0000: 48 54 54 50 2F 31 2E 31   20 33 30 32 20 46 6F 75  HTTP/1.1 302 Fou
  0010: 6E 64 0D 0A 44 61 74 65   3A 20 4D 6F 6E 2C 20 30  nd..Date: Mon, 0
  0020: 37 20 41 70 72 20 32 30   32 35 20 30 36 3A 32 30  7 Apr 2025 06:20
  0030: 3A 31 36 20 47 4D 54 0D   0A 53 65 72 76 65 72 3A  :16 GMT..Server:
  0040: 20 41 70 61 63 68 65 0D   0A 58 2D 43 6F 6E 74 65   Apache..X-Conte
  0050: 6E 74 2D 54 79 70 65 2D   4F 70 74 69 6F 6E 73 3A  nt-Type-Options:
  0060: 20 6E 6F 73 6E 69 66 66   0D 0A 58 2D 46 72 61 6D   nosniff..X-Fram
  0070: 65 2D 4F 70 74 69 6F 6E   73 3A 20 73 61 6D 65 6F  e-Options: sameo
  0080: 72 69 67 69 6E 0D 0A 52   65 66 65 72 72 65 72 2D  rigin..Referrer-
  0090: 50 6F 6C 69 63 79 3A 20   6E 6F 2D 72 65 66 65 72  Policy: no-refer
  00A0: 72 65 72 0D 0A 58 2D 58   73 73 2D 50 72 6F 74 65  rer..X-Xss-Prote
  00B0: 63 74 69 6F 6E 3A 20 31   0D 0A 50 65 72 6D 69 73  ction: 1..Permis
  00C0: 73 69 6F 6E 73 2D 50 6F   6C 69 63 79 3A 20 69 6E  sions-Policy: in
  00D0: 74 65 72 65 73 74 2D 63   6F 68 6F 72 74 3D 28 29  terest-cohort=()
  00E0: 0D 0A 53 74 72 69 63 74   2D 54 72 61 6E 73 70 6F  ..Strict-Transpo
  00F0: 72 74 2D 53 65 63 75 72   69 74 79 3A 20 6D 61 78  rt-Security: max
  0100: 2D 61 67 65 3D 31 35 35   35 32 30 30 30 0D 0A 4C  -age=15552000..L
  0110: 6F 63 61 74 69 6F 6E 3A   20 68 74 74 70 73 3A 2F  ocation: https:/
  0120: 2F 77 77 77 2E 64 65 62   69 61 6E 2E 6F 72 67 2F  /www.debian.org/
  0130: 64 69 73 74 72 69 62 2F   70 61 63 6B 61 67 65 73  distrib/packages
  0140: 0D 0A 43 6F 6E 74 65 6E   74 2D 4C 65 6E 67 74 68  ..Content-Length
  0150: 3A 20 32 39 33 0D 0A 4B   65 65 70 2D 41 6C 69 76  : 293..Keep-Aliv
  0160: 65 3A 20 74 69 6D 65 6F   75 74 3D 35 2C 20 6D 61  e: timeout=5, ma
  0170: 78 3D 31 30 30 0D 0A 43   6F 6E 6E 65 63 74 69 6F  x=100..Connectio
  0180: 6E 3A 20 4B 65 65 70 2D   41 6C 69 76 65 0D 0A 43  n: Keep-Alive..C
  0190: 6F 6E 74 65 6E 74 2D 54   79 70 65 3A 20 74 65 78  ontent-Type: tex
  01A0: 74 2F 68 74 6D 6C 3B 20   63 68 61 72 73 65 74 3D  t/html; charset=
  01B0: 69 73 6F 2D 38 38 35 39   2D 31 0D 0A 0D 0A 3C 21  iso-8859-1....<!
  01C0: 44 4F 43 54 59 50 45 20   48 54 4D 4C 20 50 55 42  DOCTYPE HTML PUB
  01D0: 4C 49 43 20 22 2D 2F 2F   49 45 54 46 2F 2F 44 54  LIC "-//IETF//DT
  01E0: 44 20 48 54 4D 4C 20 32   2E 30 2F 2F 45 4E 22 3E  D HTML 2.0//EN">
  01F0: 0A 3C 68 74 6D 6C 3E 3C   68 65 61 64 3E 0A 3C 74  .<html><head>.<t
  0200: 69 74 6C 65 3E 33 30 32   20 46 6F 75 6E 64 3C 2F  itle>302 Found</
  0210: 74 69 74 6C 65 3E 0A 3C   2F 68 65 61 64 3E 3C 62  title>.</head><b
  0220: 6F 64 79 3E 0A 3C 68 31   3E 46 6F 75 6E 64 3C 2F  ody>.<h1>Found</
  0230: 68 31 3E 0A 3C 70 3E 54   68 65 20 64 6F 63 75 6D  h1>.<p>The docum
  0240: 65 6E 74 20 68 61 73 20   6D 6F 76 65 64 20 3C 61  ent has moved <a
  0250: 20 68 72 65 66 3D 22 68   74 74 70 73 3A 2F 2F 77   href="https://w
  0260: 77 77 2E 64 65 62 69 61   6E 2E 6F 72 67 2F 64 69  ww.debian.org/di
  0270: 73 74 72 69 62 2F 70 61   63 6B 61 67 65 73 22 3E  strib/packages">
  0280: 68 65 72 65 3C 2F 61 3E   2E 3C 2F 70 3E 0A 3C 68  here</a>.</p>.<h
  0290: 72 3E 0A 3C 61 64 64 72   65 73 73 3E 41 70 61 63  r>.<address>Apac
  02A0: 68 65 20 53 65 72 76 65   72 20 61 74 20 70 61 63  he Server at pac
  02B0: 6B 61 67 65 73 2E 64 65   62 69 61 6E 2E 6F 72 67  kages.debian.org
  02C0: 20 50 6F 72 74 20 34 34   33 3C 2F 61 64 64 72 65   Port 443</addre
  02D0: 73 73 3E 0A 3C 2F 62 6F   64 79 3E 3C 2F 68 74 6D  ss>.</body></htm
  02E0: 6C 3E 0A                                           l>.
)

...

javax.net.ssl|DEBUG|30|main|2025-04-07 08:20:17.907 CEST|SSLSocketOutputRecord.java:334|WRITE: TLSv1.3 application_data, length = 114
javax.net.ssl|DEBUG|30|main|2025-04-07 08:20:17.907 CEST|SSLCipher.java:2030|Plaintext before ENCRYPTION (
  0000: 47 45 54 20 2F 64 69 73   74 72 69 62 2F 70 61 63  GET /distrib/pac
  0010: 6B 61 67 65 73 20 48 54   54 50 2F 31 2E 31 0D 0A  kages HTTP/1.1..
  0020: 55 73 65 72 2D 41 67 65   6E 74 3A 20 4A 61 76 61  User-Agent: Java
  0030: 2F 32 34 0D 0A 48 6F 73   74 3A 20 77 77 77 2E 64  /24..Host: www.d
  0040: 65 62 69 61 6E 2E 6F 72   67 0D 0A 41 63 63 65 70  ebian.org..Accep
  0050: 74 3A 20 2A 2F 2A 0D 0A   43 6F 6E 6E 65 63 74 69  t: */*..Connecti
  0060: 6F 6E 3A 20 6B 65 65 70   2D 61 6C 69 76 65 0D 0A  on: keep-alive..
  0070: 0D 0A 17 00 00 00 00 00   00 00 00 00 00 00 00 00  ................
  0080: 00 00 00                                           ...
)

...

javax.net.ssl|DEBUG|30|main|2025-04-07 08:20:17.974 CEST|SSLSocketInputRecord.java:214|READ: TLSv1.2 application_data, length = 8209
javax.net.ssl|DEBUG|30|main|2025-04-07 08:20:17.974 CEST|SSLSocketInputRecord.java:247|READ: TLSv1.2 application_data, length = 8209
javax.net.ssl|DEBUG|30|main|2025-04-07 08:20:17.985 CEST|SSLCipher.java:1936|Plaintext after DECRYPTION (
  0000: 48 54 54 50 2F 31 2E 31   20 32 30 30 20 4F 4B 0D  HTTP/1.1 200 OK.
  0010: 0A 44 61 74 65 3A 20 4D   6F 6E 2C 20 30 37 20 41  .Date: Mon, 07 A
  0020: 70 72 20 32 30 32 35 20   30 36 3A 32 30 3A 31 37  pr 2025 06:20:17
  0030: 20 47 4D 54 0D 0A 53 65   72 76 65 72 3A 20 41 70   GMT..Server: Ap
  0040: 61 63 68 65 0D 0A 43 6F   6E 74 65 6E 74 2D 4C 6F  ache..Content-Lo
  0050: 63 61 74 69 6F 6E 3A 20   70 61 63 6B 61 67 65 73  cation: packages
  0060: 2E 65 6E 2E 68 74 6D 6C   0D 0A 56 61 72 79 3A 20  .en.html..Vary: 
  0070: 6E 65 67 6F 74 69 61 74   65 2C 61 63 63 65 70 74  negotiate,accept
  0080: 2D 6C 61 6E 67 75 61 67   65 2C 41 63 63 65 70 74  -language,Accept
  0090: 2D 45 6E 63 6F 64 69 6E   67 2C 63 6F 6F 6B 69 65  -Encoding,cookie
  00A0: 0D 0A 54 43 4E 3A 20 63   68 6F 69 63 65 0D 0A 58  ..TCN: choice..X
  00B0: 2D 43 6F 6E 74 65 6E 74   2D 54 79 70 65 2D 4F 70  -Content-Type-Op
  00C0: 74 69 6F 6E 73 3A 20 6E   6F 73 6E 69 66 66 0D 0A  tions: nosniff..
  00D0: 58 2D 46 72 61 6D 65 2D   4F 70 74 69 6F 6E 73 3A  X-Frame-Options:
  00E0: 20 73 61 6D 65 6F 72 69   67 69 6E 0D 0A 52 65 66   sameorigin..Ref
  00F0: 65 72 72 65 72 2D 50 6F   6C 69 63 79 3A 20 6E 6F  errer-Policy: no
  0100: 2D 72 65 66 65 72 72 65   72 0D 0A 58 2D 58 73 73  -referrer..X-Xss
  0110: 2D 50 72 6F 74 65 63 74   69 6F 6E 3A 20 31 0D 0A  -Protection: 1..
  0120: 50 65 72 6D 69 73 73 69   6F 6E 73 2D 50 6F 6C 69  Permissions-Poli
  0130: 63 79 3A 20 69 6E 74 65   72 65 73 74 2D 63 6F 68  cy: interest-coh
  0140: 6F 72 74 3D 28 29 0D 0A   53 74 72 69 63 74 2D 54  ort=()..Strict-T
  0150: 72 61 6E 73 70 6F 72 74   2D 53 65 63 75 72 69 74  ransport-Securit
  0160: 79 3A 20 6D 61 78 2D 61   67 65 3D 31 35 35 35 32  y: max-age=15552
  0170: 30 30 30 0D 0A 55 70 67   72 61 64 65 3A 20 68 32  000..Upgrade: h2
  0180: 2C 68 32 63 0D 0A 43 6F   6E 6E 65 63 74 69 6F 6E  ,h2c..Connection
  0190: 3A 20 55 70 67 72 61 64   65 2C 20 4B 65 65 70 2D  : Upgrade, Keep-
  01A0: 41 6C 69 76 65 0D 0A 4C   61 73 74 2D 4D 6F 64 69  Alive..Last-Modi
  01B0: 66 69 65 64 3A 20 54 68   75 2C 20 32 37 20 4D 61  fied: Thu, 27 Ma
  01C0: 72 20 32 30 32 35 20 31   35 3A 32 38 3A 35 35 20  r 2025 15:28:55 
  01D0: 47 4D 54 0D 0A 45 54 61   67 3A 20 22 33 65 32 66  GMT..ETag: "3e2f
  01E0: 2D 36 33 31 35 34 39 63   61 35 61 64 37 34 3B 36  -631549ca5ad74;6
  01F0: 33 32 32 38 31 39 36 66   30 38 35 64 0D 0A 41 63  3228196f085d..Ac
  0200: 63 65 70 74 2D 52 61 6E   67 65 73 3A 20 62 79 74  cept-Ranges: byt
  0210: 65 73 0D 0A 43 6F 6E 74   65 6E 74 2D 4C 65 6E 67  es..Content-Leng
  0220: 74 68 3A 20 31 35 39 31   39 0D 0A 43 61 63 68 65  th: 15919..Cache
  0230: 2D 43 6F 6E 74 72 6F 6C   3A 20 6D 61 78 2D 61 67  -Control: max-ag
  0240: 65 3D 38 36 34 30 30 0D   0A 45 78 70 69 72 65 73  e=86400..Expires
  0250: 3A 20 54 75 65 2C 20 30   38 20 41 70 72 20 32 30  : Tue, 08 Apr 20
  0260: 32 35 20 30 36 3A 32 30   3A 31 37 20 47 4D 54 0D  25 06:20:17 GMT.
  0270: 0A 58 2D 43 6C 61 63 6B   73 2D 4F 76 65 72 68 65  .X-Clacks-Overhe
  0280: 61 64 3A 20 47 4E 55 20   54 65 72 72 79 20 50 72  ad: GNU Terry Pr
  0290: 61 74 63 68 65 74 74 0D   0A 4B 65 65 70 2D 41 6C  atchett..Keep-Al
  02A0: 69 76 65 3A 20 74 69 6D   65 6F 75 74 3D 35 2C 20  ive: timeout=5, 
  02B0: 6D 61 78 3D 31 30 30 0D   0A 43 6F 6E 74 65 6E 74  max=100..Content
  02C0: 2D 54 79 70 65 3A 20 74   65 78 74 2F 68 74 6D 6C  -Type: text/html
  02D0: 0D 0A 43 6F 6E 74 65 6E   74 2D 4C 61 6E 67 75 61  ..Content-Langua
  02E0: 67 65 3A 20 65 6E 0D 0A   0D 0A 3C 21 44 4F 43 54  ge: en....<!DOCT
  02F0: 59 50 45 20 48 54 4D 4C   20 50 55 42 4C 49 43 20  YPE HTML PUBLIC 
  0300: 22 2D 2F 2F 57 33 43 2F   2F 44 54 44 20 48 54 4D  "-//W3C//DTD HTM
  0310: 4C 20 34 2E 30 31 2F 2F   45 4E 22 20 22 68 74 74  L 4.01//EN" "htt
  0320: 70 3A 2F 2F 77 77 77 2E   77 33 2E 6F 72 67 2F 54  p://www.w3.org/T
  0330: 52 2F 68 74 6D 6C 34 2F   73 74 72 69 63 74 2E 64  R/html4/strict.d
  0340: 74 64 22 3E 0A 3C 68 74   6D 6C 20 6C 61 6E 67 3D  td">.<html lang=
  0350: 22 65 6E 22 3E 0A 3C 68   65 61 64 3E 0A 20 20 3C  "en">.<head>.  <
  0360: 6D 65 74 61 20 68 74 74   70 2D 65 71 75 69 76 3D  meta http-equiv=
  0370: 22 43 6F 6E 74 65 6E 74   2D 54 79 70 65 22 20 63  "Content-Type" c
  0380: 6F 6E 74 65 6E 74 3D 22   74 65 78 74 2F 68 74 6D  ontent="text/htm
  0390: 6C 3B 20 63 68 61 72 73   65 74 3D 75 74 66 2D 38  l; charset=utf-8
  03A0: 22 3E 0A 20 20 3C 74 69   74 6C 65 3E 44 65 62 69  ">.  <title>Debi
  03B0: 61 6E 20 2D 2D 20 50 61   63 6B 61 67 65 73 20 3C  an -- Packages <
  03C0: 2F 74 69 74 6C 65 3E 0A   20 20 3C 6C 69 6E 6B 20  /title>.  <link 
...

La séquence des appels a été la suivante :

  1. GET packages.debian.org
  2. Réponse 302 avec l’en-tête Location: https://www.debian.org/distrib/packages
  3. GET www.debian.org/distrib/packages
  4. Réponse 200 avec le contenu de la page

URLConnection#connect a bien suivi la redirection automatiquement.

A la fin, la taille du contenu affiché dans la console correspond bien au Content-length du deuxième GET.

Alternative avec java.util.logging Link to heading

En activant des niveaux plus fins de log avec java.util.logging, on peut également récupérer des informations sur :

  • le proxy utilisé (ou non)
  • la requête http exécutée (verbe et url)
  • les en-têtes (requête et réponse)
  • code retour http
  • le suivi de la redirection

L’activation d’un niveau de log plus fin pour les connexions via URLConnection#connect fonctionne en définissant un fichier de configuration personnalisé pour java.util.logging via la propriété java.util.logging.config.file. Pour obtenir le fichier personnalisé pour loguer dans la console, partir du fichier de configuration par défaut ($JAVA_HOME/conf/logging.properties) et :

  • modifier la valeur de java.util.logging.ConsoleHandler.level en FINEST
  • ajouter la ligne sun.net.www.protocol.http.level = FINEST : nouveau logger en FINEST pour le package sun.net.www.protocol.http

… qui ne fonctionne pas avec HttpClient Link to heading

Néanmoins cette dernière solution ne permet de loguer que les connexions avec URLConnection#connect : les logs ne sont pas affichées si on utilise HttpClient à la place :

HttpClient.newBuilder()
         .followRedirects(HttpClient.Redirect.NORMAL) /*pour avoir le même comportement que URLConnection#connect pour les redirections*/
         .build()
         .send(HttpRequest.newBuilder()
                        .uri(URI.create("https://packages.debian.org/"))
                        .GET()
                        .build(),
                HttpResponse.BodyHandlers.discarding())
        .headers().firstValue("Content-Length").get();

Pour avoir des logs à peu près équivalentes avec HttpClient, il faudra activer l’option -Djdk.httpclient.HttpClient.log=requests,headers,content sur la ligne de commande.

… ce qui fait de javax.net.debug une option préférable Link to heading

-Djavax.net.debug=ssl:record:plaintext qui intervient au niveau de la couche SSL, appelée dans les deux cas, permet d’afficher les informations quelle que soir la méthode utilisée pour accéder à une ressource désignée par une URL en https.

Références Link to heading