Skip to content

Пакет http в Go

Пакет 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()
}

Добавление заголовка

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-сервера требует всего одной строки кода.

Первый параметр — адрес прослушивания, второй параметр — обработчик, если он равен nil, используется обработчик по умолчанию. В большинстве случаев достаточно использовать обработчик по умолчанию 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.HandleFunc, где нужно написать только функцию обработки, не создавая структуру. Внутри используется тип адаптера 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 by www.golangdev.cn edit