Fampandrosoana ny mpizara tranonkala ao Golang - manomboka amin'ny tsotra ka hatramin'ny sarotra

Fampandrosoana ny mpizara tranonkala ao Golang - manomboka amin'ny tsotra ka hatramin'ny sarotra

Dimy taona lasa izay aho no nanomboka mampivelatra Gophish, izany dia nanome fahafahana hianatra Golang. Tsapako fa fiteny mahery vaika ny Go, nomen'ny tranomboky maro. Mahavariana ny Go: indrindra, azo ampiasaina amin'ny famolavolana rindranasa amin'ny lafiny server tsy misy olana.

Ity lahatsoratra ity dia momba ny fanoratana mpizara ao amin'ny Go. Andeha isika hanomboka amin'ny zavatra tsotra toy ny "Manahoana izao tontolo izao!" ary faranana amin'ny fampiharana manana ireto fahaiza-manao manaraka ireto:

- Mampiasa Let's Encrypt ho an'ny HTTPS.
- Miasa toy ny router API.
- Miasa amin'ny middleware.
- Fanodinana rakitra static.
- Ahitsio fanakatonana.

Skillbox dia manoro hevitra: Mazava ho azy "Developer Python avy amin'ny scratch".

Mampahatsiahy izahay: ho an'ny mpamaky rehetra ny "Habr" - fihenam-bidy 10 roubles rehefa misoratra anarana amin'ny taranja Skillbox rehetra mampiasa ny code promotional "Habr".

Hello World!

Afaka mamorona mpizara tranonkala ao amin'ny Go ianao haingana dia haingana. Ity misy ohatra iray amin'ny fampiasana mpitantana izay mamerina ny "Manahoana, izao tontolo izao!" nampanantenaina etsy ambony.

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

Rehefa afaka izany, raha mihazakazaka ny fampiharana sy manokatra ny pejy localhost, dia ho hitanao avy hatrany ilay lahatsoratra hoe β€œManahoana, izao tontolo izao!” (raha mandeha tsara ny zava-drehetra, mazava ho azy).

Hampiasa im-betsaka ny mpandrindra isika any aoriana any, fa aleo aloha hahatakatra ny fomba fiasan'ny zava-drehetra.

net/http

Ny ohatra dia nampiasa ny fonosana net/http, io no fitaovana voalohany ao amin'ny Go amin'ny fampivoarana ireo mpizara sy mpanjifa HTTP. Mba hahatakarana ny kaody, andao ho azontsika ny dikan'ny singa telo manan-danja: http.Handler, http.ServeMux ary http.Server.

Mpampiasa HTTP

Rehefa mahazo fangatahana izahay, dia mamakafaka izany ny mpitantana ary mamorona valiny. Ny mpitantana ao amin'ny Go dia ampiharina toy izao manaraka izao:

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

Ny ohatra voalohany dia mampiasa ny fiasa mpanampy http.HandleFunc. Izy io dia mamehy fiasa hafa, izay mitondra ny http.ResponseWriter sy http.Request ho ServeHTTP.

Raha lazaina amin'ny teny hafa, ny mpitantana ao amin'ny Golang dia aseho amin'ny interface tokana, izay manome safidy maro ho an'ny programmer. Noho izany, ohatra, ny middleware dia ampiharina amin'ny fampiasana mpandrindra, izay ServeHTTP voalohany manao zavatra ary avy eo dia miantso ny fomba ServeHTTP an'ny mpitantana iray hafa.

Araka ny voalaza etsy ambony, ny mpitantana dia mamorona valiny amin'ny fangatahana fotsiny. Iza anefa no tokony hampiasaina amin'ny fotoana iray?

Mangataka Routing

Mba hanaovana safidy tsara, ampiasao ny multiplexer HTTP. Ao amin'ny trano famakiam-boky maromaro dia antsoina hoe muxer na router izy io, saingy zavatra iray ihany izy ireo. Ny asan'ny multiplexer dia ny mamakafaka ny lalan'ny fangatahana ary mifantina ny mpitantana mety.

Raha mila fanohanana ho an'ny lalana sarotra ianao, dia tsara kokoa ny mampiasa tranomboky antoko fahatelo. Ny sasany amin'ireo mandroso indrindra - gorila / mux ΠΈ go-chi/chi, ireo trano famakiam-boky ireo dia mamela ny fampiharana ny fanodinana anelanelanana tsy misy olana. Miaraka amin'ny fanampian'izy ireo, azonao atao ny manitsy ny lalana amin'ny wildcard ary manao asa maro hafa. Ny tombony dia ny mifanaraka amin'ireo mpitantana HTTP mahazatra. Vokatr'izany dia azonao atao ny manoratra kaody tsotra izay azo ovaina amin'ny ho avy.

Ny fiasana amin'ny rafitra sarotra amin'ny toe-javatra mahazatra dia mitaky vahaolana tsy manara-penitra, ary izany dia manasarotra ny fampiasana ireo mpandrindra mahazatra. Mba hamoronana ny ankamaroan'ny rindranasa dia ampy ny fitambaran'ny tranomboky default sy ny router tsotra.

Fanodinana fanontaniana

Ho fanampin'izany, mila singa iray izay "hihaino" amin'ny fifandraisana miditra isika ary mandefa ny fangatahana rehetra amin'ny mpitantana marina. http.Server dia afaka mitantana mora foana ity asa ity.

Ity manaraka ity dia mampiseho fa ny mpizara dia tompon'andraikitra amin'ny asa rehetra mifandraika amin'ny fanodinana fifandraisana. Ity, ohatra, dia miasa amin'ny protocol TLS. Mba hampiharana ny antso http.ListenAndServer dia mampiasa server HTTP mahazatra.

Andeha isika hijery ohatra sarotra kokoa.

Manampy ny Let's Encrypt

Amin'ny alΓ lan'ny default, ny fampiharana anay dia mandeha amin'ny protocol HTTP, saingy asaina mampiasa ny protocol HTTPS. Azo atao tsy misy olana izany ao amin'ny Go. Raha nahazo mari-pankasitrahana sy fanalahidy manokana ianao, dia ampy ny misoratra anarana ListenAndServeTLS miaraka amin'ny taratasy fanamarinana marina sy ny rakitra fanalahidy.

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

Afaka manao tsaratsara kokoa hatrany ianao.

Andao isika hamehy manome mari-pankasitrahana maimaim-poana miaraka amin'ny fanavaozana mandeha ho azy. Mba hampiasana ny serivisy dia mila fonosana ianao autocert.

Ny fomba tsotra indrindra hanamboarana azy dia ny fampiasana ny fomba autocert.NewListener miaraka amin'ny http.Serve. Ny fomba dia ahafahanao mahazo sy manavao ny mari-pankasitrahana TLS raha toa ka mangataka ny mpizara HTTP:

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

Raha misokatra amin'ny navigateur isika example.com, dia hahazo valiny HTTPS izahay "Manahoana, izao tontolo izao!"

Raha mila fanamafisam-peo bebe kokoa ianao dia tokony hampiasa ny mpitantana autocert.Manager. Avy eo dia mamorona ohatra http.Server-nay manokana izahay (hatramin'izao fotoana izao dia nampiasa azy io izahay) ary ampio ny mpitantana amin'ny mpizara 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("", "")

Ity dia fomba mora hampiharana ny fanohanana HTTPS feno miaraka amin'ny fanavaozana fanamarinana mandeha ho azy.

Manampy lalana mahazatra

Ny router default tafiditra ao amin'ny tranomboky mahazatra dia tsara, fa tena fototra. Ny ankamaroan'ny fampiharana dia mitaky lalana sarotra kokoa, ao anatin'izany ny lalan'ny nested sy wildcard, na ny fomba fametrahana ny lamina sy ny masontsivana lalana.

Amin'ity tranga ity dia mendrika ny mampiasa fonosana gorila / mux ΠΈ go-chi/chi. Hianarantsika ny fomba fiasa miaraka amin'ity farany - ohatra iray aseho eto ambany.

Omena ny rakitra api/v1/api.go misy lalana ho an'ny 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
}

Napetrakay ny prefix api/vq ho an'ny lalana ao amin'ny rakitra lehibe.

Avy eo isika dia afaka mametraka izany amin'ny router lehibe eo ambanin'ny prefix api/v1/ miverina ao amin'ny fampiharana fototra:

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

Ny fahamoran'i Go amin'ny fiasana amin'ny lalana sarotra dia ahafahana manamora ny fandrafetana sy fikojakojana ireo rindranasa lehibe sy sarotra.

Miasa amin'ny middleware

Ny staging dia misy ny famonosana mpandrindra HTTP iray miaraka amin'ny iray hafa, izay ahafahana manatanteraka haingana ny fanamarinana, ny famatrarana, ny fanoratana ary ny asa maro hafa.

Ohatra, andeha hojerentsika ny http.Handler interface; hampiasa izany isika hanoratana mpitantana iray izay manamarina ny mpampiasa serivisy.

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

Misy ny router an'ny antoko fahatelo, toy ny chi, izay ahafahanao manitatra ny fiasan'ny middleware.

Miasa amin'ny rakitra static

Ny tranomboky manara-penitra Go dia ahitana ny fahafahana miasa miaraka amin'ny atiny static, ao anatin'izany ny sary, ny JavaScript ary ny rakitra CSS. Azo idirana amin'ny alalan'ny fiasa http.FileServer izy ireo. Mamerina mpitantana iray izay manompo rakitra avy amin'ny lahatahiry manokana.

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

Tena ilaina ny mitadidy fa ny http.Dir dia mampiseho ny votoatin'ny lahatahiry raha tsy misy ny rakitra index.html fototra. Amin'ity tranga ity, mba hisorohana ny lahatahiry tsy hikorontana, dia tokony hampiasa ny fonosana ianao unindexed.

Ahitsio fanakatonana

Go koa dia manana endri-javatra antsoina hoe fanakatonana tsara ny mpizara HTTP. Azo atao izany amin'ny alΓ lan'ny fomba Shutdown (). Atomboka amin'ny goroutine ny mpizara, ary avy eo dia henoina ny fantsona mba hahazoana famantarana manapaka. Raha vantany vao voaray ny famantarana dia maty ny mpizara, fa tsy avy hatrany, fa rehefa afaka segondra vitsy.

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)

Ho famaranana

Ny Go dia fiteny matanjaka manana tranomboky manara-penitra saika manerana izao rehetra izao. Ny fahaiza-manaony dia midadasika be, ary azo ampitomboina amin'ny alΓ lan'ny interface tsara - izany dia ahafahanao mamorona mpizara HTTP azo antoka.

Skillbox dia manoro hevitra:

Source: www.habr.com

Add a comment