Horumarinta server-ka ee Golang - laga bilaabo fudud ilaa kakan

Horumarinta server-ka ee Golang - laga bilaabo fudud ilaa kakan

Shan sano ka hor ayaan bilaabay horumarinta Gophish, tani waxay siisay fursad lagu barto Golang. Waxaan gartay in Go uu yahay luqad awood leh, oo ay kaabayaan maktabado badan. Go waa wax badan: gaar ahaan, waxaa loo isticmaali karaa in lagu horumariyo codsiyada dhinaca server-ka iyada oo aan wax dhibaato ah dhicin.

Maqaalkani waxa uu ku saabsan yahay qorista server gudaha Go. Aan ku bilowno waxyaabo fudud sida "Hello world!" oo aan ku dhameyno codsi leh awoodaha soo socda:

Isticmaalka Aynu sir u dhigno HTTPS.
- U shaqeeya sidii router API ah.
- Ku shaqaynta qalabka dhexe.
- Habaynta faylasha taagan
- Xiritaan sax ah

Skillbox waxay ku talinaysaa: Koorso wax ku ool ah "Horumariyaha Python meel eber ah".

Waxaan xusuusineynaa: dhammaan akhristayaasha "Habr" - qiimo dhimis ah 10 rubles marka la qorayo koorso kasta oo Skillbox ah iyadoo la adeegsanayo koodhka xayeysiinta "Habr".

Hello, adduunka!

Waxaad si dhakhso leh ugu abuuri kartaa server-ka shabakadda Go. Halkan waxaa ah tusaale isticmaalka maamule soo celinaya "Hello, aduunka!" kor lagu balan qaaday.

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

Taas ka dib, haddii aad socodsiiso codsiga oo aad furto bogga localhost, markaas waxaad isla markiiba arki doontaa qoraalka "Hello, adduunyo!" (haddii wax waliba si sax ah u shaqeeyaan, dabcan).

Waxaan isticmaaleynaa maamulaha dhowr jeer ka dib, laakiin marka hore aan fahamno sida wax walba u shaqeeyaan.

net/http

Tusaalaha ayaa isticmaalay xirmada net/http, waa aaladda aasaasiga ah ee Go ee horumarinta server-yada iyo macaamiisha HTTP labadaba. Si aan u fahamno koodka, aan fahanno macnaha saddex walxood oo muhiim ah: http.Handler, http.ServeMux iyo http.Server.

Maamulayaasha HTTP

Markaan helno codsi, maamulaha ayaa falanqeeya oo soo saara jawaab. Handlers in Go waxaa loo fuliyaa sida soo socota:

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

Tusaalaha ugu horreeya waxa uu isticmaalaa http.HandleFunc caawiyaha. Waxay soo duubtaa hawl kale, taas oo iyana qaadanaysa http.ResponseWriter iyo http.Codsiga ServeHTTP.

Si kale haddii loo dhigo, maamulayaasha Golang waxaa lagu soo bandhigay hal interface, taas oo siinaysa fursado badan oo barnaamijka ah. Marka, tusaale ahaan, dhexdhexaadiyaha waxaa lagu fuliyaa iyadoo la isticmaalayo maamule, halkaasoo ServeHTTP marka hore wax qabato ka dibna u wac habka ServeHTTP ee maamule kale.

Sida kor ku xusan, maareeyayaashu waxay si fudud u dhaliyaan jawaabaha codsiyada. Laakiin waa kuwee maamule gaar ah oo ay tahay in la isticmaalo waqti gaar ah?

Codso Jideynta

Si aad u samayso doorashada saxda ah, isticmaal HTTP multiplexer. Tiro ka mid ah maktabadaha waxaa loogu yeeraa muxer ama router, laakiin dhammaantood waa isku mid. Hawsha laba-geeye waa in la falanqeeyo dariiqa codsiga oo uu doorto maamulaha ku habboon.

Haddii aad u baahan tahay taageero loogu talagalay marinka adag, markaa waxa fiican inaad isticmaasho maktabadaha qolo saddexaad. Qaar ka mid ah kuwa ugu horumarsan - gorilla/mux ΠΈ go-chi/chi, Maktabadahani waxay suurtogal ka dhigayaan in la hirgeliyo farsamaynta dhexdhexaadka ah iyada oo aan wax dhibaato ah dhicin. Caawintooda, waxaad habayn kartaa marin-u-qaadista kaadhadhka duurjoogta ah oo aad qabato hawlo kale oo badan. Faa'iidadooda ayaa ah la jaanqaadka maamulayaasha HTTP caadiga ah. Natiijo ahaan, waxaad qori kartaa kood fudud oo wax laga beddeli karo mustaqbalka.

Ku shaqeynta qaab-dhismeedka adag ee xaalad caadi ah waxay u baahan doontaa xalal aan caadi ahayn, tani waxay si weyn u adkeyneysaa isticmaalka maamulayaasha caadiga ah. Si loo abuuro inta badan codsiyada, isku darka maktabadda caadiga ah iyo router fudud ayaa ku filnaan doona.

Hagaajinta weydiinta

Intaa waxaa dheer, waxaan u baahanahay qayb "dhegeysan doonta" isku xirka soo socda oo u wareejin doona dhammaan codsiyada maamulaha saxda ah. http.Server si fudud ayuu hawshan u qabsan karaa.

Kuwa soo socdaa waxay muujinayaan in server-ku uu mas'uul ka yahay dhammaan hawlaha la xidhiidha habaynta isku xirka. Tani, tusaale ahaan, waxay ku shaqeysaa iyadoo la isticmaalayo borotokoolka TLS. Si loo hirgeliyo wicitaanka http.ListenAndServer, server HTTP caadiga ah ayaa la isticmaalaa.

Haddaba aan eegno tusaalooyin kakan oo kale.

Ku darida Aynu Sirinno

Sida caadiga ah, codsigayagu waxa uu ka sarreeyaa borotokoolka HTTP, laakiin waxa lagu talinayaa in la isticmaalo borotokoolka HTTPS. Tan waxaa la samayn karaa dhibaato la'aan gudaha Go. Haddii aad heshay shahaado iyo fure gaar ah, markaa waxa kugu filan inaad ku diwaangeliso ListenAndServeTLS shahaadada saxda ah iyo faylasha muhiimka ah.

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

Had iyo jeer waxaad samayn kartaa si ka wanaagsan.

Aan isku dayno waxay bixisaa shahaadooyin bilaash ah oo dib u cusbooneysiin toos ah. Si aad u isticmaasho adeegga, waxaad u baahan tahay xirmo autocert.

Habka ugu fudud ee loo habayn karo waa in la isticmaalo habka autocert.NewListener marka lagu daro http.Serve. Qaabku wuxuu kuu ogolaanayaa inaad hesho oo aad cusboonaysiiso shahaadooyinka TLS halka adeegaha HTTP uu codsanayo:

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

Haddii aan ku furno browserka example.com, waxaan heli doonaa jawaabta HTTPS "Hello, aduunka!"

Haddii aad u baahan tahay qaabayn faahfaahsan, markaa waa inaad isticmaashaa maamulaha autocert.Manager. Markaa waxaan abuurnaa tusaale http.Server noo gaar ah (ilaa hadda waxaan u isticmaalnay si caadi ah) oo ku dar maamulaha server-ka 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("", "")

Tani waa hab fudud oo lagu hirgelinayo taageerada HTTPS oo buuxda oo leh dib u cusboonaysiinta shahaadada.

Ku darida waddooyinka gaarka ah

Router-ka caadiga ah ee ku jira maktabadda caadiga ah waa mid wanaagsan, laakiin waa mid aasaasi ah. Codsiyada badankoodu waxay u baahan yihiin marin aad u adag, oo ay ku jiraan dariiqyada buul leh iyo kuwa duurjoogta ah, ama habraaca dejinta qaababka iyo cabbirrada waddooyinka.

Xaaladdan oo kale waxaa habboon in la isticmaalo baakadaha gorilla/mux ΠΈ go-chi/chi. Waxaan baran doonaa sida loola shaqeeyo kan dambe - tusaale ayaa lagu muujiyay hoos.

Waxaa la siiyay faylka api/v1/api.go ka kooban dariiqooyin API-gayada:

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

Waxaanu dejinay horgalaha api/vq ee dariiqyada faylka ugu weyn.

Waxaan markaa ku dhejin karnaa tan router-keena ugu weyn ee hoos yimaada api/v1/ horgalaha dib ugu soo celinta codsigeena ugu muhiimsan:

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

Fududeynta Go's ee ku shaqeynta waddooyinka adag waxay suurtogal ka dhigeysaa in la fududeeyo qaabeynta iyo dayactirka codsiyada waaweyn ee adag.

Ku shaqaynta qalabka dhexe

Habayntu waxa ay ku lug leedahay in hal qof oo HTTP ah lagu duubo mid kale, taas oo suurtogal ka dhigaysa in si dhakhso ah loo sameeyo xaqiijinta, isku xidhka, gooynta, iyo hawlo kale oo badan.

Tusaale ahaan, aan eegno interface-ka http.Handler, waxaan u isticmaali doonaa si aan u qorno maamule xaqiijinaya isticmaalayaasha adeegga.

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

Waxaa jira jiheeyayaal dhinac saddexaad ah, sida chi, oo kuu ogolaanaya inaad kordhiso shaqeynta dhexda.

Ku shaqaynta faylasha taagan

Maktabadda caadiga ah ee Go waxaa ku jira awoodaha loogu shaqeynayo nuxurka taagan, oo ay ku jiraan sawirrada, JavaScript iyo faylasha CSS. Waxaa laga heli karaa shaqada http.FileServer. Waxay soo celisaa maamule u adeegaya faylalka hage gaar ah.

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

Waxaa hubaal ah in la xasuusto in http.Dir uu soo bandhigayo waxa ku jira hagaha haddii uusan ku jirin faylka index.html ee ugu muhiimsan. Xaaladdan oo kale, si aad uga hortagto hagaha in la jabiyo, waa inaad isticmaashaa xirmada unindexed.

Xiritaan sax ah

Go waxa kale oo uu leeyahay sifo la yidhaahdo xidhidh qurux badan oo server HTTP ah. Tan waxa lagu samayn karaa iyadoo la isticmaalayo habka Shutdown(). Seerfarka waxa lagu bilaabay goroutine, ka dibna kanaalka waa la dhegaystay si uu u helo signalka joojinta. Isla marka calaamada la helo, server-ku wuu dami, laakiin isla markiiba ma aha, laakiin dhowr ilbiriqsi ka dib.

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)

Sida gabagabada

Go waa luqad awood leh oo leh maktabad heer caalami ah oo ku dhow. Awoodeeda caadiga ah waa mid aad u ballaaran, waxaana lagu wanaajin karaa iyada oo la adeegsanayo interfaces - tani waxay kuu ogolaaneysaa inaad horumariso server HTTP oo dhab ah oo la isku halayn karo.

Skillbox waxay ku talinaysaa:

Source: www.habr.com

Add a comment