Skip to content

Go حزمة http

حزمة net/http في المكتبة القياسية للغة Go ممتازة جداً، وتوفر تنفيذاً كاملاً جداً لعميل وخادم HTTP، ويمكن من خلال بضعة أسطر من الكود فقط بناء خادم HTTP بسيط جداً.

جميع أطر عمل الويب في لغة Go تقريباً هي تغليف وتعديل لحزمة http الموجودة، لذلك يُنصح بشدة بإتقان حزمة http قبل تعلم أطر العمل الأخرى.

مثال Get

لن يتم تكرار المعرفة المتعلقة بـ Http هنا، إذا كنت تريد معرفة المزيد يمكنك البحث في بايدو.

go
func main() {
  resp, err := http.Get("https://baidu.com")
  if err != nil {
    fmt.Println(err)
    return
  }
  defer resp.Body.Close()
  content, err := io.ReadAll(resp.Body)
  fmt.Println(string(content))
}

من خلال استدعاء الدوال تحت حزمة Http مباشرة يمكن بدء طلب بسيط، وسيُرجع مؤشراً وخطأ، ويجب إغلاقه يدوياً بعد الاستدعاء.

مثال Post

go
func main() {
   person := Person{
      UserId:   "120",
      Username: "jack",
      Age:      18,
      Address:  "usa",
   }

   json, _ := json.Marshal(person)
   reader := bytes.NewReader(json)

   resp, err := http.Post("https://golang.org", "application/json;charset=utf-8", reader)
   if err != nil {
      fmt.Println(err)
   }
   defer resp.Body.Close()
}

العميل

في الظروف العادية، لن نستخدم الطرق المذكورة أعلاه مباشرة، بل سنقوم بتكوين عميل بأنفسنا لتحقيق متطلبات أكثر دقة. سيستخدم هذا البنية http.Client{}، وإجمالي عناصر التكوين المتاحة أربعة:

  • Transport: تكوين عناصر التكوين المتعلقة بنقل بيانات عميل Http، إذا لم يكن موجوداً يُستخدم الاستراتيجية الافتراضية
  • Timeout: تكوين وقت انتهاء الطلب
  • Jar: تكوين متعلق بـ Cookie
  • CheckRedirect: تكوين إعادة التوجيه

مثال بسيط

go
func main() {
  client := &http.Client{}
  request, _ := http.NewRequest("GET", "https://golang.org", nil)
  resp, _ := client.Do(request)
  defer resp.Body.Close()
}

إضافة header

go
func main() {
   client := &http.Client{}
   request, _ := http.NewRequest("GET", "https://golang.org", nil)
   request.Header.Add("Authorization","123456")
   resp, _ := client.Do(request)
   defer resp.Body.Close()
}

بعض التكوينات التفصيلية لن يتم تكرارها هنا، يرجى التعرف عليها بنفسك.

الخادم

بالنسبة لـ Go، إنشاء خادم http يتطلب سطر كود واحد فقط.

المعامل الأول هو العنوان المراد الاستماع إليه، والمعامل الثاني هو المعالج، إذا كان فارغاً يُستخدم المعالج الافتراضي. في معظم الحالات يكفي استخدام المعالج الافتراضي DefaultServeMux.

go
http.ListenAndServe("localhost:8080", nil)

تخصيص

بالطبع يمكن أيضاً تكوين خادم مخصص

go
func main() {
   server := &http.Server{
      Addr:              ":8080",
      Handler:           nil,
      TLSConfig:         nil,
      ReadTimeout:       0,
      ReadHeaderTimeout: 0,
      WriteTimeout:      0,
      IdleTimeout:       0,
      MaxHeaderBytes:    0,
      TLSNextProto:      nil,
      ConnState:         nil,
      ErrorLog:          nil,
      BaseContext:       nil,
      ConnContext:       nil,
   }
   server.ListenAndServe()
}

بعض التكوينات التفصيلية يرجى التعرف عليها بنفسك.

التوجيه

أولاً يجب تعريف هيكل مخصص يُنفذ الطريقة ServeHTTP(ResponseWriter, *Request) في واجهة Handler، ثم استدعاء الدالة http.handle()

go
func main() {
   http.Handle("/index", &MyHandler{})
   http.ListenAndServe(":8080", nil)
}

type MyHandler struct {
}

func (h *MyHandler) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
   fmt.Println("my implement")
}

لكن في كل مرة يجب تعريف هيكل مخصص سيكون ذلك مملّاً، يمكن أيضاً استخدام الدالة http.handlerFunc مباشرة، نحتاج فقط لكتابة دالة المعالجة، وبالتالي لا نحتاج لإنشاء هيكل. داخلياً يُستخدم نوع المحول HandlerFunc، ونوع HandlerFunc هو محول يسمح باستخدام الدوال العادية كمعالجات لـ HTTP. إذا كانت f دالة ذات توقيع مناسب، فإن HandlerFunc(f) هي Handler الذي يستدعي f.

go
func main() {
   http.HandleFunc("/index", func(responseWriter http.ResponseWriter, request *http.Request) {
      fmt.Println(responseWriter, "index")
   })
   http.ListenAndServe(":8080", nil)
}

ServerMux هو الهيكل الأساسي، وينفذ الطرق الأساسية، وDefaultServeMux هو المثيل الافتراضي.

الوكيل العكسي

توفر حزمة http وظيفة وكيل عكسي جاهزة للاستخدام

go
func main() {
   http.HandleFunc("/forward", func(writer http.ResponseWriter, request *http.Request) {
      director := func(request *http.Request) {
         request.URL.Scheme = "https"
         request.URL.Host = "golang.org"
         request.URL.Path = "index"
      }

      proxy := httputil.ReverseProxy{Director: director}
      proxy.ServeHTTP(writer, request)

   })

   http.ListenAndServe(":8080", nil)
}

الكود أعلاه سيُحوّل جميع الطلبات إلى https://golang.org/index.

Golang تم تحريره بواسطة www.golangdev.cn