/
Stormcoder
/
snippetbox
Обзор
Документация
Войти
/
Stormcoder
/
snippetbox
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
develop
cmd/web/main.go
94 строки
4 KB
steryaev
Внедрение зависимостей в Golang (Dependency Injection)
01 окт 2025, 17:02
01 окт 2025, 17:02
ce94643
Код
Авторство
О чём код?
package main import ( "flag" "log" "net/http" "os" "path/filepath" ) // Создаем структуру `application` для хранения зависимостей всего веб-приложения. // Пока, что мы добавим поля только для двух логгеров, но // мы будем расширять данную структуру по мере усложнения приложения. type application struct { errorLog *log.Logger infoLog *log.Logger } func main() { address := flag.String("addr", ":4000", "Сетевой адрес HTTP") staticDir := flag.String("static-dir", "./ui/static", "Путь к статическим файлам") flag.Parse() // Используйте log.New() для создания логгера для записи информационных сообщений. Для этого нужно // три параметра: место назначения для записи логов (os.Stdout), строка // с префиксом сообщения (INFO или ERROR) и флаги, указывающие, какая // дополнительная информация будет добавлена. Обратите внимание, что флаги // соединяются с помощью оператора OR |. infoLog := log.New(os.Stdout, "INFO\t", log.Ldate|log.Ltime|log.Lmicroseconds|log.Lmsgprefix) f, err := os.OpenFile("logs/info.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) if err != nil { log.Fatal(err) } defer f.Close() // Создаем логгер для записи сообщений об ошибках таким же образом, но используем stderr как // место для записи и используем флаг log.Lshortfile для включения в лог // названия файла и номера строки где обнаружилась ошибка. errorLog := log.New(f, "ERROR\t", log.Ldate|log.Ltime|log.Lmicroseconds|log.Llongfile) app := &application{errorLog: errorLog, infoLog: infoLog} mux := http.NewServeMux() mux.HandleFunc("/", app.home) mux.HandleFunc("/snippet", app.showSnippet) mux.HandleFunc("/snippet/create", app.createSnippet) fileServer := http.FileServer(neuteredFileSystem{http.Dir(*staticDir)}) mux.Handle("/static/", http.StripPrefix("/static", fileServer)) // Инициализируем новую структуру http.Server. Мы устанавливаем поля Addr и Handler, так // что сервер использует тот же сетевой адрес и маршруты, что и раньше, и назначаем // поле ErrorLog, чтобы сервер использовал наш логгер // при возникновении проблем. srv := &http.Server{ Addr: *address, ErrorLog: errorLog, Handler: mux, } infoLog.Printf("Запуск сервера на %s", *address) err = srv.ListenAndServe() errorLog.Fatal(err) } // Важным моментом является необходимость предоставить доступ к статическим файлам // для обеспечения функциональности, при этом сохранить необходимый уровень безопасности, // ограничив доступ к просмотру списка файлов в директориях, // а также доступ к директориям более высокого уровня type neuteredFileSystem struct { fs http.FileSystem } func (nfs neuteredFileSystem) Open(path string) (http.File, error) { f, err := nfs.fs.Open(path) if err != nil { return nil, err } s, err := f.Stat() if s.IsDir() { index := filepath.Join(path, "index.html") if _, err := nfs.fs.Open(index); err != nil { closeErr := f.Close() if closeErr != nil { return nil, closeErr } return nil, err } } return f, nil }