podman

Форк
0
73 строки · 1.9 Кб
1
package handlers
2

3
import (
4
	"net/http"
5
	"net/url"
6
	"strings"
7
)
8

9
type canonical struct {
10
	h      http.Handler
11
	domain string
12
	code   int
13
}
14

15
// CanonicalHost is HTTP middleware that re-directs requests to the canonical
16
// domain. It accepts a domain and a status code (e.g. 301 or 302) and
17
// re-directs clients to this domain. The existing request path is maintained.
18
//
19
// Note: If the provided domain is considered invalid by url.Parse or otherwise
20
// returns an empty scheme or host, clients are not re-directed.
21
//
22
// Example:
23
//
24
//	r := mux.NewRouter()
25
//	canonical := handlers.CanonicalHost("http://www.gorillatoolkit.org", 302)
26
//	r.HandleFunc("/route", YourHandler)
27
//
28
//	log.Fatal(http.ListenAndServe(":7000", canonical(r)))
29
func CanonicalHost(domain string, code int) func(h http.Handler) http.Handler {
30
	fn := func(h http.Handler) http.Handler {
31
		return canonical{h, domain, code}
32
	}
33

34
	return fn
35
}
36

37
func (c canonical) ServeHTTP(w http.ResponseWriter, r *http.Request) {
38
	dest, err := url.Parse(c.domain)
39
	if err != nil {
40
		// Call the next handler if the provided domain fails to parse.
41
		c.h.ServeHTTP(w, r)
42
		return
43
	}
44

45
	if dest.Scheme == "" || dest.Host == "" {
46
		// Call the next handler if the scheme or host are empty.
47
		// Note that url.Parse won't fail on in this case.
48
		c.h.ServeHTTP(w, r)
49
		return
50
	}
51

52
	if !strings.EqualFold(cleanHost(r.Host), dest.Host) {
53
		// Re-build the destination URL
54
		dest := dest.Scheme + "://" + dest.Host + r.URL.Path
55
		if r.URL.RawQuery != "" {
56
			dest += "?" + r.URL.RawQuery
57
		}
58
		http.Redirect(w, r, dest, c.code)
59
		return
60
	}
61

62
	c.h.ServeHTTP(w, r)
63
}
64

65
// cleanHost cleans invalid Host headers by stripping anything after '/' or ' '.
66
// This is backported from Go 1.5 (in response to issue #11206) and attempts to
67
// mitigate malformed Host headers that do not match the format in RFC7230.
68
func cleanHost(in string) string {
69
	if i := strings.IndexAny(in, " /"); i != -1 {
70
		return in[:i]
71
	}
72
	return in
73
}
74

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.