cpp

Веб-сервер на Go. Отправка статических файлов

Оправить содержимое статического файла позволяет функция ServeFile() из пакета net/http. Формат функции:

http.ServeFile(w http.ResponseWriter, r *http.Request, name string)

В третьем параметре указывается абсолютный или относительный путь. При этом пути, содержащие фрагмент .., будут отклоняться в целях безопасности. Если r.URL.Path заканчивается фрагментом /index.html, то запрос перенаправляется на путь без index.html. В остальных случаях значение r.URL.Path не используется. Программист должен самостоятельно сформировать название файла и указать его в третьем параметре функции ServeFile(), при этом подумав о безопасности.

Пример:

if r.URL.Path == "/file.txt" {
   http.ServeFile(rw, r, `C:\book\file.txt`)
   return
}

При вводе в адресной строке веб-браузера http://localhost:3000/file.txt получим содержимое файла C:\book\file.txt и следующие заголовки:

HTTP/1.1 200 OK
Accept-Ranges: bytes
Content-Length: 28
Content-Type: text/plain; charset=utf-8
Last-Modified: Mon, 11 Apr 2022 19:20:47 GMT
Server: MyServer 1.0
Date: Fri, 06 May 2022 19:56:30 GMT

Если файл не найден, то получим такие заголовки:

HTTP/1.1 404 Not Found
Content-Type: text/plain; charset=utf-8
Server: MyServer 1.0
X-Content-Type-Options: nosniff
Date: Fri, 06 May 2022 20:00:10 GMT
Content-Length: 19

Оправить содержимое статического файла позволяет также функция ServeContent() из пакета net/http. Формат функции:

http.ServeContent(w http.ResponseWriter, req *http.Request, name string,
                  modtime time.Time, content io.ReadSeeker)

В третьем параметре указывается название файла, в четвертом — дата изменения файла или нулевая дата, а в пятом — поток, из которого будут считываться данные, например, открытый для чтения файл. Функция корректно обрабатывает все заголовки. Если заголовок Content-Type не установлен, то функция автоматически определяет тип файла и отправляет соответствующий заголовок.

Пример:

http.HandleFunc("/file.txt",
   func(rw http.ResponseWriter, r *http.Request) {
      rw.Header().Add("Server", "MyServer 1.0")
      p := `C:\book\file.txt`
      file, err := os.Open(p)
      if err != nil {
         rw.Header()["Date"] = nil
         http.Error(rw, "Ошибка 404. Файл не найден", 404)
         return
      }
      defer file.Close()
      info, err := file.Stat()
      if err != nil {
         rw.Header()["Date"] = nil
         http.Error(rw, "Ошибка 404. Файл не найден", 404)
         return
      }
      rw.Header().Add("Content-Type", "text/plain; charset=UTF-8")
      http.ServeContent(rw, r, p, info.ModTime(), file)
   })

При вводе в адресной строке веб-браузера http://localhost:3000/file.txt получим содержимое файла C:\book\file.txt и следующие заголовки:

HTTP/1.1 200 OK
Accept-Ranges: bytes
Content-Length: 28
Content-Type: text/plain; charset=UTF-8
Last-Modified: Mon, 11 Apr 2022 19:20:47 GMT
Server: MyServer 1.0
Date: Sat, 07 May 2022 18:10:37 GMT

Если мы обновим страницу, то заголовки будут уже другими, т. к. браузер выполнил кеширование содержимого файла:

HTTP/1.1 304 Not Modified
Last-Modified: Mon, 11 Apr 2022 19:20:47 GMT
Server: MyServer 1.0
Date: Sat, 07 May 2022 18:19:37 GMT

Если мы изменим содержимое файла, то файл опять будет загружаться с сервера:

HTTP/1.1 200 OK
Accept-Ranges: bytes
Content-Length: 42
Content-Type: text/plain; charset=UTF-8
Last-Modified: Sat, 07 May 2022 18:21:13 GMT
Server: MyServer 1.0
Date: Sat, 07 May 2022 18:21:50 GMT

Если статических файлов много, то лучше поместить их в одном каталоге, например, с названием static. Загрузить любые файлы из этого каталога и автоматически отправить их браузеру позволяет функция FileServer() из пакета net/http. Формат функции:

http.FileServer(root http.FileSystem) http.Handler

Указать каталог, из которого будут загружаться файлы, позволяет тип Dir из пакета net/http. Объявление типа:

type Dir string
(http.Dir).Open(name string) (http.File, error)

Чтобы ограничить загрузку статических файлов, следует в URL-адресе добавить префикс /static. При передаче строки запроса в функцию FileServer() этот префикс нужно удалить. Удалить префикс позволяет функция StripPrefix() из пакета net/http. Формат функции:

http.StripPrefix(prefix string, h http.Handler) http.Handler

Пример:

http.Handle("/static/", http.StripPrefix("/static",
                        http.FileServer(http.Dir(`C:\book\static\`))))

Давайте создадим каталог C:\book\static\ и поместим в него какие-либо файлы. Теперь в адресной строке браузера вводим: http://localhost:3000/static/. В результате отобразится список всех файлов и каталогов, расположенных внутри каталога C:\book\static\. Каждое название является ссылкой, при переходе по которой ресурс отобразится в окне браузера. Мы можем напрямую запрашивать какой-либо файл, например: http://localhost:3000/static/file.txt. Если файл не найден, то отобразится страница с ошибкой 404.

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

Реквизиты

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

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

cpp