"http.client" --- HTTP protocol client
**************************************

**Code source :** Lib/http/client.py

======================================================================

This module defines classes that implement the client side of the HTTP
and HTTPS protocols.  It is normally not used directly --- the module
"urllib.request" uses it to handle URLs that use HTTP and HTTPS.

Voir aussi:

  The Requests package is recommended for a higher-level HTTP client
  interface.

Note:

  L'implémentation d'HTTPS n'est disponible que si Python a été
  compilé avec la prise en charge de SSL (au moyen du module "ssl").

Availability: not Emscripten, not WASI.

This module does not work or is not available on WebAssembly platforms
"wasm32-emscripten" and "wasm32-wasi". See Plateformes WebAssembly for
more information.

Le module fournit les classes suivantes :

class http.client.HTTPConnection(host, port=None, [timeout, ]source_address=None, blocksize=8192)

   An "HTTPConnection" instance represents one transaction with an
   HTTP server.  It should be instantiated by passing it a host and
   optional port number.  If no port number is passed, the port is
   extracted from the host string if it has the form "host:port", else
   the default HTTP port (80) is used.  If the optional *timeout*
   parameter is given, blocking operations (like connection attempts)
   will timeout after that many seconds (if it is not given, the
   global default timeout setting is used). The optional
   *source_address* parameter may be a tuple of a (host, port) to use
   as the source address the HTTP connection is made from. The
   optional *blocksize* parameter sets the buffer size in bytes for
   sending a file-like message body.

   Par exemple, tous les appels suivants créent des instances qui se
   connectent à un serveur sur le même hôte et le même port :

      >>> h1 = http.client.HTTPConnection('www.python.org')
      >>> h2 = http.client.HTTPConnection('www.python.org:80')
      >>> h3 = http.client.HTTPConnection('www.python.org', 80)
      >>> h4 = http.client.HTTPConnection('www.python.org', 80, timeout=10)

   Modifié dans la version 3.2: Le paramètre *source_address* a été
   ajouté.

   Modifié dans la version 3.4: The  *strict* parameter was removed.
   HTTP 0.9-style "Simple Responses" are no longer supported.

   Modifié dans la version 3.7: Le paramètre *blocksize* a été ajouté.

class http.client.HTTPSConnection(host, port=None, *, [timeout, ]source_address=None, context=None, blocksize=8192)

   Cette sous-classe de "HTTPConnection" utilise SSL pour communiquer
   avec des serveurs sécurisés. Le port par défaut est "443". Si le
   paramètre *context* est fourni, ce doit être une instance de
   "ssl.SSLContext" décrivant les diverses options SSL.

   Il est conseillé de lire Security considerations pour plus
   d'informations sur les bonnes pratiques.

   Modifié dans la version 3.2: Les paramètres *source_address*,
   *context* et *check_hostname* ont été ajoutés.

   Modifié dans la version 3.2: This class now supports HTTPS virtual
   hosts if possible (that is, if "ssl.HAS_SNI" is true).

   Modifié dans la version 3.4: Le paramètre *strict* a été supprimé.
   Les « réponses simples » de HTTP 0.9 ne sont plus prises en charge.

   Modifié dans la version 3.4.3: This class now performs all the
   necessary certificate and hostname checks by default. To revert to
   the previous, unverified, behavior
   "ssl._create_unverified_context()" can be passed to the *context*
   parameter.

   Modifié dans la version 3.8: Cette classe sélectionne désormais TLS
   1.3 pour "ssl.SSLContext.post_handshake_auth" dans le *context* par
   défaut ou quand *cert_file* est fourni avec une valeur de *context*
   personnalisée.

   Modifié dans la version 3.10: This class now sends an ALPN
   extension with protocol indicator "http/1.1" when no *context* is
   given. Custom *context* should set ALPN protocols with
   "set_alpn_protocols()".

   Modifié dans la version 3.12: The deprecated *key_file*,
   *cert_file* and *check_hostname* parameters have been removed.

class http.client.HTTPResponse(sock, debuglevel=0, method=None, url=None)

   Classe dont les instances sont renvoyées dès qu'une connexion est
   établie.  Cette classe n'est jamais instanciée directement par
   l'utilisateur.

   Modifié dans la version 3.4: Le paramètre *strict* a été supprimé.
   Les « réponses simples » de HTTP 0.9 ne sont plus prises en charge.

Ce module fournit les fonctions suivantes :

http.client.parse_headers(fp)

   Parse the headers from a file pointer *fp* representing a HTTP
   request/response. The file has to be a "BufferedIOBase" reader
   (i.e. not text) and must provide a valid **RFC 2822** style header.

   Cette fonction renvoie une instance de "http.client.HTTPMessage"
   qui contient les champs d'en-tête, mais pas la charge utile (de
   même que "HTTPResponse.msg" et
   "http.server.BaseHTTPRequestHandler.headers"). Après le retour, le
   pointeur de fichier *fp* est prêt à lire le corps HTTP.

   Note:

     La méthode "parse_headers()" n'analyse pas la ligne initiale d'un
     message HTTP ; elle n'analyse que les lignes "Name: value". Le
     fichier doit être prêt à lire ces lignes de champs, aussi la
     première ligne doit déjà avoir été consommée avant l'appel de la
     fonction.

Les exceptions suivantes sont levées selon les cas :

exception http.client.HTTPException

   La classe de base des autres exceptions de ce module.  C'est une
   sous-classe de  "Exception".

exception http.client.NotConnected

   Sous-classe de "HTTPException".

exception http.client.InvalidURL

   Sous-classe de "HTTPException", levée si le port donné n'est pas
   numérique ou est vide.

exception http.client.UnknownProtocol

   Sous-classe de "HTTPException".

exception http.client.UnknownTransferEncoding

   Sous-classe de "HTTPException".

exception http.client.UnimplementedFileMode

   Sous-classe de "HTTPException".

exception http.client.IncompleteRead

   Sous-classe de "HTTPException".

exception http.client.ImproperConnectionState

   Sous-classe de "HTTPException".

exception http.client.CannotSendRequest

   Sous-classe de "ImproperConnectionState".

exception http.client.CannotSendHeader

   Sous-classe de "ImproperConnectionState".

exception http.client.ResponseNotReady

   Sous-classe de "ImproperConnectionState".

exception http.client.BadStatusLine

   Sous-classe de "HTTPException".  Levée si un serveur répond avec un
   code d'état HTTP qui n'est pas compris.

exception http.client.LineTooLong

   Sous-classe de "HTTPException".  Levée si une ligne du protocole
   HTTP est excessivement longue dans ce qui provient du serveur.

exception http.client.RemoteDisconnected

   Sous-classe de "ConnectionResetError" et "BadStatusLine".  Levée
   par la méthode "HTTPConnection.getresponse()" quand la tentative de
   lire la réponse n'aboutit à aucune donnée provenant de la
   connexion, indiquant ainsi que la partie distante a fermé celle-ci.

   Added in version 3.5: Antérieurement, "BadStatusLine""('')" était
   levée.

Les constantes définies dans ce module sont :

http.client.HTTP_PORT

   Le port par défaut du protocole HTTP (toujours "80").

http.client.HTTPS_PORT

   Le port par défaut du protocole HTTPS (toujours "443").

http.client.responses

   Ce dictionnaire associe les codes d'états HTTP 1.1 à leurs noms
   tels que définis par le W3C.

   Par exemple : "http.client.responses[http.client.NOT_FOUND]" est
   "'Not Found'".

Voir Codes d'état HTTP pour une liste des codes d'état HTTP qui sont
disponibles comme constantes dans ce module.


Les objets HTTPConnection
=========================

Les instances de la classe "HTTPConnection" possèdent les méthodes
suivantes :

HTTPConnection.request(method, url, body=None, headers={}, *, encode_chunked=False)

   This will send a request to the server using the HTTP request
   method *method* and the request URI *url*. The provided *url* must
   be an absolute path to conform with **RFC 2616 §5.1.2** (unless
   connecting to an HTTP proxy server or using the "OPTIONS" or
   "CONNECT" methods).

   Si *body* est passé en paramètre, les données transmises sont
   envoyées à la suite des en-têtes. Ce paramètre peut-être une "str",
   un *objet octet-comptatible*, un *objet fichier* préalablement
   ouvert, ou un itérable de classe "bytes". Si *body* est une chaîne,
   elle est encodée en ISO-8859-1, valeur par défaut pour HTTP. Si
   c'est un objet octet-compatible, les octets sont envoyés tels
   quels. Si c'est un *objet fichier*, le contenu du fichier est
   envoyé ; cet objet fichier doit implémenter au moins la méthode
   "read()". Si l'objet fichier est une instance de "io.TextIOBase",
   les données renvoyées par la méthode "read()" sont encodées en
   ISO-8859-1, sinon les données renvoyées par "read()" sont envoyées
   telles quelles. Si *body* est un itérable, les éléments de cet
   itérable sont envoyés jusqu'à ce que l'itérable soit vide.

   The *headers* argument should be a mapping of extra HTTP headers to
   send with the request. A **Host header** must be provided to
   conform with **RFC 2616 §5.1.2** (unless connecting to an HTTP
   proxy server or using the "OPTIONS" or "CONNECT" methods).

   Si *headers* ne contient ni "Content-Length:" ni "Transfer-
   Encoding:", mais qu'un corps de requête est fourni, un de ces en-
   têtes est ajouté automatiquement. Si *body* est "None", l'en-tête
   "Content-Length:" est paramétré à "0" pour les méthodes qui
   attendent un corps ("PUT", "POST", et "PATCH"). Si *body* est une
   chaîne ou un objet de type octets qui n'est pas un (*objet
   fichier*), l'en-tête "Content-Length" est paramétré à sa longueur.
   Un *body* de tout autre type (fichiers ou itérables en général) est
   encodé par morceaux et l'en-tête "Transfer-Encoding" est
   automatiquement paramétré à la place de "Content-Length".

   L'argument *encode_chunked* n'est pertinent que si l'en-tête
   "Transfer-Encoding:" est présent. Si *encode_chunked* est "False",
   l'objet  HTTPConnection suppose que l'encodage est géré par le code
   d'appel. S'il vaut "True", le corps est encodé par morceaux.

   For example, to perform a "GET" request to
   "https://docs.python.org/3/":

      >>> import http.client
      >>> host = "docs.python.org"
      >>> conn = http.client.HTTPSConnection(host)
      >>> conn.request("GET", "/3/", headers={"Host": host})
      >>> response = conn.getresponse()
      >>> print(response.status, response.reason)
      200 OK

   Note:

     L'encodage pour les transferts par morceaux a été ajouté à la
     version 1.1 du protocole HTTP. À moins que le serveur HTTP sache
     gérer HTTP 1.1, l'appelant doit soit spécifier l'en-tête
     "Content-Length:", soit passer la représentation du corps de
     message dans un objet de classe "str" ou un objet octet-
     compatible qui ne soit pas un fichier.

   Modifié dans la version 3.2: *body* peut désormais être un
   itérable.

   Modifié dans la version 3.6: Si parmi les en-têtes ne figure ni
   "Content-Length:", ni "Transfer-Encoding:", les objets fichiers et
   itérables *body* sont désormais encodés par morceaux. L'argument
   *encode_chunked* a été ajouté. Aucune tentative n'est faite pour
   essayer de déterminer la valeur de l'en-tête "Content-Length" pour
   un objet fichier.

HTTPConnection.getresponse()

   Doit être appelé après qu'une requête a été envoyée pour récupérer
   la réponse du serveur. Renvoie une instance de "HTTPResponse".

   Note:

     Notez que la totalité de la réponse doit être lue avant de
     pouvoir envoyer une nouvelle requête au serveur.

   Modifié dans la version 3.5: Si une exception "ConnectionError" ou
   une de ses sous-classes est levée, l'objet de classe
   "HTTPConnection" sera prêt à se reconnecter quand une nouvelle
   requête sera envoyée.

HTTPConnection.set_debuglevel(level)

   Règle le niveau de débogage. Le niveau de débogage par défaut est
   "0" (aucune sortie de débogage n'est affichée). Toute valeur plus
   grande que "0" provoque l'affichage sur "sys.stdout" de toutes les
   sorties de débogage actuellement définies. Le paramètre
   "debuglevel" est passé à tout nouvel objet de classe "HTTPResponse"
   qui est créé.

   Added in version 3.1.

HTTPConnection.set_tunnel(host, port=None, headers=None)

   Paramètre l'hôte et le port pour le tunnel de connexion HTTP. Il
   permet de réaliser la connexion au travers d'un serveur mandataire.

   The *host* and *port* arguments specify the endpoint of the
   tunneled connection (i.e. the address included in the CONNECT
   request, *not* the address of the proxy server).

   The *headers* argument should be a mapping of extra HTTP headers to
   send with the CONNECT request.

   As HTTP/1.1 is used for HTTP CONNECT tunnelling request, as per the
   RFC, a HTTP "Host:" header must be provided, matching the
   authority-form of the request target provided as the destination
   for the CONNECT request. If a HTTP "Host:" header is not provided
   via the headers argument, one is generated and transmitted
   automatically.

   Par exemple, pour un tunnel traversant un serveur mandataire HTTPS
   accessible localement sur le port 8080, nous devons passer
   l'adresse du serveur mandataire au constructeur de la classe
   "HTTPSConnection", en plus de l'éventuelle adresse de l'hôte que
   nous voulons atteindre, qui elle doit être passée à la méthode
   "set_tunnel()" :

      >>> import http.client
      >>> conn = http.client.HTTPSConnection("localhost", 8080)
      >>> conn.set_tunnel("www.python.org")
      >>> conn.request("HEAD","/index.html")

   Added in version 3.2.

   Modifié dans la version 3.12: HTTP CONNECT tunnelling requests use
   protocol HTTP/1.1, upgraded from protocol HTTP/1.0. "Host:" HTTP
   headers are mandatory for HTTP/1.1, so one will be automatically
   generated and transmitted if not provided in the headers argument.

HTTPConnection.get_proxy_response_headers()

   Returns a dictionary with the headers of the response received from
   the proxy server to the CONNECT request.

   If the CONNECT request was not sent, the method returns "None".

   Added in version 3.12.

HTTPConnection.connect()

   Se connecte au serveur spécifié quand l'objet est créé. Par défaut,
   est appelée automatiquement lorsqu'une requête est faite alors que
   le client ne s'est pas connecté au préalable.

   Lève un évènement d'audit "http.client.connect" contenant les
   arguments "self", "host", "port".

HTTPConnection.close()

   Ferme la connexion au serveur.

HTTPConnection.blocksize

   Taille en octets du tampon utilisé pour transmettre un corps de
   message de type fichier.

   Added in version 3.7.

As an alternative to using the "request()" method described above, you
can also send your request step by step, by using the four functions
below.

HTTPConnection.putrequest(method, url, skip_host=False, skip_accept_encoding=False)

   Ce doit être le premier appel une fois que la connexion au serveur
   a été réalisée. Est envoyée au serveur une ligne consistant en la
   chaîne *method*, la chaîne d'*url*, et la version du protocole HTTP
   ("HTTP/1.1"). Pour désactiver l'envoi automatique des en-têtes
   "Host:" ou "Accept-Encoding:" (par exemple pour accepter des
   encodages supplémentaires de contenus), il est nécessaire de passer
   les paramètres *skip_host* ou *skip_accept_encoding* avec des
   valeurs différentes de "False".

HTTPConnection.putheader(header, argument[, ...])

   Envoie un en-tête de style **RFC 822** au serveur. Elle envoie au
   serveur une ligne regroupant un en-tête, une espace, un ":", une
   espace et le premier argument. Si plusieurs arguments sont donnés,
   des lignes de continuation sont envoyées, chacune d'elle étant
   constituée d'une espace suivie d'un argument.

HTTPConnection.endheaders(message_body=None, *, encode_chunked=False)

   Envoie une ligne blanche au serveur, signalant la fin des en-têtes.
   L'argument optionnel *message_body* peut-être utilisé pour passer
   le corps du message associé à la requête.

   Si *encode_chunked* est "True", le résultat de chaque itération sur
   *message_body* est un morceau encodé selon la **RFC 7230**, section
   3.3.1. La façon dont les données sont encodées dépend du type de
   *message_body*. Si *message_body* implémente l'interface tampon
   l'encodage donne un unique morceau. Si *message_body* est un
   itérable de classe "collections.abc.Iterable", chaque itération sur
   *message_body* donne un morceau. Si *message_body* est un *fichier
   objet*, chaque appel à ".read()" renvoie un morceau. La méthode
   signale automatiquement la fin des données encodées par morceaux
   immédiatement après *message_body*.

   Note:

     Selon la spécification de l'encodage des morceaux, les morceaux
     vides renvoyés par un itérateur associé au corps du message sont
     ignorés par l'encodeur de morceaux. Ce comportement est choisi
     pour éviter que la lecture de la requête par le serveur cible ne
     se termine prématurément pour cause d'encodage mal formé.

   Modifié dans la version 3.6: Added chunked encoding support and the
   *encode_chunked* parameter.

HTTPConnection.send(data)

   Envoie les données au serveur. Elle ne peut être utilisée
   directement qu'une fois la méthode "endheaders()" a été appelée et
   avant que la méthode "getresponse()" ait été appelée.

   Lève un évènement d'audit "http.client.send" avec comme arguments
   "self", "data".


Les objets HTTPResponse
=======================

Une instance de "HTTPResponse" encapsule la réponse HTTP du serveur.
Elle fournit un accès aux en-têtes et au corps de la réponse. La
réponse est un objet itérable pouvant être utilisé avec l'instruction
"with".

Modifié dans la version 3.5: L'interface de la classe
"io.BufferedIOBase" est désormais implémentée et toutes ses opérations
de lecture sont gérées.

HTTPResponse.read([amt])

   Lit et renvoie soit tout le corps de la réponse soit une partie de
   celui-ci se limitant aux *amt* octets suivants.

HTTPResponse.readinto(b)

   Lit les prochains "len(b)" octets du corps de la réponse et les
   place dans le tampon *b*. Renvoie le nombre d'octets lus.

   Added in version 3.3.

HTTPResponse.getheader(name, default=None)

   Return the value of the header *name*, or *default* if there is no
   header matching *name*.  If there is more than one  header with the
   name *name*, return all of the values joined by ', '.  If *default*
   is any iterable other than a single string, its elements are
   similarly returned joined by commas.

HTTPResponse.getheaders()

   Renvoie une liste d'*n*-uplets "(en-tête, valeur)".

HTTPResponse.fileno()

   Renvoie le "fileno" du connecteur réseau sous-jacent.

HTTPResponse.msg

   Une instance de "http.client.HTTPMessage" contenant les en-têtes de
   la réponse. La classe "http.client.HTTPMessage" est une sous-classe
   de la classe "email.message.Message".

HTTPResponse.version

   La version du protocole HTTP utilisée par le serveur : 10 pour
   HTTP/1.0, 11 pour HTTP/1.1.

HTTPResponse.url

   L'URL de la ressource récupérée, utilisée habituellement pour
   déterminer si une redirection a été suivie.

HTTPResponse.headers

   Les en-têtes de la réponse sous la forme d'une instance de
   "email.message.EmailMessage".

HTTPResponse.status

   Code d'état renvoyé par le serveur.

HTTPResponse.reason

   Phrase renvoyée par le serveur et indiquant la cause.

HTTPResponse.debuglevel

   Un point d'entrée pour débogage. Si "debuglevel" est plus grand que
   zéro, les messages sont envoyés à "sys.stdout" pendant la lecture
   et l'analyse de la réponse.

HTTPResponse.closed

   Vaut "True" si le flux est terminé.

HTTPResponse.geturl()

   Obsolète depuis la version 3.9: Rendu obsolète par "url".

HTTPResponse.info()

   Obsolète depuis la version 3.9: Rendu obsolète par "headers".

HTTPResponse.getcode()

   Obsolète depuis la version 3.9: Rendu obsolète par "status".


Exemples
========

Voici un exemple de session utilisant la méthode "GET" :

   >>> import http.client
   >>> conn = http.client.HTTPSConnection("www.python.org")
   >>> conn.request("GET", "/")
   >>> r1 = conn.getresponse()
   >>> print(r1.status, r1.reason)
   200 OK
   >>> data1 = r1.read()  # This will return entire content.
   >>> # The following example demonstrates reading data in chunks.
   >>> conn.request("GET", "/")
   >>> r1 = conn.getresponse()
   >>> while chunk := r1.read(200):
   ...     print(repr(chunk))
   b'<!doctype html>\n<!--[if"...
   ...
   >>> # Example of an invalid request
   >>> conn = http.client.HTTPSConnection("docs.python.org")
   >>> conn.request("GET", "/parrot.spam")
   >>> r2 = conn.getresponse()
   >>> print(r2.status, r2.reason)
   404 Not Found
   >>> data2 = r2.read()
   >>> conn.close()

Voici un exemple de session utilisant la méthode  "HEAD".  Notez que
la méthode "HEAD" ne renvoie jamais de données.

   >>> import http.client
   >>> conn = http.client.HTTPSConnection("www.python.org")
   >>> conn.request("HEAD", "/")
   >>> res = conn.getresponse()
   >>> print(res.status, res.reason)
   200 OK
   >>> data = res.read()
   >>> print(len(data))
   0
   >>> data == b''
   True

Here is an example session that uses the "POST" method:

   >>> import http.client, urllib.parse
   >>> params = urllib.parse.urlencode({'@number': 12524, '@type': 'issue', '@action': 'show'})
   >>> headers = {"Content-type": "application/x-www-form-urlencoded",
   ...            "Accept": "text/plain"}
   >>> conn = http.client.HTTPConnection("bugs.python.org")
   >>> conn.request("POST", "", params, headers)
   >>> response = conn.getresponse()
   >>> print(response.status, response.reason)
   302 Found
   >>> data = response.read()
   >>> data
   b'Redirecting to <a href="https://bugs.python.org/issue12524">https://bugs.python.org/issue12524</a>'
   >>> conn.close()

Client side HTTP "PUT" requests are very similar to "POST" requests.
The difference lies only on the server side where HTTP servers will
allow resources to be created via "PUT" requests. It should be noted
that custom HTTP methods are also handled in "urllib.request.Request"
by setting the appropriate method attribute. Here is an example
session that uses the "PUT" method:

   >>> # This creates an HTTP request
   >>> # with the content of BODY as the enclosed representation
   >>> # for the resource http://localhost:8080/file
   ...
   >>> import http.client
   >>> BODY = "***filecontents***"
   >>> conn = http.client.HTTPConnection("localhost", 8080)
   >>> conn.request("PUT", "/file", BODY)
   >>> response = conn.getresponse()
   >>> print(response.status, response.reason)
   200, OK


Les objets HTTPMessage
======================

class http.client.HTTPMessage(email.message.Message)

Une instance de classe "http.client.HTTPMessage" contient les en-têtes
d'une réponse HTTP. Elle est implémentée en utilisant la classe
"email.message.Message".
