Uphuhliso lweseva yewebhu eGolang-ukusuka kokulula ukuya kubunzima

Uphuhliso lweseva yewebhu eGolang-ukusuka kokulula ukuya kubunzima

Kwiminyaka emihlanu edlulileyo ndaqala phuhlisa iGophish, oku kwanika ithuba lokufunda isiGolang. Ndabona ukuba iGo lulwimi olunamandla, oluncediswa ngamathala eencwadi amaninzi. I-Go iyaguquguquka: ngokukodwa, ingasetyenziselwa ukuphuhlisa umncedisi wecala lezicelo ngaphandle kweengxaki.

Eli nqaku limalunga nokubhala iseva kwi-Go. Masiqale ngezinto ezilula ezinje "Molo hlabathi!" kwaye sigqibe ngesicelo esinezi zakhono zilandelayo:

-Usebenzisa i-Let Encrypting ye-HTTPS.
-Isebenza njenge-API router.
- Ukusebenza kunye ne-middleware.
-Ukwenziwa kweefayile ezimileyo.
— Ukuvalwa okuchanekileyo.

I-Skillbox iyacebisa: Ikhosi esebenzayo "Umphuhlisi wePython ukusuka ekuqaleni".

Siyakhumbuza: kubo bonke abafundi be "Habr" - isaphulelo se-ruble ye-10 xa ubhalisa kuyo nayiphi na ikhosi ye-Skillbox usebenzisa ikhowudi yokuphromotha "Habr".

Molo Lizwe!

Unokwenza iseva yewebhu kwi-Go ngokukhawuleza okukhulu. Nanku umzekelo wokusebenzisa isibambi esibuyisela “Molo, hlabathi!” othenjiswe ngasentla.

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

Emva koku, ukuba uqhuba isicelo kwaye uvule iphepha localhost, ngoko uya kuwubona ngoko nangoko umbhalo othi “Molo, hlabathi!” (ukuba yonke into isebenza ngokuchanekileyo, kunjalo).

Siza kusebenzisa isibambi amaxesha amaninzi kamva, kodwa masiqale siqonde ukuba yonke into isebenza njani.

umnatha/http

Umzekelo usebenzise ipakethe net/http, sisixhobo sokuqala kwi-Go sokuphuhlisa zombini iiseva kunye nabaxhasi be-HTTP. Ukuqonda ikhowudi, masiqonde intsingiselo yezinto ezintathu ezibalulekileyo: http.Handler, http.ServeMux kunye ne-http.Server.

abaphathi beHTTP

Xa sifumana isicelo, umphathi uyasihlalutya kwaye avelise impendulo. IiHandlers in Go ziphunyezwa ngolu hlobo lulandelayo:

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

Umzekelo wokuqala usebenzisa umsebenzi womncedisi we-http.HandleFunc. Isonga omnye umsebenzi, othi wona uthathe i-http.ResponseWriter kunye ne-http.Request kwi-ServeHTTP.

Ngamanye amazwi, abaphathi kwiGolang bavezwa kujongano olulodwa, olunika iinketho ezininzi kumdwelisi wenkqubo. Ngoko ke, umzekelo, i-middleware iphunyezwa kusetyenziswa isibambi, apho i-ServeHTTP iqala ukwenza into kwaye emva koko ibize indlela ye-ServeHTTP yomnye umphathi.

Njengoko kukhankanyiwe ngasentla, abaphathi bavelisa nje iimpendulo kwizicelo. Kodwa nguwuphi umqhubi ofanelekileyo ofanele asetyenziswe ngexesha elithile?

Cela indlela

Ukwenza ukhetho olufanelekileyo, sebenzisa i-HTTP multiplexer. Kwinani lamathala eencwadi kuthiwa yi-muxer okanye i-router, kodwa zonke ziyafana. Umsebenzi we-multiplexer kukuhlalutya indlela yokucela kwaye ukhethe umphathi ofanelekileyo.

Ukuba ufuna inkxaso kwindlela entsonkothileyo, ke kungcono ukusebenzisa iilayibrari zomntu wesithathu. Ezinye zezona ziphambili - igorila/mux и go-chi/chi, la mathala eencwadi enza kube nokwenzeka ukuphumeza inkqubo ephakathi ngaphandle kweengxaki. Ngoncedo lwabo, ungaqwalasela i-wildcard routing kwaye wenze inani leminye imisebenzi. Inzuzo yabo iyahambelana nabaphathi be-HTTP abaqhelekileyo. Ngenxa yoko, unokubhala ikhowudi elula enokuthi iguqulwe kwixesha elizayo.

Ukusebenza kunye nezicwangciso eziyinkimbinkimbi kwimeko eqhelekileyo kuya kufuna izisombululo ezingezizo eziqhelekileyo, kwaye oku kunzima kakhulu ukusetyenziswa kwabaphathi abangagqibekanga. Ukwenza uninzi lwezicelo, indibaniselwano yelayibrari engagqibekanga kunye ne-router elula iya kwanela.

Ukuqhubekeka koMbuzo

Ukongeza, sidinga icandelo eliya "kumamela" kuqhagamshelo olungenayo kwaye liqondise ngokutsha zonke izicelo kumphathi ochanekileyo. http.Umncedisi unokusingatha ngokulula lo msebenzi.

Oku kulandelayo kubonisa ukuba umncedisi unoxanduva lwayo yonke imisebenzi enxulumene nokulungiswa koqhagamshelwano. Oku, umzekelo, kusebenza usebenzisa i-TLS protocol. Ukuphumeza umnxeba we-http.ListenAndServer, umncedisi oqhelekileyo weHTTP uyasetyenziswa.

Ngoku makhe sijonge imizekelo entsonkothileyo.

Ukongeza Masi Fihla

Ngokungagqibekanga, usetyenziso lwethu luhamba ngaphezulu kweprotocol yeHTTP, kodwa kuyacetyiswa ukuba usebenzise iprotocol yeHTTPS. Oku kunokwenziwa ngaphandle kweengxaki kwi-Go. Ukuba ufumene isatifikethi kunye nesitshixo sangasese, ngoko kwanele ukubhalisa i- ListenAndServeTLS kunye nesatifikethi esichanekileyo kunye neefayile eziphambili.

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

Ungasoloko usenza ngcono.

Masibhale inikeza izatifikethi zasimahla ngohlaziyo oluzenzekelayo. Ukuze usebenzise inkonzo, udinga ipakethe autocert.

Eyona ndlela ilula yokuyiqwalasela kukusebenzisa indlela ye-autocert.NewListener ngokudityaniswa ne-http.Serve. Indlela ikuvumela ukuba ufumane kwaye uhlaziye izatifikethi ze-TLS ngelixa iseva yeHTTP iqhuba izicelo:

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

Ukuba sivula kwibhrawuza example.com, siya kufumana impendulo ye-HTTPS "Molo, hlabathi!"

Ukuba ufuna uqwalaselo oluneenkcukacha ezininzi, kufuneka usebenzise i-autocert.Manager manager. Emva koko siyila eyethu i-http.Umncedisi umzekelo (kude kube ngoku siwusebenzise ngokungagqibekanga) kwaye songeze umphathi kumncedisi we 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("", "")

Le yindlela elula yokuphumeza inkxaso epheleleyo yeHTTPS ngohlaziyo lwesatifikethi oluzenzekelayo.

Ukongeza iindlela eziqhelekileyo

I-router engagqibekanga ebandakanyiwe kwilayibrari eqhelekileyo ilungile, kodwa isisiseko kakhulu. Uninzi lwezicelo zifuna umzila onzima ngakumbi, kubandakanya iindlela ezibekwe kwindlwane kunye nekhadi lasendle, okanye inkqubo yokuseta iipatheni zendlela kunye neeparamitha.

Kule meko kuyafaneleka ukusebenzisa iipakethi igorila/mux и go-chi/chi. Siza kufunda ukusebenza kunye nokugqibela - umzekelo uboniswe ngezantsi.

Inikwe ifayile api/v1/api.go equlethe iindlela ze-API yethu:

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

Siseta i-api/vq isimaphambili seendlela kwifayile ephambili.

Emva koko sinokuyinyusa le kwi-router yethu ephambili phantsi kwe-api/v1/ isimaphambili sibuyele kwisicelo sethu esingundoqo:

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

Ukuhamba ngokulula kokusebenza kunye neendlela eziyinkimbinkimbi kwenza kube lula ukucwangciswa kunye nokugcinwa kwezicelo ezinkulu, ezinzima.

Ukusebenza kunye ne-middleware

Ukulinganisa kubandakanya ukusonga isibambi esinye se-HTTP kunye nomnye, okwenza kube lula ukwenza uqinisekiso, uxinzelelo, ukugawulwa, kunye neminye imisebenzi emininzi.

Njengomzekelo, makhe sijonge ujongano lwe-http.Handler, siza kuyisebenzisa ukubhala isibambi esiqinisekisa abasebenzisi benkonzo.

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

Kukho iirotha zeqela lesithathu, ezifana ne-chi, ezikuvumela ukuba wandise ukusebenza kwe-middleware.

Ukusebenza ngeefayile ezimileyo

Ilayibrari esemgangathweni yeGo ibandakanya amandla okusebenza ngomxholo omileyo, kubandakanywa imifanekiso, iJavaScript kunye neefayile zeCSS. Zinokufikelelwa ngomsebenzi we-http.FileServer. Ibuyisela isiphathi esikhonza iifayile kulawulo oluthile.

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

Ngokuqinisekileyo kufanelekile ukukhumbula ukuba i-http.Dir ibonisa imixholo yolawulo ukuba ayiqulathanga ifayile ye index.html engundoqo. Kulo mzekelo, ukunqanda uvimba weefayili ekubeni usengozini, kufuneka usebenzise ipakethe unindexed.

Ukuvalwa okuchanekileyo

UGo kwakhona unophawu olubizwa ngokuba luvale ukuvalwa kweseva yeHTTP. Oku kunokwenziwa ngokusebenzisa i Cima () indlela. Umncedisi uqalwa kwi-goroutine, kwaye ke itshaneli imanyelwa ukufumana umqondiso wokuphazamiseka. Ngokukhawuleza ukuba umqondiso ufunyenwe, umncedisi uyacima, kodwa kungekhona ngokukhawuleza, kodwa emva kwemizuzwana embalwa.

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)

Njengesiphelo

UGo lulwimi olunamandla oluphantse lube nethala leencwadi elisemgangathweni jikelele. Izakhono zayo ezingagqibekanga zibanzi kakhulu, kwaye zinokuphuculwa kusetyenziswa ujongano-oku kukuvumela ukuba uphuhlise iiseva ezithembekileyo zeHTTP.

I-Skillbox iyacebisa:

umthombo: www.habr.com

Yongeza izimvo