From 15bba281ee36ff9af69aced1068a9fc6925a0a6b Mon Sep 17 00:00:00 2001
From: Ainar Garipov <a.garipov@adguard.com>
Date: Fri, 7 Apr 2023 14:21:37 +0300
Subject: [PATCH] Pull request 1807: upd-golibs

Merge in DNS/adguard-home from upd-golibs to master

Squashed commit of the following:

commit cde42a72c2140245f345681cbb936ed3bc4645a1
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Fri Apr 7 13:57:02 2023 +0300

    all: upd golibs, use hdrs
---
 go.mod                             |  2 +-
 go.sum                             |  4 ++--
 internal/aghhttp/aghhttp.go        |  5 +++--
 internal/aghhttp/header.go         | 18 +-----------------
 internal/dnsforward/http_test.go   |  3 ++-
 internal/home/auth.go              | 27 ++++++++++++++-------------
 internal/home/auth_test.go         | 25 +++++++++++++------------
 internal/home/control.go           |  9 +++++----
 internal/home/mobileconfig.go      |  5 +++--
 internal/next/websvc/json.go       |  5 +++--
 internal/next/websvc/middleware.go |  9 +++++++--
 scripts/translations/main.go       |  8 +++++---
 12 files changed, 59 insertions(+), 61 deletions(-)

diff --git a/go.mod b/go.mod
index 77fb014d..5b8c57f4 100644
--- a/go.mod
+++ b/go.mod
@@ -4,7 +4,7 @@ go 1.19
 
 require (
 	github.com/AdguardTeam/dnsproxy v0.48.3
-	github.com/AdguardTeam/golibs v0.13.1
+	github.com/AdguardTeam/golibs v0.13.2
 	github.com/AdguardTeam/urlfilter v0.16.1
 	github.com/NYTimes/gziphandler v1.1.1
 	github.com/ameshkov/dnscrypt/v2 v2.2.6
diff --git a/go.sum b/go.sum
index ff541d8d..7e93f138 100644
--- a/go.sum
+++ b/go.sum
@@ -2,8 +2,8 @@ github.com/AdguardTeam/dnsproxy v0.48.3 h1:h9xgDSmd1MqsPFNApyaPVXolmSTtzOWOcfWvP
 github.com/AdguardTeam/dnsproxy v0.48.3/go.mod h1:Y7g7jRTd/u7+KJ/QvnGI2PCE8vnisp6EsW47/Sz0DZw=
 github.com/AdguardTeam/golibs v0.4.0/go.mod h1:skKsDKIBB7kkFflLJBpfGX+G8QFTx0WKUzB6TIgtUj4=
 github.com/AdguardTeam/golibs v0.10.4/go.mod h1:rSfQRGHIdgfxriDDNgNJ7HmE5zRoURq8R+VdR81Zuzw=
-github.com/AdguardTeam/golibs v0.13.1 h1:x6ChoXk2jborbCWJ01TyBAEY3SilHts0SCG7yjnf6Sc=
-github.com/AdguardTeam/golibs v0.13.1/go.mod h1:7ylQLv2Lqsc3UW3jHoITynYk6Y1tYtgEMkR09ppfsN8=
+github.com/AdguardTeam/golibs v0.13.2 h1:BPASsyQKmb+b8VnvsNOHp7bKfcZl9Z+Z2UhPjOiupSc=
+github.com/AdguardTeam/golibs v0.13.2/go.mod h1:7ylQLv2Lqsc3UW3jHoITynYk6Y1tYtgEMkR09ppfsN8=
 github.com/AdguardTeam/gomitmproxy v0.2.0/go.mod h1:Qdv0Mktnzer5zpdpi5rAwixNJzW2FN91LjKJCkVbYGU=
 github.com/AdguardTeam/urlfilter v0.16.1 h1:ZPi0rjqo8cQf2FVdzo6cqumNoHZx2KPXj2yZa1A5BBw=
 github.com/AdguardTeam/urlfilter v0.16.1/go.mod h1:46YZDOV1+qtdRDuhZKVPSSp7JWWes0KayqHrKAFBdEI=
diff --git a/internal/aghhttp/aghhttp.go b/internal/aghhttp/aghhttp.go
index bde0112a..b5878f92 100644
--- a/internal/aghhttp/aghhttp.go
+++ b/internal/aghhttp/aghhttp.go
@@ -8,6 +8,7 @@ import (
 	"net/http"
 
 	"github.com/AdguardTeam/AdGuardHome/internal/version"
+	"github.com/AdguardTeam/golibs/httphdr"
 	"github.com/AdguardTeam/golibs/log"
 )
 
@@ -52,7 +53,7 @@ const textPlainDeprMsg = `using this api with the text/plain content-type is dep
 // deprecation and removal of a plain-text API if the request is made with the
 // "text/plain" content-type.
 func WriteTextPlainDeprecated(w http.ResponseWriter, r *http.Request) (isPlainText bool) {
-	if r.Header.Get(HdrNameContentType) != HdrValTextPlain {
+	if r.Header.Get(httphdr.ContentType) != HdrValTextPlain {
 		return false
 	}
 
@@ -72,7 +73,7 @@ func WriteJSONResponse(w http.ResponseWriter, r *http.Request, resp any) (err er
 // redefine the status code.
 func WriteJSONResponseCode(w http.ResponseWriter, r *http.Request, code int, resp any) (err error) {
 	w.WriteHeader(code)
-	w.Header().Set(HdrNameContentType, HdrValApplicationJSON)
+	w.Header().Set(httphdr.ContentType, HdrValApplicationJSON)
 	err = json.NewEncoder(w).Encode(resp)
 	if err != nil {
 		Error(r, w, http.StatusInternalServerError, "encoding resp: %s", err)
diff --git a/internal/aghhttp/header.go b/internal/aghhttp/header.go
index 0bfbcff2..eff50473 100644
--- a/internal/aghhttp/header.go
+++ b/internal/aghhttp/header.go
@@ -1,22 +1,6 @@
 package aghhttp
 
-// HTTP Headers
-
-// HTTP header name constants.
-//
-// TODO(a.garipov): Remove unused.
-const (
-	HdrNameAcceptEncoding           = "Accept-Encoding"
-	HdrNameAccessControlAllowOrigin = "Access-Control-Allow-Origin"
-	HdrNameAltSvc                   = "Alt-Svc"
-	HdrNameContentEncoding          = "Content-Encoding"
-	HdrNameContentType              = "Content-Type"
-	HdrNameOrigin                   = "Origin"
-	HdrNameServer                   = "Server"
-	HdrNameTrailer                  = "Trailer"
-	HdrNameUserAgent                = "User-Agent"
-	HdrNameVary                     = "Vary"
-)
+// HTTP headers
 
 // HTTP header value constants.
 const (
diff --git a/internal/dnsforward/http_test.go b/internal/dnsforward/http_test.go
index 144568d3..622f7cb8 100644
--- a/internal/dnsforward/http_test.go
+++ b/internal/dnsforward/http_test.go
@@ -18,6 +18,7 @@ import (
 	"github.com/AdguardTeam/AdGuardHome/internal/aghhttp"
 	"github.com/AdguardTeam/AdGuardHome/internal/aghnet"
 	"github.com/AdguardTeam/AdGuardHome/internal/filtering"
+	"github.com/AdguardTeam/golibs/httphdr"
 	"github.com/AdguardTeam/golibs/netutil"
 	"github.com/AdguardTeam/golibs/testutil"
 	"github.com/miekg/dns"
@@ -122,7 +123,7 @@ func TestDNSForwardHTTP_handleGetConfig(t *testing.T) {
 			s.conf = tc.conf()
 			s.handleGetConfig(w, nil)
 
-			cType := w.Header().Get(aghhttp.HdrNameContentType)
+			cType := w.Header().Get(httphdr.ContentType)
 			assert.Equal(t, aghhttp.HdrValApplicationJSON, cType)
 			assert.JSONEq(t, string(caseWant), w.Body.String())
 		})
diff --git a/internal/home/auth.go b/internal/home/auth.go
index 14d2f52b..7881a413 100644
--- a/internal/home/auth.go
+++ b/internal/home/auth.go
@@ -16,6 +16,7 @@ import (
 
 	"github.com/AdguardTeam/AdGuardHome/internal/aghhttp"
 	"github.com/AdguardTeam/golibs/errors"
+	"github.com/AdguardTeam/golibs/httphdr"
 	"github.com/AdguardTeam/golibs/log"
 	"github.com/AdguardTeam/golibs/netutil"
 	"github.com/AdguardTeam/golibs/timeutil"
@@ -379,9 +380,9 @@ func (a *Auth) newCookie(req loginJSON, addr string) (c *http.Cookie, err error)
 // TODO(a.garipov): Support header Forwarded from RFC 7329.
 func realIP(r *http.Request) (ip net.IP, err error) {
 	proxyHeaders := []string{
-		"CF-Connecting-IP",
-		"True-Client-IP",
-		"X-Real-IP",
+		httphdr.CFConnectingIP,
+		httphdr.TrueClientIP,
+		httphdr.XRealIP,
 	}
 
 	for _, h := range proxyHeaders {
@@ -394,7 +395,7 @@ func realIP(r *http.Request) (ip net.IP, err error) {
 
 	// If none of the above yielded any results, get the leftmost IP address
 	// from the X-Forwarded-For header.
-	s := r.Header.Get("X-Forwarded-For")
+	s := r.Header.Get(httphdr.XForwardedFor)
 	ipStrs := strings.SplitN(s, ", ", 2)
 	ip = net.ParseIP(ipStrs[0])
 	if ip != nil {
@@ -435,7 +436,7 @@ func handleLogin(w http.ResponseWriter, r *http.Request) {
 
 	if rateLimiter := Context.auth.raleLimiter; rateLimiter != nil {
 		if left := rateLimiter.check(remoteAddr); left > 0 {
-			w.Header().Set("Retry-After", strconv.Itoa(int(left.Seconds())))
+			w.Header().Set(httphdr.RetryAfter, strconv.Itoa(int(left.Seconds())))
 			aghhttp.Error(r, w, http.StatusTooManyRequests, "auth: blocked for %s", left)
 
 			return
@@ -463,9 +464,9 @@ func handleLogin(w http.ResponseWriter, r *http.Request) {
 	http.SetCookie(w, cookie)
 
 	h := w.Header()
-	h.Set("Cache-Control", "no-store, no-cache, must-revalidate, proxy-revalidate")
-	h.Set("Pragma", "no-cache")
-	h.Set("Expires", "0")
+	h.Set(httphdr.CacheControl, "no-store, no-cache, must-revalidate, proxy-revalidate")
+	h.Set(httphdr.Pragma, "no-cache")
+	h.Set(httphdr.Expires, "0")
 
 	aghhttp.OK(w)
 }
@@ -476,7 +477,7 @@ func handleLogout(w http.ResponseWriter, r *http.Request) {
 	if err != nil {
 		// The only error that is returned from r.Cookie is [http.ErrNoCookie].
 		// The user is already logged out.
-		respHdr.Set("Location", "/login.html")
+		respHdr.Set(httphdr.Location, "/login.html")
 		w.WriteHeader(http.StatusFound)
 
 		return
@@ -494,8 +495,8 @@ func handleLogout(w http.ResponseWriter, r *http.Request) {
 		SameSite: http.SameSiteLaxMode,
 	}
 
-	respHdr.Set("Location", "/login.html")
-	respHdr.Set("Set-Cookie", c.String())
+	respHdr.Set(httphdr.Location, "/login.html")
+	respHdr.Set(httphdr.SetCookie, c.String())
 	w.WriteHeader(http.StatusFound)
 }
 
@@ -543,7 +544,7 @@ func optionalAuthThird(w http.ResponseWriter, r *http.Request) (mustAuth bool) {
 			log.Debug("auth: redirected to login page by GL-Inet submodule")
 		} else {
 			log.Debug("auth: redirected to login page")
-			w.Header().Set("Location", "/login.html")
+			w.Header().Set(httphdr.Location, "/login.html")
 			w.WriteHeader(http.StatusFound)
 		}
 	} else {
@@ -569,7 +570,7 @@ func optionalAuth(
 				// Redirect to the dashboard if already authenticated.
 				res := Context.auth.checkSession(cookie.Value)
 				if res == checkSessionOK {
-					w.Header().Set("Location", "/")
+					w.Header().Set(httphdr.Location, "/")
 					w.WriteHeader(http.StatusFound)
 
 					return
diff --git a/internal/home/auth_test.go b/internal/home/auth_test.go
index 46767f7d..379d3fc5 100644
--- a/internal/home/auth_test.go
+++ b/internal/home/auth_test.go
@@ -12,6 +12,7 @@ import (
 	"testing"
 	"time"
 
+	"github.com/AdguardTeam/golibs/httphdr"
 	"github.com/AdguardTeam/golibs/testutil"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
@@ -135,11 +136,11 @@ func TestAuthHTTP(t *testing.T) {
 	handlerCalled = false
 	handler2(&w, &r)
 	assert.Equal(t, http.StatusFound, w.statusCode)
-	assert.NotEmpty(t, w.hdr.Get("Location"))
+	assert.NotEmpty(t, w.hdr.Get(httphdr.Location))
 	assert.False(t, handlerCalled)
 
 	// go to login page
-	loginURL := w.hdr.Get("Location")
+	loginURL := w.hdr.Get(httphdr.Location)
 	r.URL = &url.URL{Path: loginURL}
 	handlerCalled = false
 	handler2(&w, &r)
@@ -153,13 +154,13 @@ func TestAuthHTTP(t *testing.T) {
 	// get /
 	handler2 = optionalAuth(handler)
 	w.hdr = make(http.Header)
-	r.Header.Set("Cookie", cookie.String())
+	r.Header.Set(httphdr.Cookie, cookie.String())
 	r.URL = &url.URL{Path: "/"}
 	handlerCalled = false
 	handler2(&w, &r)
 	assert.True(t, handlerCalled)
 
-	r.Header.Del("Cookie")
+	r.Header.Del(httphdr.Cookie)
 
 	// get / with basic auth
 	handler2 = optionalAuth(handler)
@@ -169,28 +170,28 @@ func TestAuthHTTP(t *testing.T) {
 	handlerCalled = false
 	handler2(&w, &r)
 	assert.True(t, handlerCalled)
-	r.Header.Del("Authorization")
+	r.Header.Del(httphdr.Authorization)
 
 	// get login page with a valid cookie - we're redirected to /
 	handler2 = optionalAuth(handler)
 	w.hdr = make(http.Header)
-	r.Header.Set("Cookie", cookie.String())
+	r.Header.Set(httphdr.Cookie, cookie.String())
 	r.URL = &url.URL{Path: loginURL}
 	handlerCalled = false
 	handler2(&w, &r)
-	assert.NotEmpty(t, w.hdr.Get("Location"))
+	assert.NotEmpty(t, w.hdr.Get(httphdr.Location))
 	assert.False(t, handlerCalled)
-	r.Header.Del("Cookie")
+	r.Header.Del(httphdr.Cookie)
 
 	// get login page with an invalid cookie
 	handler2 = optionalAuth(handler)
 	w.hdr = make(http.Header)
-	r.Header.Set("Cookie", "bad")
+	r.Header.Set(httphdr.Cookie, "bad")
 	r.URL = &url.URL{Path: loginURL}
 	handlerCalled = false
 	handler2(&w, &r)
 	assert.True(t, handlerCalled)
-	r.Header.Del("Cookie")
+	r.Header.Del(httphdr.Cookie)
 
 	Context.auth.Close()
 }
@@ -213,7 +214,7 @@ func TestRealIP(t *testing.T) {
 	}, {
 		name: "success_proxy",
 		header: http.Header{
-			textproto.CanonicalMIMEHeaderKey("X-Real-IP"): []string{"1.2.3.5"},
+			textproto.CanonicalMIMEHeaderKey(httphdr.XRealIP): []string{"1.2.3.5"},
 		},
 		remoteAddr: remoteAddr,
 		wantErrMsg: "",
@@ -221,7 +222,7 @@ func TestRealIP(t *testing.T) {
 	}, {
 		name: "success_proxy_multiple",
 		header: http.Header{
-			textproto.CanonicalMIMEHeaderKey("X-Forwarded-For"): []string{
+			textproto.CanonicalMIMEHeaderKey(httphdr.XForwardedFor): []string{
 				"1.2.3.6, 1.2.3.5",
 			},
 		},
diff --git a/internal/home/control.go b/internal/home/control.go
index 6e79b8b1..3f654b3c 100644
--- a/internal/home/control.go
+++ b/internal/home/control.go
@@ -13,6 +13,7 @@ import (
 	"github.com/AdguardTeam/AdGuardHome/internal/aghnet"
 	"github.com/AdguardTeam/AdGuardHome/internal/dnsforward"
 	"github.com/AdguardTeam/AdGuardHome/internal/version"
+	"github.com/AdguardTeam/golibs/httphdr"
 	"github.com/AdguardTeam/golibs/log"
 	"github.com/AdguardTeam/golibs/netutil"
 	"github.com/NYTimes/gziphandler"
@@ -229,7 +230,7 @@ func modifiesData(m string) (ok bool) {
 func ensureContentType(w http.ResponseWriter, r *http.Request) (ok bool) {
 	const statusUnsup = http.StatusUnsupportedMediaType
 
-	cType := r.Header.Get(aghhttp.HdrNameContentType)
+	cType := r.Header.Get(httphdr.ContentType)
 	if r.ContentLength == 0 {
 		if cType == "" {
 			return true
@@ -337,7 +338,7 @@ func handleHTTPSRedirect(w http.ResponseWriter, r *http.Request) (ok bool) {
 	// default is 24 hours.
 	if serveHTTP3 {
 		altSvc := fmt.Sprintf(`h3=":%d"`, portHTTPS)
-		respHdr.Set(aghhttp.HdrNameAltSvc, altSvc)
+		respHdr.Set(httphdr.AltSvc, altSvc)
 	}
 
 	if r.TLS == nil && web.forceHTTPS {
@@ -367,8 +368,8 @@ func handleHTTPSRedirect(w http.ResponseWriter, r *http.Request) (ok bool) {
 		Host:   r.Host,
 	}
 
-	respHdr.Set(aghhttp.HdrNameAccessControlAllowOrigin, originURL.String())
-	respHdr.Set(aghhttp.HdrNameVary, aghhttp.HdrNameOrigin)
+	respHdr.Set(httphdr.AccessControlAllowOrigin, originURL.String())
+	respHdr.Set(httphdr.Vary, httphdr.Origin)
 
 	return true
 }
diff --git a/internal/home/mobileconfig.go b/internal/home/mobileconfig.go
index e2f7283f..8d9deb56 100644
--- a/internal/home/mobileconfig.go
+++ b/internal/home/mobileconfig.go
@@ -11,6 +11,7 @@ import (
 	"github.com/AdguardTeam/AdGuardHome/internal/aghhttp"
 	"github.com/AdguardTeam/AdGuardHome/internal/dnsforward"
 	"github.com/AdguardTeam/golibs/errors"
+	"github.com/AdguardTeam/golibs/httphdr"
 	"github.com/AdguardTeam/golibs/log"
 	"github.com/google/uuid"
 	"howett.net/plist"
@@ -170,7 +171,7 @@ func handleMobileConfig(w http.ResponseWriter, r *http.Request, dnsp string) {
 		return
 	}
 
-	w.Header().Set("Content-Type", "application/xml")
+	w.Header().Set(httphdr.ContentType, "application/xml")
 
 	const (
 		dohContDisp = `attachment; filename=doh.mobileconfig`
@@ -182,7 +183,7 @@ func handleMobileConfig(w http.ResponseWriter, r *http.Request, dnsp string) {
 		contDisp = dotContDisp
 	}
 
-	w.Header().Set("Content-Disposition", contDisp)
+	w.Header().Set(httphdr.ContentDisposition, contDisp)
 
 	_, _ = w.Write(mobileconfig)
 }
diff --git a/internal/next/websvc/json.go b/internal/next/websvc/json.go
index fa2010a8..f7622b63 100644
--- a/internal/next/websvc/json.go
+++ b/internal/next/websvc/json.go
@@ -8,6 +8,7 @@ import (
 	"time"
 
 	"github.com/AdguardTeam/AdGuardHome/internal/aghhttp"
+	"github.com/AdguardTeam/golibs/httphdr"
 	"github.com/AdguardTeam/golibs/log"
 )
 
@@ -99,8 +100,8 @@ func writeJSONOKResponse(w http.ResponseWriter, r *http.Request, v any) {
 func writeJSONResponse(w http.ResponseWriter, r *http.Request, v any, code int) {
 	// TODO(a.garipov): Put some of these to a middleware.
 	h := w.Header()
-	h.Set(aghhttp.HdrNameContentType, aghhttp.HdrValApplicationJSON)
-	h.Set(aghhttp.HdrNameServer, aghhttp.UserAgent())
+	h.Set(httphdr.ContentType, aghhttp.HdrValApplicationJSON)
+	h.Set(httphdr.Server, aghhttp.UserAgent())
 
 	w.WriteHeader(code)
 
diff --git a/internal/next/websvc/middleware.go b/internal/next/websvc/middleware.go
index c87c57d5..c5a5e999 100644
--- a/internal/next/websvc/middleware.go
+++ b/internal/next/websvc/middleware.go
@@ -1,13 +1,18 @@
 package websvc
 
-import "net/http"
+import (
+	"net/http"
+
+	"github.com/AdguardTeam/AdGuardHome/internal/aghhttp"
+	"github.com/AdguardTeam/golibs/httphdr"
+)
 
 // Middlewares
 
 // jsonMw sets the content type of the response to application/json.
 func jsonMw(h http.Handler) (wrapped http.HandlerFunc) {
 	f := func(w http.ResponseWriter, r *http.Request) {
-		w.Header().Set("Content-Type", "application/json")
+		w.Header().Set(httphdr.ContentType, aghhttp.HdrValApplicationJSON)
 
 		h.ServeHTTP(w, r)
 	}
diff --git a/scripts/translations/main.go b/scripts/translations/main.go
index a555be19..683f2be7 100644
--- a/scripts/translations/main.go
+++ b/scripts/translations/main.go
@@ -20,9 +20,11 @@ import (
 	"sync"
 	"time"
 
+	"github.com/AdguardTeam/AdGuardHome/internal/aghhttp"
 	"github.com/AdguardTeam/AdGuardHome/internal/aghio"
 	"github.com/AdguardTeam/AdGuardHome/internal/aghos"
 	"github.com/AdguardTeam/golibs/errors"
+	"github.com/AdguardTeam/golibs/httphdr"
 	"github.com/AdguardTeam/golibs/log"
 	"golang.org/x/exp/maps"
 	"golang.org/x/exp/slices"
@@ -491,10 +493,10 @@ func prepareMultipartMsg(
 	}()
 
 	h := make(textproto.MIMEHeader)
-	h.Set("Content-Type", "application/json")
+	h.Set(httphdr.ContentType, aghhttp.HdrValApplicationJSON)
 
 	d := fmt.Sprintf("form-data; name=%q; filename=%q", "file", defaultBaseFile)
-	h.Set("Content-Disposition", d)
+	h.Set(httphdr.ContentDisposition, d)
 
 	fw, err = w.CreatePart(h)
 	if err != nil {
@@ -523,7 +525,7 @@ func send(uriStr, cType string, buf *bytes.Buffer) (err error) {
 		return fmt.Errorf("bad request: %w", err)
 	}
 
-	req.Header.Set("Content-Type", cType)
+	req.Header.Set(httphdr.ContentType, cType)
 
 	resp, err := client.Do(req)
 	if err != nil {