ืคื™ืชื•ื— ืฉืจืชื™ ืื™ื ื˜ืจื ื˜ ื‘ื’ื•ืœื ื’ - ืžืคืฉื•ื˜ ืœืžื•ืจื›ื‘

ืคื™ืชื•ื— ืฉืจืชื™ ืื™ื ื˜ืจื ื˜ ื‘ื’ื•ืœื ื’ - ืžืคืฉื•ื˜ ืœืžื•ืจื›ื‘

ืœืคื ื™ ื—ืžืฉ ืฉื ื™ื ื”ืชื—ืœืชื™ ืœืคืชื— ืืช Gophish, ื–ื” ืกื™ืคืง ื”ื–ื“ืžื ื•ืช ืœืœืžื•ื“ ื’ื•ืœืื ื’. ื”ื‘ื ืชื™ ืฉ-Go ื”ื™ื ืฉืคื” ืจื‘ืช ืขื•ืฆืžื”, ืžืฉืœื™ืžื” ืกืคืจื™ื•ืช ืจื‘ื•ืช. Go ื”ื•ื ืจื‘ ืชื›ืœื™ืชื™: ื‘ืžื™ื•ื—ื“, ื ื™ืชืŸ ืœื”ืฉืชืžืฉ ื‘ื• ืœืคื™ืชื•ื— ื™ื™ืฉื•ืžื™ื ื‘ืฆื“ ื”ืฉืจืช ืœืœื ื‘ืขื™ื•ืช.

ืžืืžืจ ื–ื” ืขื•ืกืง ื‘ื›ืชื™ื‘ืช ืฉืจืช ื‘-Go. ื ืชื—ื™ืœ ื‘ื“ื‘ืจื™ื ืคืฉื•ื˜ื™ื ื›ืžื• "ืฉืœื•ื ืขื•ืœื!" ื•ื ืกื™ื™ื ื‘ืืคืœื™ืงืฆื™ื” ืขื ื”ื™ื›ื•ืœื•ืช ื”ื‘ืื•ืช:

- ืฉื™ืžื•ืฉ ื‘-Let's Encrypt ืขื‘ื•ืจ HTTPS.
- ืขื‘ื•ื“ื” ื›ื ืชื‘ API.
- ืขื‘ื•ื“ื” ืขื ืชื•ื›ื ืช ื‘ื™ื ื™ื™ื.
- ืขื™ื‘ื•ื“ ืงื‘ืฆื™ื ืกื˜ื˜ื™ื™ื.
- ื›ื™ื‘ื•ื™ ื ื›ื•ืŸ.

Skillbox ืžืžืœื™ืฆื”: ืงื•ืจืก ืžืขืฉื™ "ืžืคืชื— Python ืžืืคืก".

ืื ื• ืžื–ื›ื™ืจื™ื: ืœื›ืœ ืงื•ืจืื™ Habr - ื”ื ื—ื” ืฉืœ 10 ืจื•ื‘ืœ ื‘ืขืช ื”ืจืฉืžื” ืœื›ืœ ืงื•ืจืก Skillbox ื‘ืืžืฆืขื•ืช ืงื•ื“ ื”ื”ื˜ื‘ื” ืฉืœ Habr.

ืฉืœื•ื, ืขื•ืœื!

ืืชื” ื™ื›ื•ืœ ืœื™ืฆื•ืจ ืฉืจืช ืื™ื ื˜ืจื ื˜ ื‘-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)
}

ืœืื—ืจ ืžื›ืŸ, ืื ืืชื” ืžืคืขื™ืœ ืืช ื”ื™ื™ืฉื•ื ื•ืคื•ืชื— ืืช ื”ื“ืฃ localhost, ืื– ืชืจืื” ืžื™ื“ ืืช ื”ื˜ืงืกื˜ "ืฉืœื•ื, ืขื•ืœื!" (ืื ื”ื›ืœ ืขื•ื‘ื“ ื›ืžื• ืฉืฆืจื™ืš, ื›ืžื•ื‘ืŸ).

ื ืฉืชืžืฉ ื‘ืžื˜ืคืœ ืžืกืคืจ ืคืขืžื™ื ืžืื•ื—ืจ ื™ื•ืชืจ, ืื‘ืœ ืงื•ื“ื ื›ืœ ื‘ื•ืื• ื ื‘ื™ืŸ ืื™ืš ื”ื›ืœ ืขื•ื‘ื“.

net/http

ื”ื“ื•ื’ืžื” ื”ืฉืชืžืฉื” ื‘ื—ื‘ื™ืœื” net/http, ื–ื”ื• ื”ื›ืœื™ ื”ืขื™ืงืจื™ ื‘-Go ืœืคื™ืชื•ื— ื’ื ืฉืจืชื™ื ื•ื’ื ืœืงื•ื—ื•ืช HTTP. ื›ื“ื™ ืœื”ื‘ื™ืŸ ืืช ื”ืงื•ื“, ื‘ื•ืื• ื ื‘ื™ืŸ ืืช ื”ืžืฉืžืขื•ืช ืฉืœ ืฉืœื•ืฉื” ืืœืžื ื˜ื™ื ื—ืฉื•ื‘ื™ื: http.Handler, http.ServeMux ื•-http.Server.

ืžื˜ืคืœื™ HTTP

ื›ืืฉืจ ืื ื• ืžืงื‘ืœื™ื ื‘ืงืฉื”, ื”ืžื˜ืคืœ ืžื ืชื— ืื•ืชื” ื•ื™ื•ืฆืจ ืชื’ื•ื‘ื”. ืžื˜ืคืœื™ื ื‘-Go ืžื™ื•ืฉืžื™ื ื‘ืื•ืคืŸ ื”ื‘ื:

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

ื”ื“ื•ื’ืžื” ื”ืจืืฉื•ื ื” ืžืฉืชืžืฉืช ื‘ืคื•ื ืงืฆื™ื™ืช ื”ืขื–ืจ http.HandleFunc. ื–ื” ืขื•ื˜ืฃ ืคื•ื ืงืฆื™ื” ื ื•ืกืคืช, ืฉื‘ืชื•ืจื” ืœื•ืงื—ืช ืืช http.ResponseWriter ื•- http.Request ืœืชื•ืš ServeHTTP.

ื‘ืžื™ืœื™ื ืื—ืจื•ืช, ืžื˜ืคืœื™ื ื‘ื’ื•ืœื ื’ ืžื•ืฆื’ื™ื ื‘ืžืžืฉืง ืื—ื“, ืžื” ืฉื ื•ืชืŸ ื”ืจื‘ื” ืืคืฉืจื•ื™ื•ืช ืœืžืชื›ื ืช. ื›ืš, ืœืžืฉืœ, ืชื•ื›ื ืช ื”ื‘ื™ื ื™ื™ื ืžื™ื•ืฉืžืช ื‘ืืžืฆืขื•ืช ืžื˜ืคืœ, ื›ืืฉืจ ServeHTTP ืชื—ื™ืœื” ืขื•ืฉื” ืžืฉื”ื• ื•ืื– ืงื•ืจื ืœืฉื™ื˜ืช ServeHTTP ืฉืœ ืžื˜ืคืœ ืื—ืจ.

ื›ืคื™ ืฉื”ื•ื–ื›ืจ ืœืขื™ืœ, ื”ืžื˜ืคืœื™ื ืคืฉื•ื˜ ื™ื•ืฆืจื™ื ืชื’ื•ื‘ื•ืช ืœื‘ืงืฉื•ืช. ืื‘ืœ ื‘ืื™ื–ื” ืžื˜ืคืœ ืžืกื•ื™ื ื™ืฉ ืœื”ืฉืชืžืฉ ื‘ื ืงื•ื“ืช ื–ืžืŸ ืžืกื•ื™ืžืช?

ื‘ืงืฉ ื ื™ืชื•ื‘

ื›ื“ื™ ืœืขืฉื•ืช ืืช ื”ื‘ื—ื™ืจื” ื”ื ื›ื•ื ื”, ื”ืฉืชืžืฉ ื‘ืžืจื‘ื‘ HTTP. ื‘ืžืกืคืจ ืกืคืจื™ื•ืช ื–ื” ื ืงืจื muxer ืื• ื ืชื‘, ืื‘ืœ ื›ื•ืœื ืื•ืชื• ื“ื‘ืจ. ืชืคืงื™ื“ื• ืฉืœ ื”ืžืจื‘ื” ื”ื•ื ืœื ืชื— ืืช ื ืชื™ื‘ ื”ื‘ืงืฉื” ื•ืœื‘ื—ื•ืจ ืืช ื”ืžื˜ืคืœ ื”ืžืชืื™ื.

ืื ืืชื” ื–ืงื•ืง ืœืชืžื™ื›ื” ื‘ื ื™ืชื•ื‘ ืžื•ืจื›ื‘, ืขื“ื™ืฃ ืœื”ืฉืชืžืฉ ื‘ืกืคืจื™ื•ืช ืฉืœ ืฆื“ ืฉืœื™ืฉื™. ื›ืžื” ืžื”ืžืชืงื“ืžื™ื ื‘ื™ื•ืชืจ - ื’ื•ืจื™ืœื”/ืžื•ืงืก ะธ ื’ื•-ืฆ'ื™/ืฆ'ื™, ืกืคืจื™ื•ืช ืืœื• ืžืืคืฉืจื•ืช ืœื™ื™ืฉื ืขื™ื‘ื•ื“ ื‘ื™ื ื™ื™ื ืœืœื ื‘ืขื™ื•ืช. ื‘ืขื–ืจืชื, ืชื•ื›ืœ ืœื”ื’ื“ื™ืจ ื ื™ืชื•ื‘ ืชื•ื•ื™ื ื›ืœืœื™ื™ื ื•ืœื‘ืฆืข ืžืกืคืจ ืžืฉื™ืžื•ืช ืื—ืจื•ืช. ื”ื™ืชืจื•ืŸ ืฉืœื”ื ื”ื•ื ืชืื™ืžื•ืช ืขื ืžื˜ืคืœื™ HTTP ืกื˜ื ื“ืจื˜ื™ื™ื. ื›ืชื•ืฆืื” ืžื›ืš, ืืชื” ื™ื›ื•ืœ ืœื›ืชื•ื‘ ืงื•ื“ ืคืฉื•ื˜ ืฉื ื™ืชืŸ ืœืฉื ื•ืช ืื•ืชื• ื‘ืขืชื™ื“.

ืขื‘ื•ื“ื” ืขื ืžืกื’ืจื•ืช ืžื•ืจื›ื‘ื•ืช ื‘ืžืฆื‘ ืจื’ื™ืœ ืชื“ืจื•ืฉ ืคืชืจื•ื ื•ืช ืœื ืกื˜ื ื“ืจื˜ื™ื™ื, ื•ื”ื“ื‘ืจ ืžืกื‘ืš ืžืฉืžืขื•ืชื™ืช ืืช ื”ืฉื™ืžื•ืฉ ื‘ืžื˜ืคืœื™ ื‘ืจื™ืจืช ืžื—ื“ืœ. ื›ื“ื™ ืœื™ืฆื•ืจ ืืช ื”ืจื•ื‘ ื”ืžื›ืจื™ืข ืฉืœ ื”ื™ื™ืฉื•ืžื™ื, ืฉื™ืœื•ื‘ ืฉืœ ืกืคืจื™ื™ืช ื‘ืจื™ืจืช ื”ืžื—ื“ืœ ื•ื ืชื‘ ืคืฉื•ื˜ ื™ืกืคื™ืง.

ืขื™ื‘ื•ื“ ืฉืื™ืœืชื•ืช

ื‘ื ื•ืกืฃ, ืื ื—ื ื• ืฆืจื™ื›ื™ื ืจื›ื™ื‘ ืฉ"ื™ืงืฉื™ื‘" ืœื—ื™ื‘ื•ืจื™ื ื ื›ื ืกื™ื ื•ื™ืคื ื” ืืช ื›ืœ ื”ื‘ืงืฉื•ืช ืœืžื˜ืคืœ ื”ื ื›ื•ืŸ. http.Server ื™ื›ื•ืœ ืœื”ืชืžื•ื“ื“ ื‘ืงืœื•ืช ืขื ืžืฉื™ืžื” ื–ื•.

ืœื”ืœืŸ ืขื•ืœื” ื›ื™ ื”ืฉืจืช ืื—ืจืื™ ืœื›ืœ ื”ืžืฉื™ืžื•ืช ื”ืงืฉื•ืจื•ืช ืœืขื™ื‘ื•ื“ ื—ื™ื‘ื•ืจื™ื. ื–ื”, ืœืžืฉืœ, ืขื•ื‘ื“ ื‘ืืžืฆืขื•ืช ืคืจื•ื˜ื•ืงื•ืœ TLS. ื›ื“ื™ ืœื™ื™ืฉื ืืช ื”ืงืจื™ืื” http.ListenAndServer, ื ืขืฉื” ืฉื™ืžื•ืฉ ื‘ืฉืจืช HTTP ืกื˜ื ื“ืจื˜ื™.

ืขื›ืฉื™ื• ื‘ื•ืื• ื ืกืชื›ืœ ืขืœ ื“ื•ื’ืžืื•ืช ืžื•ืจื›ื‘ื•ืช ื™ื•ืชืจ.

ื”ื•ืกืคืช Let's Encrypt

ื›ื‘ืจื™ืจืช ืžื—ื“ืœ, ื”ืืคืœื™ืงืฆื™ื” ืฉืœื ื• ืคื•ืขืœืช ืขืœ ืคืจื•ื˜ื•ืงื•ืœ HTTP, ืืš ืžื•ืžืœืฅ ืœื”ืฉืชืžืฉ ื‘ืคืจื•ื˜ื•ืงื•ืœ HTTPS. ื ื™ืชืŸ ืœืขืฉื•ืช ื–ืืช ืœืœื ื‘ืขื™ื•ืช ื‘-Go. ืื ืงื™ื‘ืœืชื ืชืขื•ื“ื” ื•ืžืคืชื— ืคืจื˜ื™, ืžืกืคื™ืง ืœืจืฉื•ื ืืช ListenAndServeTLS ืขื ืงื‘ืฆื™ ื”ืชืขื•ื“ื” ื•ื”ืžืคืชื— ื”ื ื›ื•ื ื™ื.

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

ืืชื” ืชืžื™ื“ ื™ื›ื•ืœ ืœืขืฉื•ืช ื™ื•ืชืจ ื˜ื•ื‘.

ื‘ื•ืื• ืœื”ืฆืคื™ืŸ ืžืกืคืง ืชืขื•ื“ื•ืช ื—ื™ื ื ืขื ื—ื™ื“ื•ืฉ ืื•ื˜ื•ืžื˜ื™. ืขืœ ืžื ืช ืœื”ืฉืชืžืฉ ื‘ืฉื™ืจื•ืช ื™ืฉ ืฆื•ืจืš ื‘ื—ื‘ื™ืœื” autocert.

ื”ื“ืจืš ื”ืงืœื” ื‘ื™ื•ืชืจ ืœื”ื’ื“ื™ืจ ืื•ืชื” ื”ื™ื ืœื”ืฉืชืžืฉ ื‘ืฉื™ื˜ืช autocert.NewListener ื‘ืฉื™ืœื•ื‘ ืขื http.Serve. ื”ืฉื™ื˜ื” ืžืืคืฉืจืช ืœืš ืœื”ืฉื™ื’ ื•ืœืขื“ื›ืŸ ืื™ืฉื•ืจื™ 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 ืขื ื—ื™ื“ื•ืฉ ืื™ืฉื•ืจ ืื•ื˜ื•ืžื˜ื™.

ื”ื•ืกืคืช ืžืกืœื•ืœื™ื ืžื•ืชืืžื™ื ืื™ืฉื™ืช

ื ืชื‘ ื‘ืจื™ืจืช ื”ืžื—ื“ืœ ื”ื›ืœื•ืœ ื‘ืกืคืจื™ื™ื” ื”ืกื˜ื ื“ืจื˜ื™ืช ื”ื•ื ื˜ื•ื‘, ืื‘ืœ ื”ื•ื ื‘ืกื™ืกื™ ืžืื•ื“. ืจื•ื‘ ื”ื™ื™ืฉื•ืžื™ื ื“ื•ืจืฉื™ื ื ื™ืชื•ื‘ ืžื•ืจื›ื‘ ื™ื•ืชืจ, ื›ื•ืœืœ ืžืกืœื•ืœื™ื ืžืงื•ื ื ื™ื ื•ืชื•ื•ื™ื ื›ืœืœื™ื™ื, ืื• ื”ืœื™ืš ืœื”ื’ื“ืจืช ื“ืคื•ืกื™ ื ืชื™ื‘ ื•ืคืจืžื˜ืจื™ื.

ื‘ืžืงืจื” ื–ื” ื›ื“ืื™ ืœื”ืฉืชืžืฉ ื‘ื—ื‘ื™ืœื•ืช ื’ื•ืจื™ืœื”/ืžื•ืงืก ะธ ื’ื•-ืฆ'ื™/ืฆ'ื™. ื ืœืžื“ ื›ื™ืฆื“ ืœืขื‘ื•ื“ ืขื ื”ืื—ืจื•ืŸ - ื“ื•ื’ืžื” ืžื•ืฆื’ืช ืœื”ืœืŸ.

ื ืชื•ืŸ ื”ืงื•ื‘ืฅ api/v1/api.go ื”ืžื›ื™ืœ ืžืกืœื•ืœื™ื ืขื‘ื•ืจ ื”-API ืฉืœื ื•:

/ 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)
    })
}

ื™ืฉื ื ื ืชื‘ื™ื ืฉืœ ืฆื“ ืฉืœื™ืฉื™, ื›ื’ื•ืŸ chi, ื”ืžืืคืฉืจื™ื ืœืš ืœื”ืจื—ื™ื‘ ืืช ืคื•ื ืงืฆื™ื•ื ืœื™ื•ืช ื”ืชื•ื•ืš.

ืขื‘ื•ื“ื” ืขื ืงื‘ืฆื™ื ืกื˜ื˜ื™ื™ื

ืกืคืจื™ื™ืช ื”ืชืงืŸ 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() . ื”ืฉืจืช ืžื•ืคืขืœ ื‘-goroutine, ื•ืœืื—ืจ ืžื›ืŸ ืžืื–ื™ื ื™ื ืœืขืจื•ืฅ ื›ื“ื™ ืœืงื‘ืœ ืื•ืช ืคืกื™ืงื”. ื‘ืจื’ืข ืฉื”ืื•ืช ืžืชืงื‘ืœ, ื”ืฉืจืช ื ื›ื‘ื”, ืืš ืœื ืžื™ื“, ืืœื ืœืื—ืจ ืžืกืคืจ ืฉื ื™ื•ืช.

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

ื”ื•ืกืคืช ืชื’ื•ื‘ื”