Lancement d'un service web
http.ListenAndServe()- Premier paramètre : adresse réseau, si vide, écoute sur tous les interfaces réseau au port 80.
- Deuxième paramètre : gestionnaire (handler), si
nil, utiliseDefaultServeMux. DefaultServeMuxest un multiplexeur (comparable à un routeur).http.Serverest une structure.- Champ
Addr: adresse réseau, si vide, écoute sur tous les interfaces réseau au port 80. - Champ
Handler: gestionnaire, sinil, utiliseDefaultServeMux. - Fonction
ListenAndServe()
Lancement du serveur se fait de deux façons possibles
http.ListenAndServe() //HTTPhttp.ListenAndServeTLS() //HTTPSserver.ListenAndServe() //HTTPserver.ListenAndServeTLS() //HTTPS
// fonctions équivalentes s1 et s2
func demarrerServeur1() {
serveur := http.Server{
Addr: "localhost:8080",
Handler: nil,
}
serveur.ListenAndServe()
}
func demarrerServeur2() {
http.ListenAndServe("localhost:8080", nil)
}
Gestion des requêtes
Gestionnaire (Handler)
- Interface (interface)
- Définit une méthode
ServeHTTP() http.ResponseWriter*http.Requestpointeur vers la structure Request
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
DefaultServeMux
- Multiplexeur (comparable à un routeur)
- Est également un gestionnaire (Handler)
Multiples gestionnaires
- Ne spécifiez pas le champ
Handlerde la structureServer - Utilisez
http.Handlepour attacher un gestionnaire àDefaultServeMux - Package
httpa une fonctionHandle - Structure
ServerMuxa aussi une méthodeHandle - Lorsque vous appelez
http.Handle, vous appelez en réalité la méthodeHandledeDefaultServeMux DefaultServeMuxest un pointeur vers une structureServerMux
type gestionnairePrincipal struct{}
type gestionnaireAPropos struct{}
func (g *gestionnairePrincipal) ServeHTTP(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Un beau jour"))
}
func (a *gestionnaireAPropos) ServeHTTP(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("À propos!"))
}
func configurerGestionnaires() {
gp := gestionnairePrincipal{}
serveur := http.Server{
Addr: "localhost:8080",
Handler: &gp,
}
serveur.ListenAndServe()
}
func accueil(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Bienvenue"))
}
func index(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Index"))
}
func configurerGestionnairesAvances() {
gp := gestionnairePrincipal{}
ga := gestionnaireAPropos{}
serveur := http.Server{
Addr: "localhost:8080",
Handler: nil, // Utilise DefaultServeMux
}
http.Handle("/bonjour", &gp)
http.Handle("/apropos", &ga)
http.HandleFunc("/accueil", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Accueil"))
})
http.Handle("/salutation", http.HandlerFunc(accueil))
http.HandleFunc("/index", index)
serveur.ListenAndServe()
}
Deux formes de gestion des requêtes
http.Handle- Deuxième paramètre : gestionnaire (Handler)
http.HandleFunc- Deuxième paramètre : fonction gestionnaire
http.HandlerFuncpermet de convertir une fonction gestionnaire en gestionnaire- Apelle en interne
http.Handle
Gestionnaires intégrés
404 Not Found
http.NotFoundHandler- Fonction qui retourne un gestionnaire qui répond par "404 page not found" à chaque requête
Redirection
http.RedirectHandler- Fonction qui retourne un gestionnaire qui redirige chaque requête vers une URL spécifiée avec un code d'état donné
Traitement de chemin
http.StripPrefix- Fonction qui retourne un gestionnaire qui supprime un préfixe spécifique de l'URL de la requête avant de la transmettre à un autre gestionnaire
Gestion du timeout
http.TimeoutHandler- Fonction qui retourne un gestionnaire qui exécute un autre gestionnaire dans un délai spécifié
Serveur de fichiers
http.FileServer- Fonction qui retourne un gestionnaire qui sert des fichiers à partir d'un système de fichiers spécifié
http.ListenAndServe(":8080", http.FileServer(http.Dir("racineWeb")))
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, "racineWeb"+r.URL.Path)
})
http.ListenAndServe(":8080", nil)
Requêtes HTTP
Message HTTP
- Structure identique pour les requêtes et les réponses HTTP
- Ligne de requête (ou réponse)
- Zéro ou plusieurs en-têtes (headers)
- Ligne vide
- Corps du message (body) optionnel
Requête
- Structure
Requestreprésente une requête HTTP envoyée par le client - Champs importants :
URL,Header,Body,Form,PostForm,MultipartForm
URL de la requête
- Structure
URL: champsScheme,Opaque,User,Host,Path,RawQuery,Fragment - Format général :
scheme://[userinfo@]host/path[?query][#fragment] RawQuerycontient la chaîne de requête bruter.URL.Query()retourne une carte correspondant aux paramètres de la requête
http.HandleFunc("/requete", func(w http.ResponseWriter, r *http.Request) {
parametres := r.URL.Query()
id := parametres["id"]
log.Println(id)
nom := parametres.Get("nom")
log.Println(nom)
})
http.ListenAndServe("localhost:8080", nil)
En-têtes de la requête
- En-têtes sont représentés par un type
Header, qui est une carte des paires clé-valeur des en-têtes HTTP - Clés de type
string, valeurs de type[]string
http.HandleFunc("/entetes", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, r.Header)
fmt.Fprintln(w, r.Header["Accept-Encoding"])
fmt.Fprintln(w, r.Header.Get("Accept-Encoding"))
})
Corps de la requête
- Corps est représenté par le champ
Body - Interface
io.ReadCloser - Lire le corps avec la méthode
Read
http.HandleFunc("/poster", func(w http.ResponseWriter, r *http.Request) {
longueur := r.ContentLength
corps := make([]byte, longueur)
r.Body.Read(corps)
fmt.Fprintln(w, string(corps))
})
Formulaires
- Données envoyées par formulaire placées dans le corps de la requête POST
- Format des données déterminé par l'attribut
enctypedu formulaire - Valeurs disponibles dans les champs
Form,PostForm,MultipartForm
r.ParseForm()
fmt.Fprintln(w, r.Form)
r.ParseForm()
fmt.Fprintln(w, r.PostForm)
r.ParseMultipartForm(1024)
fmt.Fprintln(w, r.MultipartForm)
valeur := r.FormValue("cle")
fmt.Fprintln(w, valeur)
Fichiers téléversés
r.ParseMultipartForm(1024)
fichierHeader := r.MultipartForm.File["telecharge"][0]
fichier, err := fichierHeader.Open()
if err == nil {
donnees, err := ioutil.ReadAll(fichier)
if err == nil {
fmt.Fprintln(w, string(donnees))
}
}
fichier, _, err := r.FormFile("telecharge")
if err == nil {
donnees, err := ioutil.ReadAll(fichier)
if err == nil {
fmt.Fprintln(w, string(donnees))
}
}