cpp

Веб-сервер на Go. Функция Handle()

Функция Handle() из пакета net/http позволяет назначить обработчики для запросов, соответствующих шаблону. Формат функции:

http.Handle(pattern string, handler http.Handler)

В первом параметре указывается строка с шаблоном запроса. Если указан символ /, то будут перехватываться все запросы, для которых нет других зарегистрированных обработчиков. Если шаблон заканчивается символом /, то он будет перехватывать все вложенные запросы. Например, если указан шаблон /contact/, то при запросах http://localhost:3000/contact/ и http://localhost:3000/contact/test.php будет вызван один и тот же обработчик. Причем, если запрос указан без завершающего слеша (/contact), то будет выполнено перенаправление на /contact/:

HTTP/1.1 301 Moved Permanently
Content-Type: text/html; charset=utf-8
Location: /contact/
Date: Fri, 06 May 2022 18:38:19 GMT
Content-Length: 44

При использовании функции Handle() нужно передать значение nil во втором параметре функции ListenAndServe():

fmt.Println(http.ListenAndServe(":3000", nil))

Переделаем код из листинга 20.2 и используем функцию Handle() (листинг 20.3).

Листинг 20.3. Функция Handle()

package main

import (
   "fmt"
   "net/http"
)

type ContactHandler struct{}
func (h ContactHandler) ServeHTTP(rw http.ResponseWriter, 
                                  r *http.Request) {
   // Запрос http://localhost:3000/contact/
   rw.Header().Add("Server", "MyServer 1.0")
   rw.Header().Add("Content-Type", "text/html; charset=UTF-8")
   fmt.Fprintln(rw, "Страница", r.URL.Path)
}

type MyHandler struct{}
func (h MyHandler) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
   rw.Header().Add("Server", "MyServer 1.0")
   // Запрос http://localhost:3000/
   if r.URL.Path == "/" && r.Method == "GET" {
      rw.Header().Add("Content-Type", "text/html; charset=UTF-8")
      fmt.Fprintln(rw, "Страница /")
      return
   }
   // Ошибка 404 (страница не найдена)
   rw.Header()["Date"] = nil
   // http.NotFound(rw, r)
   http.Error(rw, "Ошибка 404. Страница не найдена", 404)
}

func main() {
   http.Handle("/", new(MyHandler))
   http.Handle("/contact/", new(ContactHandler))
   fmt.Println(http.ListenAndServe(":3000", nil))
}

Учебник Go (Golang)
Учебник Go (Golang) в формате PDF