په ګولنګ کې د ویب سرور پراختیا - له ساده څخه پیچلې ته

په ګولنګ کې د ویب سرور پراختیا - له ساده څخه پیچلې ته

پنځه کاله دمخه ما پیل کړ Gophish ته وده ورکړيدا د ګولنګ زده کړې فرصت برابر کړ. ما پوهیده چې ګو یوه پیاوړې ژبه ده، چې د ډیری کتابتونونو لخوا تکمیل شوې. Go هر اړخیز دی: په ځانګړي توګه ، دا پرته له کومې ستونزې د سرور اړخ غوښتنلیکونو رامینځته کولو لپاره کارول کیدی شي.

دا مقاله په Go کې د سرور لیکلو په اړه ده. راځئ چې د ساده شیانو سره پیل وکړو لکه "سلام نړۍ!" او د لاندې وړتیاو سره د غوښتنلیک سره پای ته ورسیږو:

- د HTTPS لپاره د لیټز کوډ کولو کارول.
- د API روټر په توګه کار کول.
- د منځني وسایلو سره کار کول.
- د جامد فایلونو پروسس کول.
- سم بندول.

Skillbox وړاندیز کوي: عملي کورس "د پایتون پراختیا کونکی له پیل څخه".

موږ یادونه کوو: د ټولو هابر لوستونکو لپاره - د 10 روبل تخفیف کله چې د هابر پرومو کوډ په کارولو سره د مهارت بکس کوم کورس کې نوم لیکنه وکړئ.

سلام نړی!

تاسو کولی شئ په Go کې خورا ګړندي ویب سرور رامینځته کړئ. دلته د هینډلر کارولو مثال دی چې پورته ژمنه شوې "هیلو، نړۍ!" بیرته راګرځوي.

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

له دې وروسته، که تاسو اپلیکیشن چل کړئ او پاڼه خلاص کړئ ځایی لوسټ، بیا به تاسو سمدلاسه متن وګورئ "سلام، نړۍ!" (که هرڅه سم کار کوي، البته).

موږ به وروسته څو ځله هینډلر وکاروو، مګر لومړی راځئ چې پوه شو چې هر څه څنګه کار کوي.

net/http

مثال د کڅوړې کارول net/http، دا د دواړو سرورونو او HTTP مراجعینو رامینځته کولو لپاره په Go کې لومړنۍ وسیله ده. د کوډ د پوهیدو لپاره، راځئ چې د دریو مهمو عناصرو په معنی پوه شو: http.Handler، http.ServeMux او http.Server.

د HTTP سمبالونکي

کله چې موږ غوښتنه ترلاسه کړو، سمبالونکی یې تحلیلوي او ځواب تولیدوي. په Go کې سمبالونکي په لاندې ډول پلي کیږي:

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

لومړی مثال د http.HandleFunc مرستندویه فعالیت کاروي. دا یو بل فعالیت پوښي، کوم چې په پایله کې http.ResponseWriter او http.Request په ServeHTTP کې اخلي.

په بل عبارت، په ګولنګ کې سمبالونکي په یو واحد انٹرفیس کې وړاندې کیږي، کوم چې پروګرامر ته ډیری اختیارونه ورکوي. نو، د مثال په توګه، منځنی وییر د هینډلر په کارولو سره پلي کیږي، چیرته چې ServeHTTP لومړی یو څه کوي او بیا د بل هینډلر ServeHTTP میتود ته زنګ ووهي.

لکه څنګه چې پورته یادونه وشوه، سمبالونکي په ساده ډول غوښتنو ته ځوابونه تولیدوي. مګر کوم ځانګړی هینډلر باید په یو ځانګړي وخت کې وکارول شي؟

د روټینګ غوښتنه وکړئ

د سم انتخاب کولو لپاره، د HTTP ملټي پلیکسر وکاروئ. په یو شمیر کتابتونونو کې دې ته مکسر یا روټر ویل کیږي، مګر دا ټول یو شان دي. د ملټي پلیکسر دنده دا ده چې د غوښتنې لاره تحلیل کړي او مناسب هینډلر غوره کړي.

که تاسو د پیچلي روټینګ لپاره ملاتړ ته اړتیا لرئ ، نو دا غوره ده چې د دریمې ډلې کتابتونونه وکاروئ. ځینې ​​خورا پرمختللي - ګوریلا/مکس и go-chi/chiدا کتابتونونه پرته له کومې ستونزې د منځګړیتوب پروسس پلي کول ممکنه کوي. د دوی په مرسته، تاسو کولی شئ د وائلډ کارډ روټینګ تنظیم کړئ او یو شمیر نورې دندې ترسره کړئ. د دوی ګټه د معیاري HTTP هینډلرونو سره مطابقت دی. د پایلې په توګه، تاسو کولی شئ ساده کوډ ولیکئ چې په راتلونکي کې تعدیل کیدی شي.

په عادي حالت کې د پیچلي چوکاټونو سره کار کول به غیر معیاري حلونو ته اړتیا ولري، او دا د ډیفالټ هینډلرونو کارول د پام وړ پیچلي کوي. د ډیری غوښتنلیکونو رامینځته کولو لپاره ، د ډیفالټ کتابتون ترکیب او یو ساده روټر به کافي وي.

د پوښتنې پروسس کول

برسېره پردې، موږ یوې برخې ته اړتیا لرو چې د راتلونکو اړیکو لپاره "اوریدل" وکړي او ټولې غوښتنې سم سمبالونکي ته واستول شي. http.Server کولی شي دا دنده په اسانۍ سره سمبال کړي.

لاندې ښیې چې سرور د ټولو دندو لپاره مسؤل دی چې د پیوستون پروسس پورې اړه لري. دا، د مثال په توګه، د TLS پروتوکول په کارولو سره کار کوي. د http.ListenAndServer کال پلي کولو لپاره، یو معیاري HTTP سرور کارول کیږي.

اوس راځئ چې نور پیچلي مثالونه وګورو.

اضافه کول راځئ چې کوډ کړو

په ډیفالټ ډول، زموږ غوښتنلیک د HTTP پروتوکول پرمخ ځي، مګر دا سپارښتنه کیږي چې د HTTPS پروتوکول وکاروئ. دا په Go کې پرته له کومې ستونزې ترسره کیدی شي. که تاسو یو سند او شخصي کیلي ترلاسه کړې وي ، نو دا د سم سند او کلیدي فایلونو سره د ListenAndServeTLS راجسټر کولو لپاره کافي ده.

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

تاسو تل ښه کولی شئ.

راځئ چې انډیټ کړئ د اتوماتیک تجدید سره وړیا سندونه چمتو کوي. د خدمت کارولو لپاره، تاسو یو بسته بندي ته اړتیا لرئ autocert.

د دې تنظیم کولو ترټولو اسانه لاره د http.Serve سره په ترکیب کې د autocert.NewListener میتود کارول دي. میتود تاسو ته اجازه درکوي د TLS سندونه ترلاسه او تازه کړئ پداسې حال کې چې HTTP سرور غوښتنې پروسس کوي:

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

که موږ په براوزر کې خلاص کړو example.com، موږ به د HTTPS ځواب ترلاسه کړو "سلام، نړۍ!"

که تاسو نور تفصیلي ترتیب ته اړتیا لرئ، نو تاسو باید د autocert.Manager مدیر وکاروئ. بیا موږ خپل د http.Server مثال جوړ کړو (تر دې چې موږ دا د ډیفالټ په توګه کاروو) او مدیر د 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("", "")

دا د اتوماتیک سند نوي کولو سره د بشپړ HTTPS ملاتړ پلي کولو لپاره اسانه لار ده.

د دودیزو لارو اضافه کول

په معیاري کتابتون کې شامل ډیفالټ روټر ښه دی، مګر دا خورا بنسټیز دی. ډیری غوښتنلیکونه ډیر پیچلي روټینګ ته اړتیا لري، پشمول د نیسټډ او وائلډ کارډ لارې، یا د لارې نمونو او پیرامیټونو ترتیبولو لپاره کړنلاره.

پدې حالت کې دا د کڅوړو کارولو ارزښت لري ګوریلا/مکس и go-chi/chi. موږ به زده کړو چې څنګه د وروستي سره کار وکړو - یو مثال لاندې ښودل شوی.

د api/v1/api.go فایل ورکړل شوی چې زموږ د 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
}

موږ په اصلي فایل کې د لارو لپاره د api/vq مختګ ترتیب کړ.

بیا موږ کولی شو دا زموږ اصلي روټر ته د api/v1/ مخکیني لاندې زموږ اصلي غوښتنلیک کې نصب کړو:

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

د پیچلو لارو سره د کار کولو اسانتیا د دې امکان رامینځته کوي چې د لوی ، پیچلي غوښتنلیکونو جوړښت او ساتنه ساده کړي.

د منځني وسایلو سره کار کول

سټیګینګ کې د یو HTTP هینډلر له بل سره پوښل شامل دي، دا ممکنه کوي چې ژر تر ژره تصدیق، کمپریشن، لاګنګ، او یو شمیر نورې دندې ترسره کړي.

د مثال په توګه، راځئ چې د http.Handler انٹرفیس وګورو؛ موږ به دا د یو هینډلر لیکلو لپاره وکاروو چې د خدماتو کاروونکو تصدیق کوي.

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

د دریمې ډلې روټرونه شتون لري، لکه chi، چې تاسو ته اجازه درکوي د منځني وییر فعالیت پراخ کړئ.

د جامد فایلونو سره کار کول

د Go معیاري کتابتون کې د جامد مینځپانګې سره د کار کولو وړتیاوې شاملې دي ، پشمول د عکسونو ، جاواسکریپټ او CSS فایلونو. دوی د http.FileServer فنکشن له لارې لاسرسی کیدی شي. دا یو هینډلر بیرته راګرځوي چې د ځانګړي لارښود څخه فایلونه خدمت کوي.

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

دا یقینا د یادولو وړ ده چې http.Dir د ډایرکټر مینځپانګې ښکاره کوي که چیرې اصلي index.html فایل نه وي. پدې حالت کې ، د دې لپاره چې لارښود له جوړیدو څخه مخنیوی وشي ، تاسو باید بسته وکاروئ unindexed.

سمه بندول

Go د HTTP سرور د زړه راښکونکي بند په نوم یو ځانګړتیا هم لري. دا د Shutdown() میتود په کارولو سره ترسره کیدی شي. سرور په ګوروټین کې پیل شوی ، او بیا چینل د مداخلې سیګنال ترلاسه کولو لپاره لیست شوی. هرڅومره ژر چې سیګنال ترلاسه شي ، سرور بندیږي ، مګر سمدستي نه ، مګر څو ثانیې وروسته.

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)

د پایلې په توګه

Go یوه پیاوړې ژبه ده چې نږدې نړیوال معیاري کتابتون لري. د دې ډیفالټ وړتیاوې خورا پراخه دي ، او دوی د انٹرفیسونو په کارولو سره وده کولی شي - دا تاسو ته اجازه درکوي واقعیا معتبر HTTP سرورونه رامینځته کړئ.

Skillbox وړاندیز کوي:

سرچینه: www.habr.com

Add a comment