Обработка http.Request на Go

Подскажите, пожалуйста. Для роута во всех мануалах написан один и тот же код.

http.HandleFunc("/", hendler) // отдаем функции hendler
http.HandleFunc("/admin/", hendlerCMS) // отдаем функции hendlerCMS

Так вот, когда запрос http://domain/admin/, то выполняется две функции: и hendler, и hendlerCMS. Как же этого избежать?

2 ответа

Как всегда забыл про то, что у браузеров есть еще запрос на /favicon.ico, который заводит обрабочик на главную страницу. Сделав специальный обработчик

http.HandleFunc("/favicon.ico", favicon)

или если вы пользуетесь google app engine в файле app.yaml

- url: /favicon.ico static_files: static/images/favicon.ico upload: static/images/favicon.ico

все будет, как написано в мануале. Обработка будет происходить от длинного паттерна к короткому.


Вы можете написать свои собственные обработчики, которые будут использовать другой алгоритм соответствия, нежели простое сопоставление, например, регулярные выражения. За основу можно взять код обработчиков из исходников Go. Например:

type Match struct { regexp *regexp.Regexp handler http.Handler
}
type RegExpHandler struct { matches []*Match
}
func (reh *RegExpHandler) Handler(regexp *regexp.Regexp, handler http.Handler) { reh.matches = append(reh.matches, &Match{regexp, handler})
}
func (reh *RegExpHandler) HandleFunc(regexp *regexp.Regexp, handler func(http.ResponseWriter, *http.Request)) { reh.matches = append(reh.matches, &Match{regexp, http.HandlerFunc(handler)})
}
func (reh *RegExpHandler) ServeHTTP(writer http.ResponseWriter, reader *http.Request) { for _, match := range reh.matches { if match.regexp.MatchString(reader.URL.Path) { match.handler.ServeHTTP(writer, reader) return } } http.NotFound(writer, reader)
}

licensed under cc by-sa 3.0 with attribution.