Golang рдорд╛ рд╡реЗрдм рд╕рд░реНрднрд░ рд╡рд┐рдХрд╛рд╕ - рд╕рд░рд▓ рджреЗрдЦрд┐ рдЬрдЯрд┐рд▓

Golang рдорд╛ рд╡реЗрдм рд╕рд░реНрднрд░ рд╡рд┐рдХрд╛рд╕ - рд╕рд░рд▓ рджреЗрдЦрд┐ рдЬрдЯрд┐рд▓

рдкрд╛рдБрдЪ рд╡рд░реНрд╖рдЕрдШрд┐ рд╕реБрд░реБ рдЧрд░реЗрдБ Gophish рдХреЛ рд╡рд┐рдХрд╛рд╕, рдпрд╕рд▓реЗ рдЧреЛрд▓рд╛рдЩ рд╕рд┐рдХреНрдиреЗ рдЕрд╡рд╕рд░ рдкреНрд░рджрд╛рди рдЧрд░реНрдпреЛред рдореИрд▓реЗ рдорд╣рд╕реБрд╕ рдЧрд░реЗрдВ рдХрд┐ рдЧреЛ рдПрдХ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рднрд╛рд╖рд╛ рд╣реЛ, рдзреЗрд░реИ рдкреБрд╕реНрддрдХрд╛рд▓рдпрд╣рд░реВ рджреНрд╡рд╛рд░рд╛ рдкреВрд░рдХред рдЧреЛ рдмрд╣реБрдореБрдЦреА рдЫ: рд╡рд┐рд╢реЗрд╖ рдЧрд░реА, рдпреЛ рдХреБрдиреИ рдкрдирд┐ рд╕рдорд╕реНрдпрд╛ рдмрд┐рдирд╛ рд╕рд░реНрднрд░-рд╕рд╛рдЗрдб рдЕрдиреБрдкреНрд░рдпреЛрдЧрд╣рд░реВ рд╡рд┐рдХрд╛рд╕ рдЧрд░реНрди рдкреНрд░рдпреЛрдЧ рдЧрд░реНрди рд╕рдХрд┐рдиреНрдЫред

рдпреЛ рд▓реЗрдЦ Go рдорд╛ рд╕рд░реНрднрд░ рд▓реЗрдЦреНрдиреЗ рдмрд╛рд░реЗ рд╣реЛред "рдирдорд╕реНрддреЗ рд╕рдВрд╕рд╛рд░!" рдЬрд╕реНрддрд╛ рд╕рд╛рдзрд╛рд░рдг рдЪреАрдЬрд╣рд░реВрдмрд╛рдЯ рд╕реБрд░реБ рдЧрд░реМрдВ рд░ рдирд┐рдореНрди рдХреНрд╖рдорддрд╛рд╣рд░реВ рднрдПрдХреЛ рдЕрдиреБрдкреНрд░рдпреЛрдЧрдХреЛ рд╕рд╛рде рдЕрдиреНрддреНрдп рдЧрд░реМрдВ:

- HTTPS рдХреЛ рд▓рд╛рдЧрд┐ рдПрдиреНрдХреНрд░рд┐рдкреНрдЯ рдЧрд░реМрдВ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрджреИред
- рдПрдкреАрдЖрдИ рд░рд╛рдЙрдЯрд░рдХреЛ рд░реВрдкрдорд╛ рдХрд╛рдо рдЧрд░реНрджреИред
тАФ Middleware рдорд╛ рдХрд╛рдо рдЧрд░реНрджреИред
- рд╕реНрдерд┐рд░ рдлрд╛рдЗрд▓рд╣рд░реВрдХреЛ рдкреНрд░рд╢реЛрдзрдиред
- рд╕рд╣реА рдмрдиреНрджред

Skillbox рд╕рд┐рдлрд╛рд░рд┐рд╕ рдЧрд░реНрджрдЫ: рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рдкрд╛рдареНрдпрдХреНрд░рдо "рд╕реНрдХреНрд░реНрдпрд╛рдЪрдмрд╛рдЯ рдкрд╛рдЗрдерди рд╡рд┐рдХрд╛рд╕рдХрд░реНрддрд╛".

рд╣рд╛рдореА рд╕рдореНрдЭрд╛рдЙрдБрдЫреМрдВ: рд╕рдмреИ Habr рдкрд╛рдардХрд╣рд░реВрдХрд╛ рд▓рд╛рдЧрд┐ - Habr рдкреНрд░реЛрдореЛ рдХреЛрдб рдкреНрд░рдпреЛрдЧ рдЧрд░реА рдХреБрдиреИ рдкрдирд┐ Skillbox рдкрд╛рдареНрдпрдХреНрд░рдордорд╛ рднрд░реНрдирд╛ рдЧрд░реНрджрд╛ резреж,режрежреж рд░реВрдмрд▓ рдЫреБрдЯред

рдирдорд╕реНрдХрд╛рд░ рд╕рдВрд╕рд╛рд░!

рддрдкрд╛рдИрдВ рдзреЗрд░реИ рдЪрд╛рдБрдбреИ Go рдорд╛ рд╡реЗрдм рд╕рд░реНрднрд░ рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫред рдорд╛рдерд┐ рдкреНрд░рддрд┐рдЬреНрдЮрд╛ рдЧрд░рд┐рдПрдХреЛ "рд╣реЗрд▓реЛ, рд╕рдВрд╕рд╛рд░!" рдлрд░реНрдХрд╛рдЙрдиреЗ рд╣реНрдпрд╛рдиреНрдбрд▓рд░ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрдиреЗ рдПрдЙрдЯрд╛ рдЙрджрд╛рд╣рд░рдг рдпрд╣рд╛рдБ рдЫред

package main
 
import (
"fmt"
"net/http"
)
 
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello World!")
})
http.ListenAndServe(":80", nil)
}

рдпрд╕ рдкрдЫрд┐, рдпрджрд┐ рддрдкрд╛рдЗрдБ рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдЪрд▓рд╛рдЙрдиреБрд╣реБрдиреНрдЫ рд░ рдкреГрд╖реНрда рдЦреЛрд▓реНрдиреБрд╣реЛрд╕реН рд▓реЛрдХрд▓рд╣реЛрд╕реНрдЯ, рддреНрдпрд╕рдкрдЫрд┐ рддрдкрд╛рдИрд▓реЗ рддреБрд░реБрдиреНрддреИ "рдирдорд╕реНрддреЗ, рд╕рдВрд╕рд╛рд░!" рдкрд╛рда рджреЗрдЦреНрдиреБрд╣реБрдиреЗрдЫред (рдпрджрд┐ рд╕рдмреИ рдХреБрд░рд╛ рд╕рд╣реА рдХрд╛рдо рдЧрд░реНрдЫ, рдЕрд╡рд╢реНрдп)ред

рд╣рд╛рдореА рдкрдЫрд┐ рдзреЗрд░реИ рдкрдЯрдХ рд╣реНрдпрд╛рдиреНрдбрд▓рд░ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрдиреЗрдЫреМрдВ, рддрд░ рдкрд╣рд┐рд▓реЗ рд╕рдмреИ рдХреБрд░рд╛ рдХрд╕рд░реА рдХрд╛рдо рдЧрд░реНрдЫ рднрдиреЗрд░ рдмреБрдЭреМрдВред

рдиреЗрдЯ/http

рдЙрджрд╛рд╣рд░рдг рдкреНрдпрд╛рдХреЗрдЬ рдкреНрд░рдпреЛрдЧ рдЧрд░рд┐рдпреЛ net/http, рдпреЛ рджреБрдмреИ рд╕рд░реНрднрд░ рд░ HTTP рдХреНрд▓рд╛рдЗрдиреНрдЯрд╣рд░реВ рд╡рд┐рдХрд╛рд╕ рдЧрд░реНрди Go рдорд╛ рдкреНрд░рд╛рдердорд┐рдХ рдЙрдкрдХрд░рдг рд╣реЛред рдХреЛрдб рдмреБрдЭреНрдирдХреЛ рд▓рд╛рдЧрд┐, рддреАрди рдорд╣рддреНрддреНрд╡рдкреВрд░реНрдг рддрддреНрд╡рд╣рд░реВрдХреЛ рдЕрд░реНрде рдмреБрдЭреМрдВ: http.Handler, http.ServeMux рд░ http.Serverред

HTTP рд╣реНрдпрд╛рдиреНрдбрд▓рд░рд╣рд░реВ

рд╣рд╛рдореАрд▓реЗ рдЕрдиреБрд░реЛрдз рдкреНрд░рд╛рдкреНрдд рдЧрд░реНрджрд╛, рд╣реНрдпрд╛рдиреНрдбрд▓рд░рд▓реЗ рдпрд╕рдХреЛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдЧрд░реНрдЫ рд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдЙрддреНрдкрдиреНрди рдЧрд░реНрдЫред Go рдорд╛ рд╣реНрдпрд╛рдиреНрдбрд▓рд░рд╣рд░реВ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд▓рд╛рдЧреВ рд╣реБрдиреНрдЫрдиреН:

type Handler interface {
        ServeHTTP(ResponseWriter, *Request)
}

рдкрд╣рд┐рд▓реЛ рдЙрджрд╛рд╣рд░рдгрд▓реЗ http.HandleFunc рд╕рд╣рд╛рдпрдХ рдкреНрд░рдХрд╛рд░реНрдп рдкреНрд░рдпреЛрдЧ рдЧрд░реНрджрдЫред рдпрд╕рд▓реЗ рдЕрд░реНрдХреЛ рдкреНрд░рдХрд╛рд░реНрдп рд▓рдкреЗрдЯреНрдЫ, рдЬрд╕рд▓реЗ рдлрд▓рд╕реНрд╡рд░реВрдк http.ResponseWriter рд░ http.Request рд▓рд╛рдИ ServeHTTP рдорд╛ рд▓рд┐рдиреНрдЫред

рдЕрд░реНрдХреЛ рд╢рдмреНрджрдорд╛, Golang рдорд╛ рд╣реНрдпрд╛рдиреНрдбрд▓рд░рд╣рд░реВ рдПрдХрд▓ рдЗрдиреНрдЯрд░рдлреЗрд╕рдорд╛ рдкреНрд░рд╕реНрддреБрдд рд╣реБрдиреНрдЫрдиреН, рдЬрд╕рд▓реЗ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░рд▓рд╛рдИ рдзреЗрд░реИ рд╡рд┐рдХрд▓реНрдкрд╣рд░реВ рджрд┐рдиреНрдЫред рддреНрдпрд╕реЛрднрдП, рдЙрджрд╛рд╣рд░рдгрдХрд╛ рд▓рд╛рдЧрд┐, рдорд┐рдбрд▓рд╡реЗрдпрд░ рд╣реНрдпрд╛рдиреНрдбрд▓рд░ рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рд▓рд╛рдЧреВ рдЧрд░рд┐рдиреНрдЫ, рдЬрд╣рд╛рдБ ServeHTTP рд▓реЗ рдкрд╣рд┐рд▓реЗ рдХреЗрд╣рд┐ рдЧрд░реНрдЫ рд░ рддреНрдпрд╕рдкрдЫрд┐ рдЕрд░реНрдХреЛ рд╣реНрдпрд╛рдиреНрдбрд▓рд░рдХреЛ ServeHTTP рд╡рд┐рдзрд┐рд▓рд╛рдИ рдХрд▓ рдЧрд░реНрджрдЫред

рдорд╛рдерд┐ рдЙрд▓реНрд▓реЗрдЦ рдЧрд░рд┐рдП рдЕрдиреБрд╕рд╛рд░, рд╣реНрдпрд╛рдиреНрдбрд▓рд░рд╣рд░реВрд▓реЗ рдЕрдиреБрд░реЛрдзрд╣рд░реВрдорд╛ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рд╣рд░реВ рдЙрддреНрдкрдиреНрди рдЧрд░реНрдЫрдиреНред рддрд░ рдХреБрди рд╡рд┐рд╢реЗрд╖ рд╣реНрдпрд╛рдиреНрдбрд▓рд░ рд╕рдордп рдорд╛ рдПрдХ рд╡рд┐рд╢реЗрд╖ рдмрд┐рдиреНрджреБ рдорд╛ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрдиреБрдкрд░реНрдЫ?

рд░реБрдЯрд┐рдЩ рдЕрдиреБрд░реЛрдз рдЧрд░реНрдиреБрд╣реЛрд╕реН

рд╕рд╣реА рдЫрдиреЛрдЯ рдЧрд░реНрди, HTTP рдорд▓реНрдЯрд┐рдкреНрд▓реЗрдХреНрд╕рд░ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрдиреБрд╣реЛрд╕реНред рдзреЗрд░реИ рдкреБрд╕реНрддрдХрд╛рд▓рдпрд╣рд░реВрдорд╛ рдпрд╕рд▓рд╛рдИ рдордХреНрд╕рд░ рд╡рд╛ рд░рд╛рдЙрдЯрд░ рднрдирд┐рдиреНрдЫ, рддрд░ рддрд┐рдиреАрд╣рд░реВ рд╕рдмреИ рдПрдЙрдЯреИ рдХреБрд░рд╛ рд╣реБрдиреНред рдорд▓реНрдЯрд┐рдкреНрд▓реЗрдХреНрд╕рд░рдХреЛ рдХрд╛рд░реНрдп рдЕрдиреБрд░реЛрдз рдорд╛рд░реНрдЧрдХреЛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдЧрд░реНрдиреБ рд░ рдЙрдкрдпреБрдХреНрдд рд╣реНрдпрд╛рдиреНрдбрд▓рд░ рдЪрдпрди рдЧрд░реНрдиреБ рд╣реЛред

рдпрджрд┐ рддрдкрд╛рдИрдВрд▓рд╛рдИ рдЬрдЯрд┐рд▓ рдорд╛рд░реНрдЧрдХреЛ рд▓рд╛рдЧрд┐ рд╕рдорд░реНрдерди рдЪрд╛рд╣рд┐рдиреНрдЫ рднрдиреЗ, рддреЗрд╕реНрд░реЛ-рдкрдХреНрд╖ рдкреБрд╕реНрддрдХрд╛рд▓рдпрд╣рд░реВ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрдиреБ рд░рд╛рдореНрд░реЛ рд╣реБрдиреНрдЫред рдХреЗрд╣рд┐ рд╕рдмреИрднрдиреНрджрд╛ рдЙрдиреНрдирдд - рдЧреЛрд░рд┐рд▓реНрд▓рд╛/рдордХреНрд╕ ╨╕ go-chi/chi, рдпреА рдкреБрд╕реНрддрдХрд╛рд▓рдпрд╣рд░реВрд▓реЗ рдХреБрдиреИ рдкрдирд┐ рд╕рдорд╕реНрдпрд╛ рдмрд┐рдирд╛ рдордзреНрдпрд╡рд░реНрддреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЧрд░реНрди рд╕рдореНрднрд╡ рдмрдирд╛рдЙрдБрдЫред рддрд┐рдиреАрд╣рд░реВрдХреЛ рдорджреНрджрддрд▓реЗ, рддрдкрд╛рдИрдВрд▓реЗ рд╡рд╛рдЗрд▓реНрдбрдХрд╛рд░реНрдб рд░рд╛рдЙрдЯрд┐рдЩ рдХрдиреНрдлрд┐рдЧрд░ рдЧрд░реНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫ рд░ рдЕрдиреНрдп рдзреЗрд░реИ рдХрд╛рд░реНрдпрд╣рд░реВ рдЧрд░реНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫред рддрд┐рдиреАрд╣рд░реВрдХреЛ рдлрд╛рдЗрджрд╛ рдорд╛рдирдХ HTTP рд╣реНрдпрд╛рдиреНрдбрд▓рд░рд╣рд░реВрд╕рдБрдЧ рдЕрдиреБрдХреВрд▓рддрд╛ рд╣реЛред рдирддрд┐рдЬрд╛рдХреЛ рд░реВрдкрдорд╛, рддрдкрд╛рдИрд▓реЗ рд╕рд╛рдзрд╛рд░рдг рдХреЛрдб рд▓реЗрдЦреНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫ рдЬреБрди рднрд╡рд┐рд╖реНрдпрдорд╛ рдкрд░рд┐рдорд╛рд░реНрдЬрди рдЧрд░реНрди рд╕рдХрд┐рдиреНрдЫред

рд╕рд╛рдорд╛рдиреНрдп рдЕрд╡рд╕реНрдерд╛рдорд╛ рдЬрдЯрд┐рд▓ рдлреНрд░реЗрдорд╡рд░реНрдХрд╣рд░реВрд╕рдБрдЧ рдХрд╛рдо рдЧрд░реНрди рдЧреИрд░-рдорд╛рдирдХ рд╕рдорд╛рдзрд╛рдирд╣рд░реВ рдЖрд╡рд╢реНрдпрдХ рдкрд░реНрджрдЫ, рд░ рдпрд╕рд▓реЗ рдкреВрд░реНрд╡рдирд┐рд░реНрдзрд╛рд░рд┐рдд рд╣реНрдпрд╛рдиреНрдбрд▓рд░рд╣рд░реВрдХреЛ рдкреНрд░рдпреЛрдЧрд▓рд╛рдИ рдорд╣рддреНрддреНрд╡рдкреВрд░реНрдг рд░реВрдкрдорд╛ рдЬрдЯрд┐рд▓ рдмрдирд╛рдЙрдБрдЫред рдЕрдиреБрдкреНрд░рдпреЛрдЧрд╣рд░реВрдХреЛ рд╡рд┐рд╢рд╛рд▓ рдмрд╣реБрдордд рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрди, рдкреВрд░реНрд╡рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдкреБрд╕реНрддрдХрд╛рд▓рдп рд░ рдПрдХ рд╕рд╛рдзрд╛рд░рдг рд░рд╛рдЙрдЯрд░рдХреЛ рд╕рдВрдпреЛрдЬрди рдкрд░реНрдпрд╛рдкреНрдд рд╣реБрдиреЗрдЫред

рдХреНрд╡реЗрд░реА рдкреНрд░рд╢реЛрдзрди

рдердк рд░реВрдкрдорд╛, рд╣рд╛рдореАрд▓рд╛рдИ рдЖрдЧрдорди рдЬрдбрд╛рдирд╣рд░реВрдХреЛ рд▓рд╛рдЧрд┐ "рд╕реБрдиреНрди" рд░ рд╕рд╣реА рд╣реНрдпрд╛рдиреНрдбрд▓рд░рдорд╛ рд╕рдмреИ рдЕрдиреБрд░реЛрдзрд╣рд░реВ рд░рд┐рдбрд┐рд░реЗрдХреНрдЯ рдЧрд░реНрдиреЗ рдХрдореНрдкреЛрдиреЗрдиреНрдЯ рдЪрд╛рд╣рд┐рдиреНрдЫред http.Server рд▓реЗ рдпреЛ рдХрд╛рд░реНрдп рд╕рдЬрд┐рд▓реИрд╕рдБрдЧ рд╣реНрдпрд╛рдиреНрдбрд▓ рдЧрд░реНрди рд╕рдХреНрдЫред

рдирд┐рдореНрдирд▓реЗ рджреЗрдЦрд╛рдЙрдБрджрдЫ рдХрд┐ рд╕рд░реНрднрд░ рд╕рдмреИ рдХрд╛рд░реНрдпрд╣рд░реВрдХреЛ рд▓рд╛рдЧрд┐ рдЬрд┐рдореНрдореЗрд╡рд╛рд░ рдЫ рдЬреБрди рдЬрдбрд╛рди рдкреНрд░рд╢реЛрдзрдирд╕рдБрдЧ рд╕рдореНрдмрдиреНрдзрд┐рдд рдЫред рдпреЛ, рдЙрджрд╛рд╣рд░рдг рдХреЛ рд▓рд╛рдЧреА, TLS рдкреНрд░реЛрдЯреЛрдХрд▓ рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рдХрд╛рдо рдЧрд░реНрджрдЫред http.ListenAndServer рдХрд▓ рд▓рд╛рдЧреВ рдЧрд░реНрди, рдорд╛рдирдХ HTTP рд╕рд░реНрднрд░ рдкреНрд░рдпреЛрдЧ рдЧрд░рд┐рдиреНрдЫред

рдЕрдм рдердк рдЬрдЯрд┐рд▓ рдЙрджрд╛рд╣рд░рдгрд╣рд░реВ рд╣реЗрд░реМрдВред

Encrypt рдЧрд░реМрдВ рдердкреНрджреИ

рдкреВрд░реНрд╡рдирд┐рд░реНрдзрд╛рд░рд┐рдд рд░реВрдкрдорд╛, рд╣рд╛рдореНрд░реЛ рдЕрдиреБрдкреНрд░рдпреЛрдЧ HTTP рдкреНрд░реЛрдЯреЛрдХрд▓рдорд╛ рдЪрд▓реНрдЫ, рддрд░ рдпрд╕рд▓рд╛рдИ HTTPS рдкреНрд░реЛрдЯреЛрдХрд▓ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрди рд╕рд┐рдлрд╛рд░рд┐рд╕ рдЧрд░рд┐рдиреНрдЫред рдпреЛ Go рдорд╛ рд╕рдорд╕реНрдпрд╛ рдмрд┐рдирд╛ рдЧрд░реНрди рд╕рдХрд┐рдиреНрдЫред рдпрджрд┐ рддрдкрд╛рдИрдВрд▓реЗ рдкреНрд░рдорд╛рдгрдкрддреНрд░ рд░ рдирд┐рдЬреА рдХреБрдЮреНрдЬреА рдкреНрд░рд╛рдкреНрдд рдЧрд░реНрдиреБрднрдПрдХреЛ рдЫ рднрдиреЗ, рддреНрдпрд╕рдкрдЫрд┐ рдпреЛ рд╕рд╣реА рдкреНрд░рдорд╛рдгрдкрддреНрд░ рд░ рдХреБрдЮреНрдЬреА рдлрд╛рдЗрд▓рд╣рд░реВрд╕рдБрдЧ ListenAndServeTLS рджрд░реНрддрд╛ рдЧрд░реНрди рдкрд░реНрдпрд╛рдкреНрдд рдЫред

http.ListenAndServeTLS(":443", "cert.pem", "key.pem", nil)

рддрдкрд╛рдИрдВ рд╕рдзреИрдВ рд░рд╛рдореНрд░реЛ рдЧрд░реНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫред

рдЧреБрдкреНрддрд┐рдХрд░рдг рдЧрд░реМрдВ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдирд╡реАрдХрд░рдг рд╕рдВрдЧ рдирд┐: рд╢реБрд▓реНрдХ рдкреНрд░рдорд╛рдгрдкрддреНрд░ рдкреНрд░рджрд╛рди рдЧрд░реНрджрдЫред рд╕реЗрд╡рд╛ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрдирдХреЛ рд▓рд╛рдЧрд┐, рддрдкрд╛рдИрдВрд▓рд╛рдИ рдкреНрдпрд╛рдХреЗрдЬ рдЪрд╛рд╣рд┐рдиреНрдЫ autocert.

рдпрд╕рд▓рд╛рдИ рдХрдиреНрдлрд┐рдЧрд░ рдЧрд░реНрдиреЗ рд╕рдмреИрднрдиреНрджрд╛ рд╕рдЬрд┐рд▓реЛ рддрд░рд┐рдХрд╛ http.Serve рд╕рдБрдЧ рд╕рдВрдпреЛрдЬрдирдорд╛ autocert.NewListener рд╡рд┐рдзрд┐ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрдиреБ рд╣реЛред рд╡рд┐рдзрд┐рд▓реЗ рддрдкрд╛рдЗрдБрд▓рд╛рдИ TLS рдкреНрд░рдорд╛рдгрдкрддреНрд░рд╣рд░реВ рдкреНрд░рд╛рдкреНрдд рдЧрд░реНрди рд░ рдЕрджреНрдпрд╛рд╡рдзрд┐рдХ рдЧрд░реНрди рдЕрдиреБрдорддрд┐ рджрд┐рдиреНрдЫ рдЬрдм HTTP рд╕рд░реНрднрд░рд▓реЗ рдЕрдиреБрд░реЛрдзрд╣рд░реВ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдЧрд░реНрджрдЫ:

http.Serve(autocert.NewListener("example.com"), nil)

рдпрджрд┐ рд╣рд╛рдореА рдмреНрд░рд╛рдЙрдЬрд░рдорд╛ рдЦреЛрд▓реНрдЫреМрдВ example.com, рд╣рд╛рдореАрд▓реЗ HTTPS рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ "рдирдорд╕реНрддреЗ, рд╕рдВрд╕рд╛рд░!" рдкреНрд░рд╛рдкреНрдд рдЧрд░реНрдиреЗрдЫреМрдВред

рдпрджрд┐ рддрдкрд╛рдИрдВрд▓рд╛рдИ рдердк рд╡рд┐рд╕реНрддреГрдд рдХрдиреНрдлрд┐рдЧрд░реЗрд╕рди рдЪрд╛рд╣рд┐рдиреНрдЫ рднрдиреЗ, рддрдкрд╛рдИрдВрд▓реЗ autocert.Manager рдкреНрд░рдмрдиреНрдзрдХ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрдиреБрдкрд░реНрдЫред рддреНрдпрд╕рдкрдЫрд┐ рд╣рд╛рдореА рд╣рд╛рдореНрд░реЛ рдЖрдлреНрдиреИ http.Server рдЙрджрд╛рд╣рд░рдг рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрдЫреМрдВ (рдЕрд╣рд┐рд▓реЗрд╕рдореНрдо рд╣рд╛рдореАрд▓реЗ рдпрд╕рд▓рд╛рдИ рдкреВрд░реНрд╡рдирд┐рд░реНрдзрд╛рд░рд┐рдд рд░реВрдкрдорд╛ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрдпреМрдВ) рд░ TLSConfig рд╕рд░реНрднрд░рдорд╛ рдкреНрд░рдмрдиреНрдзрдХ рдердкреНрдиреБрд╣реЛрд╕реН:

m := &autocert.Manager{
Cache:      autocert.DirCache("golang-autocert"),
Prompt:     autocert.AcceptTOS,
HostPolicy: autocert.HostWhitelist("example.org", "www.example.org"),
}
server := &http.Server{
    Addr:      ":443",
    TLSConfig: m.TLSConfig(),
}
server.ListenAndServeTLS("", "")

рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдкреНрд░рдорд╛рдгрдкрддреНрд░ рдирд╡реАрдХрд░рдгрдХреЛ рд╕рд╛рде рдкреВрд░реНрдг HTTPS рд╕рдорд░реНрдерди рд▓рд╛рдЧреВ рдЧрд░реНрдиреЗ рдпреЛ рд╕рдЬрд┐рд▓реЛ рддрд░рд┐рдХрд╛ рд╣реЛред

рдЕрдиреБрдХреВрд▓рди рдорд╛рд░реНрдЧрд╣рд░реВ рдердкреНрджреИ

рдорд╛рдирдХ рдкреБрд╕реНрддрдХрд╛рд▓рдпрдорд╛ рд╕рдорд╛рд╡реЗрд╢ рдкреВрд░реНрд╡рдирд┐рд░реНрдзрд╛рд░рд┐рдд рд░рд╛рдЙрдЯрд░ рд░рд╛рдореНрд░реЛ рдЫ, рддрд░ рдпреЛ рдзреЗрд░реИ рдЖрдзрд╛рд░рднреВрдд рдЫред рдзреЗрд░реИ рдЬрд╕реЛ рдЕрдиреБрдкреНрд░рдпреЛрдЧрд╣рд░реВрд▓рд╛рдИ рдиреЗрд╕реНрдЯреЗрдб рд░ рд╡рд╛рдЗрд▓реНрдбрдХрд╛рд░реНрдб рдорд╛рд░реНрдЧрд╣рд░реВ, рд╡рд╛ рдкрде рдврд╛рдБрдЪрд╛ рд░ рдкреНрдпрд╛рд░рд╛рдорд┐рдЯрд░рд╣рд░реВ рд╕реЗрдЯ рдЧрд░реНрдиреЗ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╕рд╣рд┐рдд рдердк рдЬрдЯрд┐рд▓ рд░рд╛рдЙрдЯрд┐рдВрдЧ рдЪрд╛рд╣рд┐рдиреНрдЫред

рдпрд╕ рдЕрд╡рд╕реНрдерд╛рдорд╛ рдпреЛ рдкреНрдпрд╛рдХреЗрдЬрд╣рд░реВ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрди рд▓рд╛рдпрдХ рдЫ рдЧреЛрд░рд┐рд▓реНрд▓рд╛/рдордХреНрд╕ ╨╕ go-chi/chiред рд╣рд╛рдореА рдкрдЫрд┐рд▓реНрд▓реЛ рд╕рдВрдЧ рдХрд╛рдо рдЧрд░реНрди рд╕рд┐рдХреНрди рд╣реБрдиреЗрдЫ - рдПрдХ рдЙрджрд╛рд╣рд░рдг рддрд▓ рджреЗрдЦрд╛рдЗрдПрдХреЛ рдЫред

рд╣рд╛рдореНрд░реЛ API рдХреЛ рд▓рд╛рдЧрд┐ рдорд╛рд░реНрдЧрд╣рд░реВ рд╕рдорд╛рд╡реЗрд╢ рдлрд╛рдЗрд▓ api/v1/api.go рджрд┐рдЗрдПрдХреЛ рдЫ:

/ HelloResponse is the JSON representation for a customized message
type HelloResponse struct {
Message string `json:"message"`
}
 
// HelloName returns a personalized JSON message
func HelloName(w http.ResponseWriter, r *http.Request) {
name := chi.URLParam(r, "name")
response := HelloResponse{
Message: fmt.Sprintf("Hello %s!", name),
}
jsonResponse(w, response, http.StatusOK)
}
 
// NewRouter returns an HTTP handler that implements the routes for the API
func NewRouter() http.Handler {
r := chi.NewRouter()
r.Get("/{name}", HelloName)
return r
}

рд╣рд╛рдореАрд▓реЗ рдореБрдЦреНрдп рдлрд╛рдЗрд▓рдорд╛ рдорд╛рд░реНрдЧрд╣рд░реВрдХреЛ рд▓рд╛рдЧрд┐ api/vq рдЙрдкрд╕рд░реНрдЧ рд╕реЗрдЯ рдЧрд░реНрдЫреМрдВред

рддреНрдпрд╕рдкрдЫрд┐ рд╣рд╛рдореА рдпрд╕рд▓рд╛рдИ рд╣рд╛рдореНрд░реЛ рдореБрдЦреНрдп рд░рд╛рдЙрдЯрд░рдорд╛ api/v1/ рдЙрдкрд╕рд░реНрдЧ рдЕрдиреНрддрд░реНрдЧрдд рд╣рд╛рдореНрд░реЛ рдореБрдЦреНрдп рдЕрдиреБрдкреНрд░рдпреЛрдЧрдорд╛ рдорд╛рдЙрдиреНрдЯ рдЧрд░реНрди рд╕рдХреНрдЫреМрдВ:

// NewRouter returns a new HTTP handler that implements the main server routes
func NewRouter() http.Handler {
router := chi.NewRouter()
    router.Mount("/api/v1/", v1.NewRouter())
    return router
}
http.Serve(autocert.NewListener("example.com"), NewRouter())

рдЬрдЯрд┐рд▓ рдорд╛рд░реНрдЧрд╣рд░реВрд╕рдБрдЧ рдХрд╛рдо рдЧрд░реНрдиреЗ Go рдХреЛ рд╕рд╣рдЬрддрд╛рд▓реЗ рдареВрд▓рд╛, рдЬрдЯрд┐рд▓ рдЕрдиреБрдкреНрд░рдпреЛрдЧрд╣рд░реВрдХреЛ рд╕рдВрд░рдЪрдирд╛ рд░ рдорд░реНрдорддрд╕рдореНрднрд╛рд░рд▓рд╛рдИ рд╕рд░рд▓ рдмрдирд╛рдЙрди рд╕рдореНрднрд╡ рдмрдирд╛рдЙрдБрдЫред

рдорд┐рдбрд▓рд╡реЗрдпрд░рд╕рдБрдЧ рдХрд╛рдо рдЧрд░реНрджреИ

рд╕реНрдЯреЗрдЬрд┐рдЩрдорд╛ рдПрдЙрдЯрд╛ HTTP рд╣реНрдпрд╛рдиреНрдбрд▓рд░рд▓рд╛рдИ рдЕрд░реНрдХреЛрд╕рдБрдЧ рд░реНтАНрдпрд╛рдк рдЧрд░реНрдиреЗ, рдкреНрд░рдорд╛рдгреАрдХрд░рдг, рдХрдореНрдкреНрд░реЗрд╕рди, рд▓рдЧрд┐рдЩ рд░ рдЕрдиреНрдп рдзреЗрд░реИ рдкреНрд░рдХрд╛рд░реНрдпрд╣рд░реВ рдЫрд┐рдЯреЛ рдЧрд░реНрди рд╕рдореНрднрд╡ рдмрдирд╛рдЙрдБрдЫред

рдЙрджрд╛рд╣рд░рдгрдХреЛ рд░реВрдкрдорд╛, http.Handler рдЗрдиреНрдЯрд░рдлреЗрд╕ рд╣реЗрд░реМрдВ; рд╣рд╛рдореА рдпрд╕рд▓рд╛рдИ рд╕реЗрд╡рд╛ рдкреНрд░рдпреЛрдЧрдХрд░реНрддрд╛рд╣рд░реВрд▓рд╛рдИ рдкреНрд░рдорд╛рдгрд┐рдХрд░рдг рдЧрд░реНрдиреЗ рд╣реНрдпрд╛рдиреНрдбрд▓рд░ рд▓реЗрдЦреНрди рдкреНрд░рдпреЛрдЧ рдЧрд░реНрдиреЗрдЫреМрдВред

func RequireAuthentication(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        if !isAuthenticated(r) {
            http.Redirect(w, r, "/login", http.StatusTemporaryRedirect)
            return
        }
        // Assuming authentication passed, run the original handler
        next.ServeHTTP(w, r)
    })
}

рддреНрдпрд╣рд╛рдБ рддреЗрд╕реНрд░реЛ рдкрдХреНрд╖ рд░рд╛рдЙрдЯрд░рд╣рд░реВ рдЫрдиреН, рдЬрд╕реНрддреИ рдЪреА, рдЬрд╕рд▓реЗ рддрдкрд╛рдИрдВрд▓рд╛рдИ рдорд┐рдбрд▓рд╡реЗрдпрд░ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдЧрд░реНрди рдЕрдиреБрдорддрд┐ рджрд┐рдиреНрдЫред

рд╕реНрдерд┐рд░ рдлрд╛рдЗрд▓рд╣рд░реВрд╕рдБрдЧ рдХрд╛рдо рдЧрд░реНрджреИ

Go рдорд╛рдирдХ рдкреБрд╕реНрддрдХрд╛рд▓рдпрдорд╛ рдЫрд╡рд┐рд╣рд░реВ, JavaScript рд░ CSS рдлрд╛рдЗрд▓рд╣рд░реВ рд╕рд╣рд┐рдд рд╕реНрдерд┐рд░ рд╕рд╛рдордЧреНрд░реАрд╕рдБрдЧ рдХрд╛рдо рдЧрд░реНрдиреЗ рдХреНрд╖рдорддрд╛рд╣рд░реВ рд╕рдорд╛рд╡реЗрд╢ рдЫрдиреНред рддрд┐рдиреАрд╣рд░реВ http.FileServer рдкреНрд░рдХрд╛рд░реНрдп рдорд╛рд░реНрдлрдд рдкрд╣реБрдБрдЪ рдЧрд░реНрди рд╕рдХрд┐рдиреНрдЫред рдпрд╕рд▓реЗ рдПрдХ рд╣реНрдпрд╛рдиреНрдбрд▓рд░рд▓рд╛рдИ рдлрд░реНрдХрд╛рдЙрдБрдЫ рдЬрд╕рд▓реЗ рд╡рд┐рд╢реЗрд╖ рдбрд╛рдЗрд░реЗрдХреНрдЯрд░реАрдмрд╛рдЯ рдлрд╛рдЗрд▓рд╣рд░реВ рд╕реЗрд╡рд╛ рдЧрд░реНрджрдЫред

func NewRouter() http.Handler {
    router := chi.NewRouter()
    r.Get("/{name}", HelloName)
 
// ╨Э╨░╤Б╤В╤А╨╛╨╣╨║╨░ ╤А╨░╨╖╨┤╨░╤З╨╕ ╤Б╤В╨░╤В╨╕╤З╨╡╤Б╨║╨╕╤Е ╤Д╨░╨╣╨╗╨╛╨▓
staticPath, _ := filepath.Abs("../../static/")
fs := http.FileServer(http.Dir(staticPath))
    router.Handle("/*", fs)
    
    return r

рдпреЛ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдкрдорд╛ рдпрд╛рдж рдЧрд░реНрди рд▓рд╛рдпрдХ рдЫ рдХрд┐ http.Dir рд▓реЗ рдбрд╛рдЗрд░реЗрдХреНрдЯрд░реАрдХрд╛ рд╕рд╛рдордЧреНрд░реАрд╣рд░реВ рдкреНрд░рджрд░реНрд╢рди рдЧрд░реНрджрдЫ рдпрджрд┐ рдпрд╕рд▓реЗ рдореБрдЦреНрдп index.html рдлрд╛рдЗрд▓ рд╕рдорд╛рд╡реЗрд╢ рдЧрд░реНрджреИрдиред рдпрд╕ рдЕрд╡рд╕реНрдерд╛рдорд╛, рдбрд╛рдЗрд░реЗрдХреНрдЯрд░реАрд▓рд╛рдИ рд╕рдореНрдЭреМрддрд╛ рд╣реБрдирдмрд╛рдЯ рд░реЛрдХреНрди, рддрдкрд╛рдИрдВрд▓реЗ рдкреНрдпрд╛рдХреЗрдЬ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрдиреБрдкрд░реНрдЫ unindexed.

рд╕рд╣реА рдмрдиреНрдж

Go рдорд╛ HTTP рд╕рд░реНрднрд░рдХреЛ рдЧреНрд░реЗрд╕рдлреБрд▓ рд╢рдЯрдбрд╛рдЙрди рднрдирд┐рдиреЗ рд╕реБрд╡рд┐рдзрд╛ рдкрдирд┐ рдЫред рдпреЛ Shutdown() рд╡рд┐рдзрд┐ рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рдЧрд░реНрди рд╕рдХрд┐рдиреНрдЫред рд╕рд░реНрднрд░ рдПрдХ рдЧреЛрд░рд╛рдЙрдЯрд┐рдирдорд╛ рд╕реБрд░реБ рд╣реБрдиреНрдЫ, рд░ рддреНрдпрд╕рдкрдЫрд┐ рдЪреНрдпрд╛рдирд▓ рдПрдХ рдЕрд╡рд░реЛрдз рд╕рдВрдХреЗрдд рдкреНрд░рд╛рдкреНрдд рдЧрд░реНрди рд╕реБрдирд┐рдиреНрдЫред рд╕рдВрдХреЗрдд рдкреНрд░рд╛рдкреНрдд рд╣реБрдиреЗ рдмрд┐рддреНрддрд┐рдХреИ, рд╕рд░реНрднрд░ рдмрдиреНрдж рд╣реБрдиреНрдЫ, рддрд░ рддреБрд░реБрдиреНрддреИ рд╣реЛрдЗрди, рддрд░ рдХреЗрд╣рд┐ рд╕реЗрдХреЗрдиреНрдб рдкрдЫрд┐ред

handler := server.NewRouter()
srv := &http.Server{
    Handler: handler,
}
 
go func() {
srv.Serve(autocert.NewListener(domains...))
}()
 
// Wait for an interrupt
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)
<-c
 
// Attempt a graceful shutdown
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
srv.Shutdown(ctx)

рдПрдХ рдирд┐рд╖реНрдХрд░реНрд╖рдХреЛ рд░реВрдкрдорд╛

Go рд▓рдЧрднрдЧ рд╡рд┐рд╢реНрд╡рд╡реНрдпрд╛рдкреА рдорд╛рдирдХ рдкреБрд╕реНрддрдХрд╛рд▓рдпрдХреЛ рд╕рд╛рде рдПрдХ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рднрд╛рд╖рд╛ рд╣реЛред рдпрд╕рдХреЛ рдкреВрд░реНрд╡рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХреНрд╖рдорддрд╛рд╣рд░реВ рдзреЗрд░реИ рдлрд░рд╛рдХрд┐рд▓реЛ рдЫрдиреН, рд░ рддрд┐рдиреАрд╣рд░реВрд▓рд╛рдИ рдЗрдиреНрдЯрд░рдлреЗрд╕рд╣рд░реВ рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рдмреГрджреНрдзрд┐ рдЧрд░реНрди рд╕рдХрд┐рдиреНрдЫ - рдпрд╕рд▓реЗ рддрдкрд╛рдИрдВрд▓рд╛рдИ рд╡рд╛рд╕реНрддрд╡рдореИ рднрд░рдкрд░реНрджреЛ HTTP рд╕рд░реНрднрд░рд╣рд░реВ рд╡рд┐рдХрд╛рд╕ рдЧрд░реНрди рдЕрдиреБрдорддрд┐ рджрд┐рдиреНрдЫред

Skillbox рд╕рд┐рдлрд╛рд░рд┐рд╕ рдЧрд░реНрджрдЫ:

рд╕реНрд░реЛрдд: www.habr.com

рдПрдХ рдЯрд┐рдкреНрдкрдгреА рдердкреНрди