Whanaketanga tūmau Tukutuku i Golang - mai i te ngawari ki te uaua

Whanaketanga tūmau Tukutuku i Golang - mai i te ngawari ki te uaua

E rima tau ki muri ka timata ahau whakawhanake Gophish, i whai waahi tenei ki te ako i a Golang. I mohio ahau he reo kaha a Go, e tautokohia ana e te maha o nga whare pukapuka. He pai te haere: ina koa, ka taea te whakamahi ki te whakawhanake i nga tono taha-tumau kaore he raru.

Ko tenei tuhinga mo te tuhi i tetahi tūmau i Go. Me timata ma nga mea ngawari penei "Kia ora te ao!" ka mutu me te tono me nga kaha e whai ake nei:

- Ma te Whakamuna tatou mo HTTPS.
— Mahi hei pouara API.
— Te mahi tahi me te middleware.
— Te tukatuka i nga konae pateko.
— Kati tika.

Ka tūtohu a Skillbox: Akoranga mahi "Python kaiwhakawhanake mai i te wahanga".

Ka whakamahara matou: mo nga kaipānui katoa o "Habr" - he utu mo te 10 rubles i te wa e whakauru ana ki tetahi akoranga Skillbox ma te whakamahi i te waehere whakatairanga "Habr".

Bonjour Monde!

Ka taea e koe te hanga i tetahi tūmau tukutuku i roto i te Haere tere rawa. Anei tetahi tauira o te whakamahi i te kaikawe ka whakahoki i te "Kia ora, te ao!" i oati i runga ake nei.

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

I muri i tenei, ki te whakahaere koe i te tono me te whakatuwhera i te whaarangi localhost, ka kite tonu koe i te kupu “Kia ora, e te ao!” (mehemea ka tika nga mea katoa, o te akoranga).

Ka whakamahia e matou te kaihautu i nga wa maha i muri mai, engari me maarama taatau ki te mahi o nga mea katoa.

kupenga/http

I whakamahia e te tauira te kete net/http, Koia te taputapu tuatahi i roto i te Haere mo te whakawhanake i nga kaitoro me nga kaihoko HTTP. Kia mohio ki te waehere, kia mohio tatou ki te tikanga o nga mea nui e toru: http.Handler, http.ServeMux me http.Server.

Kaihautu HTTP

Ka tae mai he tono, ka tātarihia e te kaihautu me te whakaputa whakautu. Ka whakatinanahia nga Kaihautu i roto i a Go e whai ake nei:

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

Ko te tauira tuatahi ka whakamahi i te mahi awhina http.HandleFunc. Ka takai i tetahi atu mahi, ka mau te http.ResponseWriter me te http.Request ki ServeHTTP.

I etahi atu kupu, ko nga kaikawe i Golang e whakaatuhia ana i roto i te atanga kotahi, he maha nga whiringa ki te kaiwhakaputa. Na, hei tauira, ka whakatinanahia te middleware ma te whakamahi i tetahi kaihautu, kei reira a ServeHTTP i te tuatahi ka mahi i tetahi mea ka karangahia te tikanga ServeHTTP o tetahi atu kaihautu.

Ka rite ki te korero i runga ake nei, ka whakaputa noa nga kaikawe i nga whakautu ki nga tono. Engari ko wai te kaihautu me whakamahi i tetahi wa?

Tono Ararere

Hei whiriwhiri tika, whakamahia te HTTP multiplexer. I roto i te maha o nga whare pukapuka ka kiia ko te muxer, ko te pouara ranei, engari he rite tonu. Ko te mahi a te multiplexer he tātari i te ara tono me te kowhiri i te kaihautu tika.

Mena ka hiahia koe ki te tautoko mo te ararere uaua, he pai ake te whakamahi i nga whare pukapuka tuatoru. Ko etahi o nga tino matatau - gorila/mux и haere-chi/chi, ka taea e enei whare pukapuka te whakatinana i te tukatuka takawaenga kaore he raru. Ma ta raatau awhina, ka taea e koe te whirihora i te ararere kaari mohoao me te mahi i etahi atu mahi. Ko to raatau painga ko te hototahi ki nga kaiwhakahaere HTTP paerewa. Ko te mutunga, ka taea e koe te tuhi waehere ngawari ka taea te whakarereke i nga ra kei mua.

Ko te mahi me nga anga matatini i roto i te ahuatanga noa ka hiahiatia he otinga kore-paerewa, a na tenei ka tino whakararu i te whakamahinga o nga kaikawe taunoa. Hei waihanga i te nuinga o nga tono, ka nui te huinga o te whare pukapuka taunoa me te pouara ngawari.

Tukatuka Uiui

I tua atu, me hiahia he waahanga ka "whakarongo" mo nga hononga taumai me te tuku ano i nga tono katoa ki te kaihautu tika. Ka taea e http.Server te whakahaere i tenei mahi.

Ko nga mea e whai ake nei e whakaatu ana ko te tūmau te kawenga mo nga mahi katoa e pa ana ki te tukatuka hononga. Ko tenei, hei tauira, ka mahi ma te whakamahi i te kawa TLS. Hei whakatinana i te waea http.ListenAndServer, ka whakamahia he tūmau HTTP paerewa.

Inaianei ka titiro tatou ki etahi tauira uaua ake.

Te taapiri Kia Whakamuna

Ma te taunoa, ka rere to maatau tono i runga i te kawa HTTP, engari e taunaki ana kia whakamahia te kawa HTTPS. Ka taea tenei kaore he raruraru i roto i te Haere. Mena kua whiwhi koe i tetahi tiwhikete me te taviri tūmataiti, katahi ka nui ki te rehita ListenAndServeTLS me te tiwhikete tika me nga konae matua.

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

Ka taea e koe te mahi pai ake.

Kia Whakamuna whakarato tiwhikete kore utu me te whakahou aunoa. Hei whakamahi i te ratonga, me hiahia koe ki tetahi kete autocert.

Ko te huarahi ngawari ki te whirihora ko te whakamahi i te tikanga autocert.NewListener me te http.Serve. Ma te tikanga ka taea e koe te tiki me te whakahou i nga tiwhikete TLS i te wa e tono ana te tūmau HTTP:

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

Ki te whakatuwhera tatou i roto i te pūtirotiro example.com, ka whiwhi tatou i te whakautu HTTPS "Kia ora, te ao!"

Mena ka hiahia koe ki etahi atu whirihoranga, me whakamahi koe i te kaiwhakahaere autocert.Manager. Na ka hanga e matou to maatau ake tauira http.Server (tae noa ki tenei wa ka whakamahia e matou ma te taunoa) ka taapiri i te kaiwhakahaere ki te tūmau 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("", "")

He huarahi ngawari tenei ki te whakatinana i te tautoko HTTPS katoa me te whakahoutanga tiwhikete aunoa.

Te taapiri i nga huarahi ritenga

Ko te pouara taunoa kei roto i te whare pukapuka paerewa he pai, engari he tino taketake. Ko te nuinga o nga tono me ararere uaua ake, tae atu ki nga ara kohanga me nga ara mohoao, he tikanga ranei mo te whakatakoto tauira ara me nga tawhā.

I tenei keehi he pai te whakamahi i nga kohinga gorila/mux и haere-chi/chi. Ka ako tatou me pehea te mahi me o muri - he tauira kei raro nei.

Ko te konae api/v1/api.go kei roto nga huarahi mo to tatou 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
}

I tautuhia e matou te tohu tuatahi o te api/vq mo nga ara i te konae matua.

Ka taea e tatou te whakairi i tenei ki to tatou pouara matua i raro i te api/v1/ prefix hoki i roto i ta tatou tono matua:

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

Ma te ngawari o Go ki te mahi me nga huarahi uaua ka taea te whakangawari i te hanganga me te tiaki i nga tono nui, uaua.

Te mahi me te middleware

Ko te mahinga ko te takai i tetahi kaihautu HTTP ki tetahi atu, kia tere ai te mahi motuhēhēnga, te kōpeketanga, te takiuru, me etahi atu mahi.

Hei tauira, me titiro ki te atanga http.Handler, ka whakamahia hei tuhi i tetahi kaihautu e whakamana ana i nga kaiwhakamahi ratonga.

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

He pouara tuatoru, penei i te chi, ka taea e koe te toro atu i te mahi middleware.

Te mahi me nga konae pateko

Kei roto i te whare pukapuka paerewa Go nga kaha mo te mahi me nga ihirangi pateko, tae atu ki nga whakaahua, JavaScript me nga konae CSS. Ka taea te uru atu ma te mahi http.FileServer. Ka whakahokia he kaihautu e mahi ana i nga konae mai i tetahi raarangi motuhake.

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

He mea tika kia maumahara ka whakaatu a http.Dir i nga ihirangi o te whaiaronga mena karekau te konae index.html matua. I tenei keehi, kia kore ai e taupatupatu te raarangi, me whakamahi koe i te kete unindexed.

Kati tika

Kei a Go ano tetahi ahuatanga e kiia ana ko te katinga ataahua o te tūmau HTTP. Ka taea tenei ma te whakamahi i te tikanga Whakaweto(). Ka timata te tūmau i roto i te goroutine, katahi ka whakarongohia te hongere kia whiwhi tohu haukoti. Ka tae mai te tohu, ka whakaweto te tūmau, engari kaore i te wa tonu, engari i muri i etahi hēkona.

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)

Hei mutunga

He reo kaha a Go me te whare pukapuka paerewa tata ki te ao. Ko ona kaha taunoa he tino whanui, a ka taea te whakarei ake ma te whakamahi atanga - ma tenei ka taea e koe te whakawhanake i nga tūmau HTTP pono.

Ka tūtohu a Skillbox:

Source: will.com

Tāpiri i te kōrero