Ci gaban sabar gidan yanar gizo a Golang - daga sauki zuwa hadaddun

Ci gaban sabar gidan yanar gizo a Golang - daga sauki zuwa hadaddun

Shekaru biyar da suka wuce na fara raya Gophish, wannan ya ba da damar koyon Golang. Na gane cewa Go harshe ne mai ƙarfi, wanda ɗakunan karatu da yawa suka cika su. Go yana da yawa: musamman, ana iya amfani dashi don haɓaka aikace-aikacen gefen uwar garke ba tare da wata matsala ba.

Wannan labarin yana game da rubuta sabar a cikin Go. Bari mu fara da abubuwa masu sauƙi kamar "Hello duniya!" kuma mu ƙare da aikace-aikace tare da iyakoki masu zuwa:

- Amfani da Bari mu Encrypt don HTTPS.
- Yana aiki azaman mai ba da hanya tsakanin hanyoyin sadarwa API.
- Aiki tare da middleware.
- Gudanar da fayilolin tsaye.
- Madaidaicin rufewa.

Skillbox yana ba da shawarar: Hakikanin hanya "Python developer daga karce".

Muna tunatarwa: ga duk masu karatu na "Habr" - rangwame na 10 rubles lokacin yin rajista a kowane kwas na Skillbox ta amfani da lambar talla "Habr".

Sannu Duniya!

Kuna iya ƙirƙirar sabar yanar gizo a cikin Go da sauri. Ga misali na yin amfani da mai kula da ke mayar da “Sannu, duniya!” da aka yi alkawari a sama.

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

Bayan haka, idan kun kunna aikace-aikacen kuma buɗe shafin Localhost, to, nan da nan za ku ga rubutun "Sannu, duniya!" (idan komai yayi daidai, ba shakka).

Za mu yi amfani da mai sarrafa sau da yawa daga baya, amma da farko bari mu fahimci yadda komai ke aiki.

net/http

Misali ya yi amfani da kunshin net/http, shine kayan aiki na farko a cikin Go don haɓaka sabobin biyu da abokan cinikin HTTP. Don fahimtar lambar, bari mu fahimci ma'anar abubuwa masu mahimmanci guda uku: http.Handler, http.ServeMux da http.Server.

HTTP masu sarrafa

Lokacin da muka karɓi buƙatu, mai sarrafa yana bincika ta kuma ya samar da amsa. Ana aiwatar da masu kulawa a cikin Go kamar haka:

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

Misali na farko yana amfani da aikin taimakon http.HandleFunc. Yana kunshe da wani aiki, wanda kuma yana ɗaukar http.ResponseWriter da http.Request zuwa ServeHTTP.

A wasu kalmomi, ana gabatar da masu aiki a cikin Golang a cikin mahaɗin guda ɗaya, wanda ke ba da dama ga mai tsara shirye-shirye. Don haka, alal misali, ana aiwatar da middleware ta amfani da mai sarrafa, inda ServeHTTP ya fara yin wani abu sannan ya kira hanyar ServeHTTP na wani mai sarrafa.

Kamar yadda aka ambata a sama, masu sarrafa kawai suna samar da amsa ga buƙatun. Amma wane ma'aikaci ya kamata a yi amfani da shi a wani lokaci na musamman?

Nemi Hanyar Hanya

Don yin zaɓin da ya dace, yi amfani da HTTP multiplexer. A cikin ɗakunan karatu da yawa ana kiran shi muxer ko na'ura mai ba da hanya tsakanin hanyoyin sadarwa, amma duk abu ɗaya ne. Ayyukan multixer shine bincika hanyar buƙatar kuma zaɓi mai kulawa da ya dace.

Idan kana buƙatar goyon baya don hadaddun kwatance, to yana da kyau a yi amfani da ɗakunan karatu na ɓangare na uku. Wasu daga cikin mafi ci gaba - gorilla/mux и go-chi/chi, waɗannan ɗakunan karatu suna ba da damar aiwatar da sarrafa tsaka-tsaki ba tare da wata matsala ba. Tare da taimakonsu, za ku iya saita hanyar sarrafa katin waya da yin wasu ayyuka da dama. Amfaninsu shine dacewa da daidaitattun masu sarrafa HTTP. A sakamakon haka, za ka iya rubuta sauki code wanda za a iya gyara a nan gaba.

Yin aiki tare da hadaddun tsarin aiki a cikin al'ada na al'ada zai buƙaci hanyoyin da ba daidai ba, kuma wannan yana da matukar damuwa da amfani da masu sarrafa tsoho. Don ƙirƙirar mafi yawan aikace-aikacen, haɗin ɗakin karatu na tsoho da na'ura mai ba da hanya tsakanin hanyoyin sadarwa zai isa.

Gudanar da Tambayoyi

Bugu da ƙari, muna buƙatar ɓangaren da zai "saurara" don haɗin haɗin gwiwa da kuma tura duk buƙatun zuwa ga mai sarrafa daidai. http.Server na iya ɗaukar wannan aikin cikin sauƙi.

Mai zuwa yana nuna cewa uwar garken yana da alhakin duk ayyuka waɗanda ke da alaƙa da sarrafa haɗin gwiwa. Wannan, alal misali, yana aiki ta amfani da ka'idar TLS. Don aiwatar da kiran http.ListenAndServer, ana amfani da daidaitaccen uwar garken HTTP.

Yanzu bari mu kalli wasu misalai masu rikitarwa.

Ƙara Mu Rufewa

Ta hanyar tsoho, aikace-aikacenmu yana aiki akan ka'idar HTTP, amma ana ba da shawarar amfani da ka'idar HTTPS. Ana iya yin hakan ba tare da matsala ba a cikin Go. Idan kun karɓi takaddun shaida da maɓalli na sirri, to ya isa kuyi rijistar ListenAndServeTLS tare da madaidaicin takaddun shaida da fayilolin maɓalli.

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

Kullum kuna iya yin mafi kyau.

Bari mu Encrypt yana ba da takaddun shaida kyauta tare da sabuntawa ta atomatik. Domin amfani da sabis ɗin, kuna buƙatar fakiti autocert.

Hanya mafi sauƙi don daidaita shi ita ce amfani da autocert.NewListener hanya a hade tare da http.Serve. Hanyar tana ba ku damar samu da sabunta takaddun shaida na TLS yayin da uwar garken HTTP ke buƙatar:

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

Idan muka bude a browser Misali.com, za mu sami amsa HTTPS "Sannu, duniya!"

Idan kuna buƙatar ƙarin cikakkun bayanai, to yakamata kuyi amfani da autocert.Manager Manager. Sa'an nan kuma mu ƙirƙiri misalin http.Server namu (har yanzu mun yi amfani da shi ta tsohuwa) kuma mu ƙara mai sarrafa zuwa uwar garken 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("", "")

Wannan hanya ce mai sauƙi don aiwatar da cikakken tallafin HTTPS tare da sabunta takaddun shaida ta atomatik.

Ƙara hanyoyin al'ada

Tsohuwar na'ura mai ba da hanya tsakanin hanyoyin sadarwa da aka haɗa a cikin daidaitaccen ɗakin karatu yana da kyau, amma yana da asali sosai. Yawancin aikace-aikacen suna buƙatar ƙarin hadaddun hanyoyin zirga-zirga, gami da guraben hanyoyi da kati, ko hanya don saita alamu da sigogi.

A wannan yanayin yana da daraja amfani da fakiti gorilla/mux и go-chi/chi. Za mu koyi yadda za a yi aiki tare da na ƙarshe - an nuna misali a kasa.

An ba da fayil ɗin api/v1/api.go mai ɗauke da hanyoyi don API ɗin mu:

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

Mun saita prefix api/vq don hanyoyi a cikin babban fayil ɗin.

Za mu iya hawan wannan zuwa babban hanyar sadarwar mu a ƙarƙashin api/v1/ prefix baya a cikin babban aikace-aikacen mu:

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

Sauƙin Go na aiki tare da hadaddun hanyoyi yana ba da damar sauƙaƙe tsari da kiyaye manyan aikace-aikace masu rikitarwa.

Aiki tare da middleware

Tsari ya ƙunshi naɗa mai sarrafa HTTP guda ɗaya tare da wani, yana ba da damar aiwatar da ingantaccen aiki da sauri, matsawa, shiga, da sauran ayyuka da yawa.

A matsayin misali, bari mu kalli mahallin http.Handler; za mu yi amfani da shi don rubuta mai sarrafa wanda ke tabbatar da masu amfani da sabis.

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

Akwai na'ura mai ba da hanya tsakanin hanyoyin sadarwa, irin su chi, waɗanda ke ba ku damar tsawaita ayyukan tsakiyarware.

Aiki tare da a tsaye fayiloli

Madaidaicin ɗakin karatu na Go ya haɗa da damar aiki tare da abun ciki na tsaye, gami da hotuna, JavaScript da fayilolin CSS. Ana iya isa gare su ta hanyar aikin http.FileServer. Yana dawo da mai sarrafa wanda ke ba da fayiloli daga takamaiman jagorar.

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

Yana da shakka ya kamata a tuna cewa http.Dir yana nuna abubuwan da ke cikin kundin adireshi idan bai ƙunshi babban fayil ɗin index.html ba. A wannan yanayin, don hana ɓata kundin adireshi, ya kamata ku yi amfani da kunshin unindexed.

Madaidaicin rufewa

Go kuma yana da fasalin da ake kira kyakkyawan rufe uwar garken HTTP. Ana iya yin wannan ta amfani da hanyar Shutdown(). Ana kunna uwar garken a cikin goroutine, sannan ana sauraron tashar don karɓar siginar katsewa. Da zarar an karɓi siginar, uwar garken yana kashe, amma ba nan da nan ba, amma bayan ƴan daƙiƙa.

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)

A matsayin ƙarshe

Go harshe ne mai ƙarfi tare da kusan daidaitaccen ɗakin karatu na duniya. Ƙarfin sa na asali yana da faɗi sosai, kuma ana iya haɓaka su ta amfani da musaya - wannan yana ba ku damar haɓaka sabar HTTP da gaske.

Skillbox yana ba da shawarar:

source: www.habr.com

Add a comment