cpp

Веб-сервер на Go. Маршрутизация

При использовании кода из листинга 20.1 при любом запросе мы получим один и тот же результат (кроме изменения даты):

http://localhost:3000/
http://localhost:3000/test
http://localhost:3000/contact
http://localhost:3000/favicon.ico

Согласитесь, что это неправильно. Чтобы вернуть разный результат для разных запросов нужно внутри метода ServeHTTP() обработать значение r.URL.Path. Кроме того, можно обработать метод отправки данных с помощью r.Method. В качестве примера обработаем запросы / и /contact, а для остальных запросов отправим ошибку 404 (страница не найдена) (листинг 20.2).

Листинг 20.2. Маршрутизация

package main

import (
   "fmt"
   "net/http"
   "time"
)

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, "Страница /<br>", h.String())
      return
   }
   // Запрос http://localhost:3000/contact
   if r.URL.Path == "/contact" && r.Method == "GET" {
      rw.Header().Add("Content-Type", "text/html; charset=UTF-8")
      fmt.Fprintln(rw, "Страница /contact<br>", h.String())
      return
   }
   // Ошибка 404 (страница не найдена)
   rw.Header()["Date"] = nil
   rw.WriteHeader(http.StatusNotFound)
   fmt.Fprintln(rw, "Ошибка 404. Страница не найдена")
}
func (h MyHandler) String() string {
   return time.Now().Format("02.01.2006 15:04:05")
}
func main() {
   handler := MyHandler{}
   fmt.Println(http.ListenAndServe(":3000", handler))
}

При запросе страницы http://localhost:3000/contact будут отправлены следующие заголовки:

HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Server: MyServer 1.0
Date: Fri, 06 May 2022 17:39:58 GMT
Content-Length: 50

Если страница не найдена, то будут отправлены следующие заголовки:

HTTP/1.1 404 Not Found
Server: MyServer 1.0
Content-Length: 55
Content-Type: text/plain; charset=utf-8

Функция NotFound() из пакета net/http позволяет автоматически отправить ответ с ошибкой 404. Формат функции:

http.NotFound(w http.ResponseWriter, r *http.Request)

Пример:

rw.Header()["Date"] = nil
http.NotFound(rw, r)

Если страница не найдена, то будут отправлены следующие заголовки:

HTTP/1.1 404 Not Found
Content-Type: text/plain; charset=utf-8
Server: MyServer 1.0
X-Content-Type-Options: nosniff
Content-Length: 19

В окне веб-браузера отобразится сообщение:

404 page not found

Для отображения страницы с описанием ошибки сервера можно воспользоваться функцией Error() из пакета net/http. Формат функции:

http.Error(w http.ResponseWriter, error string, code int)

Пример возврата ошибки 404:

rw.Header()["Date"] = nil
http.Error(rw, "Ошибка 404. Страница не найдена", 404)

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

Помощь сайту

ЮMoney (Yandex-деньги): 410011140483022

ПАО Сбербанк:
Счет: 40817810855006152256
Реквизиты банка:
Наименование: СЕВЕРО-ЗАПАДНЫЙ БАНК ПАО СБЕРБАНК
Корреспондентский счет: 30101810500000000653
БИК: 044030653
КПП: 784243001
ОКПО: 09171401
ОКОНХ: 96130
Скриншот реквизитов

cpp